Date : Thu, 18 Aug 1994 09:20:37 +0100
From : Bonfield James <jkb@...>
Subject: Interrupts
Stephen Quan writes:
>The AUG is not very definitive on what happens here. In one case, it
>says "on a NMI it makes a call to 0xD00 with interrupts disabled", in
>another cases, it says "NMI makes a jump to 0xD00". Well, in any case,
>what I have done is define two variables, called NMI and MI which
>are normally 0 and changes to 1 when an interrupt is raised, and to
>detect an interrupt, in my 6502 emulator I have :
This is a bit confusing, it actually does 'JMP (&FFFA)' (with a little stack
pushing). Maskable interrupts indirect via &FFFE instead. Ok, this won't make
any difference in our case, as the beeb always has &0D00 stored in &FFFA, but
for a true emulation you should be aware of such things.
I'm not worrying about NMIs to start with. They are never generated anyway as
far as I can see, except by the disk system. Most interrupts are caused by the
6522. These include video refresh, 100Hz timer and keyboard keypresses
amongst other things.
> if (NMI == 1)
> {
> NMI = 0;
> pushw(PC);
> PC = 0xD00;
> P |= P_I;
> }
You should add a pushb(P) between the pushw and the PC line too. The same
applies for MI.
>Also, when I do a JSR, I throw PC-1 on a stack (since RTS pulls PC and
>adds 1 back to it). With the interupt I think I just throw PC on the
>stack as the RTI will pull PC *without* adding 1 to it, is this the
>correct behaviour?
It appears to be so :-) My RTS and RTI are:
#define RTS(len, time) \
{ \
PC = readwq(SP + 0x101) + 1; SP += 2; \
inc_time(time); \
}
#define RTI(len, time) \
{ \
P = pullb(); \
PC = readwq(SP + 0x101); SP += 2; \
inc_time(time); \
}
I'm unsure why I've got this discrepancy now. I guess I did some tests to see
precisely what was pushed on the stack. Anyone have any accurate details on
this? The above works for me, but only because I ensure I push the correct
thing on the stack anyway. It seems unlikely to be correct, but then again (my
memory as always lets me down here) I can't see why I coded it this way
without good reason.
My interrupts, under UNIX, are currently being generated in a hacky way. I use
the UNIX itimer() facility to generate the 100Hz 6522 timer. Ideally it ought
to be what the 6522 latches are actually set to. The 'proper' method of
checking every machine opcode is dead slow in comparison, but I fear I may
require this sometime.
James