From 0fef6516f497880f0aadcf351e25f51a099dcd41 Mon Sep 17 00:00:00 2001 From: tomcw Date: Tue, 15 Aug 2017 22:12:51 +0100 Subject: [PATCH] Debugger: fix _6502_GetTargets() when abs addr16 wraps over 64K boundary (crash bug) & extend debugger unit-tests --- source/Debugger/Debugger_Assembler.cpp | 6 +- test/TestDebugger/TestDebugger.cpp | 120 ++++++++++++++++++++++--- 2 files changed, 112 insertions(+), 14 deletions(-) diff --git a/source/Debugger/Debugger_Assembler.cpp b/source/Debugger/Debugger_Assembler.cpp index 01a476de..db74dcb5 100644 --- a/source/Debugger/Debugger_Assembler.cpp +++ b/source/Debugger/Debugger_Assembler.cpp @@ -608,9 +608,9 @@ bool _6502_GetTargets ( WORD nAddress, int *pTargetPartial_, int *pTargetPartial bStatus = true; - BYTE nOpcode = *(LPBYTE)(mem + nAddress ); - BYTE nTarget8 = *(LPBYTE)(mem + nAddress + 1); - WORD nTarget16 = *(LPWORD)(mem + nAddress + 1); + BYTE nOpcode = mem[nAddress]; + BYTE nTarget8 = mem[(nAddress+1)&0xFFFF]; + WORD nTarget16 = (mem[(nAddress+2)&0xFFFF]<<8) | nTarget8; int eMode = g_aOpcodes[ nOpcode ].nAddressMode; diff --git a/test/TestDebugger/TestDebugger.cpp b/test/TestDebugger/TestDebugger.cpp index 89e765d0..dfc1e7e9 100644 --- a/test/TestDebugger/TestDebugger.cpp +++ b/test/TestDebugger/TestDebugger.cpp @@ -66,7 +66,7 @@ bool FindAddressFromSymbol ( const char* pSymbol, WORD * pAddress_, int * iTable void init(void) { - mem = (LPBYTE)VirtualAlloc(NULL,64*1024,MEM_COMMIT,PAGE_READWRITE); + mem = (LPBYTE)VirtualAlloc(NULL,128*1024,MEM_COMMIT,PAGE_READWRITE); // alloc >64K to test wrap-around at 64K boundary } void reset(void) @@ -82,7 +82,7 @@ void reset(void) //------------------------------------- -int GH445_test_sub_PHn(BYTE op) +int GH445_test_PHn(BYTE op) { bool bRes; int TargetAddr[3]; @@ -105,7 +105,7 @@ int GH445_test_sub_PHn(BYTE op) return 0; } -int GH445_test_sub_PLn(BYTE op) +int GH445_test_PLn(BYTE op) { bool bRes; int TargetAddr[3]; @@ -128,41 +128,139 @@ int GH445_test_sub_PLn(BYTE op) return 0; } +int GH445_test_abs(BYTE op, WORD target2) +{ + bool bRes; + int TargetAddr[3]; + int TargetBytes; + + mem[regs.pc] = op; + mem[(regs.pc+1)&0xFFFF] = (BYTE) (target2&0xff); + mem[(regs.pc+2)&0xFFFF] = (BYTE) ((target2>>8)&0xff); + bRes = _6502_GetTargets(regs.pc, &TargetAddr[0], &TargetAddr[1], &TargetAddr[2], &TargetBytes); + if (!bRes || TargetAddr[2] != target2) return 1; + + return 0; +} + +int GH445_test_jsr(void) +{ + bool bRes; + int TargetAddr[3]; + int TargetBytes; + + mem[regs.pc] = 0x20; + + regs.sp = 0x1FF; + bRes = _6502_GetTargets(regs.pc, &TargetAddr[0], &TargetAddr[1], &TargetAddr[2], &TargetBytes, false); + if (!bRes || TargetAddr[0] != regs.sp || TargetAddr[1] != regs.sp-1) return 1; + + regs.sp = 0x100; + bRes = _6502_GetTargets(regs.pc, &TargetAddr[0], &TargetAddr[1], &TargetAddr[2], &TargetBytes, false); + if (!bRes || TargetAddr[0] != regs.sp || TargetAddr[1] != 0x1FF) return 1; + + regs.sp = 0x101; + bRes = _6502_GetTargets(regs.pc, &TargetAddr[0], &TargetAddr[1], &TargetAddr[2], &TargetBytes, false); + if (!bRes || TargetAddr[0] != regs.sp || TargetAddr[1] != regs.sp-1) return 1; + + return 0; +} + +int GH445_test_rts(WORD sp) +{ + bool bRes; + int TargetAddr[3]; + int TargetBytes; + + mem[regs.pc] = 0x60; + + regs.sp = sp; + WORD sp_addr_l = 0x100 + ((regs.sp+1)&0xFF); + WORD sp_addr_h = 0x100 + ((regs.sp+2)&0xFF); + WORD rts_addr = 0x1234; + mem[sp_addr_l] = (BYTE) (rts_addr&0xFF); + mem[sp_addr_h] = (BYTE) ((rts_addr>>8)&0xFF); + rts_addr++; // NB. return addr from stack is incremented before being transferred to PC + bRes = _6502_GetTargets(regs.pc, &TargetAddr[0], &TargetAddr[1], &TargetAddr[2], &TargetBytes, false); + if (!bRes || TargetAddr[0] != sp_addr_l || TargetAddr[1] != sp_addr_h || TargetAddr[2] != rts_addr) return 1; + + return 0; +} int GH445_test_sub(bool bIs65C02) { int res; + mem[0x10000] = 0xDD; // Bad data if 64K wrap not working + mem[0x10001] = 0xDD; + + mem[0x200] = 0xDD; // Bad data if SP wrap not working + mem[0x201] = 0xDD; + + // + // PHn/PLn + regs.pc = 0x300; - res = GH445_test_sub_PHn(0x08); // PHP + res = GH445_test_PHn(0x08); // PHP if (res) return res; - res = GH445_test_sub_PHn(0x48); // PHA + res = GH445_test_PHn(0x48); // PHA if (res) return res; if (bIs65C02) { - res = GH445_test_sub_PHn(0x5A); // PHY + res = GH445_test_PHn(0x5A); // PHY if (res) return res; - res = GH445_test_sub_PHn(0xDA); // PHX + res = GH445_test_PHn(0xDA); // PHX if (res) return res; } // - res = GH445_test_sub_PLn(0x28); // PLP + res = GH445_test_PLn(0x28); // PLP if (res) return res; - res = GH445_test_sub_PLn(0x68); // PLA + res = GH445_test_PLn(0x68); // PLA if (res) return res; if (bIs65C02) { - res = GH445_test_sub_PLn(0x7A); // PLY + res = GH445_test_PLn(0x7A); // PLY if (res) return res; - res = GH445_test_sub_PLn(0xFA); // PLX + res = GH445_test_PLn(0xFA); // PLX if (res) return res; } + // + // ABS + + regs.pc = 0xFFFD; + res = GH445_test_abs(0xAD, 0x1234); // LDA ABS + if (res) return res; + + regs.pc = 0xFFFE; + res = GH445_test_abs(0xAD, 0x1234); // LDA ABS + if (res) return res; + + regs.pc = 0xFFFF; + res = GH445_test_abs(0xAD, 0x1234); // LDA ABS + if (res) return res; + + // + // JSR ABS + + res = GH445_test_jsr(); + if (res) return res; + + // + // RTS + + res = GH445_test_rts(0x1FE); + if (res) return res; + res = GH445_test_rts(0x1FF); + if (res) return res; + res = GH445_test_rts(0x100); + if (res) return res; + return 0; }