ticalc.org
Basics Archives Community Services Programming
Hardware Help About Search Your Account
   Home :: Programming :: Columns and Tutorials :: The TI-86 Assembly Guide: Lesson 2
The TI-86 Assembly Guide: Lesson 2

by Ahmed El-Helw


Introduction to Registers

What are registers? Registers are important parts of ASM that allow the user to get in touch with other parts of the ASM Program. Registers come in 8 bit and 16 bit... see the variables section for an explanation. Without registers, programming is impossible... you can think of them as transports that transport numbers. Here are the most important registers for you to know now. There are more, but these are the most important...

  • a - the most IMPORTANT register... 8 bit, used for loading 8 bit numbers into variables, displaying text, etc. [See Variables for more information].
  • af - the above a with "f" ... this is 16 bit, vs. a alone which is 8 bit.
  • hl - as important as a ... used for text, graphics, etc.
  • de / bc - 16 bit registers, graphics, and can be used with hl.

You will eventually see the importance of these as the lessons go by. See the next section and the Variables section for more information.

The Stack

Ever eaten PanCakes for breakfast? You can think of the stack as a stack of pancakes. Suppose you have the number "5" loaded into a... suppose you don't want to load a into a variable, and you want to save it for use after another action... that is when you use the stack... The stack is simply controlled by 2 commands : push and pop. These can ONLY be used with 16 bit registers [see variable section for more detail about registers]. Here is an example of a program that uses the stack...

Note - Please remember that .. means to tab or press space bar 2+ times..


#include "asm86.h"
#include "ti86asm.inc"

#include "ti86math.inc"
#include "ti86ops.inc"
#include "ti86abs.inc"

.org _asm_exec_ram

..call _clrLCD ;Clears the Screen
..ld a,0 ;Loads 0 into a
..ld (_curRow),a ;Loads A into CurRow
;Notice here that I loaded 0 into A, then CurCol ...
;now suppose i wanted to save A for use later....
..push af ;Save A in stack
..ld a,1 ;Loads 1 into A
..ld (_curCol),a ;Loads A into CurCol
..ld hl,String ;Loads String Name into HL
..call _puts ;Displays it
;Now I want this A that I saved back.. so i can store
;it as a coordinate for the text... now I do this:
..pop af ;Restore A
..ld (_penRow),a ;Load that A into penRow
..ld (_penCol),a ;Same with that into penCol
..ld hl,String ;String name into HL
..call _vputs ;Display small text
..call _getkey ;Pause
..ret

String: .db "Made in @sm!",0

.end
END

Now, when you run that program, it should display the string twice, on top of each other, which will make it look like Gibberish... but it was the best way to illustrate my point of how you can use the stack... you can use it in many ways.. to hide af [since you cannot do "push a", you have to group it with something, and a only groups with f, therefore you do "push af".] Basically, when you do "push", you hide the variable... that means you put it at the bottom of the stack. When you "pop" something, you take the bottom thing up to the top. You can push/pop bc, hl, af, etc. This illustration may help you understand:

[A]
[B]
[C]
...

push af does this:
[B]
[C]
...
[A]

pop af does this:
[A]
[B]
[C]
...

Again, as I said, the stack does have many uses, you'll end up using it when you start programming ...

KeyLoops

There are several ways to input and get in a keypress in ASM. There are three major ways of doing it: _getkey, GET_KEY, and DirectInput. _getkey waits for a keypress, and does nothing until a key is pressed. This is the one TI supplies, and you can get all the names of the keys from ti86asm.inc. Basically, here is a _getkey loop:

Loop:
..call _getkey
..cp kF1
..jp z,F1_Was_Pressed
..jp nz,Loop

GET_KEY is the exact same thing, except it does not wait for a keypress... the keys are also different... for example, you cannot say "cp kF1", you must say "cp K_F1". The keys are listed for GET_KEY under the asm86.h file. Direct Input is a bit more complex than all of these... therefore, I will cover it in more detail in another lesson. For now, know that direct input takes input directly from the ports, it reads the ports to get keypresses, and is usually a lot faster.

Variables

In basic, you got to do "5->x" and if X = 4 and all that neat stuff... can you do that in ASM? Heck yeah! In ASM, you can do it even better... you can name your own variables, etc. But before we get into that, let us go and discover the difference between 8 and 16 bit registers. "A" as we established earlier is an 8 bit register... "AF", "HL", "BC", etc are all 16 bit registers. The "A" register is commonly used for small actions, dealing with text and the screen. The "A" register can hold a maximum of 255... Therefore, the maximum you can load into a is 255... Again, to load something into a, you do ld a,255 will load 255 into a. To load something into hl, you follow suit... ld hl,255 will load 255 into hl... those are the two most important registers for now... HL can hold a maximum of 65536.

In order to have a variable, you must first define it... There are several ways to do that, but the simplest way is as follows: Near the bottom of your Assembly program, you define variables like this:

varname: .db 0
varname1: .db 0,0

The first variable, varname is .db 0.. this is because it is an 8 bit variable. The second variable, however, is .db 0,0, because it is a 16 bit variable... in otherwords, I cannot load a number more than 255 into varname variable, because it is an 8 bit variable, but I can with varname1... if I wanted varname1 to be an 8 bit variable, i would remove the ",0"... if I wanted varname to be a 16 bit variable, I would add a ",0". You can replace varname for the name of your variables... they can be whatever you want them to be, no spaces though.

So now that you defined these variables, how do I use them? Very simple... This ASM Program will explain [I hope] how to use the variables.

#include "asm86.h"
#include "ti86asm.inc"

#include "ti86math.inc"
#include "ti86ops.inc"
#include "ti86abs.inc"

.org _asm_exec_ram

..call _clrLCD ;Clear the screen
..ld a,4 ;Loads 4 into A
..ld (XCoord),a ;Loads A into XCoord
..ld a,5 ;Loads 5 into A
..ld (YCoord),a ;Loads A into YCoord
..ld a,(XCoord) ;Load XCoord back into A
..ld (_penCol),a ;Loads A into PenCol
..ld a,(YCoord) ;YCoord into A
..ld (_penRow),a ;A into PenRow ..ld hl,String ;Load String into HL
..call _vputs ;Display it
..call _getkey ;wait for keypress
..ret ;return from ASM Program

XCoord: .db 0 ;8 bit Variable
YCoord: .db 0 ;8 bit Variable
String: .db "Placed with Variables!",0

.end
END

Well, as you see, you can treat a variable simmilarly to the registers, but you still need the registers. For example, you could not load (XCoord) directly into _penCol, you had to load it into A first, then into penCol or penRow. With time, it will get easier...


Author's Notes

This is the ASM Guide Lesson 2, Copyright (C) 1998 By: Ahmed El-Helw. This document was completed on February 1, 1998. If anyone finds any mistakes, please EMail me. You will always find the latest ASM Guide lessons on ticalc.org. Again, if anyone has any questions, comments, etc., please feel free to email me. My ICQ UIN is 3350394, you can ask me questions t here too, and I am known as Ahmed or Ahmed_ on IRC on #ti sometimes.

  Copyright © 1996-2012, the ticalc.org project. All rights reserved. | Contact Us | Disclaimer