Re: Interrupt modes
[Prev][Next][Index][Thread]
Re: Interrupt modes
On Mon, 11 Aug 1997 23:38:53 -0400, "Thomas J. Hruska"
<thruska@TIR.COM> wrote:
>Quicky question about interrupt modes. I've seen several programs that use
>IM 2. So, what exactly is IM 0-2? TIA
A short interrupt explanation... the Z80 has two different interrupt
types, non-maskable interrupts and maskable. You can't do anything
about the NMI interrupts (and I know little about them) but the
maskabled interrupts are those controlled by IM 0- IM 1, and also DI &
EI.
An interrupt (maskable) occurs about 200 times/sec (depending a bit on
battery strength - more often if much battery left of course) if the
interrupts are enabled (EI) and also when the ON key is pressed (even
when DI). If the current interrupt mode is 0, the Z80 expects an
external unit to put two bytes (word) on the databus. The Z80 will
then jump to that address and execute code until a RETI instruction is
encountered, and then it will resume where it was. However, since
there are no external units connected to the 85 (and can never be),
those two bytes will be selected at random (not random, but you can
never know what those bytes will be) so basically, if you put IM 0
in your code, a random jump will occur = 100% crash.
IM 1 is default on the 85. When an interrupt occurs, a jump is made to
38h (on the TI keyboard reading, checking linkport etc is done there).
Since you, as a programmer, can't control what's at 38h (since it's
the ROM), IM 1 is not something that can be used if you want to make
an interrupt handler.
IM 2 is the most flexible interrupt mode. When an interrupt occurs,
the Z80 expects one byte to be put on the databus (random again).
That byte will be used as the least significant byte in a word, where
the MSB is the contents of the I register. The Z80 will then read a
word from that address (I'256+<databus byte>) and jump there.
If you want to use IM 2, you'll have to create a 257 byte table
from an adress $xy00 to $x(y+1)00 (for example, $8700-$8800)
and at that address store a byte, $ab (for example $88). The
interrupt handler must then be at address $8888 (always in $abab
"format"). The handler should end with a JP 38h, so it continues
with the normal interrupt execution. I don't know if it would be
possible to but a RETI there.
If you want to make an interrupt handler, don't forget to EX AF,AF'
and EXX which will swap all registers with the shadow registers. Those
instructions are also needed before JP 38h.
Good luck with interrupt programming!
Jimmy Merdell <mja@algonet.se>
http://www.algonet.se/~mja
References: