TI BASIC

From Ninerpedia
Revision as of 22:18, 6 December 2022 by Stefan Haubenthal (talk | contribs) (→‎In Extended Basic)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
(Page requires expansion)

See How a BASIC program is stored in the computers memory

Color

The TI used color codes with CALL COLOR and CALL SCREEN. The 16 colors available included white, black and transparent. Refer to the color code chart

AND OR

One omission from TI Basic is the lack of logical operators such as AND and OR used for example in expressions such as IF V<8 AND W>4 THEN 120 ELSE 240. TI Basic programmers instead used mathematical operators to replace logical operators.

LIST to a printer

LIST "PIO":130-240 - will LIST to PIO lines 130 to 240 (inclusive)

Reading DATA in a program

For example:

100 FOR A=1 TO 5
110 READ A
120 PRINT A
130 NEXT A
140 DATA 32,45,65,23,4
150 END

It is a peculiarity of the system that when it reaches the last item of data, it takes time out to look to see if there is any more, which can introduce a pause in a long program. A simple solution is to add a couple of dummy DATA items which will never be used, but which will satisfy the computer as to the location of the next data item.

Line 32767

When you have a program with a GOTO or a GOSUB and the line number does not exist - because you have not written it or have deleted it, when you RESequence the program the transfer line will be changed to 32767. eg you will see GOTO 32767 which you never intended.

ODD or EVEN?

Is variable N odd or even?

You might use:

100 X=(N=2*INT(N/2))+1 

which will set X=0 if N is even, and X=1 if N is odd.

Faster:

100 X=N AND 1

Try it.



Check Alpha Lock

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:

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.


Month number using POS

Extract a month number, 1 to 12, when the first three letters of any month are entered.

100 INPUT "MONTH?":M$
110 M=(POS("JANFEBMARAPRMAYJ
UNJULAUGSEPOCTNOVDEC",M$,1)+
2)/3
120 IF M<>INT(M) THEN 100
130 PRINT "MONTH NUMBER IS 
";M

Cassette to Disk

If you have a collection of TI Basic programs on tape and wish to move them to tape the easy way is:

NEW
OLD CS1
SAVE DSK1.PROGNAME

and it is done.

Unfortunately when you connect a disk system, it will use up around 2k of memory. Very often you will be able to use the above procedure.

Sometimes if you run the program in TI Basic, it will give you a memory error. This is because TI Basic programs run from VDP memory and you have 2k less with a disk controller attached. You can take advantage of Extended Basic and your expansion memory using the VDP program in the next section. Extended basic runs the programs from a 24k part of the 32k ram.

Some long TI Basic programs create their own problems - they may be too long when you add the vdp routine below, or there are some programs that are too long to be loaded into the VDP and will throw an error when you do the OLD CS1. This section deals with that problem.

In XB you can use a CALL LOAD to tell your console the disk controller is not attached, this may allow the long TI Basic program to at least be loaded. CALL LOAD(-31888,63,255) then NEW

NB Do not try to use the disk controller after doing this unless you power cycle the console OR use:

CALL LOAD(-31888,55,255) then NEW

If the CALL LOAD allows you to now load the TI Basic program from tape, you may be able to reduce the size of the program by editing and then SAVE back to tape, then see if it will load with CALL FILES(1) NEW OLD CS1 to enable you to save it to disk. OR the really tough way...


It may be possible to edit the loaded TI Basic program into two parts (yes it is hard work) and save each part to tape, then with CALL FILES(1) set, move both parts to DISK. You can then use Extended Basic's MERGE facility to get the two parts back together and add the VDP utility found in the next section.

 set disk drive off with the call load - CALL LOAD(-31888,63,255) then NEW
 OLD program from tape 
 edit out a hundred or so lines at the end 
 save to another tape 
 reload original program and edit out a hundred or so lines from the start 
 save to another tape 
Switch to Extended Basic, reset the disk controller with CALL LOAD(-31888,55,255) then NEW.  

If you still need more memory you can now use CALL FILES(1) then NEW which saves about 1k.

Load one of the tapes and save to disk in MERGE format. (SAVE DSK1.PART1,MERGE)

Load the other part of the program and MERGE in the first part and the VDP utility (MERGE DSK1.PART1 then MERGE DSK1.VDP).

Don't forget to save the multi merged program to another disk filename before you turn off.

In Extended Basic

If you have a disk system you may wish for example to use a standard menu loader on each disk to load programs, which may be a mix of TI Basic and Extended Basic. It is possible to run many TI Basic programs in Extended Basic, but some use the two character sets that Extended Basic has dropped and you receive an error.

It is possible to create a small program on disk in merge format which you can then merge into your TI Basic program and they will run in Extended Basic. This routine requires you have a disk system and 32k expansion ram.

First, in Extended Basic, type this code as shown and SAVE it as for example: SAVE DSK1.VDP,MERGE which will create a small file on disk in DV 163 format.

1 CALL VDP
32600 SUB VDP :: CALL INIT :: CALL LOAD(8194,37,194,63,240)
32610 CALL LOAD(16368,80,79,67,72,65,82,37,58,80,79,75,69,86,32,37,168)
32620 CALL LOAD(9530,2,224,37,20,3,0,0,0,2,5,48,48,2,6,37,2,205,133,2,134,37,17)
32630 CALL LOAD(9552,17,252,4,192,2,1,0,1,2,2,37,1,2,3,18,0,212,131,4,32,32,20)
32640 CALL LOAD(9574,208,4,9,80,2,32,3,0,2,1,37,2,2,2,0,8,2,7,11,0,2,8,7,0,193)
32650 CALL LOAD(9599,1,192,193,193,180,97,133,145,135,21,1,113,136,6,198,145)
32660 CALL LOAD(9615,135,21,1,113,136,210,70,10,198,177,137,220,198,2,131,37,10)
32670 CALL LOAD(9632,17,240,4,32,32,36,16,6,2,224,37,20,3,0,0,0,4,32,32,32,4)
32680 CALL LOAD(9653,192,216,0,131,124,2,224,131,224,4,96,0,112):: SUBEND
32690 SUB CHAR(A,A$):: CALL LOAD(9500,A):: CALL LINK("POCHAR",A$):: SUBEND
32700 SUB COLOR(A,B,C):: CALL LOAD(9492,8,15+A,(B-1)*16+C-1)
32710 CALL LINK("POKEV"):: SUBEND
32720 END

Now load your TI Basic program, check that it does not use a line number 1 or over 32000. RESequence if required. If all clear merge in the little routine above:

MERGE DSK1.VDP

which will add the routine to your TI Basic program. Save to disk (use a different name or disk to preserve the original TI Basic program) eg SAVE DSK1.TIBPROGX Your TI Basic program will now run in Extended Basic even if it does use the extra character sets,

Sprites in TI BASIC

You can have sprites if there is a special module inserted such as mini-memory, but this is how to have NO modules inserted and still have 32 sprites in TI Basic. You will need to use cassette files.

This routine allows you to have 32 sprites in TI Basic, with NO modules or peripherals required. The sprites do not have automatic motion, and there is no CALL COINC, but the routine opens up the 32 graphic planes, and allows a character to be placed with single pixel precision. Sprites can be moved manually to give single pixel movement of characters if required.

Now, with no module in place, we do not have POKEV available, so the puzzle is: how, using TI BASIC, can we change memory?

TI Basic has one easy to use command which can change 8 bytes of memory very quickly... it is called CALL CHAR, and it writes these bytes into any area of VDP RAM mapped as 'character definitions'.

VDP Registers shows how by changing VDP Register FIVE, we can move the SPRITE ATTRIBUTE LIST to any part of VDP RAM, INCLUDING the area the console considers to be the character definition table.

If we can do this, then we can use CALL CHAR to write to VDP RAM in an area considered by the CPU to define characters, AND AT THE SAME TIME, define our sprites.

So, the puzzle becomes one of: How do we change the VDP registers using no modules... CALL PEEKV is not available in ordinary TI BASIC.

When you load a program from cassette, there is a HEADER at the start which tells the computer what you are loading and where to put it. Why don't we use the header to place a value into VDP RAM to change the VDP REGISTER!!

NB: If you have more than a cassette recorder, disconnect now! This article is for Console and Cassette ONLY.

The first step is to set the VDP Register, and here is a general register changer ....

Type in this program, then RUN it, with a blank tape in the recorder!

10 REM FILES GENERATOR
20 TO MODIFY VDP REGISTERS
30 REM THANKS IT U.G. BOLOGNA, ITALY
100 CALL CLEAR
110 INPUT "REGISTER # 0-7":R
115 INPUT "VALUE (0-255)":D `
120 A=18429-(256*R+D)
130 X$=CHR$(0)&CHR$(O)&CHRS(0)
14O OPEN #1:"CS1",OUTPUT,FIXED
150 PRINT #1:X$&X$&CHR$(INT(A/256))&CHR$(A)
160 CLOSE #1
170 END

To use the program below, with sprites, you must ENTER the values:

REGISTER=5, VALUE=15

With a value of 15, the sprite table occupies the same memory as the definitions of characters 144 to 159.

If you enter a value of 14, the sprite details are in the same location as characters 128 to 145.

After you have RUN the above program, you will have an odd file on tape.

Do a FULL RESET by typing BYE and reselect TI BASIC. Now LOAD the tape file as though it was a program, with OLD CS1. After you press ENTER at the end of the load, the screen will misbehave (watch for the colour black).

Now press an alphabetic key and then press ENTER. Look .... "MEMORY FULL"!!!

Type in NEW.
The VDP register is now reset until you QUIT or BYE.

Sprites can be placed on the screen as follows:

CALL CHAR(144,"Y1X1F1C1Y2X2F2C2") 
  where Y1, X1 etc are values - 4 values for each sprite)
eg CALL CHAR(144,"04037A0C02057B0B") 
(that is 8 values for TWO sprites, TWO numbers per value)

Where each CALL CHAR carries the four parameters required for two sprites, with each parameter a two digit hexadecimal number.

Y=Row (0-191), X=Column(0-255), F=ASCII+96, C=COLOR(0-15)
What is the HEX for decimal 122?:
122/16= 7 remainder 10 (10=>A where > means HEX)
7/16= 0 remainder 7 ( 7 = >7 )
Therefore 122= >7A

As we are defining two sprites at a time, if you only want one, the final 8 values will be D0000000 to mark the end of the sprite table. If you want two sprites you need to define the next character with a D and 17 zeroes. D0 is the hexadecimal equivalent of 208.

NOTE: As with mini memory, we MUST terminate the sprite table with a value of 208. In other words the final sprite is defined with the values D0000000,

No matter which is the highest value sprite, always end the definition with a hexadecimal equivalent to decimal 208.

The following demo program builds an array H$ such that we can use this to build up the hexadecimal string required.

Ready...
1 REM IT U.G. BOLOGNA ITALY
5 CALL CLEAR
10 DIM(A$(16),H$(255)
20 FOR P=1 TO 15
30 A$(P)=SEG$("0123456789ABCDEF",P+1,1)
35 NEXT P
40 FOR P=0 TO 15
45 K=16*P
50 FOR J=0 TO 15
55 H$(K+J)=A$(P)&A$(J)
50 NEXT J
65 NEXT P
70 REM SPRITE MAGENTA DEMO
75 F$=H$(128)&H$(64+96)
80 F$=F$&H$(14-1)&H$(208)
85 FOR Y=0 TO 191
90 CALL HCHAR(12,12,144)
95 CALL CHAR(144,H$(Y)&F$)
100 NEXT Y
105 GOTO 100