The Stack

z80 » Intermediate

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