[ Go to Stephen's Entry Page ]
[ TI99/4a Articles index |   TI Book front page |    TI Resources Page |   PC99 Programs ]
contact- please use subject="pc99 page" to avoid spam trap!

This web page contains the text of articles I wrote for Personal Computer News and an Australian review of my book. It is of use to users of the TI-99/4a emulators and of historic interest regarding home computer use in the UK in 1983.

Jump to How programs are stored in memory

TI99/4a Clippings

(Australian) Your Computer April 1985

Author not known.

For beginners, I have two unusual books. I say unusual not because the subject matter or the treatment is unusual, but because both authors were once heavily involved in TISHUG's sister group in the UK, TIHome.

Peter Brooks, the author of Mastering the TI99 (Micro Press through ANZ, $21.95) was a pioneering member of TIHome in early 1981. Brooks established himself as a knowledgeable writer and programmer for Tidings the UK group's newsletter.

Mastering the TI99 is a valuable purchase, if only for the chapter on translating BASIC code between machines. Other chapters discuss file handling, graphics plotting, printing errors, hints and tips - all in Brooks' typically concise style, There are routines for checking memory, using CALL FlLES(), and a short program for visually checking tape loading. There are another 28 tips included, and with its highly functional index I would recommend this book for the more 'advanced' beginners among you.

Stephen Shaw continues his involve- ment with the 4A in his book Getting Started with the Texas TI99/4A (Phoenix through ANZ, $l9.95). Shaw wrote for Tidings as well as conducting a successful import business from his home in Stockport, Cheshire. He was bringing the best American software into England at a time when the majority of British computer magazines. with the exception of perhaps Computer and Video Games, was giving little or no coverage to the 4A machine. Texas Instruments' attempts to launch the early model 4 there were abortive, causing many journalists to write it off as a bad joke, and even with the introduction of the more versatile 4A no-one wanted to know it!

With the first-time user in mind, Getting Started is a guided tour from setting up and understanding your computer to programming in BASIC and Extended BASIC. (Did you know there are two versions of Extended BASIC? One is the Vn100 and the other, which is more common, is the Vn110. Apparently the latter version is significantly faster. but there is some degree of incompatibility between the two versions with respect to sprite handling and user sub-routines.)

This book, with its encyclopedia-like entries could almost qualify as a dictionary for the 4A. All the listings included have been fully developed and represent excellent examples of the Shaw approach to programming. They equal anything he has published in earlier editions of Compu-

---sadly, I don't have the rest of the cutting. Aaagh.

Letter from Stephen Shaw to a magazine

Letter published in a UK computer magazine. Undated. From the style, this was probably Personal Computer News:

TI logic

Here is a tip to help TI99/4A owners utilise the full power of their home computer. It will also apply to other micros.
There are frequently situations where you would like to enter lines such as:-
IF A=3 OR A=5 THEN 120
or
IF A=3 AND B=6 THEN 120
In TI Basic (Console Basic) you cannot use either OR or AND. You can get round this by using lots of IF ... THEN lines, but there is an easier way.
The line 
IF A = 4 THEN 120 
is treated by the computer as follows: it evaluates the expression after IF. If it is true (logic value -1) then the line transfer takes place. If it is untrue (logic value 0) the line transfer does not take place.
Try entering 

PRINT 2=2 and 
PRINT 2=4 
The computer looks at the logical value of the expression and interprets any non-zero answer as true.
Thus we can use 
IF A THEN 120 
and if A is not zero, the transfer takes place.

We can therefore create our own OR/AND by manipulating the logical values of the expression. To ensure that the logical value of the expression is properly evaluated we need to place it in brackets.:-

IF (A=2) + (A=5) THEN 120 
If either A=2 or A=5 then the sum of these two logic expressions will be -1 ie true. The + acts as an OR.
IF (A=2) * (B=5) THEN 120 
If both A=2 and B=5:
 (-1 * -1) = +1
the expression is evaluated as non-zero, and the transfer takes place, but if either expression is false, the value will be zero (0 * -1) = 0.

Thus we have our AND.

By knowing how these expressions work, you can create more powerful conditional transfers than by using OR & AND themselves.

Stephen Shaw Stockport, Cheshire

Compact Programming

Personal Computer News - a UK Magazine - May 6th 1983. page 26.
(Referred to as "Issue 8 - April 29th - May 6th 1983" but actual pages marked as above)
See full index and cover jpg at http://www.bobmockford.co.uk/pcn/008/

COMPACT PROGRAMMING

Everything from Texas is big except the 99/4A memory. Stephen Shaw shows how to save it

The TI99/4A MEMORY MISER

The Texas Instruments TI99/4A home computer is provided with 16K of RAM with the console. Expansion is quite expensive and it pays to learn memory-saving procedures as soon as possible.

The basic 16K of RAM is not completely available for your programs. The computer uses some of the RAM for the screen display, leaving 14847 bytes for programs. Some of this will be used to store return addresses, variable values and extra character definitions (referred to as value stack, and string space).

When you key a program into your 99/4A, the computer stores each line input in the order you key it in - that is, if you key in line 200 before line 100, line 200 will occupy the first memory area. The computer keeps track of the program lines by means of a line number table.

The line number table uses two bytes to indicate the line number, and two bytes to indicate the memory location of that line- so each line occupies four bytes immediately (and a few bytes more, as will be shown shortly). The line number table is in line number order.

In TI Basic your program is in what is known as VDP RAM and occupies memory addresses 1536 to 16383 (hex 0600 to 37FF). If no disk controller is connected, the first line entered begins at 16383.

In Extended Basic with 32K memory expansion connected, your program is in CPU RAM, addresses -1 to -24576 (hex A000 to FFFF). The stack is separated from your program and occupies the VDP RAM. (The other 8K of the 32K expansion is reserved for machine code programs). The first program line entered starts at location -25.

With Extended Basic and 32K RAM, or with TI Basic and the 4K Mini Memory, you may look at the coding or your program using PEEK and PEEKV respectively. It is also possible to amend a program with LOAD and POKEV. (With Extended Basic Version 110, the first 24 bytes of program space are used by the computer, that is why your program starts at -25, not -1).

Interesting - but what about saving memory? To save memory you need to know how the computer actually uses it. As an example, the TI99/4A is probably the most accurate computer around for mathematical use, partly because of the way it stores numbers. The manual gives information on this.

When you use a variable, a full 8 bytes of memory is used to store the value whatever it is.

MEMORY SAVER 1
Use as few variables as possible -every one used knocks off 8 bytes.

MEMORY SAVER 2
If a number is used frequently, it may be more economic to set a variable and use that instead.

A = 128 as a program line will use 13 bytes for the line plus 8 bytes for the variable value -total 21 bytes.

The number 128 uses 5 bytes every time it is used, the variable A just one byte, so every time you substitute the variable A for the number 128, you save 4 bytes. If the number occurs in your program six times, you save a total of 24 bytes, which you offset against the memory used to set the variable A (21 bytes) for a net saving of 3 bytes.

That isn't much, but some numbers occur many more than six times in a program (eg 1 ,2,28,32 etc). And you do not need to set a variable to zero -just use a Z (not used elsewhere) and the 'overhead' is only 8 bytes, not 21 bytes as previously. Similar principles apply to strings, which are sometimes quite long. I have seen too many programs setting characters to the same definition using the same string again and again, instead of setting a variable and using that.

MEMORY SAVER 3
Keep variable names short

MEMORY SAVER 4
LET is not required with the 99/4A: do not use it, it occupies a byte. GO TO uses 2 bytes but GOTO only one byte - use the single word.

A frequent bug I have found is very heavy on memory: using GOSUB and then not using RETURN. Every GOSUB adds to the stack a return address, which can only be cancelled with a RETURN. Watch out for that.

The 99/4A uses a lot of subprograms, eg CALL SCREEN, CALL COLOR and so on. Although the command CALL uses only 1 byte, the next word uses up as many bytes as it is long plus one (it is treated as an unquoted string, using the same program format as a number). So a lot of subprogram calls can use up memory.

 
CALL COLOR (1,1,1)
CALL COLOR (2,1,1) 
CALL COLOR (3,1,1)
CALL COLOR (4,1,1)

or

FOR I=1 TO 4 
CALL COLOR (1, 1, 1) 
NEXT I 
Which uses the least memory? The second version actually uses 51 bytes less than the first. It may take an odd microsecond longer, but what an easy saving.

If a loop cannot be used, it may sometimes be worthwhile to READ a DATA statement with a loop - for instance:-
FOR I =1 TO 4
READ A,B,C
CALL SOUND (A, B, C)
NEXT I
DATA 200,110,0,300,200,4,440
,440,2,100,-3,2

The only trouble with this approach is that the 99/4A is incredibly slow at reading DATA.It is often worth using up memory to increase execution speed.

Programmers quite frequently use the CALL KEY command and follow it with many lines of IF ... THEN, branching in various directions if a particular key is pressed.

The 99/4A has a much more compact way of tackling this.

In this example, the program is to branch if keys representing the numbers 1,2,3 or 4 are pressed, otherwise to read the keyboard again.

100 CALL KEY (0, A, B) 
110 IF A = 49 THEN 200 
120 IF A = 50 THEN 300 
130 IF A = 51 THEN 400 
140 IF A = 52 THEN 500 ELSE 100 
Better, especially if more keys could be pressed:-
100 CALL KEY (0, A, B)
110 ON POS("1234",CHR$(A),1)
+1 GOTO 100,200,300,400,500

Some examples much longer than the one shown here (above) have been seen. The POS function returns a value of 0 if the key pressed is not in the quoted string, so we need to add one to go back to the call key routine (+1 at the end - you did notice it?).

Very often you need to branch to another part of your program if both of two conditions are met or if either is met - this can be done with a great many IF ... THEN tests, but the programmer does have AND and OR.

In TI Basic it is necessary to use a little logical manipulation, whereby a TRUE statement is evaluated as -1 and a FALSE statement as 0.

Try PRINT 2=2 and PRINT 2=3 to prove that statement.

The line 'IF X=3 THEN 100' is treated by the Computer as 'IF (X=3) THEN 100'.

If (X=3) evaluates as TRUE (-1) the line transfer takes place.

The 99/4A treats any non-zero value as true, so instead of 'IF (A<>0) THEN 100' you could simply use 'IF A THEN 100'.

Remember this - it is useful in Extended Basic when using CALL COINC with sprites, where the return value is - 1 if there is a coincidence and 0 if none.

Where this leads is to:-
To use OR in TI Basic, use the sign + between the tests - which must be in brackets to ensure correct evaluation.
For instance, Extended Basic
IF A=3 or A= 4 THEN 100
becomes in TI Basic
IF (A=3) + (A=4) THEN 100
Similarly. AND can be emulated with a *
In Extended Basic
IF A=3 AND B=4 THEN 100
Becomes in TI Basic
IF (A=3) * (B=4) THEN 100
Using this form can save a great deal of memory when testing several variables/ values.

If you are the lucky owner of an Extended Basic module, ensure you fully utilise the memory-saving devices provided.

Instead of :- 
CALL CHAR(33, "FFFFFFFFFFFFFFFF") 
use:
CALL CHAR(33,RPT$("F", 16)) 
This uses several bytes less memory.
And on CALL CHAR:- in Extended Basic you may define four characters with only one CALL, using up to 64 characters in the defining string to define Character A, A+1, A+2, A+3.

In Extended Basic several of the CALLS can be used for several items at one time - for example, CALL COLOR (1,1,1,2,1,1,3,1,l,4,1,1) and so on. Read the manual very carefully.

CALL PEEK and CALL LOAD are especially powerful as the memory locations need not be consecutive: CALL PEEK (100,A,B,C,"" 200,D,E,F) will return to A,B,C,D,E,F, the values in memory locations 100,101,102,200,201, 202- Idon't think any other computer can do that in one command.

Shorter hints DIM - If you DIM an array A(3,9,3) how many bytes does that use? In default the lowest value is A(0,0,0) and each numeric variable occupies 8 bytes, so that's 4 x 10 x 4 x 8 bytes = 1280 bytes.

If you are not using the 0 value of the array, you may reset the lowest value to 1 by using OPTION BASE 1.

This really reduces memory usage - with the SAME DIM statement we are now only using 3 x 9 x3 x 8 bytes = 648 bytes (saving: 632 bytes).

If memory is still scarce, look to see if you can use a string array - numbers can still be used, with use of the VAL function as required.

Using option base 1, and single digit numbers, the array A$(3,9,3) uses: 3 x 9 x3 x 2 = 162 bytes (saving 1118 bytes on the original).

GOSUB: If you find lines of coding appearing several times, see if you can put them in once and then use GOSUB.

In Extended Basic you may input a line up to five screen lines long, instead of four in TI Basic. Using editing features you can extend some lines to six or even seven screen lines. Sometimes your entry of four and a half lines will return 'Line Too Long'. The reason is that the internal limit on the length of the line is the number of bytes the line occupies - not the number of characters on the screen.

TI Basic plays safe and gives you only four. Extended Basic allows you another line - perhaps. But by bringing the line back onto the screen and using INSERT you can often make it longer.

Make your lines as long as possible; each line less saves at least 6 bytes.


[2014 note: If the above looks familiar, I have found a very similar article (even with headings eg MEMORY SAVER A, MEMORY SAVER B etc) in TI Lines V1 No 6 dated September 1st 1984 under the pen of David Brown. No acknowledgement to PCN or Stephen Shaw. It is said that "Imitation is the sincerest form of flattery" . The same copy of TI Lines also refers to commercial piracy of Stainless Software computer programs. I don't need all this flattery... send cheques to...].

Program in memory


100 REM PCN 
110 A=B+2 
120 C$ = D$ & "E"
 
This program was keyed in in the order shown, and not edited. When you change a line it is treated as a new entry and drops to the last memory location.

The example program teaches many things about the TI99/4A:

COMMANDS although printed (and entered) in full are tokenised and use only 1 byte each (REM is code 154).

A NUMBER takes up 2 bytes more than it has digits- 1 byte says 'this is a number', the other indicates how many digits. So for strings: 2 bytes more than the number of characters.

A VARIABLE takes up only as many bytes as it is long -but will also use up stack space.

Note that line 100 occupies locations -31 to -25 and is read in that order. In addition to 4 bytes used in the line index, line 100 uses two more 'null content' bytes-one is a zero to mark end of line , and the other byte indicates to the computer how long the line is (and also sets an absolute limit to line length in memory of 127 bytes).

Line 100 can be found in the line index allocations -55 to -52. The memory location is 255 *256 +226 = 65506.

Our memory locations don't go that high. Subtract 65536 (64 * 1024) and the result becomes -30, which is where we can find line 100.
Mem Loc = address in memory.
memory use
Above list in text format


TI Memory

From the UK magazine Personal Computer News, September 1st to September 7th 1983, page 20:

(this issue - pages marked as above, referred to as: Issue 26 - September 1st to 7th, 1983)
See full index to issue and cover jpg at: http://www.bobmockford.co.uk/pcn/026/

TEXAS ARRANGER

Plug in the TI Mini Memory Module and your Basic programming takes off, says Stephen Shaw

TI memory jogger

The TI Mini Memory Module may be used as a file for data or programs; as a means of writing and running machine code programs; or as a means of extending the features of TI Basic. It is this last facility that we are about to look into.

When the Mini Memory Module is inserted into the cartridge slot, what difference does it make to programs in TI Basic?

Seven new commands are added, five of which are relevant to programs in TI Basic:

CALL LOAD, CALL PEEK, CALL POKEV, CALL PEEKV, and CALL CHARPAT. The other two, CALL UNIT and CALL LINK, are concerned only with assembly-language programming.

CHARPAT is used to return to a string variable the current definition of a character. For example:
CALL CHARPAT (65,A$)
will place the string '003844447C444444' into the variable A$.

It is also possible to use the subprogram to return several definitions in one go:
CALL CHARPAT (65,A$, 66, B$, 67, C$, 68, D$, 69, E$) and so on.

By being able to return a character definition in this way, it is possible for a program to return a character on the screen using CALL GCHAR and then, using CALL CHARPAT, to return the definition. The program can then modify the definition.

This can be used in a pseudo high-resolution drawing routine, where characters are continually redefined as the cursor is directed around the screen.

The other four commands are of great interest, as they permit you to look at and amend the contents of the machine's memory.

In TI Basic, the program resides in visual display processor RAM, and the Mini Memory command CALL PEEKV provides the only way to look at this area of memory.

The console has '16K of RAM' but this is not directly accessible to the CPU. The on-board RAM is controlled by the visual display processor (VDP) and the CPU has access to only two bytes at a time.

In issue 8 of PCN I gave a program to investigate the storage of programs in the Expansion Memory. Here is a program to look at programs stored when using Mini Memory.

If you have a disk controller, it should be switched off before you switch the console on, as memory is otherwise used differently.

Key in the program in this order and do not edit it.

100 REM PCN 
110 A=B+2 
120 C$=D$&"E" 
130 FOR I= 16383 TO 16350 STEP -1 
140 CALL PEEKV (I, V) 
150 PRINT I; V; CHR$(V) 
160 NEXT I 
Here is the result Mem=memory location address.
32k ram program locations
Above data as a text file
The above represents the code for the first three lines of the program.

If you compare the above result with the similar list in PCN issue 8, it is interesting to note that TI Basic has added a space after the REM text of line 100.

Once the means has been provided to look at the program in memory, it is possible to amend the program: a program can, with care, write a completely new program over itself.

Here is an example. Type in the following program in this order:

100 REM PCN 
110 CALL POKEV (16379, 77, 65, 71) 
Before you RUN the program, LIST it
Now RUN it and LIST it again: notice any change?

This is a very simple example, but the means has been provided to carry out some very serious programming.

You will note the instruction not to edit these examples: the computer holds the program lines in the order that they are keyed in. Try the above two-line program again, but before you RUN it, edit the first line to read say PCW, and try again.

The computer can find its way about the program lines by means of a line index, which appears below the program in memory. If you are rewriting a program line using POKEV, you must either ensure the new line occupies the SAME number of bytes as the old one, or you face the task of rewriting the line index as well.

Extended Basic uses a different memory map from TI Basic. When TI Basic is selected, some of the memory used by sprites is not in use, and it is possible to POKEV values there to provide limited sprites using TI Basic.

The TI Basic interpreter does not recognise sprites, and in some instances you could cause a system lock-out. If you do, switch off and start again.

The examples given below will work without fuss.

Sprite information is divided into three areas of memory:
Initial position
Velocity
How many sprites are moving?

The initial positions of the sprites are kept in an area of memory which is above the TI Basic screen map but below the TI Basic colour tables. There is enough unused memory for three sprites to be defined.

The velocity values are kept in an area used by TI Basic for the value stack, but it is possible to push the stack down by redefining characters, to leave the velocities free from stack interference.

The number of sprites moving is loaded in the small CPU RAM in the CPU.

Here is a simple example, placing one sprite on screen and moving it:

100 CALL CLEAR 
200 CALL PEEKV (768,98,128,161,1 208) 
300 CALL POKEV (1920,20,20) 
400 CALL LOAD (-31878,1) 
500 GOTO 500 
Line 200 defines the initial sprite position, its colour and shape:
768 is the base address in memory,
98 and 128 are the position in pixel row and column ( 192 pixel rows and 255 pixel columns represent the full screen);
161 is the character. The equivalent ASCII code is arrived at by subtracting 96: hence 161 is character 'A'. The offset is always 96.
The number 1 is the sprite colour. Use the standard colour codes, but deduct 1: the 1 here is colour 2;
208 must always appear at the end of the sprite POKEV, whether one, two or three sprites are defined.

Line 300 provides the sprite with a velocity: 1920 is the base address , and each sprite then occupies four bytes. The last two are used by the computer and can be loaded as zeros in the POKEV. The two values are row and column velocities from 0 to 255, which represent - 127 to +128 in Extended Basic.

Line 400 tells the CPU that one sprite should be moved.

For more than one sprite, the equivalent lines would be:
200 CALL POKEV (768,98,128,
161,1,88,128,162,2,95,156,1
63,3,208)
and
300 CALL POKEV (1930,50,50,0
,0 130,2,0,0,5,140)
and
400 CALL LOAD (-31878,3)

Here are some sample programs to try
100 CALL CLEAR
110 MEM=768
120 FOR X=0 TO 3
130 CALL POKEV (MEM+X*4,20+
X*3,140-X*9,161+X,X)
140 NEXT X
150 CALL POKEV (780,208)
160 GOTO 160

100 CALL CLEAR
110 FOR T=1TO 150
120 CALL POKEV (768,30+T,40+
T/2,161+T/2,(T/10)+1,208)
130 NEXT T
If you wish to use moving sprites in a TI Basic program, first define the following characters:

100 FOR T=96 TO 159 
110 CALL CHAR (T, "0") 
120 NEXT T 
Characters up to 140 or so can be subsequently redefined without halting your sprites. The other null definitions serve to keep the variable stack from growing so that it overwrites the data, thus halting your sprites or crashing your program.

The screen resides in VDP RAM 0 to 767, but using POKEV is no faster than using CALL HCHAR.

The Colour Table follows the screen, and TI says it starts at 768. In fact it starts at 783, which is why we can use those sprites.

One byte is used to define the foreground and background colour of each character set. VDP RAM location 783 is where the cursor and edge character colours are defined, We can therefore change the cursor colour by POKEVing here.

[[ revised 2014- the magazine rewrote my work and got it horribly wrong - confusing binary and hex and introducing a strange $ symbol! - sjs ]]

Turn each colour value into a 4-bit binary number, after subtracting 1 from the usual value, eg:
BLACK = normal code 2 less 1 = BINARY of 0001
WHITE = normal code 16 less 1 = 15 = BINARY of 1111
To define the cursor as black on white, we place the black binary number before the white binary number:
00011111
Now this 8-bit binary number is converted to decimal:
00011111 = digital 31
So: CALL POKEV (783,31) will change the cursor colour.

TI says the Character Tables run from VDP RAM 1024 to 1535. As each character occupies eight bytes, this covers only characters 32 to 96.
What of the rest?
It seems the smaller characters are normally derived from the large ones by the removal of two bytes of information, thus allowing an extra set of characters with no loss of memory.

However, when it is necessary to define the small characters and ASCII codes above them, the definitions are placed above VDP RAM 1536. Then follows value stack, string space, symbol tables, line index and finally your program.

The cursor is also defined in VDP in RAM in eight bytes from 1008, while the edge character (31) is from 1016.
The normal character definition is in 16 hexadecimal characters.
VDP stores the definition in 8 numbers, the digital equivalent of eight binary numbers with one number for each of the 8 rows of 8 pixels.

Each row of pixels for a character is defined in one byte. In an 8-digit binary number, each number has a specific digital value:
128 ... 64 ... 32 ... 16 ... 4 ... 2 ... 1

Each on pixel in the line is summed with the others, giving a full line total of 255 if all the dots are on.
If the left-most pixel only is on, the value placed in VDP RAM is 128, and so on.
Thus a box cursor can be defined as
CALL POKEV (1008,255,129,129,129 129,129,129,255)

To revert to normal cursor and definition use QUIT or switch off. Or redefine!

As you can see, the Mini Memory Module can be used to make your TI Basic programs much more interesting.



Read about addfreestats visitor tracker, the data your browser reveals and how you may control it.

[ TI Book front page   |    TI Resources Page    |   TI Articles    |  PC99 and MESS Programs ]