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