First TI produced TI BASIC, built into the console. Then came the first attempt at an Extended BASIC, in module format, which returned the value of 100 with CALL VERSION(A). This first version is quite rare and suffered several problems.
Very quickly a rewrite was issued. The second version was still called TI Extended BASIC but this time when you used CALL VERsion(A) it returned a value of 110. It was faster. (Mostly because it was no longer trying to keep track of graphic sprites that you weren't using).
Subsequent versions of Extended Basic from third parties added more powerful versions of commands or new commands- some example versions are:
Triton Super Extended BASIC (Returned 120 with CALL VERSION(A) )
This page links to some notes on using Extended Basic generically and where possible each comment will address the variations.
Program Line content
PROGRAM LINES: May now contain more than one command, and can be entered up to 5 screen lines long (but limited to 128 bytes long internally).
You may use IN COMMAND MODE for instance: FOR A=110 to 220 :: CALL SOUND(200,A,0) :: NEXT A
The double colon is a statement separator. In TI Basic you could enter PRINT A::B::C.
In Extended Basic you must leave a space between the colons: PRINT A: :B: :C
(A program in TI Basic is converted automatically by the machine to the new format, but you must take care when typing in a program. Due to an omission in the error handling system, typing too many colons together in Extended Basic can cause the processor to 'lock out')
When this is linked to the new capabilities of the IF...THEN command, it is possible to put together some very powerful program lines:
IF A=B THEN C=5 :: PRINT A :: ELSE IF A=8 AND B=C THEN GOTO 3400 ELSE CALL SOUND(100,110,0) :: GOTO 200
As the lines become longer and more complex, you do need to take greater care, but the language gives you a very powerful tool.
In addition to using REM after double colons, you may use a 'tail remark', which is a '!' as follows:
140 SCORE=0 ! RESET SCORE
EXTENDED BASIC uses some of the system RAM, and you do not have quite as much memory available for your programs. In addition, the cassette loader cannot handle programs over 12k.
The good news is that with Extended Basic you may access the memory expansion unit, which permits you to load (from DISK) a program up to 24k, and still have some 14k available for variables and so on.
The new function key REDO will repeat your last entry, and if the last entry was a program line (either just entered, or recalled using FCTN X) the line reappears on the screen with the cursor at the beginning of the line NUMBER, allowing you to change the line number if you wish. This function is useful if your program contains a lot of lines either the same or with only small differences.
Also see the article on the different function keys used on the TI99/4 (no a) TI99/4 and 4a differences
A program using the joysticks requires the alpha lock is UP, a relic of the TI99/4 days.
If your program requires the alpha lock to be DOWN for input etc you can instruct the console it is down:
Insert a dummy line CALL KEY(3, Z, Z)
The use of key unit 3 tells the computer to treat the alpha lock as if it were down whilst the program is running, unless we reset. Use of key unit 0 has no effect on alpha lock status. Key unit 5 will reset normal operation.
Using Sprites with different consoles
Sprite speed depends to some degree to the VDP speed, and PAL and NTSC consoles differ significantly. This can cause problems especially in Extended Basic games where sprite auto-motion is used, as the speeds will vary.
Here is a little Extended BASIC test program (could be useful when setting up emulators?):
100 CALL SPRITE(#1,32,1,100,1,0,60) :: FOR C=1 T0 71 :: NEXT C :: CALL POSIT ION(#1,C,C) :: CALL DELSPRITE(#1) :: PRINT C :: GOTO 100
Now, when you run this tiny ExBas program, a string of numbers will scroll up the screen. They will fall between two values, with a difference of 5 or 6 between the upper and lower limits.
On my consoles the range is 53 to 59. However, on USA consoles, operating at differing speeds, the sprite can travel farther, and on 26 USA consoles, the value range ie 64 to 69.
For a number of American written Extended Basic games I had to amend sprite speeds to prevent the sprites moving too far.
In addition to a limit of four visible sprites in a screen row, higher numbered sprites becoming invisible, there is another odd limitation:
On some TI99/4a consoles, a sprite on row 208 (which is off screen) may cause all sprites with a higher sprite number of disappear and if the sprite is moving, the other higher numbered sprites will all flicker off and on together.
Expansion Memory Test
"Is the 32K expansion connected?" (in Extended Basic programs) - there is no need to trouble the user with this, the computer can answer this question itself:
CALL PEEK(-45, A, B, C) IF A+ B+ C> 0 THEN (the 32K RAM is attached!)
Machine code programs
An added attraction of the module is that it permits you to load and run Assembly language programs, provided you have the extra peripherals required.
Example: In the USA, TI release TI INVADERS on disk for half the price of the module. You require a disk system and the 32k memory expansion.
If you use CALL PEEK at some locations the console will cease to respond.
Users have encountered more system lock outs due to dirty module contacts with Extended Basic as it uses more of them than most modules.
Sound and Sprites Pausing
From time to time you may notice your sprites freeze for a moment or a musical note sound just a little longer than it should. This is due to the computer having a clearout of redundant variables, making room for more. In Extended Basic you can take charge of this fairly random behaviour. Refer to the article Garbage collection.
Extended BASIC commands
ACCEPT AT, DISPLAY AT
Using DISPLAY AT you can use TAB as follows: eg: To set up the following display
MAIN MENU: 1 - Edit 2 - Add 3 - Exit
you can set up each line with an individual DISPLAY AT statement or you can do the following:
DISPLAY AT(5,5):"MAIN MENU";TAB(7);"1 - Edit";TAB(7);"2 - Add";TAB(7);"3 - Exit"
This will put the information on 4 separate lines because when the computer tries to perform the TAB(7) it finds that that location has been already bypassed on the present row and therefore it automatically goes to the next row.
IF THEN ELSE
See excerpt from the final Users Reference Guide IF THEN ELSE
ON BREAK NEXT
Refer to Randomize bug using disk LOAD
See article Speech
CALL COLOR and CALL SCREEN used numeric color codes. The 16 colors available included white, black and transparent. Refer to the color code chart. CALL SCREEN(C) and CALL COLOR(Set,FG,GG). For COLOR the characters were split into groups of eight identified by the first variable. CALL COLOR could also be used to set a sprites color (CALL COLOR,SN,SC).
Your own sub programs
As well as the built in CALLs Extended BASIC allows you to create your own sub programs. There is an article on this at CALL subprograms.
Using CALL LOAD in Extended Basic
Refer to Programming article.
Convert decimal to binary number
This little routine will work for any 16 bit digital number - nothing over 65,536. Decimal 5 is binary 101 - now quickly what is the binary form of 365? Try this:
100 INPUT D :: D=D/16^4 :: FOR X=0 T0 15 :: D=2*(D-INT(D)) :: PRINT (D>=1) :: NEXT X
Pre-scan is used to allocate memory before the BASIC program starts. It causes a notable pause before the first statement executes, because the pre-scan process scans the whole program for variables and subprograms. Extended Basic allows for a quicker start-up by turning pre-scan off and on; these lines are specific comment lines.
100 GOTO 150 110 A=0 :: B$="" 120 DATA 1 150 !@P-
turns off pre-scan after line 150
turns it on after line 200. Pre-scan is enabled by default.
Pre-scan must be active for the following program parts:
- The first DATA statement
- The first use of a variable or an array
- OPTION BASE (if used)
- Reference to each subprogram called in the program
- SUB and SUBEND
Variables introduced in the SUB statement (formal arguments) are locally valid, so they must be included. CALLs in the pre-scan need not list actual arguments. You do not need to build correct assignments to variables either. However, the lines must not be executed, or an error will occur.
100 GOTO 150 110 CALL SCREEN :: CALL MYOWNSUB :: CALL CLEAR :: A,B,C=D :: E :: NAME$ :: !@P- 120 DATA 10 150 CALL CLEAR 160 REM REST OF PROGRAM
Because pre scan uses "dead code" that you can place after a GOTO it is acceptable and demonstrated in the TI Extended Basic Addendum to use the following format:
10 DATA 3 20 GOTO 100 :: DELAY :: CALL CHAR :: CALL CLEAR :: CALL HCHAR :: CALL VCHAR :: !@p- 100 CALL CLEAR
(where DELAY is a variable)
DATA statements at the top or the end?
Where does DATA belong?
The answer is not so simple. It depends on whether or not your program uses RESTORE.
With DATA at the start of your program, RESTORE is faster but READ is slower, while conversely if your DATA is at the end of your program, RESTORE slows down a lot but READ is much faster. NB: this MAY differ on consoles with differing operating systems.
On average, how many RESTORES do you process, and how many READs?
If the number of RESTOREs TIMES FIVE exceeds the number of READs, place your data at the beginning. If the number of reads is more than five tines the number of RESTOREs, place the data at the end. The difference in the timing of RESTORE in a 10k progran is unbeleivable!
Catching errors on numeric entry
If someone just presses ENTER when they should input a number, it can be disruptive.
Using ACCEPT AT for a numeric variable, you can insert a default input value, and use a negative size, and also use VALIDATE.
However, the user CAN blank the default variable with CLEAR, and if the input variable is a numeric variable, trying to input a blank will cause an error condition.
Using ON WARNING NEXT will test for the nul input and go back for you. Try it.
eg 100 ON WARNING NEXT 110 ACCEPT AT(4,5)ERASE ALL VALIDATE(DIGIT):A 120 GOTO 110
Right Adjust displayed numbers
To right adjust money or other decimal numbers so that numeric input of 4 or 4.5 or 4.26 neatly line up:
DISPLAY AT(R,C):USING "####.##":VALUE
Using this command, any positive number up to 9999.99 with no decimal places, or one or two decimal places, will display correctly lined up and showing two decimal places.
MIN and MAX
MIN - If a variable is restricted to being no higher than 6 you would normally say IF A>6 THEN A=6 however you can say A=MIN(A,6)
MAX - If a variable is restricted to being no lower than 6 you would normally say IF A<6 THEN A=6 however you can say A=MAX(A,6)
Randomize bug using disk LOAD
This from Bruce Harrison of Harrison Software via Micropendium:-
If you have a disk system, and have a disk of XB programs which has a program called LOAD, your system will automatically load the LOAD program from DSK1 when you select Extended Basic.
It also kicks RANDOMIZE into touch, not only for the LOAD program but also for any program that the LOAD program loads and runs (see note re console variations below).
If the computer manages to find a LOAD program, then your RND will always provide the same sequence every time you boot up, even if your program has a RANDOMIZE. Save this program to disk as DSK1.LOAD and boot into Extended Basic.
100 RANDOMIZE 110 FOR T=1 TO 6 120 PRINT INT (RND*100) 130 NEXT T 140 RUN "DSK1.LOAD"
and watch the six numbers repeat again and again, in defiance of the RANDOMIZE command.
Thus if you use a LOAD menu program to put in XB programs such as games or graphics or what have you, you may as well forget about RANDOMIZE... except...
70 CALL INIT 80 CALL PEEK(-31880, [ , ]) 90 CALL LOAD(-31808,[,])
and now try it... see, different numbers.
(Yes you can use [ and ] as variable names!)
NOTE that you must omit the CALL INIT if it has already been used for example to load an assembly utility such as The Missing Link else you will destroy the utility! Call Init is also not required it you use the Triton version of XB titled Super Extended Basic on the module label and (c)1987 T PC.
Bruce tells us this fix can be attributed to Harry Wilhelm and dates back a couple of years.
UPDATE This bug has also been seen when LOADing from ramdisk, but appears to be dependent on specific TI99/4a consoles. The RANDOMIZE routine would appear to be using a memory address or routine in the console which at some point was changed, some versions receiving interference from the disk LOAD routine.
On Error (not a bug) workround
100 ON ERROR 600 110 RUN "DSK1.NOFILE" 600 ON ERROR 600 :: RETURN
the RETURN will fail as the failed RUN seems to remove the internal pointers.
This is a deliberate ploy by TI to avoid the "accidental" removal of the List Protection flag- which happens with Version 100 of ExBas.
You need to use the format RETURN XXXX where XXXX is a line number to go to which will RUN your original program again- you could use RUN 100 or something if required. The second RUN will of course reset all required pointers.
100 ON ERROR 600 110 RUN "DSK1.NOFILE" 120 GOTO 120 550 RUN 100 600 ON ERROR 600 :: RETURN 550
PRINT USING and DISPLAY USING
(from Mark Schafer) When putting data on screen you can control the format (what it looks like) with a format command known as USING. See separate article Print Using which also applies to DISPLAY USING.
Exchanging Variable Values
Nice bit of code here for you to look at. Let's suppose we have CAT=6 and DOG=9, how do we change those around?
We could set up a, temporary variable like this:
10 CAT=6 :: DOG=9 20 PET=CAT :: CAT=DOG :: DOG=PET 30 PRINT CAT;DOG
But we can save a little variable storage space and produce more interesting code like this...
10 CAT=6 :: DOG=9 20 CAT=CAT+DOG :: DOG=CAT-DOG :: CAT=CAT-DOG 30 PRINT CAT;DOG
Try it- it works! And saving variable names is of great value if you are programming for THE MISSING LINK, which only has limited VDP space for variable storage.
Purely in the interests of science, ExBas programmers can tackle this another way, but it is slower:
10 CAT=6 :: DOG=9 20 CAT=CAT XOR DOG :: DOG=CAT XOR DOG :: CAT=CAT XOR DOG 30 PRINT CAT:DOG
Passing variables to a second program
See article Maintaining variable values
Hi resolution pseudo-graphics
This routine places characters on the screen and redefines them in a manner that looks like hi resolution graphics- but when you run out of characters to redefine, you are out of ink. The listing is of value for the use of the OR operator. Nothing except TI Extended Basic is required. It is not as fast as using a machine code extension to Extended BASIC.
It is not possible to say when you will 'run out of ink'. TI Logo uses a similar method of drawing.
The routine is written to prevent crashes if you do run out of ink, but in itself will not check that R and C are within the screen boundaries.
It is in Extended Basic and is by Gary Harding.
Where in the other programs we have: CALL DOT(1,R,C) you should use CALL PLOT(R,C,S) and for CALL LINK("POINT",N,R,C) you should use CALL PLOT(R,C,S) etc etc.
Your program must commence: 1 CALL SCREEN(2) :: S=3l :: CALL HCHAR(1,1,S,768) 2 FOR T=1 TO 14 :: CALL COLOR(T,16,2) :: NEXT T = = = =
YOUR GRAPHICS PROGRAM THEN FOLLOWS.
Ignore any initialisation for other graphics languages, such as CALL LOADS and CALL LINKS or CALL GRAPHICS
= = = = Now the subroutine which sho uld be at the END of the program: 31010 SUB PLOT(R,C,S) 31020 Y=INT(R/8+0.875) :: X=INT( C/8+0.875) 31030 H$="0123456789AB CDEF" 31040 B=C-X*8 :: P=2*R-16*Y+16+ (B<5) 31050 IF B>4 THEN B=B-4 31060 CALL GCHAR(Y,X,H) 31070 IF H>31 THEN 31100 ELS E IF S=143 THEN SUBEXIT 31080 S=S+1 :: D$=RPT$("000 0",4) :: CALL CHAR(S,D$) 31090 CALL HCHAR(Y,X,S) ::H =S :: GOTO 31110 31100 CALL CHARPAT(H,D$) 31110 N=(POS(H$,SEG$(D$,P,1) ,1)OR(2^(4-B)) 31120 D=SEG$(D$,1,P-1)&SEG$( H$,N+1,1)&SEG$(D$,P+1,16-P) 31130 CALL CHAR(H,D$) :: SU BEND 31140 ! ROUTINE BY GARY HARDIN6 31150 ! FROM TIDINGS OCTOBER 1982 32000 END
A note on line 31110- that is the word OR that you see. This bitwise "OR" effectively sets the bit in the relevant digit of the character definition hexstring corresponding to the pixel which it is required to plot. (Gary Harding).
Convert the numbers on each side of the OR to a binary number (made up of 1s and 0s. From Microsoft: "The bitwise OR operator performs a bitwise logical OR between the two expressions, taking each corresponding bit for both expressions. The bits in the result are set to 1 if either or both bits (for the current bit being resolved) in the input expressions have a value of 1; if neither bit in the input expressions is 1, the bit in the result is set to 0.". eg (1001 OR 0100)=1101 also (0010 OR 0010)=0010.