From WikiTI
Revision as of 10:14, 8 March 2013 by Dr. D'nar (Talk | contribs)

Jump to: navigation, search

The Z80 CPU supports three different modes of handling interrupts. They are called IM 0, IM 1, and IM 2. The IM 0 mode is identical to the Intel 8080's interrupt handling and is provided for compatibility. In IM 0, the interrupting hardware takes over the bus and sends an instruction to the CPU to execute. This instruction would usually be an RST instruction, which is what the RST instructions were designed for. In IM 1, the Z80 always executes RST 38h.

In IM 2, the Z80 uses an interrupt vector table. The interrupting hardware gives the Z80 an index into the table, such that up to 128 devices can automatically specify which interrupt service routine (ISR) needs to be run. The I register specifies where the IVT starts. Since I is 8 bits, it only specifies the high byte; the table always starts at an address in which the low byte is zero. The interrupting hardware is supposed to send an 8-bit number that's an index into the table. So the Z80 combines the index and the value of the I register to form a 16-bit address. The Z80 uses the 16-bit number at that address as the location of the ISR.

The TI-83+ family operating system always operates in IM 1, in which any interrupt signal causes the CPU to execute the RST 38h instruction. The OS provides no hooks for allowing software to catch and process interrupts. Fortunately, the Z80 also has the IM 2 mode, which allows us to move the interrupt vector table (IVT) to any of 256 different locations. Unfortunately, in the TI-83+ IM 2 is semibroken because it would actually be useful to us if it functioned properly. The ASIC doesn't bother to specify an index into the table, so we have to poll different ports to figure out what generated the interrupt. Furthermore, you will note that the number the Z80 expects to be passed is an 8-bit number. Because the addresses in the table are 16-bits, each address takes 2 bytes. But the number the Z80 receives from the ASIC is effectively random. And the Z80 doesn't mask out the bottom bit. So you have to fill the table with 257 repeating bytes, and your ISR can only be at an address in which the high and lows bytes are the same.

The TA3 ASIC, used in older TI-84+s/SEs and the TI-83+CSE, has a useful quirk. It always sends the byte FF when an interrupt is generated. So IM 0 and IM 1 are the same. Even better, you only need to specify the final address in the IVT, and the high and low bytes don't have to be the same. Unfortunately, the TA1 ASIC doesn't do this, so TI-84+/SE software can't depend on this quirk. Also, if TI does anything to address the speed issues of the TI-84+CSE, they will probably break this useful feature just to spite us.