Z80: Check for NOP in interrupt mode 0. This allows code like ei / halt / di to work correctly. A better solution would be to implement full support for arbitrary opcodes in mode 0.

This commit is contained in:
Dirk Best 2009-11-03 16:54:46 +00:00
parent 19ea3c4ef9
commit 3cfb47f7dd

View File

@ -18,6 +18,7 @@
* - This entire notice must remain in the source code. * - This entire notice must remain in the source code.
* *
* TODO: * TODO:
* - Interrupt mode 0 should be able to execute arbitrary opcodes
* - If LD A,I or LD A,R is interrupted, P/V flag gets reset, even if IFF2 * - If LD A,I or LD A,R is interrupted, P/V flag gets reset, even if IFF2
* was set before this instruction * was set before this instruction
* - Ideally, the tiny differences between Z80 types should be supported, * - Ideally, the tiny differences between Z80 types should be supported,
@ -3316,26 +3317,34 @@ static void take_interrupt(z80_state *z80)
/* if neither of these were found we assume a 1 byte opcode */ /* if neither of these were found we assume a 1 byte opcode */
/* was placed on the databus */ /* was placed on the databus */
LOG(("Z80 '%s' IM0 $%04x\n", z80->device->tag, irq_vector)); LOG(("Z80 '%s' IM0 $%04x\n", z80->device->tag, irq_vector));
switch (irq_vector & 0xff0000)
/* check for nop */
if (irq_vector != 0x00)
{ {
case 0xcd0000: /* call */ switch (irq_vector & 0xff0000)
PUSH(z80, pc); {
z80->PCD = irq_vector & 0xffff; case 0xcd0000: /* call */
/* CALL $xxxx + 'interrupt latency' cycles */ PUSH(z80, pc);
z80->icount -= z80->cc_op[0xcd] + z80->cc_ex[0xff]; z80->PCD = irq_vector & 0xffff;
break; /* CALL $xxxx cycles */
case 0xc30000: /* jump */ z80->icount -= z80->cc_op[0xcd];
z80->PCD = irq_vector & 0xffff; break;
/* JP $xxxx + 2 cycles */ case 0xc30000: /* jump */
z80->icount -= z80->cc_op[0xc3] + z80->cc_ex[0xff]; z80->PCD = irq_vector & 0xffff;
break; /* JP $xxxx cycles */
default: /* rst (or other opcodes?) */ z80->icount -= z80->cc_op[0xc3];
PUSH(z80, pc); break;
z80->PCD = irq_vector & 0x0038; default: /* rst (or other opcodes?) */
/* RST $xx + 2 cycles */ PUSH(z80, pc);
z80->icount -= z80->cc_op[0xff] + z80->cc_ex[0xff]; z80->PCD = irq_vector & 0x0038;
break; /* RST $xx cycles */
z80->icount -= z80->cc_op[0xff];
break;
}
} }
/* 'interrupt latency' cycles */
z80->icount -= z80->cc_ex[0xff];
} }
z80->WZ=z80->PCD; z80->WZ=z80->PCD;
} }