This lesson will tell you everything you need to know about interrupts. What they are, what different interrupt modes there are and how you can use them on the TI-82 calculator. The next chapter contains an example interrupt routine for the TI-82.
What is an interrupt |
Non-maskable interrupts |
Maskable interrupts |
Programming a TI-82 interrupt
What is an interrupt?
When the Z80 is executing commands on the TI-82, there is an interruption of the program about 200 times a second (this depends a bit on battery strenght) and when the ON key is pressed. They don't occur when interrupts are disabled (DI instruction
to disable / EI instruction to enable interrupts)
Note : The ON-key interrupt keeps working even when interrupts disabled.
The interrupt routine on the calculator takes care of keypresses (places the scancode for pressed keys in the system ram), checks the link port, etc.
On the Z80 there are 2 types of interrupts:
The Non-Maskable interrupts are not useful on the TI-82.
A non-maskable interrupt is invoked by an external unit. It causes the Z80 to run the routine that starts at $0066
There are 3 modes of maskable interrupts : IM 0, IM 1 and IM 2
Interrupt mode 0 (IM 0)
When interrupt mode 0 is set, the Z80 will read a byte from the databus and execute this as an opcode. So, if $FF is put on the databus, the instruction RST $38 will be executed. Since you can't control what's on the databus of the Z80 in the TI-82, you
can not use this interrupt mode in your programs. When you do try to use it, a random instruction will be executed and your calc will most likely crash as a consequence.
Interrupt mode 1 (IM 1)
This is the default interrupt mode on the TI-82. What happens when this interrupt occurs is the following :
PC is placed on the stack
PC is loaded with $0038
This means the routine at $0038 is executed. This is the interrupt service routine. When this routine is finished, the program continues where it was interrupted.
Interrupt mode 2 (IM 2)
This is the most powerfull interrupt mode of the Z80. Several interrupt routines on different memory locations can be executed by external units. This is done by placing a byte with the number of the needed interrupt vector on the databus.
This byte is added to the start address of a table in mem. This start address has a MSB equal to the I register and an LSB of $00. For example, if I is $84 then the table goes from $8400 to $84FF. (there's place for 128 addresses)
When the address is calculated, the Z80 jumps there (after pushing the PC to the stack).
Programming a TI-82 Interrupt
With interrupt mode 2 it is possible to program your own interrupt on the TI-82.
How do you do this :
you create a vector table of $FF bytes
create your interrupt routine
let I point to your vector table
set IM 2
There are some little problems with this. because the memory is always moving around on the TI-82, you need to put your routine and vector table in a place that is always on the same location.
Mostly, APD_BUF is used for this (You have to make sure that your interrupt disables APD if you do this, but that's only a small pain).
Next to that, there is also another problem. Since you can't control the byte on the databus, it can be anything from $00 to $FF, so all vectors need to be the same. Even more, they need to have the same byte as MSB and LSB. And since you also want this to be in APD_BUF, the address should be $8282,$8383 or $8484. Mostly, the table is placed from $8400 and the routine from $8383 or $8282 according to the bytes taken in by the routine.
Other things that need to be done when you write an interrupt handler for the TI-82 are saving the registers before you start (most of the time done with shadow registers) and to disable the interrupts. On the end of the interrupt routine, you need to restore the registers and enable interrupts again. Instead of using RETI (return from interrupt), you need to jump to $0038 (where the normal interrupt routine on the TI-82 is)
CrASH has the possibility for the programmer to set a certain byte if his interrupt routine is installed. Other programs know then that they cannot use the APD_BUF to store data (which is actually used quite often).
Previous lesson |