Programming FAQ

From Ninerpedia
Revision as of 18:47, 13 October 2014 by Stephen Shaw (talk | contribs) (→‎What part of my code needs to be Pre-scanned?: remove duplicated data. See Extended BASIC)
Jump to navigation Jump to search

All I have is an E/A cartridge, what else do I need?

Unfortunately what you have is the near equivalent of the menu choices without content. Most the actual E/A programs and tools are on the two diskettes that came with cartridge. You will need to get copies of those diskettes and more than likely a copy of the manual.

The manual can be found WHTech FTP site. There are images of the diskettes there so you would need to get those copied to a diskette. If you are stuck and can't do that then contact someone on the Yahoo mailing list and see if they can send you a copy.

How can I access VDP memory directly?

Also see this article:Using VDP with BASIC

The recommended method for accessing VDP memory, be it a read or a write, is via the use of the BLWP (branch and load workspace pointer) instruction, specifiying one of the following vectors:

  • VSBW - VDP Single Byte Write
  • VSBR - VDP Single Byte Read
  • VMBW - VDP Multiple Byte Write
  • VMBR - VDP Multiple Byte Read

Whilst these routines work fine, they are rather slow, for two reasons:

  • The BLWP instruction is slow, as a context switch takes place
  • If you actually ever trace the VDP access routines, you will see that they are very long, and jump around all over the place (presumably to re-use code paths thus saving memory).

It is possible to read and write from/to VDP memory yourself, of course. The following routines will help you:

; vdp single byte read
; inputs: r0=address in vdp to read, r1(msb), the byte read from vdp 
; side effects: none 

vsbr swpb r0 
     movb r0,@vdpa 
     swpb r0 
     movb r0,@vdpa 
     nop 
; nop after specifiying address is mandatory
     movb @vdpr,r1 
     rt

; vdp multiple byte read 
; inputs: r0=vdp source address, r1=cpu ram destination address, r2=number of bytes to read
; side effects: none

vmbr swpb r0
     movb r0,@vdpa
     swpb r0
     movb r0,@vdpa
     nop
; nop after specifiying address is mandatory
vmbr1 movb @vdpr,*r1+
      dec r2
      jne vmbr1
      rt

; vdp single byte write 
; inputs: r0=address in vdp to write to, r1(msb)=the byte to write
; side effects: none

vsbw ori r0,>4000
     swpb r0
     movb r0,@vdpa
     swpb r0
     movb r0,@vdpa
     nop
; nop after specifiying address is mandatory 
     movb r1,@vdpw
     rt

; vdp multiple byte write
; r0=destination in vdp, r1=source address in cpu ram, r2=number of bytes to write
; side effects: none

vmbw ori r0,>4000
     swpb r0
     movb r0,@vdpa
     swpb r0
     movb r0,@vdpa
     nop
; nop after specifiying address is mandatory
vmbw1 movb *r1+,@vdpw
      dec r2
      jne vmbw1
      rt

; vdp write to vdp register
; inputs: r0(msb)=the register to write to, r0(lsb)=the value to write
; side effects: none

vwtr ori r0,>8000
     swpb r0
     movb r0,@vdpa
     swpb r0
     movb r0,@vdpa
     rt

These routines are the routines I use in my own code, and they mimic the behaviour of the original TI routines, only much much faster, through reduced length and increased efficiency. The routines are not mine, they are long established 'short cuts' known to many. Hope this helps.

How can I learn to program in Assembly language?

Hardware: TI-99/4a with 32K Memory Expansion and at least one floppy drive.

Software: The Editor/Assembler cartridge and the two floppies that come with it. However, FunnelWeb includes all of the essential software and is perhaps more convenient.

Texts: The Editor/Assembler User's Manual. This is an absolutely necessary reference but is not a beginner's guide for learning to program.

Also, an Introduction to Assembly Language that guides you through the process of writing A/L programs. One is by Ralph Molesworth and there are several others, equally good.

Programming: You use the Editor program to write A/L SOURCE code, save it to disk as a D/V80 file, and then use the Assembler program to assemble it into A/L OBJECT code which is in machine language. This is a D/F80 file, ready to run with the E/A Loader or from Extended BASIC if you wrote it for that.

There are four Modes for A/L programming and you choose the one that suits your purpose. The Graphics mode is the simplest, most generally useful mode and the one that is at hand when you start. Bit-map and Multicolor mode is for detailed screen graphics. Text mode is for text only, as in word processing.

Writing A/L programs is laborious and not easy to learn but the results are worth the effort. They are VERY fast and can do many things that are not practical with other languages.

Original information by John Bull. Original listing in TI FAQ by Dan Eicher.

How can I splice together source code from different files?

For the sake of organization you may have your code separated into different physical files. When it comes time to compile you would like to join those separated files together. This can be done via the COPY directive in E/A.

If you have three files (src1, src2, src3) you can join them together with the following syntax, replacing the 'x' with you drive number:

COPY "DSKx.src1"
COPY "DSKx.src2"
COPY "DSKx.src3"

Source: Yahoo List - Mark Wills, Bill Sullivan

How do I run Assembly programs from Extended BASIC?

To run from Extended Basic, an Assembly Language program must be written for that purpose or modified. X/B cannot use files created by the C (compressed) option of the Assembler. X/B can handle DEFs, but the address of utilities must be EQUated, as the loader of Extended Basic is no linking loader; it cannot handle REFs (E/A manual, section 24.4). For instance, a program written for the Editor/Assembler loaders might begin:

       DEF START
       REF STRASG,STRREF

For X/B this should be:

       DEF START
STRASG EQU >2010
STRREF EQU >2014

The list of EQUates for X/B is on pages 415 and 416 of the Editor/Assembler Manual. Modifying an E/A program to run from X/B is sometimes as simple as the above.

Please note, the E/A manual has a typo. Page 416 should read

NUMREF EQU >200C

Two ways you can run an A/L program from X/B: One is to put at the beginning of your X/B program:

10 CALL INIT 
20 CALL LOAD("DSKn.FILENAME")

where FILENAME is the file name of the A/L program.

Now the program is in memory and can be run with CALL LINK("START"), where START is the entry point as defined in the program.

Another way, more work but often more convenient, is to embed the assembly language program in your X/B program, where it will stay, ready to run, whenever you load the X/B program. There are two programs available to do the embedding: Harry Wilhelm's HML, High Memory Loader and Scott Kaplan's ALSAVE, which loads into low memory. HML is easier to use but will not work with very large X/B programs.

Whatever way you load the A/L program, it remains in memory until you do CALL INIT, or BYE and so it is available in other X/B programs that you RUN from the first one.

NOTE: Issuing a new from X/B will leave your A/L program in memory.

Original information by John Bull. Original listing in TI FAQ by Dan Eicher.

Is there an electronic copy of the E/A manual available?

Yes. On Whtech FTP you can find a PDF in the "Datasheets & Manuals" section and inside "Editor Assembler". The Quick Reference Guide is there as well.

Question by roundfilesilver and answr by Bill Sullivan.

What are bits in the Status Register?

The Status Register (SR) is a 2 byte or 2 word area where each individual bit represents some aspect of an instructions execution. Here is the break down:

Bit 00 - a compare was Less Than Bit 01 - a compare was Greater Than Bit 02 - a compare was Equal Bit 03 - means there was a Carry Bit 04 - means there was an Overflow Bit 05 - means Odd Parity Bit 06 - means Extended Operation Bit 07 - NOT USED Bit 08 - NOT USED Bit 09 - NOT USED Bit 10 - NOT USED Bit 11 - NOT USED Bit 12-15 - Interupt Mask

What are the different memory addressing modes in TI Assembler?

If you are new to assembler or new to it on the TI then some of the instructions you will see may look a little bit strange. Hopefully this can clear it up just a little bit.

There are five addressing modes for operands; depending on the command, the source operand, the destination operand, or both may be used in one of the following fives modes. The source operand is always the first operand.

Register Direct: This is the mode when you are moving data between or working with registers. A simple example would be moving a value from one register to the next. The key here is that the data itself is in the register.

MOV R1,R2 

Copies the word (two bytes) in register 1 into register 2. If register 1 contains the word >1234, register 2 now also contains >1234.

Register Indirect: This is the mode when you are working with a register that has the address of where some data is and not the data itself. Programming languages like C would call it a pointer. A simple example would be moving the data from one register to memory location indicated by another register.

MOV R1,*R2 

This puts the value of R1 into the memory location pointed to by R2. The "*" denotes that the contents of R2 shall be treated as the address of the destination memory location. If R1 contains the value >3456 and R2 contains the value >A030, the memory location >A030 will now contain the value >3456.

Register Indirect Auto Increment: This is the same as Register Indirect except that the value in the register is incremented after the completion of the command. Let's assume that there is chunk of memory set aside for data at the address of >B100 and R2 contains >B100. Now you want to store data there and use R2 as a pointer.

MOV R1,*R2+ 

This takes the word in R1 and stores it at the space pointed to by R2 (>B100) and then increments R2 to >B102. The increment is 2 for a word operation (2 bytes) and 1 for a byte operation.

This operand mode is typically used for memory block transfers where it usually appears in a loop. For instance, the following code copies the contents of one memory location to another:

       LI   R1,>A000
       LI   R2,>B000
       LI   R3,>1000
LOOP   MOV  *R1+,*R2+
       DECT R3
       JNE  LOOP

This code copies the contents of memory locations >A000->AFFF to locations >B000->BFFF. As we are using a word operation (MOV), we need to decrement our loop counter by two.

Symbolic Addressing: This mode is used to indicate that the operand is a memory location address. Let's say you want to get the data from the location >B100 and move it into R5:

MOV @>B100,R5

The "symbolic" nature of the mode is more obvious when labels are used. Let's assume that the label DOGS is set to the value >B100, then you can rephrase the last example as

MOV @DOGS,R5

Indexed Addressing: This is basically the same as symbolic addressing, except that you can use offsets. The offset is retrieved as the contents of a workspace register that is indicated is parenthesis after the address or the label. With this mode, arrays can be easily realized. Arrays have indices where you can say ARRAY[0] to mean the first location or ARRAY[1] to mean the second and so on. Let's keep going with data at memory locaton DOGS which has the value >B100.

The following lines should explain how the indexed addressing works. For each block, the LI command sets a value in the given register; the following two MOV operations have the same behaviour.

      LI   R2,>0000
      MOV  @DOGS(R2),R5 
      MOV  @DOGS,R5

      LI   R2,>0001
      MOV  @DOGS(R2),R5 
      MOV  @DOGS+1,R5

      LI   R2,>0024
      MOV  @DOGS(R2),R5 
      MOV  @DOGS+>0024,R5

      LI   R2,>FFFF
      MOV  @DOGS(R2),R5 
      MOV  @DOGS-1,R5

For a 16-bit system, adding the value >FFFF has the effect of subtracting 1. Compared to the symbolic addressing, the indexed addressing determines the result of the address calculation at runtime, not at compile time.

Important: You cannot use register 0 (R0) as index register, since the index register number is used to distinguish between symbolic addressing and indexed addressing within the opcode. A value different from 0 means indexed addressing.

What books are available for Assembly programming?

This list is not an exhaustive list. All that I have included are the books that I know are dedicated to Assembly. There are other books with sections or parts for Assembly.

  • Fundamentals of TI-99/4A Assembly Language by M.S. Morley
  • Learning TI 99/4A Home Computer Assembly Language Programming by Ira McComic
  • Compute's Beginner's Guide to Assembly Language on the TI-99/4A by Peter M. L. Lottrup
  • Beginning Assembly Language for the TI Home Computer by E.York & T.Inzana
  • Introduction to Assembly Language for the TI Home Computer by R.Molesworth

What registers are available to work with in Assembler?

The TMS9900, the CPU of the TI-99/4a, has 3 internal registers. There is a Program Counter, a Workspace Pointer and a Status Register. If you worked in assembly on other systems you will notice that there are no working registers. Don't worry, there are working registers but it's a little different.

The Program Counter (PC) contains the address of the next instruction to be executed.

The Workspace Pointer (WP) contains the address to a block of memory that contains the 16 words for your 16 working registers (R0 - R15). So yes, you do have working registers but they are not in the CPU.

The Status Register (SR) holds the result flags for the last instruction that was executed. These flags are individual bits that indicate the results of the last instruction.

Where can I find source code for the lower-case alphabet to use in my program?

The following set of DATA statements contain the alphabet in lower-case from a to z:

DATA >0000,>0030,>4848,>4834 
DATA >0040,>4040,>5864,>6458 
DATA >0000,>0038,>4440,>4438 
DATA >0004,>0404,>344C,>4C34
DATA >0000,>0038,>447C,>4038
DATA >0018,>2420,>7820,>2020
DATA >0000,>0038,>443C,>0438
DATA >0040,>4040,>5864,>4444
DATA >0000,>1000,>1010,>1038
DATA >0000,>0500,>0C05,>5538
DATA >0040,>4048,>5060,>5048
DATA >0010,>1010,>1010,>1018
DATA >0000,>0028,>5454,>5444
DATA >0000,>0058,>6444,>4444
DATA >0000,>0038,>5555,>5538
DATA >0000,>0078,>4478,>4040
DATA >0000,>003C,>443C,>0404
DATA >0000,>0058,>6440,>4040
DATA >0000,>003C,>5038,>043C
DATA >0010,>107C,>1010,>1010
DATA >0000,>0044,>4444,>4438
DATA >0000,>0044,>4444,>2810
DATA >0000,>0044,>5454,>6C44
DATA >0000,>0044,>2810,>2844
DATA >0000,>0044,>443C,>0438
DATA >0000,>007C,>0810,>207C

Original content from TI Yahoo List (Adam Haase, Mark Wills)

Why do I get an "I/O ERROR CODE 3" when assembling a program in Classic99?

Example:

* ASSEMBLER * 
SOURCE FILE NAME? DSK1.ESSAI
OBJECT FILE NAME? DSK1.ESSAIOBJ

When pressing ENTER at this point I get:

* ERROR * 
I/O ERROR CODE 3 
PRESS ENTER TO CONTINUE

Reason: Unfortunately classic99 does not work with the EA assembler today. The reason is that the disk emulation does not currently support update mode, which the assembler opens the output file in.

This problem was reported by Guillaume and answered by Tursi on the TI Mailing List.

What is GPL?

First of all GPL does not stand for GNU Public License, it stands for Graphics Programming Language. This is an internal, interpreted language for the TI that lies somewhere between XB and Assembler. With the GPL interpreter, TI built up a subsystem which may to some extent be called a "virtual machine".

GPL is closer to Assembler and in fact Extended Basic is mainly written in GPL. Because it is interpreted it does take a performance hit when compared to pure assembler. This is why the BASIC implemenation in the TI is so sluggish, it acutally gets interpreted twice.

Much more information about GPL is available at Theirry's TI Tech pages. You can find a link to Thierry's pages at: http://www.ti-994a.com/links.html

Anyone know the address for the VDP blank timer offhand?

>83D6

Screen time-out counter, decremented on each VDP interrupt. Screen blanks after the word reaches >0000. Upon new key detection, the word is reset.

When should someone use GPL rather than Assembler or other languages?

GPL is a good language to use in situations where the speed of assembly is not needed, but you have memory constraints. It requires no CPU memory, leaving this for your data.

GPL is much faster than other interpreted languages for the TI. It is about the same speed as TI Forth and UCSD Pascal, falling behind assembly and c99.

GPL provides excellent access to TI resources, including OS calls, transparent access to different memories (GROM, VDP, CPU), and easily interfaces to assembly routines.

It is best to utilize a GPL-assembly hybrid if you want to conserve space and produce a fast program. GPL can be used for the user interface and setup, with the time critical routines coded in assembly.

What are some good resources to learn about GPL and how to use/program it?

Note: TI never released a GPL assembler to the public domain. There have been several GPL assemblers released by others, with some slight differences in syntax.

  • Texas Instruments Graphics Programming Language User's Gude (1979)
  • User's Guide in Thierry Nouspikel's GPL assembler (TI Tech Pages)
  • The Weiand Assembler
  • RAG (R.A. Green) GPL assembler - documentation is TI's manual above

Basic programming

What are the different BASIC languages available for the TI-99/4a in both cartridge and disk form?

This is a tough one because there are many variations that are out there. As of today we have a pretty extensive list put together and it continues to be revised and updated. An entry on ti-994a.com has been created to reference and maintain this list.? You can find it at: http://www.ti-994a.com/wiki/pmwiki.php/TI/L003-Basic

Can I use a variable in the RUN command in an XB program?

Extended Basic does not allow variables in the RUN command, you will get an error. So the following would NOT work:

10 LET A$="DSK1." 
20 RUN A$&"PROGRAM"

The good news is that with a little help from Assembly you can accomplish this. The following is a snippet of code the replicates what is being tried above:

10 LET A$="DSK1." 
15 CALL LINK("RUN",20,A$&"PROGRAM") 
20 RUN "DSKX.XXXXXXXXXXXXXXX"

Line 15 is the magic line. The second parameter, "20", refers to the line number of the statement with the RUN command. The third parameter, A$&"PROGRAM", refers to the name of the file to be opened. This utility is very useful if you want to accept input from the user to drive the RUN command.

This entry came off of the Yahoo Mailing List (W.Bertsch).

Wolfgang Bertsch maintains a site called ErrorFree and can be found at: http://www.errorfree.de

How can I turn off Extended Memory so VDP RAM is used when loading a program?

There is a document which I have seen on the wht site which gives a variety of PEEKS and POKES used in XB. One of these turns off and another turns on the 32K memory expansion:

Turns Off

CALL LOAD(-31868,0,0) 

Turns On

CALL LOAD(-31868,255,231)

Be sure to include a CALL INIT.

Original content from TI Yahoo List (Stuart Conner, Jacques Groslouis)

How can I type something and have the TI say it with the Speech Synthesiser?

Also seen main article on Speech

If you are using the Speech Module or Extended Basic:

100 CALL SAY("#THAT IS INCORRECT#")
110 CALL SAY("#WHAT WAS THAT#")
120 CALL SAY("#YOU WIN#")
130 CALL SAY("#TEXAS INSTRUMENTS#")

If your are using Extended Basic and the Text-To-Speech disk:

1 CALL INIT
2 CALL TALKLOAD
3 LINPUT "PHRASE->":A$
4 CALL TALK(A$)
5 CALL CLEAR
6 GOTO 3
7 SUB TALKLOAD
8 CALL LOAD("DSK.ALPHA1.SPEAK","DSK.ALPHA1.XLAT","DSK.ALPHA1.SETUP")
9 CALL LINK("SETUP","DSK.ALPHA1.DATABASE")
10 SUBEND
11 SUB TALK(A$)
12 CALL LINK("XLAT",A$,B$)
13 CALL LINK("SPEAK",B$,43,128)
14 SUBEND

If your are using the TI Terminal Emulator II module and want to get real fancy:

100 REM DATE: 11/27/82
110 REM AUTHOR:Randy Learned
120 REM ADDRESS:P.O.Box 382 Eagle, Nebraska 68347
130 CALL CLEAR
140 OPEN #1:"SPEECH",OUTPUT
150 M$="ABE LINCOLN"
160 R=12
170 C=11
180 GOSUB 270
190 CALL CLEAR
200 M$="GETTYSBURG ADDRESS"
210 C=7
220 GOSUB 270
230 CALL CLEAR
240 M$="NOVEMBER 19, 1863"
250 GOSUB 270
260 GOTO 340
270 FOR I=1 TO LEN(M$)
280 CODE=ASC(SEG$(M$,I,1))
290 CALL HCHAR(R,C+I,CODE)
300 NEXT I
310 FOR I=1 TO 1000
320 NEXT I
330 RETURN
340 CALL CLEAR
350 CALL CHAR(133,"FDFEFFFF1EFB74F8")
360 CALL CHAR(134,"3FFFFFFFC1FE5DBE")
370 CALL CHAR(135,"0000000000000000")
380 CALL CHAR(136,"FFFF00FF7E8209AA")
390 CALL CHAR(144,"0018187E3C3C6600")
400 CALL CHAR(152,"FFFFFFFFFFFFFFFF")
410 CALL CHAR(153,"0000000000000000")
420 CALL COLOR(16,9,16)
430 CALL COLOR(15,1,16)
440 CALL SCREEN(6)
450 FOR I=1 TO 22 STEP 4
460 CALL HCHAR(I,1,152,64)
470 NEXT I
480 FOR I=3 TO 24 STEP 4
490 CALL HCHAR(I,1,153,64)
500 NEXT I
510 FOR I=1 TO 14
520 CALL COLOR(I,16,16)
530 NEXT I
540 FOR I=6 TO 17
550 CALL HCHAR(I,12,135,9)
560 NEXT I
570 CALL HCHAR(5,11,144,10)
580 CALL VCHAR(5,21,144,14)
590 CALL HCHAR(18,11,144,10)
600 CALL VCHAR(6,11,144,12)
610 RESTORE 680
620 READ CH,R,C,A$
630 IF CH=999 THEN 1380
640 CALL CHAR(CH,A$)
650 CALL HCHAR(R,C,CH)
660 GOTO 620
670 REM HEAD
680 DATA 33,7,14,"000003070F1F3F7F"
690 DATA 34,7,15,"00FFFFFFFFFFFFFF"
700 DATA 35,7,16,"7CFFFFFFFFFFFFFF"
710 DATA 37,7,17,"00F0F8FCFEFFFFFF"
720 DATA 38,8,13,"0001030307070707"
730 DATA 39,8,14,"FFFFFFFFFFFFFEE0"
740 DATA 40,8,15,"FFFFFFFFFFFF0100"
750 DATA 41,8,16,"FFFFFFFFFFFFFC00"
760 DATA 42,8,17,"FFFFFFFFE1000000"
770 DATA 43,8,18,"80FCFFFFFFFF7F3F"
780 DATA 45,8,19,"000080C0E0F0F8F8"
790 DATA 47,9,13,"0F0F0F0F1F1F1F1F"
800 DATA 48,9,14,"C0C0C08080808080"
810 DATA 49,9,18,"4F0F274717271727"
820 DATA 50,9,19,"F0F8E0C0C0E0E0E0"
830 DATA 51,10,13,"1F1F1F3F3F3F1F1F"
840 DATA 52,10,14,"0000800080008001"
850 DATA 53,10,15,"0000000000000080"
860 DATA 54,10,17,"000000000000003F"
870 DATA 55,10,18,"130B07130F13EF13"
880 DATA 56,10,19,"E0E0F0F0F0F8F894"
890 DATA 57,11,13,"3F3F3F3F2F273323"
900 DATA 58,11,14,"03070F078A14030C"
910 DATA 59,11,15,"FDFEFFFF060304F8"
920 DATA 60,11,16,"0307E70F3F874486"
930 DATA 61,11,17,"3FFFFFFFC18041B3"
940 DATA 63,11,18,"8BE7F3F7CB23474B"
950 DATA 64,11,19,"4C54EC446CC41CEC"
960 DATA 91,12,13,"21232B2B2B151509"
970 DATA 92,12,14,"018200008080A0C0"
980 DATA 93,12,15,"040C106001000202"
990 DATA 96,12,16,"0706070203020603"
1000 DATA 97,12,17,"40B08E808040C0E0"
1010 DATA 98,12,18,"87030F030F132F5B"
1020 DATA 99,12,19,"9CDCA8D8A8C890F0"
1030 DATA 100,13,13,"0404020100000000"
1040 DATA 101,13,14,"C0EB647CF53E1C3C"
1050 DATA 102,13,15,"04041D281030E040"
1060 DATA 103,13,16,"0286FF3E1715126C"
1070 DATA 104,13,17,"40A0B19A4D364A91"
1080 DATA 105,13,18,"8F6F9F5E0E5F0F7F"
1090 DATA 106,13,19,"A0C0000000000000"
1100 DATA 107,14,14,"3F3F3F3F1F1F0F0F"
1110 DATA 108,14,15,"8F3C7463D8B6FDFA"
1120 DATA 109,14,16,"FF0000FF7E8209AA"
1130 DATA 110,14,17,"FB397592451AB777"
1140 DATA 111,14,18,"3FFF7FFEFEBCFCFC"
1150 DATA 112,15,14,"0F07070303010202"
1160 DATA 113,15,15,"FFFFFFFFFFFFFFFF"
1170 DATA 114,15,16,"DBB7D5FFFFFFFFFF"
1180 DATA 115,15,17,"DFEFFFFFFFFFFFFE"
1190 DATA 116,15,18,"FCFCF8E88C8C0C0E"
1200 DATA 117,16,14,"040C0C1C3C3C3C7C"
1210 DATA 118,16,15,"FFBF5F3F150F0000"
1220 DATA 119,16,16,"FFFFFFFE608F130F"
1230 DATA 120,16,17,"FFF8C00000FCFFE3"
1240 DATA 121,16,18,"1F1F3F3F3F7FFFFF"
1250 DATA 122,16,19,"0080C0F0FCF7FBFB"
1260 DATA 123,16,20,"00000000000080C0"
1270 DATA 124,17,12,"000000000001030F"
1280 DATA 125,17,13,"0001073FFFFFFFFF"
1290 DATA 126,17,14,"38393F3F3FEDE8E8"
1300 DATA 127,17,15,"7FFFFFF4EAEB5661"
1310 DATA 128,17,16,"FFFFFC926A56EA55"
1320 DATA 129,17,17,"CAA5D268534F3C30"
1330 DATA 130,17,18,"FFBFCFD7CF5F9F7F"
1340 DATA 131,17,19,"FBFDFDFFFDFFFDFD"
1350 DATA 132,17,20,"F0CCFFFFFFFFFFFF"
1360 DATA 999,0,0,"Z"
1370 REM SPEECH
1380 FOR I=1 TO 14
1390 CALL COLOR(I,1,16)
1400 NEXT I
1410 FOR DELAY=1 TO 1000
1420 NEXT DELAY
1430 CALL HCHAR(11,15,133)
1440 CALL HCHAR(11,17,134)
1450 FOR DELAY=1 TO 1000
1460 NEXT DELAY
1470 PRINT #1:"//50 40"
1480 RESTORE 1710
1490 READ A$
1500 IF A$="EEE" THEN 1650
1510 IF A$"DDD" THEN 1550
1520 FOR DELAY=1 TO 500
1530 NEXT DELAY
1540 GOTO 1490
1550 IF A$"BBB" THEN 1610
1560 CALL HCHAR(11,15,59)
1570 CALL HCHAR(11,17,61)
1580 CALL HCHAR(11,15,133)
1590 CALL HCHAR(11,17,134)
1600 GOTO 1490
1610 CALL HCHAR(14,16,136)
1620 PRINT #1:A$
1630 CALL HCHAR(14,16,109)
1640 GOTO 1490
1650 FOR DELAY=1 TO 1000
1660 NEXT DELAY
1670 CALL HCHAR(11,15,59)
1680 CALL HCHAR(11,17,61)
1690 GOTO 2510
1700 END
1710 DATA "_4","SCORE","AND","SEVEN YEARS","AGO"
1720 DATA BBB
1730 DATA "OUR _FATHERS","BROUGHT FORHTH"
1740 DATA "_ON THIS","CUNHTINENT"
1750 DATA BBB
1760 DATA "_A NEW NATION"
1770 DATA "CONCEIVED","IN LIBBERTY"
1780 DATA BBB
1790 DATA "_AND DEDICATED","TO THE PROPOSITION"
1800 DATA BBB
1810 DATA "_THAT ALL MEN","ARE CREATED"
1820 DATA "^>EQUAL"
1830 DATA BBB
1840 DATA DDD
1850 DATA "NOW","WE ARE N GAGED","IN A GREAT","CIVL WAR"
1860 DATA BBB
1870 DATA "TESTING","WHETHER >THAT _NATION"
1880 DATA "OR ANY NATION","SO CONCEIVED"
1890 DATA BBB
1900 DATA "AND SO DEH DICATED"
1910 DATA "CAN LONG ^>ENDYER"
1920 DATA BBB
1930 DATA DDD
1940 DATA "_WE ARE MET","ON A GREAT BATTLFILLD"
1950 DATA "OF THAT WAR"
1960 DATA BBB
1970 DATA "WE HAVE COME","TO DEH DICATE","A PORTION OF THAT","FILLD"
1980 DATA BBB
1990 DATA "AS A FINAL",">RRESTING PLACE"
2000 DATA "FOR THOSE","WHO HERE","GAVE THEIR _LI VZS"
2010 DATA BBB
2020 DATA "THAT _THAT NATION","MIGHT LIVE"
2030 DATA BBB
2040 DATA DDD
2050 DATA "_IT IS","ALL TOOGETHER","FITTING AND _PROPPER","THAT WE SHOULD DO THIS"
2060 DATA BBB
2070 DATA "BUT","IN A LARGER SENSE","WE CAN NOT","DEH DICATE"
2080 DATA BBB
2090 DATA "WE CAN NOT","CUNHSECRATE"
2100 DATA "WE CAN NOT","HAL O THIS GROUND"
2110 DATA BBB
2120 DATA "THE BRAVE MEN","LIVING AND DEAD","WHO STRUGGLED HERE"
2130 DATA BBB
2140 DATA "HAVE CUNH SECRATED IT",">FAR ABOVE"
2150 DATA BBB
2160 DATA "OUR POOR","POWER"
2170 DATA "TO ADD","OR DETRACT"
2180 DATA BBB
2190 DATA DDD
2200 DATA "THE WORLD","WILL LITTLE NOTE","NOR LONG REMEMBER","WHAT WE SAY HERE"
2210 DATA BBB
2220 DATA "BUT","IT CAN NEVER FORGET","WHAT _THEY DID HERE"
2230 DATA BBB
2240 DATA "IT IS FOR US","THE LIVING","RATHER"
2250 DATA BBB
2260 DATA "TO BE DEH DICATED HERE","TO THE _>UN FINISHED WORK","WHICH THEY","WHO FOUGHT HERE"
2270 DATA BBB
2280 DATA "HAVE THUS FAR","SO NO BLEE","ADDVANCED"
2290 DATA BBB
2300 DATA "IT IS","RATHER FOR US","TO BE HERE DEH DICATED"
2310 DATA BBB
2320 DATA "TO THE GREAT TASK","REMAINING BEFORE US"
2330 DATA BBB
2340 DATA "THAT","FROM _THESE HONERED DEAD","WE TAKE NCREASED DEVOTION","TO THAT KOZZZ"
2350 DATA BBB
2360 DATA "FOR WHICH THEY GAVE","THE LAST FULL MEASURE","OF DEVOTION"
2370 DATA BBB
2380 DATA DDD
2390 DATA "THAT WE HERE","HIGHLY RESOLVE"
2400 DATA BBB
2410 DATA "THAT THESE DEAD","SHALL NOT HAVE DIED","IN _VAIN"
2420 DATA BBB
2430 DATA "THAT THIS NATION","UNDER GOD","SHALL HAVE A NEW BIRTH","OF FREEDOM"
2440 DATA BBB
2450 DATA "AND THAT GOVERNMENT","OF THE PEOPLE"
2460 DATA "BY THE PEOPLE"
2470 DATA "FOR THE PEOPLE"
2480 DATA BBB
2490 DATA "SHALL NOT PERISH","FROM","THE _EARTHE"
2500 DATA EEE
2510 REM battle hymn
2520 V=15
2530 T=1.15
2540 RESTORE 2730
2550 READ D,F1,F2,F3
2560 IF D=0 THEN 2590
2570 CALL SOUND(D*T,F1,V,F2,V,F3,V)
2580 GOTO 2550
2590 V=2
2600 CALL HCHAR(11,17,134)
2610 CALL HCHAR(11,15,133)
2620 FOR T=1 TO 200
2630 NEXT T
2640 CALL HCHAR(11,17,61)
2650 FOR T=1 TO 150
2660 NEXT T
2670 CALL HCHAR(11,17,134)
2680 FOR T=1 TO 1000
2690 NEXT T
2700 CALL CLEAR
2710 END
2720 GOTO 2540
2730 DATA 300,349,294,233
2740 DATA 398,349,294,233
2750 DATA 150,349,294,233
2760 DATA 398,349,294,233
2770 DATA 150,311,262,175
2780 DATA 398,294,233,175
2790 DATA 150,349,294,233
2800 DATA 398,466,349,233
2810 DATA 150,523,349,220
2820 DATA 398,587,349,233
2830 DATA 150,587,349,233
2840 DATA 398,587,349,233
2850 DATA 150,523,311,220
2860 DATA 450,466,294,233
2870 DATA 263,40000,40000,40000
2880 DATA 150,466,349,233
2890 DATA 150,440,349,233
2900 DATA 398,392,311,233
2910 DATA 150,392,311,233
2920 DATA 398,392,311,233
2930 DATA 150,440,349,233
2940 DATA 398,466,392,311
2950 DATA 150,440,349,311
2960 DATA 398,466,392,311
2970 DATA 150,392,311,233
2980 DATA 398,349,294,233
2990 DATA 150,392,311,233
3000 DATA 398,349,294,233
3010 DATA 150,294,233,175
3020 DATA 450,349,294,233
3030 DATA 263,40000,40000,40000
3040 DATA 150,349,294,233
3050 DATA 150,349,294,233
3060 DATA 398,349,294,233
3070 DATA 150,349,294,233
3080 DATA 398,349,294,233
3090 DATA 150,311,262,175
3100 DATA 398,294,233,175
3110 DATA 150,349,294,233
3120 DATA 398,466,349,233
3130 DATA 150,523,349,220
3140 DATA 398,587,349,233
3150 DATA 150,587,349,233
3160 DATA 398,587,349,233
3170 DATA 150,523,311,220
3180 DATA 450,466,294,233
3190 DATA 263,40000,40000,40000
3200 DATA 263,466,349,233
3210 DATA 550,523,392,233
3220 DATA 550,523,392,311
3230 DATA 550,466,349,294
3240 DATA 550,440,311,262
3250 DATA 850,466,294,233
3260 DATA 750,40000,40000,40000
3270 DATA 675,349,294,233
3280 DATA 263,311,262,175
3290 DATA 398,294,233,175
3300 DATA 150,349,294,233
3310 DATA 398,466,349,233
3320 DATA 150,523,349,220
3330 DATA 850,587,349,233
3340 DATA 800,466,349,294
3350 DATA 450,40000,40000,40000
3360 DATA 675,392,311,233
3370 DATA 263,440,349,233
3380 DATA 398,466,392,233
3390 DATA 150,440,370,233
3400 DATA 398,466,392,233
3410 DATA 150,392,311,233
3420 DATA 850,349,294,233
3430 DATA 800,294,233,175
3440 DATA 450,40000,40000,40000
3450 DATA 675,349,294,233
3460 DATA 263,311,294,175
3470 DATA 398,294,233,175
3480 DATA 150,349,294,233
3490 DATA 398,466,349,233
3500 DATA 150,523,349,220
3510 DATA 850,587,349,233
3520 DATA 800,466,349,294
3530 DATA 263,40000,40000,40000
3540 DATA 263,466,349,233
3550 DATA 550,523,392,233
3560 DATA 550,523,392,311
3570 DATA 550,466,349,294
3580 DATA 550,440,311,262
3590 DATA 1500,466,294,233
3600 DATA 0,0,0,0

What is the Pre-scan process?

See Extended BASIC article

How do I turn the pre-scan process off and on?

!@P+ is on,  !@P- is off.  Default is on.

See Extended BASIC article

Is there a way to organize my code for faster pre-scans?

You cannot reduce what has to be scanned. What you can do is have the minimum items scanned and scanned at one time. The following example comes from the TI Extended Basic Addendum and cleverly uses a GOTO statement to accomplish this.

The code:

10 DATA 3
20 GOTO 100 :: DELAY :: CALL CHAR :: CALL CLEAR :: CALL HCHAR :: CALL VCHAR :: !@p
100 CALL CLEAR 
110 CALL CHAR(96,"FFFFFFFFFFFFFFFF") 
120 CALL CHAR(42,"0F0F0F0F0F0F0F0F")
130 ...
140 ...
150 ...
160 CALL HCHAR(12,17,42)
170 CALL VCHAR(14,17,96)
190 FOR DELAY=1 TO 500
200 NEXT DELAY
210 ...
220 ...
230 ...

Line 20 is the clever use of the GOTO statement. What it does is jump right to 100 but never executes the following commands. This is called Dead Code because it cannot be reached but it is reached during the pre-scan process that takes place prior to execution. So the entire pre-scan process is completed after line 20.

What are Tokens?

Tokens are used to aid in the parsing of Commands, Functions, and Statements in BASIC programs. When run BASIC programs are usually interpreted as opposed to being compiled. Upon running an interpreted program the contents of each program line is translated to its required functions as the program runs. On the other hand a compiled program is first converted to an assembly language program, and then is run as an A/L program. A compiled program will run faster than an interpreted program.

A TI BASIC program is interpreted twice which explains why certain functions in TI BASIC run slower than the same function on other computers. This additional interpretation is required because of the basic structure of the TI computer. Instead of using an operating system which must be booted and requiring the loading of a BASIC interpreter program, a TI has much of this already available when the TI is turned on. These preloaded programs are included in the GROM modules in the TI console. Additional GROM modules are also included in the various cartridges which can be plugged into a TI console. The program instructions contained in these GROM modules are written in Graphic Programming Language (GPL) a special language written by Texas Instruments. This is the second language which must be interpreted when a TI BASIC or Extended Basic program is run.

A TI BASIC or XBASIC program consists of a series of numbered program lines containing various Commands, Functions and/or Statements which in GPL are abbreviated to one byte tokens. For example the token for the PRINT command is represented by character 156 (>9C) and the GOSUB command is represented by character 135 (>87). An example of a program line in usual LIST (DV80) format compared to MERGE (DV163) format is as follows:

LIST format:

10 PRINT XYZ 

MERGE format:

CHR$(0)&CHR$(10)&CHR$(156)&CHR$(200)&CHR$(3)&CHR$(88)&CHR$(89)&CHR$(90)&CHR$(0) 

These tokens have the following meanings:

CHR$(0)&CHR$(10)           - Represents line number in base 256 notation.
CHR$(156)                  - Represents PRINT statement.
CHR$(200)&CHR$(3)          - Indicates following characters are quoted string with a length of 3 characters.
CHR$(88)&CHR$(89)&CHR$(90) - Represents the characters XYZ. 
CHR$(0)                    - Represents end of line marker.

XBASIC programs have been written which can be used to write Extended Basic programs or to convert DV80 listings of extended basic programs into DV163 (merge format) programs using knowledge of the token abbreviations.

More information concerning the use of GPL may be obtained by consulting the "Texas Instruments Graphics Programming Language User's Guide" June 1,1979 (Revised December 3,1979) or "The Graphics Programming Language" Copyright 1990, R. A. Green. GPL assemblers and disassemblers also exist but a GRAM device is required to load and change GPL programs.

What are the Token codes?

You can find a listing of the token codes in a single page format at the following addres: http://www.ti-994a.com/wiki/pmwiki.php/TI/L006-Tokens

Where can I find documentation for BASIC or Extended BASIC?

The first place to look, as always, is on WHTECH at ftp://ftp.whtech.com

If you are looking for a quick reference or just need to see the syntax for a particular command then there is a great online reference at Mainbyte.com that provides this. You can find these resources at: http://www.mainbyte.com/ti99/basic/basic_ref.html