[A83] Re: im 2
[Prev][Next][Index][Thread]
[A83] Re: im 2
This is old news :) People have been doing it on the 85 and 86 for a very
long time. On the 85, it's the only way to do an interrupt handler.
You bring up an interesting point regarding the lower bit being 0 to produce
word aligned addresses. Technically, it may be that the device generating
the interrupt should always do this. Matt Johnson was confused by this very
issue on the 86 Central interrupt section. Because there is only two
interrupting devices, the timer interrupt and the on interrupt, and neither
of them generate a value, you must assume that it is random. As such, 257
different addresses can be generated. This means that your interrupt table
must be 257 bytes long.
What you do is pick a place in memory that starts on an address where both
bytes are the same, like $8181. You then copy the interrupt routine there.
The interrupt routine will always jump here, because of the interrupt table
that you setup. Pick a spot that is on a 256 byte aligned address, like
$8000. The interrupt table will go from $8000 to $8100, inclusive, taking
up 257 bytes. Then set every byte in this range to the value that you
picked for the interrupt table, $81. Then load the high byte of the
starting address for the table into the i register, and set interrupt mode
2. An example is shown:
ld hl,IntStart ; relocatable interrupt routine (no absolute
jumps in the code)
ld de,$8181 ; interrupt routine goes here
ld bc,IntEnd-IntStart ; length of routine
ldir ; copy it
ld hl,$8000 ; interrupt table goes here
ld de,$8001 ; use copy-to-next-byte chain to fill it
inc b ; bc was 0, now it is $100, or 256 (first
is done already)
ld (hl),$81 ; the interrupt routine is at $8181, fill
first byte
ldir ; fill the next 256 bytes, for a total of
257
ld a,$80 ; the interrupt table starts at $8000
ld i,a ; set IM 2 jump register
im 2 ; set interrupt mode 2
IntStart:
; there might be stuff on the 83/83+ that you have to do here, but I
; haven't researched it, and don't care to, as there are likely several
; examples that you can swipe code from
; remember that if you use any registers here, to save them, including
; the flags register...a fast way to do this is to use shadow registers
; in the interrupt
reti ; just a dummy example, return immediately
IntEnd:
> According to the cpu manual, when you use interrupt mode 2, you should
create a pointer
> table somewhere in memory, then put in the I reg the most significant
byte. When an
> interrupt happens the Z80 takes the I register and the interrupting device
provides the
> lower 8 bits. Then it jumps to the pointer stored at the address that is
formed. The manual
> also says that the lowest bit provided should always be 0 to create even
numbers,
> because pointers are 16 bit and therefore take 2 bytes. For now I've
discovered that this
> isn't the case on the 83-. The interrupting device seems to generate an 8
bit numbers (not
> 7). But is this also on the 83+(SE)?
References:
- [A83] im 2
- From: Tijl Coosemans <tijl.coosemans@mail.be>