Re: A83: Interrutps...
[Prev][Next][Index][Thread]
Re: A83: Interrutps...
At 05:14 PM 11/10/97 -0600, Dimitri Andre Dugal-Hammond wrote:
>Hey, can NEone tell me about interrupts? Such things as IM, EI, DI,
>RETI, RETN, EX, EXX, etc... I'm working on a prog that's gonna require
>the use of interrupts (I know a little-tad). Thanx a lot in advance!!
>
OK, I've only played with interrupts on the 85, but since its the same
processor, I'll assume they're almost exactly the same.
First, the interrupt modes (IM). There are three interrupt modes, IM 0, IM
1, and IM 2. IM 0 is not used by the calc (the interrupting device places
the instruction directly on the data bus). IM 1 is what the calc is always
using (except when certain assembly programs change it). In IM 1, the
processor always "calls" $0038 for the interrupt handler routine. This is
not any help to us. IM 2 is the most important mode. On an interrupt in
IM 2, the processor "calls" an address pointed to by a vector table. The
MSB of the address of the vector table is given by the I register. The LSB
is given by the interrupting device, and, for out purposes is essentially
random. So in order to always jump to a fixed address, we must have a 257
byte block of memory starting at $xx00 filled with the same number. (No
that's not a typo, more later). We must then load $xx into the I register.
Now, because the LSB can be any number, the table must cover the word at
$xx00 to $xxFF, which means that the table must be 257 bytes instead of
256. It also means that your interrupt handler routine must be at an
address in the form $yzyz (i.e. the MSB and LSB of the address are the
same). For instance:
We have our table at $8000 (I know this won't actually work, but this is an
example). Every byte from $8000-$8100 is filled with the same byte (let's
say $AB).
So then we change the I register to point to this block of memory and set
im 2:
ld a,$80
ld i,a
im 2
Then (every 200th of a second), an interrupt occurs. The processor
realizes it's in IM 2, and uses a vector table. The MSB of the address in
the table is given by the I register (which is $80). The LSB is random.
(Let's say it's $01). So the processor looks at $8001 for the address of
the interrupt handler. Since $8001 and $8002 both contain $AB, the
resulting address is $ABAB. (If the LSB had been, say, $02, the address
would have been $8002, and the resulting address of the interrupt handle
would still have been $ABAB). So then the calc "calls" $ABAB.
Moving on to EI and DI. DI means disable interrupts, and stops interrupts
from occuring every 200th of a second (The ON key will still generate an
interrupt). EI obviously enables them again. You should DI at the
beginning of your interrupt handler and EI at the end.
RETI is a special return that you do at the end of your interrupt handler.
RETN is the same except it's for non-maskable interrupts, which the
calculator does not have.
EX AF,AF' exchanges the accumulator and flag registers with their shadow
registers. This is essential to your interrupt routine because YOU MUST
PRESERVE ALL REGISTERS!!! EXX will exchange B,C,D,E,H, and L with their
shadow registers. Both of these instruction should be performed twice in
your interrupt handle, once at the beginning, and once at the end.
Well, that's it. (Whew)
You can, actually just use rst 38h instead of reti. This will jump to the
actual interrupt handler on the calc, which will still allow you to use
get_key. I have an example that needs some cleaning up that I will post if
you want. Hope this helps.
--
Brian Leech
butvis@mindspring.com
ICQ UIN: 1355611
References: