The Stack
The stack is a part of the calculator's memory that it uses for calls. When something is called, the TI86 has to remember where it just came from so that it can go back. An address is two bytes, a word, and so the stack is incremented/decremented a word to allow for the storage or removal of an address.
The stack is like a deck of cards: You put Card A on, then Card B, and then Card C. When you go to take them off: first comes Card C, then Card B, and last Card A. The first one on is the last one off.
1 | 2 | 3 | ||
Card A | Card B | Card C | ||
Card A | Card B | |||
Card A |
Then as you take it off...
1 | 2 | 3 | ||
Card C | Card B | Card A | ||
Card B | Card A | |||
Card A |
We can use the stack to store values temporarily. This is useful
when you have bc
holding the value of $3205
and you want
to call a function that you know will change the contents of bc
,
so you push bc
onto the stack, call the
function, and pop bc
off the stack.
When you
push something, it is not stored with a label "I belong to bc
".
The value is just there at the top. You can pop
it off as hl
for all I care, but that might confuse you later. When you push
something, the register still has the value, the value is just
copied to the top of the stack.
ld bc,$0303 ;load bc with coordinates (3,3) push bc ; want to keep bc so i'm pushing it call clear_and_draw ;call 'clear_and_draw' routine pop bc ;put the coordinates back in their place ret ;exit clear_and_draw: ;draws bird at (3,4) call _clrLCD ;clear screen ld bc,$0304 ;erase bc, put new coordinates call draw_bird ;draw bird at (3,4) on screen ret ;go home
The same code can be written like this too. There's no change the the
actual code but the way we load the coordinates is different. Instead of
having to figure out the coordinates manually and put them in the right
spaces, we can just multiply the first coordinate by 256 so it now
a 16 bit value and is stored in the upper register of bc
which is
b
. Then we just add the second coordinate which just affects the
bottom register, c
.
ld bc,256*3+3 ;load bc with coordinates (3,3) push bc ;i want to keep bc so i'm pushing it call clear_and_draw ;call 'clear_and_draw' routine pop bc ;put the coordinates back in their place ret ;exit clear_and_draw: ;draws bird at (3,4) call _clrLCD ;clear screen ld bc,3*256+4 ;erase bc, put new coordinates call draw_bird ;draw bird at (3,4) on screen ret ;go home
The functionality of this is better used with the variable width (small) font where you have coordinates that are large hexadecimal numbers. The following loads the variable cursor position with (25,48) which would be ($19,$30) in hexadecimal.
ld bc,256*48+25 ;load the text coordinates 25,48 ;across 25 and down 48 ld (_penCol),bc ;load up the coordinates for the cursor
You can also use define to make it even easier.
#define coords(x,y) ld hl,256*y+x / ld (_penCol),hl coords(5,24) ld hl,text_to_print jp _vputs text_to_print: .db "stupid",0
More from z80 » Intermediate
All the Flags // Debugging // Down-Left Bug // _GetKey Codes // Logical Operators // Memory, ROM, RAM, and Safe Areas // Miscellaneous Instructions // PC and SP // Random Numbers // TI's ROM Calls // Restart Commands // Simulated 16-bit Addition // The Stack // Tables and Arrays // Text Display // Variables