mirror of
https://github.com/holub/mame
synced 2025-05-23 22:20:01 +03:00
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:
parent
19ea3c4ef9
commit
3cfb47f7dd
@ -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,27 +3317,35 @@ 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));
|
||||||
|
|
||||||
|
/* check for nop */
|
||||||
|
if (irq_vector != 0x00)
|
||||||
|
{
|
||||||
switch (irq_vector & 0xff0000)
|
switch (irq_vector & 0xff0000)
|
||||||
{
|
{
|
||||||
case 0xcd0000: /* call */
|
case 0xcd0000: /* call */
|
||||||
PUSH(z80, pc);
|
PUSH(z80, pc);
|
||||||
z80->PCD = irq_vector & 0xffff;
|
z80->PCD = irq_vector & 0xffff;
|
||||||
/* CALL $xxxx + 'interrupt latency' cycles */
|
/* CALL $xxxx cycles */
|
||||||
z80->icount -= z80->cc_op[0xcd] + z80->cc_ex[0xff];
|
z80->icount -= z80->cc_op[0xcd];
|
||||||
break;
|
break;
|
||||||
case 0xc30000: /* jump */
|
case 0xc30000: /* jump */
|
||||||
z80->PCD = irq_vector & 0xffff;
|
z80->PCD = irq_vector & 0xffff;
|
||||||
/* JP $xxxx + 2 cycles */
|
/* JP $xxxx cycles */
|
||||||
z80->icount -= z80->cc_op[0xc3] + z80->cc_ex[0xff];
|
z80->icount -= z80->cc_op[0xc3];
|
||||||
break;
|
break;
|
||||||
default: /* rst (or other opcodes?) */
|
default: /* rst (or other opcodes?) */
|
||||||
PUSH(z80, pc);
|
PUSH(z80, pc);
|
||||||
z80->PCD = irq_vector & 0x0038;
|
z80->PCD = irq_vector & 0x0038;
|
||||||
/* RST $xx + 2 cycles */
|
/* RST $xx cycles */
|
||||||
z80->icount -= z80->cc_op[0xff] + z80->cc_ex[0xff];
|
z80->icount -= z80->cc_op[0xff];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 'interrupt latency' cycles */
|
||||||
|
z80->icount -= z80->cc_ex[0xff];
|
||||||
|
}
|
||||||
z80->WZ=z80->PCD;
|
z80->WZ=z80->PCD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user