z80, fix sms interrupt handling in cz80

This commit is contained in:
kub 2021-10-06 19:45:37 +02:00
parent 4b3e9d92e3
commit 80bf9bcce9
5 changed files with 104 additions and 94 deletions

View file

@ -199,7 +199,6 @@ void Cz80_Init(cz80_struc *CPU)
CPU->pzR16[3] = pzAF;
zIX = zIY = 0xffff;
zF = ZF;
CPU->Interrupt_Callback = Cz80_Interrupt_Callback;
}
@ -245,7 +244,6 @@ INT32 Cz80_Exec(cz80_struc *CPU, INT32 cycles)
UINT32 adr = 0;
UINT32 res;
UINT32 val;
int afterEI = 0;
union16 *data;
PC = CPU->PC;
@ -255,33 +253,36 @@ INT32 Cz80_Exec(cz80_struc *CPU, INT32 cycles)
CPU->ICount = cycles - CPU->ExtraCycles;
CPU->ExtraCycles = 0;
if (!CPU->HaltState)
{
Cz80_Exec:
if (CPU->ICount > 0)
if (CPU->Status)
{
if (CPU->Status & CZ80_HAS_NMI)
{
Cz80_Exec_nocheck:
data = pzHL;
Opcode = READ_OP();
#if CZ80_EMULATE_R_EXACTLY
zR++;
#endif
#include "cz80_op.c"
zIFF1 = 0;
CPU->Status &= ~(CZ80_HALTED | CZ80_HAS_NMI);
CPU->ExtraCycles += 11;
PUSH_16(zRealPC);
SET_PC(0x66);
} else if (CPU->Status & CZ80_HAS_INT)
{
CHECK_INT
} else if (CPU->Status & CZ80_HALTED)
{
goto Cz80_Exec_End;
}
CPU->ICount -= CPU->ExtraCycles;
CPU->ExtraCycles = 0;
}
if (afterEI)
{
afterEI = 0;
Cz80_Check_Interrupt:
if (CPU->IRQState != CLEAR_LINE)
{
CHECK_INT
}
CPU->ICount -= CPU->ExtraCycles;
CPU->ExtraCycles = 0;
if (!CPU->HaltState)
goto Cz80_Exec;
}
if (CPU->ICount > 0)
{
Cz80_Exec_nocheck:
data = pzHL;
Opcode = READ_OP();
#if CZ80_EMULATE_R_EXACTLY
zR++;
#endif
#include "cz80_op.c"
}
Cz80_Exec_End:
@ -289,7 +290,7 @@ Cz80_Exec_End:
#if CZ80_ENCRYPTED_ROM
CPU->OPBase = OPBase;
#endif
if (!(CPU->HaltState && CPU->ICount > 0))
if (!((CPU->Status & CZ80_HALTED) && CPU->ICount > 0))
cycles -= CPU->ICount;
CPU->ICount = 0;
#if !CZ80_EMULATE_R_EXACTLY
@ -308,36 +309,23 @@ void Cz80_Set_IRQ(cz80_struc *CPU, INT32 line, INT32 state)
{
if (line == IRQ_LINE_NMI)
{
zIFF1 = 0;
CPU->ExtraCycles += 11;
CPU->HaltState = 0;
PUSH_16(CPU->PC - CPU->BasePC)
Cz80_Set_Reg(CPU, CZ80_PC, 0x66);
}
else
if (state)
CPU->Status |= CZ80_HAS_NMI;
else
CPU->Status &= ~CZ80_HAS_NMI;
} else
{
CPU->IRQLine = line;
CPU->IRQState = state;
if (state != CLEAR_LINE)
if (state)
{
FPTR PC = CPU->PC;
#if CZ80_ENCRYPTED_ROM
FPTR OPBase = CPU->OPBase;
#endif
CPU->IRQLine = line;
CHECK_INT
CPU->PC = PC;
#if CZ80_ENCRYPTED_ROM
CPU->OPBase = OPBase;
#endif
if (zIFF1)
CPU->Status |= CZ80_HAS_INT;
} else
{
CPU->Status &= ~CZ80_HAS_INT;
}
}
if (CPU->ICount > 0)
{
CPU->ICount -= CPU->ExtraCycles;
CPU->ExtraCycles = 0;
}
}
@ -366,7 +354,7 @@ UINT32 Cz80_Get_Reg(cz80_struc *CPU, INT32 regnum)
case CZ80_IM: return zIM;
case CZ80_IFF1: return zIFF1;
case CZ80_IFF2: return zIFF2;
case CZ80_HALT: return CPU->HaltState;
case CZ80_HALT: return CPU->Status & CZ80_HALTED;
case CZ80_IRQ: return CPU->IRQState;
default: return 0;
}
@ -405,7 +393,7 @@ void Cz80_Set_Reg(cz80_struc *CPU, INT32 regnum, UINT32 val)
case CZ80_IM: zIM = val; break;
case CZ80_IFF1: zIFF1 = val ? (1 << 2) : 0; break;
case CZ80_IFF2: zIFF2 = val ? (1 << 2) : 0; break;
case CZ80_HALT: CPU->HaltState = val; break;
case CZ80_HALT: CPU->Status = !!val * CZ80_HALTED; break;
case CZ80_IRQ: CPU->IRQState = val; break;
default: break;
}