Many people reacted on this question, but they aren't giving the same
answer. I will try to help out on the details :)
> >What will happen if a NEW interrupt occurs when the MSX is
> >processing obove mentioned "routine-part"?
>
> It will be remembered. As an explanation, I'll give a few facts about how
> interrupts are handled.
Yes, and no. When the interrupts are disabled (i.e. after a DI) the Z80
ignores any new detections of interrupt requests. So the Z80 doesn't
remember anything. But Maarten is right in his explanation:
> A device generating an interrupt will continue to do so until it is
> explicitly asked to "shut up". For example, the VDP will ask for an
> vertical blanking interrupt until you read status register 0. If your
> interrupt routine doesn't read that register, the VDP will keep generating
> interrupts and your MSX will crash.
So the VDP is indeed the one who does the "remembering", not the Z80. The
VDP will nag like a child :) until statusregister 0 is read. But this is not
even really the case, because a second generated interrupt from the same
device will not be remembered. So, say we're using the normal VDP vertical
blanking interrupt:
DI
read statusreg #0
ld hl,counter
inc (hl)
...
...
ld a,(event)
or a
jr z,no_event
xor a
ld (event),a
[wait for X seconds]
no_event:
EI
ret
counter:
db 0
Now, say we start this interrupt routine with (event)=0. [counter] is
incremented every 1/60 (or 1/50) second. But if we set (event)=1, the
interrupt routine will need X seconds longer to execute. In this time,
[counter] is never increased. So if you were using [counter] for a
clock, this is where it all goes wrong.
If you are only using the standard (vertical blanking VDP) interrupt, you
might be using these bits of code:
"REMEMBER ONE INTERRUPT"
(standard issue stuff)
DI
push registers
in a,(099h) ; to read statusregister 0
...
...
pop registers
EI
ret
But there is another approach (used in Space Manbow, I believe). Again,
we're only using that normal VDP interrupt in the example:
"REMEMBER NO INTERRUPT"
DI
push registers
in a,(099h) ; read statusregister 0
...
...
in a,(099h) ; cancel any lingering request
pop registers
EI
ret
This last bit of code can be adjusted to fit any kind of interrupt request.
You simply "cancel" any other request that might have been generated during
your interrupt routine.
To be precise: that first "in a,(099h)" needn't even be there, but then you
have to be careful that there's no "EI" left in the code that you put where
the dots (...) are - that could cause your MSX to crash. But if you're a
careful coder, you can put the "in a,(099h)" just a bit before the EI.
> The interrupt routine should end with an instruction that re-enables the
> interrupts. I think RETI does that. Anyway, the MSX BIOS uses EI followed
> by RET instead.
Yup. That the BIOS uses EI is very weird. But play it safe, and use EI; RET
like they do :)
> So, interrupt requests occuring while an interrupt routine is being handled
> are not different from interrupt requests occuring at any other time.
No, it's not the same, because a second request is missed :)
greetz,
Cas Cremers
****
MSX Mailinglist. To unsubscribe, send an email to [EMAIL PROTECTED] and put
in the body (not subject) "unsubscribe msx [EMAIL PROTECTED]" (without the
quotes :-) Problems? contact [EMAIL PROTECTED] (www.stack.nl/~wiebe/mailinglist/)
****