Site hosted by Angelfire.com: Build your free website today!

Beginning TI-82 Assembly Programming, Part I
By: Doug Torrance

In this column:

Starting out
Displaying text
Runnning your program
I will be writing these columns as I learn asm myself. I will try to include methods for use in both shells, Ash v3.0 and OS-82 v1.1.

Starting out
Well, first, you need to open a text editor, such as Notepad. The first lines in Ash programs will always be:

#include "ti82.h"
.org START_ADDR
.db "Description",0
And for OS-82 programs:


#include "ti-82.h"
.org 0
.db "Description",0
The #include command tells the assembler program (most likely tasm) the name of the file to use to interpret a lot of the commands you will be using, such as ROM_CALLS. Ash uses "ti82.h" and OS-82 uses "ti-82.h". The .org START_ADDR used in Ash has to do with Ash's memory relocation, and the .org 0 used in OS-82 has to do with its lack of memory relocation. Finally, the .db "Description",0 sets the string that will be used in the shell's menu. So, if you want "Tetris v1.0" to appear in the menu of Ash or OS-82, type .db "Tetris v1.0",0. The zero at the end means that the string is zero-terminated. All the strings that you will use when outputing text to the screen will have to be zero-terminated.

Displaying Text
Here is where the two shells start to get very different. First, I will explain how to write on the screen in Ash. Start out by clearing the screen with ROM_CALL(CLEARLCD). To write in the large font used on the home screen, you will use ROM_CALL(D_ZT_STR). To set where the cursor position is, use CURSOR_ROW and CURSOR_COL. These are addresses $800c and $800d in the TI-82's RAM. (If you are wondering how the assembler knows what CURSOR_ROW and CURSOR_COL are, they were defined as $800c and $800d in ti82.h.) CURSOR_POS can also be used instead of CURSOR_ROW, and vice versa (they both point to $800c). Just like in the Output( command in Basic, the cursor positions relate to positions on the 8*16 home screen. To display "Hello" in the upper left hand corner of the screen, you would use the following code:

#include "ti82.h"
.org START_ADDR
.db "Hello",0
ROM_CALL(CLEARLCD)
ld hl,$0000
ld (CURSOR_ROW),hl
ld hl,String
ROM_CALL(D_ZT_STR)
Loop:
call GET_KEY
cp $09
ret z
jr Loop
String:
.db "Hello",0
.end
.end
I'm sure you have some questions about this source code.

Why are some lines indented are others not?

The compiler expects commands, like ld and ROM_CALLs to be indented at least a space, and labels, like Loop and String, to be at the far left margin.

What is ld?

ld acts the same way as the store arrow in Basic programs. However, it's written backwards. For instance,

ld a,3

does the same thing in asm as

3\->\A

does in Basic.

What is hl?

hl is a register, which you should become very familiar with. Use registers to store values, like you would use a variable in a basic program. However, the downside of registers is that there are not that many of them, and they tend to get written over a lot. That's why we use registers normally only to keep numbers for a short time, rather than to keep something that we want to stay for a while, like a high score. For instance, hl is used here to store the number that we want to put in CURSOR_ROW. (The ld command has to have one register after it. We can't just put ld (CURSOR_ROW),$0000. That's why it takes two lines, because we have to store $0000 to a register, hl, and then hl to (CURSOR_ROW).)

Why is (CURSOR_ROW) in parentheses?

This means that we want to change what CURSOR_ROW points to, not its actual value. CURSOR_ROW's actual value is $800c, whereas (CURSOR_ROW) is the value located at $800c, which, after we changed it, is $0000.

Why do you only use CURSOR_ROW? I thought you said there was a CURSOR_COL, too.

hl is a two-byte register, so you can store two bytes of information. So if you store a two-byte value (also known as a word) to a memory address, it will write to that byte ($800c) and the next byte ($800d). The only advantage of using hl rather than a one-byte register, such as a, is that you can change the row and column of the cursor at the same time. If you used a one-byte register, it would look like this:


ld a,$00
ld (CURSOR_ROW),a
ld a,$00
ld (CURSOR_COL),a
This changes the values at $800c and $800d individually, rather than both at once.

What's with the Loop stuff?

This code just waits until you press Enter before returning to Ash. How this works will be presented in the next lesson.

What's with the String stuff?

Okay, String is defined at the end of your program as the zero-terminated string "Hello",0. ROM_CALL(D_ZT_STR) displays the zero-terminated string that hl points to. So, we have to make hl point to String if we want it to be displayed. That's why we put ld hl,String. This stores String's memory location to hl, where it can be used by ROM_CALL(D_ZT_STR) to output the text. There you go! You now have "Hello" on the screen.

If you can't figure it out, the .end's mean the end of the program. I'm not sure why you need two. If only one is put, you tend to get an error in tasm.

So, let's say you want the smaller font used on the graph screen. It's used the same way, except ROM_CALL(D_ZM_STR) is used instead. Also, CURSOR_X and CURSOR_Y ($8215 and $8216) are used for where the cursor is located. Again, you can use CURSOR_X only if you use a two-byte registers. Just like Text( in Basic, the cursor positions relate to any of the pixels in the 63*96 graph screen. Some code that would do the same thing as the one above, except using the small menu font would be:


#include "ti82.h"
.org START_ADDR
.db "Hello",0
ROM_CALL(CLEARLCD)
ld hl,$0000
ld (CURSOR_X),hl
ld hl,String
ROM_CALL(D_ZM_STR)
Loop:
call GET_KEY
cp $09
ret z
jr Loop
String:
.db "Hello",0
.end
.end
Okay, if you want to display something in an OS-82 program, you're going to have to go through a little more work due to the shell's lack of a memory relocation feature. You have to add the address of the string to (PROGRAM_ADDR) (the address in memory where the program begins) so the TI-82 will know where to look for the string. After you've set your cursor, you do this:


ld hl,String
ld de,(PROGRAM_ADDR)
add hl,de
de is another two-byte register, like hl.

Also, when using ROM_CALL(D_ZM_STR) in OS-82, you have to put

res 7,(IY+20)

This resets a bit in the RAM that tells the calculator to write to the graph. You only have to do this in OS-82 because Ash sets it beforehand.

Here are the two programs above converted for OS-82:


#include "ti-82.h"
.org 0
.db "Hello",0
ROM_CALL(CLEARLCD)
ld hl,$0000
ld (CURSOR_ROW),hl
ld hl,String
ld de,(PROGRAM_ADDR)
add hl,de
ROM_CALL(D_ZT_STR)
Loop:
call GET_KEY
cp $09
ret z
jr Loop
String:
.db "Hello",0
.end
.end

#include "ti-82.h"
.org 0
.db "Hello",0
ROM_CALL(CLEARLCD)
res 7,(IY+20)
ld hl,$0000
ld (CURSOR_X),hl
ld hl,String
ld de,(PROGRAM_ADDR)
add hl,de
ROM_CALL(D_ZM_STR)
Loop:
call GET_KEY
cp $09
ret z
jr Loop
String:
.db "Hello",0
.end
.end
The res command and its friend, set, are also used if you want to make your text white on a black background or switch it back to black on a white background.


display white on black: set 3,(IY+05)

display black on white: res 3,(IY+05)

An example of this is a modified version of the first program:
#include "ti82.h"
.org START_ADDR
.db "Hello",0
ROM_CALL(CLEARLCD)
set 3,(IY+05)
ld hl,$0000
ld (CURSOR_ROW),hl
ld hl,String
ROM_CALL(D_ZT_STR)
Loop:
call GET_KEY
cp $09
ret z
jr Loop
String:
.db "Hello",0
.end
.end
Hopefully, you understand how to display text on the screen.

Running your program
Requirements:

tasm - assembler that creates a .obj file from your .asm file
The next three come in the zip files for Ash and OS-82 (except for fix.com, which only comes in the OS-82 .zip file, even though you need it for both).
prgm82.exe (Ash) or asm82.exe (OS-82) - creates .82p file from the .obj file
fix.com - updates checksum of .82p file
asm.bat - batch file that automates everything
So, in Notepad, save your program as filename.asm. Then, in DOS, making sure you're in the directory with the .asm file and all the files mentioned above, type "asm [filename]" (no .asm extension). If you have errors in your program, tasm will tell you. Hopefully, you won't, and then you'll have a program that's ready to send to your calculator.

Next column: Jumps, Loops, and Getkeys