Debugger: fix _6502_GetTargets() when abs addr16 wraps over 64K boundary (crash bug) & extend debugger unit-tests

This commit is contained in:
tomcw 2017-08-15 22:12:51 +01:00
parent dada9e6af0
commit 0fef6516f4
2 changed files with 112 additions and 14 deletions

View File

@ -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;

View File

@ -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;
}