Fix 6502/65C02's D flag for BRK, IRQ, NMI and RESET. (Fixes #1099)

This commit is contained in:
tomcw 2023-01-02 21:41:31 +00:00
parent 3ed6a77f3b
commit 4377441c26
4 changed files with 26 additions and 7 deletions

View File

@ -388,7 +388,9 @@ static __forceinline bool NMI(ULONG& uExecutedCycles, BOOL& flagc, BOOL& flagn,
PUSH(regs.pc & 0xFF)
EF_TO_AF
PUSH(regs.ps & ~AF_BREAK)
regs.ps = regs.ps | AF_INTERRUPT & ~AF_DECIMAL;
regs.ps |= AF_INTERRUPT;
if (GetMainCpu() == CPU_65C02) // GH#1099
regs.ps &= ~AF_DECIMAL;
regs.pc = * (WORD*) (mem+0xFFFA);
UINT uExtraCycles = 0; // Needed for CYC(a) macro
CYC(7);
@ -431,7 +433,9 @@ static __forceinline bool IRQ(ULONG& uExecutedCycles, BOOL& flagc, BOOL& flagn,
PUSH(regs.pc & 0xFF)
EF_TO_AF
PUSH(regs.ps & ~AF_BREAK)
regs.ps = (regs.ps | AF_INTERRUPT) & (~AF_DECIMAL);
regs.ps |= AF_INTERRUPT;
if (GetMainCpu() == CPU_65C02) // GH#1099
regs.ps &= ~AF_DECIMAL;
regs.pc = * (WORD*) (mem+0xFFFE);
UINT uExtraCycles = 0; // Needed for CYC(a) macro
CYC(7);
@ -681,7 +685,9 @@ void CpuReset()
_ASSERT(mem != NULL);
// 7 cycles
regs.ps = (regs.ps | AF_INTERRUPT) & ~AF_DECIMAL;
regs.ps |= AF_INTERRUPT;
if (GetMainCpu() == CPU_65C02) // GH#1099
regs.ps &= ~AF_DECIMAL;
regs.pc = *(WORD*)(mem + 0xFFFC);
regs.sp = 0x0100 | ((regs.sp - 3) & 0xFF);

View File

@ -62,7 +62,7 @@ static DWORD Cpu6502(DWORD uTotalCycles, const bool bVideoUpdate)
switch (iOpcode)
{
// TODO-MP Optimization Note: ?? Move CYC(#) to array ??
case 0x00: BRK CYC(7) break;
case 0x00: BRKn CYC(7) break;
case 0x01: idx ORA CYC(6) break;
case 0x02: HLT CYC(2) break; // invalid
case 0x03: idx ASO CYC(8) break; // invalid

View File

@ -62,7 +62,7 @@ static DWORD Cpu65C02(DWORD uTotalCycles, const bool bVideoUpdate)
switch (iOpcode)
{
// TODO-MP Optimization Note: ?? Move CYC(#) to array ??
case 0x00: BRK CYC(7) break;
case 0x00: BRKc CYC(7) break;
case 0x01: idx ORA CYC(6) break;
case 0x02: IMM NOP CYC(2) break; // invalid
case 0x03: NOP CYC(1) break; // invalid

View File

@ -56,7 +56,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#undef BNE
#undef BPL
#undef BRA
#undef BRK
#undef BRK_NMOS
#undef BRK_CMOS
#undef BVC
#undef BVS
#undef CLC
@ -137,6 +138,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#undef ADCn
#undef ASLn
#undef BRKn
#undef LSRn
#undef ROLn
#undef RORn
@ -144,6 +146,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#define ADCn ADC_NMOS
#define ASLn ASL_NMOS
#define BRKn BRK_NMOS
#define LSRn LSR_NMOS
#define ROLn ROL_NMOS
#define RORn ROR_NMOS
@ -153,6 +156,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#undef ADCc
#undef ASLc
#undef BRKC
#undef LSRc
#undef ROLc
#undef RORc
@ -160,6 +164,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#define ADCc ADC_CMOS
#define ASLc ASL_CMOS
#define BRKc BRK_CMOS
#define LSRc LSR_CMOS
#define ROLc ROL_CMOS
#define RORc ROR_CMOS
@ -303,13 +308,21 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#define BNE if (!flagz) BRANCH_TAKEN;
#define BPL if (!flagn) BRANCH_TAKEN;
#define BRA BRANCH_TAKEN;
#define BRK regs.pc++; \
#define BRK_NMOS regs.pc++; \
PUSH(regs.pc >> 8) \
PUSH(regs.pc & 0xFF) \
EF_TO_AF \
PUSH(regs.ps); \
regs.ps |= AF_INTERRUPT; \
regs.pc = *(LPWORD)(mem+0xFFFE);
#define BRK_CMOS regs.pc++; \
PUSH(regs.pc >> 8) \
PUSH(regs.pc & 0xFF) \
EF_TO_AF \
PUSH(regs.ps); \
regs.ps |= AF_INTERRUPT; \
regs.ps &= ~AF_DECIMAL; /*CMOS clears D flag*/ \
regs.pc = *(LPWORD)(mem+0xFFFE);
#define BVC if (!flagv) BRANCH_TAKEN;
#define BVS if ( flagv) BRANCH_TAKEN;
#define CLC flagc = 0;