.21 Added: Help for BRK

.20 Moved: BRK and BRKOP now under HELP BREAKPOINTS
.19 Added: Shift-F7 will run the emulator at normal speed but with debugger breakpoints active
.18 Added: Implemented BPIO -- currently is the same as BPM
This commit is contained in:
mpohoreski 2011-02-21 23:54:09 +00:00
parent 56b772af43
commit 195775b703
12 changed files with 478 additions and 402 deletions

View File

@ -1,5 +1,9 @@
/*
2.7.0.#
.21 Added: Help for BRK
.20 Moved: BRK and BRKOP now under HELP BREAKPOINTS
.19 Added: Shift-F7 will run the emulator at normal speed but with debugger breakpoints active!
.18 Added: Implemented BPIO -- currently is the same as BPM
.17 Fixed: HELP <category> wasn't displaying when category was one of: FLAGS, OUTPUT, WATCHES
.16 Fixed: WL was displaying number of watches
.15 Fixed: Memory Dump was over-writing watches.

View File

@ -160,30 +160,8 @@ void RequestDebugger()
FrameWndProc( g_hFrameWindow, WM_KEYUP , DEBUG_TOGGLE_KEY, 0 );
}
bool CheckDebugBreak( int iOpcode )
{
if (g_bDebugDelayBreakCheck)
{
g_bDebugDelayBreakCheck = false;
return false;
}
// Running at full speed? (debugger not running)
if ((g_nAppMode != MODE_DEBUG) && (g_nAppMode != MODE_STEPPING))
{
if (((iOpcode == 0) && IsDebugBreakOnInvalid(0)) ||
((g_iDebugOnOpcode) && (g_iDebugOnOpcode == iOpcode))) // User wants to enter debugger on opcode?
{
RequestDebugger();
return true;
}
}
return false;
}
// Break into debugger on invalid opcodes
#define INV if (IsDebugBreakOnInvalid(1)) { RequestDebugger(); bBreakOnInvalid = true; }
#define INV IsDebugBreakOnInvalid(AM_1);
/****************************************************************************
*
@ -314,7 +292,7 @@ static __forceinline int Fetch(BYTE& iOpcode, ULONG uExecutedCycles)
? IORead[(PC>>4) & 0xFF](PC,PC,0,0,uExecutedCycles) // Fetch opcode from I/O memory, but params are still from mem[]
: *(mem+PC);
if (CheckDebugBreak( iOpcode ))
if (IsDebugBreakOpcode( iOpcode ))
return 0;
#ifdef USE_SPEECH_API
@ -376,7 +354,7 @@ static __forceinline void CheckInterruptSources(ULONG uExecutedCycles)
#include "cpu/cpu6502.h" // MOS 6502
#include "cpu/cpu65C02.h" // WDC 65C02
#include "cpu/cpu65d02.h" // Debug Cpu
#include "cpu/cpu65d02.h" // Debug CPU Memory Visualizer
//===========================================================================

View File

@ -4,7 +4,7 @@ AppleWin : An Apple //e emulator for Windows
Copyright (C) 1994-1996, Michael O'Brien
Copyright (C) 1999-2001, Oliver Schmidt
Copyright (C) 2002-2005, Tom Charlesworth
Copyright (C) 2006-2010, Tom Charlesworth, Michael Pohoreski
Copyright (C) 2006-2011, Tom Charlesworth, Michael Pohoreski
AppleWin is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -37,7 +37,7 @@ static DWORD Cpu6502 (DWORD uTotalCycles)
ULONG uExecutedCycles = 0;
BOOL bSlowerOnPagecross = 0; // Set if opcode writes to memory (eg. ASL, STA)
WORD base;
bool bBreakOnInvalid = false;
g_bDebugBreakpointHit = 0;
do
{
@ -321,12 +321,16 @@ static DWORD Cpu6502 (DWORD uTotalCycles)
NMI(uExecutedCycles, uExtraCycles, flagc, flagn, flagv, flagz);
IRQ(uExecutedCycles, uExtraCycles, flagc, flagn, flagv, flagz);
if (bBreakOnInvalid)
if ( IsDebugBreakpointHit() )
break;
} while (uExecutedCycles < uTotalCycles);
EF_TO_AF
if( g_bDebugBreakpointHit )
if ((g_nAppMode != MODE_DEBUG) && (g_nAppMode != MODE_STEPPING)) // Running at full speed? (debugger not running)
RequestDebugger();
return uExecutedCycles;
}

View File

@ -4,7 +4,7 @@ AppleWin : An Apple //e emulator for Windows
Copyright (C) 1994-1996, Michael O'Brien
Copyright (C) 1999-2001, Oliver Schmidt
Copyright (C) 2002-2005, Tom Charlesworth
Copyright (C) 2006-2010, Tom Charlesworth, Michael Pohoreski
Copyright (C) 2006-2011, Tom Charlesworth, Michael Pohoreski
AppleWin is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -40,7 +40,7 @@ static DWORD Cpu65C02 (DWORD uTotalCycles)
ULONG uExecutedCycles = 0;
BOOL bSlowerOnPagecross = 0; // Set if opcode writes to memory (eg. ASL, STA)
WORD base;
bool bBreakOnInvalid = false;
g_bDebugBreakpointHit = 0;
do
{
@ -55,283 +55,287 @@ static DWORD Cpu65C02 (DWORD uTotalCycles)
else
#endif
{
if (!Fetch(iOpcode, uExecutedCycles))
break;
if (!Fetch(iOpcode, uExecutedCycles))
break;
switch (iOpcode)
{
switch (iOpcode)
{
#define $ INV // INV = Invalid -> Debugger Break
case 0x00: BRK CYC(7) break;
case 0x01: idx ORA CYC(6) break;
case 0x02: $ IMM NOP CYC(2) break;
case 0x03: $ NOP CYC(2) break;
case 0x04: ZPG TSB CYC(5) break;
case 0x05: ZPG ORA CYC(3) break;
case 0x06: ZPG ASLc CYC(5) break;
case 0x07: $ NOP CYC(2) break;
case 0x08: PHP CYC(3) break;
case 0x09: IMM ORA CYC(2) break;
case 0x0A: asl CYC(2) break;
case 0x0B: $ NOP CYC(2) break;
case 0x0C: ABS TSB CYC(6) break;
case 0x0D: ABS ORA CYC(4) break;
case 0x0E: ABS ASLc CYC(6) break;
case 0x0F: $ NOP CYC(2) break;
case 0x10: REL BPL CYC(2) break;
case 0x11: idy ORA CYC(5) break;
case 0x12: izp ORA CYC(5) break;
case 0x13: $ NOP CYC(2) break;
case 0x14: ZPG TRB CYC(5) break;
case 0x15: zpx ORA CYC(4) break;
case 0x16: zpx ASLc CYC(6) break;
case 0x17: $ NOP CYC(2) break;
case 0x18: CLC CYC(2) break;
case 0x19: aby ORA CYC(4) break;
case 0x1A: INA CYC(2) break;
case 0x1B: $ NOP CYC(2) break;
case 0x1C: ABS TRB CYC(6) break;
case 0x1D: abx ORA CYC(4) break;
case 0x1E: abx ASLc CYC(6) break;
case 0x1F: $ NOP CYC(2) break;
case 0x20: ABS JSR CYC(6) break;
case 0x21: idx AND CYC(6) break;
case 0x22: $ IMM NOP CYC(2) break;
case 0x23: $ NOP CYC(2) break;
case 0x24: ZPG BIT CYC(3) break;
case 0x25: ZPG AND CYC(3) break;
case 0x26: ZPG ROLc CYC(5) break;
case 0x27: $ NOP CYC(2) break;
case 0x28: PLP CYC(4) break;
case 0x29: IMM AND CYC(2) break;
case 0x2A: rol CYC(2) break;
case 0x2B: $ NOP CYC(2) break;
case 0x2C: ABS BIT CYC(4) break;
case 0x2D: ABS AND CYC(2) break;
case 0x2E: ABS ROLc CYC(6) break;
case 0x2F: $ NOP CYC(2) break;
case 0x30: REL BMI CYC(2) break;
case 0x31: idy AND CYC(5) break;
case 0x32: izp AND CYC(5) break;
case 0x33: $ NOP CYC(2) break;
case 0x34: zpx BIT CYC(4) break;
case 0x35: zpx AND CYC(4) break;
case 0x36: zpx ROLc CYC(6) break;
case 0x37: $ NOP CYC(2) break;
case 0x38: SEC CYC(2) break;
case 0x39: aby AND CYC(4) break;
case 0x3A: DEA CYC(2) break;
case 0x3B: $ NOP CYC(2) break;
case 0x3C: abx BIT CYC(4) break;
case 0x3D: abx AND CYC(4) break;
case 0x3E: abx ROLc CYC(6) break;
case 0x3F: $ NOP CYC(2) break;
case 0x40: RTI CYC(6) DoIrqProfiling(uExecutedCycles); break;
case 0x41: idx EOR CYC(6) break;
case 0x42: $ IMM NOP CYC(2) break;
case 0x43: $ NOP CYC(2) break;
case 0x44: $ ZPG NOP CYC(3) break;
case 0x45: ZPG EOR CYC(3) break;
case 0x46: ZPG LSRc CYC(5) break;
case 0x47: $ NOP CYC(2) break;
case 0x48: PHA CYC(3) break;
case 0x49: IMM EOR CYC(2) break;
case 0x4A: lsr CYC(2) break;
case 0x4B: $ NOP CYC(2) break;
case 0x4C: ABS JMP CYC(3) break;
case 0x4D: ABS EOR CYC(4) break;
case 0x4E: ABS LSRc CYC(6) break;
case 0x4F: $ NOP CYC(2) break;
case 0x50: REL BVC CYC(2) break;
case 0x51: idy EOR CYC(5) break;
case 0x52: izp EOR CYC(5) break;
case 0x53: $ NOP CYC(2) break;
case 0x54: $ zpx NOP CYC(4) break;
case 0x55: zpx EOR CYC(4) break;
case 0x56: zpx LSRc CYC(6) break;
case 0x57: $ NOP CYC(2) break;
case 0x58: CLI CYC(2) break;
case 0x59: aby EOR CYC(4) break;
case 0x5A: PHY CYC(3) break;
case 0x5B: $ NOP CYC(2) break;
case 0x5C: $ abx NOP CYC(8) break;
case 0x5D: abx EOR CYC(4) break;
case 0x5E: abx LSRc CYC(6) break;
case 0x5F: $ NOP CYC(2) break;
case 0x60: RTS CYC(6) break;
case 0x61: idx ADCc CYC(6) break;
case 0x62: $ IMM NOP CYC(2) break;
case 0x63: $ NOP CYC(2) break;
case 0x64: ZPG STZ CYC(3) break;
case 0x65: ZPG ADCc CYC(3) break;
case 0x66: ZPG RORc CYC(5) break;
case 0x67: $ NOP CYC(2) break;
case 0x68: PLA CYC(4) break;
case 0x69: IMM ADCc CYC(2) break;
case 0x6A: ror CYC(2) break;
case 0x6B: $ NOP CYC(2) break;
case 0x6C: IABSCMOS JMP CYC(6) break;
case 0x6D: ABS ADCc CYC(4) break;
case 0x6E: ABS RORc CYC(6) break;
case 0x6F: $ NOP CYC(2) break;
case 0x70: REL BVS CYC(2) break;
case 0x71: idy ADCc CYC(5) break;
case 0x72: izp ADCc CYC(5) break;
case 0x73: $ NOP CYC(2) break;
case 0x74: zpx STZ CYC(4) break;
case 0x75: zpx ADCc CYC(4) break;
case 0x76: zpx RORc CYC(6) break;
case 0x77: $ NOP CYC(2) break;
case 0x78: SEI CYC(2) break;
case 0x79: aby ADCc CYC(4) break;
case 0x7A: PLY CYC(4) break;
case 0x7B: $ NOP CYC(2) break;
case 0x7C: IABSX JMP CYC(6) break; //
case 0x7D: abx ADCc CYC(4) break;
case 0x7E: abx RORc CYC(6) break;
case 0x7F: $ NOP CYC(2) break;
case 0x80: REL BRA CYC(2) break;
case 0x81: idx STA CYC(6) break;
case 0x82: $ IMM NOP CYC(2) break;
case 0x83: $ NOP CYC(2) break;
case 0x84: ZPG STY CYC(3) break;
case 0x85: ZPG STA CYC(3) break;
case 0x86: ZPG STX CYC(3) break;
case 0x87: $ NOP CYC(2) break;
case 0x88: DEY CYC(2) break;
case 0x89: IMM BITI CYC(2) break;
case 0x8A: TXA CYC(2) break;
case 0x8B: $ NOP CYC(2) break;
case 0x8C: ABS STY CYC(4) break;
case 0x8D: ABS STA CYC(4) break;
case 0x8E: ABS STX CYC(4) break;
case 0x8F: $ NOP CYC(2) break;
case 0x90: REL BCC CYC(2) break;
case 0x91: idy STA CYC(6) break;
case 0x92: izp STA CYC(5) break;
case 0x93: $ NOP CYC(2) break;
case 0x94: zpx STY CYC(4) break;
case 0x95: zpx STA CYC(4) break;
case 0x96: zpy STX CYC(4) break;
case 0x97: $ NOP CYC(2) break;
case 0x98: TYA CYC(2) break;
case 0x99: aby STA CYC(5) break;
case 0x9A: TXS CYC(2) break;
case 0x9B: $ NOP CYC(2) break;
case 0x9C: ABS STZ CYC(4) break;
case 0x9D: abx STA CYC(5) break;
case 0x9E: abx STZ CYC(5) break;
case 0x9F: $ NOP CYC(2) break;
case 0xA0: IMM LDY CYC(2) break;
case 0xA1: idx LDA CYC(6) break;
case 0xA2: IMM LDX CYC(2) break;
case 0xA3: $ NOP CYC(2) break;
case 0xA4: ZPG LDY CYC(3) break;
case 0xA5: ZPG LDA CYC(3) break;
case 0xA6: ZPG LDX CYC(3) break;
case 0xA7: $ NOP CYC(2) break;
case 0xA8: TAY CYC(2) break;
case 0xA9: IMM LDA CYC(2) break;
case 0xAA: TAX CYC(2) break;
case 0xAB: $ NOP CYC(2) break;
case 0xAC: ABS LDY CYC(4) break;
case 0xAD: ABS LDA CYC(4) break;
case 0xAE: ABS LDX CYC(4) break;
case 0xAF: $ NOP CYC(2) break;
case 0xB0: REL BCS CYC(2) break;
case 0xB1: idy LDA CYC(5) break;
case 0xB2: izp LDA CYC(5) break;
case 0xB3: $ NOP CYC(2) break;
case 0xB4: zpx LDY CYC(4) break;
case 0xB5: zpx LDA CYC(4) break;
case 0xB6: zpy LDX CYC(4) break;
case 0xB7: $ NOP CYC(2) break;
case 0xB8: CLV CYC(2) break;
case 0xB9: aby LDA CYC(4) break;
case 0xBA: TSX CYC(2) break;
case 0xBB: $ NOP CYC(2) break;
case 0xBC: abx LDY CYC(4) break;
case 0xBD: abx LDA CYC(4) break;
case 0xBE: aby LDX CYC(4) break;
case 0xBF: $ NOP CYC(2) break;
case 0xC0: IMM CPY CYC(2) break;
case 0xC1: idx CMP CYC(6) break;
case 0xC2: $ IMM NOP CYC(2) break;
case 0xC3: $ NOP CYC(2) break;
case 0xC4: ZPG CPY CYC(3) break;
case 0xC5: ZPG CMP CYC(3) break;
case 0xC6: ZPG DECc CYC(5) break;
case 0xC7: $ NOP CYC(2) break;
case 0xC8: INY CYC(2) break;
case 0xC9: IMM CMP CYC(2) break;
case 0xCA: DEX CYC(2) break;
case 0xCB: $ NOP CYC(2) break;
case 0xCC: ABS CPY CYC(4) break;
case 0xCD: ABS CMP CYC(4) break;
case 0xCE: ABS DECc CYC(5) break;
case 0xCF: $ NOP CYC(2) break;
case 0xD0: REL BNE CYC(2) break;
case 0xD1: idy CMP CYC(5) break;
case 0xD2: izp CMP CYC(5) break;
case 0xD3: $ NOP CYC(2) break;
case 0xD4: $ zpx NOP CYC(4) break;
case 0xD5: zpx CMP CYC(4) break;
case 0xD6: zpx DECc CYC(6) break;
case 0xD7: $ NOP CYC(2) break;
case 0xD8: CLD CYC(2) break;
case 0xD9: aby CMP CYC(4) break;
case 0xDA: PHX CYC(3) break;
case 0xDB: $ NOP CYC(2) break;
case 0xDC: $ abx NOP CYC(4) break;
case 0xDD: abx CMP CYC(4) break;
case 0xDE: abx DECc CYC(6) break;
case 0xDF: $ NOP CYC(2) break;
case 0xE0: IMM CPX CYC(2) break;
case 0xE1: idx SBCc CYC(6) break;
case 0xE2: $ IMM NOP CYC(2) break;
case 0xE3: $ NOP CYC(2) break;
case 0xE4: ZPG CPX CYC(3) break;
case 0xE5: ZPG SBCc CYC(3) break;
case 0xE6: ZPG INCc CYC(5) break;
case 0xE7: $ NOP CYC(2) break;
case 0xE8: INX CYC(2) break;
case 0xE9: IMM SBCc CYC(2) break;
case 0xEA: NOP CYC(2) break;
case 0xEB: $ NOP CYC(2) break;
case 0xEC: ABS CPX CYC(4) break;
case 0xED: ABS SBCc CYC(4) break;
case 0xEE: ABS INCc CYC(6) break;
case 0xEF: $ NOP CYC(2) break;
case 0xF0: REL BEQ CYC(2) break;
case 0xF1: idy SBCc CYC(5) break;
case 0xF2: izp SBCc CYC(5) break;
case 0xF3: $ NOP CYC(2) break;
case 0xF4: $ zpx NOP CYC(4) break;
case 0xF5: zpx SBCc CYC(4) break;
case 0xF6: zpx INCc CYC(6) break;
case 0xF7: $ NOP CYC(2) break;
case 0xF8: SED CYC(2) break;
case 0xF9: aby SBCc CYC(4) break;
case 0xFA: PLX CYC(4) break;
case 0xFB: $ NOP CYC(2) break;
case 0xFC: $ abx NOP CYC(4) break;
case 0xFD: abx SBCc CYC(4) break;
case 0xFE: abx INCc CYC(6) break;
case 0xFF: $ NOP CYC(2) break;
}
case 0x00: BRK CYC(7) break;
case 0x01: idx ORA CYC(6) break;
case 0x02: $ IMM NOP CYC(2) break;
case 0x03: $ NOP CYC(2) break;
case 0x04: ZPG TSB CYC(5) break;
case 0x05: ZPG ORA CYC(3) break;
case 0x06: ZPG ASLc CYC(5) break;
case 0x07: $ NOP CYC(2) break;
case 0x08: PHP CYC(3) break;
case 0x09: IMM ORA CYC(2) break;
case 0x0A: asl CYC(2) break;
case 0x0B: $ NOP CYC(2) break;
case 0x0C: ABS TSB CYC(6) break;
case 0x0D: ABS ORA CYC(4) break;
case 0x0E: ABS ASLc CYC(6) break;
case 0x0F: $ NOP CYC(2) break;
case 0x10: REL BPL CYC(2) break;
case 0x11: idy ORA CYC(5) break;
case 0x12: izp ORA CYC(5) break;
case 0x13: $ NOP CYC(2) break;
case 0x14: ZPG TRB CYC(5) break;
case 0x15: zpx ORA CYC(4) break;
case 0x16: zpx ASLc CYC(6) break;
case 0x17: $ NOP CYC(2) break;
case 0x18: CLC CYC(2) break;
case 0x19: aby ORA CYC(4) break;
case 0x1A: INA CYC(2) break;
case 0x1B: $ NOP CYC(2) break;
case 0x1C: ABS TRB CYC(6) break;
case 0x1D: abx ORA CYC(4) break;
case 0x1E: abx ASLc CYC(6) break;
case 0x1F: $ NOP CYC(2) break;
case 0x20: ABS JSR CYC(6) break;
case 0x21: idx AND CYC(6) break;
case 0x22: $ IMM NOP CYC(2) break;
case 0x23: $ NOP CYC(2) break;
case 0x24: ZPG BIT CYC(3) break;
case 0x25: ZPG AND CYC(3) break;
case 0x26: ZPG ROLc CYC(5) break;
case 0x27: $ NOP CYC(2) break;
case 0x28: PLP CYC(4) break;
case 0x29: IMM AND CYC(2) break;
case 0x2A: rol CYC(2) break;
case 0x2B: $ NOP CYC(2) break;
case 0x2C: ABS BIT CYC(4) break;
case 0x2D: ABS AND CYC(2) break;
case 0x2E: ABS ROLc CYC(6) break;
case 0x2F: $ NOP CYC(2) break;
case 0x30: REL BMI CYC(2) break;
case 0x31: idy AND CYC(5) break;
case 0x32: izp AND CYC(5) break;
case 0x33: $ NOP CYC(2) break;
case 0x34: zpx BIT CYC(4) break;
case 0x35: zpx AND CYC(4) break;
case 0x36: zpx ROLc CYC(6) break;
case 0x37: $ NOP CYC(2) break;
case 0x38: SEC CYC(2) break;
case 0x39: aby AND CYC(4) break;
case 0x3A: DEA CYC(2) break;
case 0x3B: $ NOP CYC(2) break;
case 0x3C: abx BIT CYC(4) break;
case 0x3D: abx AND CYC(4) break;
case 0x3E: abx ROLc CYC(6) break;
case 0x3F: $ NOP CYC(2) break;
case 0x40: RTI CYC(6) DoIrqProfiling(uExecutedCycles); break;
case 0x41: idx EOR CYC(6) break;
case 0x42: $ IMM NOP CYC(2) break;
case 0x43: $ NOP CYC(2) break;
case 0x44: $ ZPG NOP CYC(3) break;
case 0x45: ZPG EOR CYC(3) break;
case 0x46: ZPG LSRc CYC(5) break;
case 0x47: $ NOP CYC(2) break;
case 0x48: PHA CYC(3) break;
case 0x49: IMM EOR CYC(2) break;
case 0x4A: lsr CYC(2) break;
case 0x4B: $ NOP CYC(2) break;
case 0x4C: ABS JMP CYC(3) break;
case 0x4D: ABS EOR CYC(4) break;
case 0x4E: ABS LSRc CYC(6) break;
case 0x4F: $ NOP CYC(2) break;
case 0x50: REL BVC CYC(2) break;
case 0x51: idy EOR CYC(5) break;
case 0x52: izp EOR CYC(5) break;
case 0x53: $ NOP CYC(2) break;
case 0x54: $ zpx NOP CYC(4) break;
case 0x55: zpx EOR CYC(4) break;
case 0x56: zpx LSRc CYC(6) break;
case 0x57: $ NOP CYC(2) break;
case 0x58: CLI CYC(2) break;
case 0x59: aby EOR CYC(4) break;
case 0x5A: PHY CYC(3) break;
case 0x5B: $ NOP CYC(2) break;
case 0x5C: $ abx NOP CYC(8) break;
case 0x5D: abx EOR CYC(4) break;
case 0x5E: abx LSRc CYC(6) break;
case 0x5F: $ NOP CYC(2) break;
case 0x60: RTS CYC(6) break;
case 0x61: idx ADCc CYC(6) break;
case 0x62: $ IMM NOP CYC(2) break;
case 0x63: $ NOP CYC(2) break;
case 0x64: ZPG STZ CYC(3) break;
case 0x65: ZPG ADCc CYC(3) break;
case 0x66: ZPG RORc CYC(5) break;
case 0x67: $ NOP CYC(2) break;
case 0x68: PLA CYC(4) break;
case 0x69: IMM ADCc CYC(2) break;
case 0x6A: ror CYC(2) break;
case 0x6B: $ NOP CYC(2) break;
case 0x6C: IABSCMOS JMP CYC(6) break;
case 0x6D: ABS ADCc CYC(4) break;
case 0x6E: ABS RORc CYC(6) break;
case 0x6F: $ NOP CYC(2) break;
case 0x70: REL BVS CYC(2) break;
case 0x71: idy ADCc CYC(5) break;
case 0x72: izp ADCc CYC(5) break;
case 0x73: $ NOP CYC(2) break;
case 0x74: zpx STZ CYC(4) break;
case 0x75: zpx ADCc CYC(4) break;
case 0x76: zpx RORc CYC(6) break;
case 0x77: $ NOP CYC(2) break;
case 0x78: SEI CYC(2) break;
case 0x79: aby ADCc CYC(4) break;
case 0x7A: PLY CYC(4) break;
case 0x7B: $ NOP CYC(2) break;
case 0x7C: IABSX JMP CYC(6) break; //
case 0x7D: abx ADCc CYC(4) break;
case 0x7E: abx RORc CYC(6) break;
case 0x7F: $ NOP CYC(2) break;
case 0x80: REL BRA CYC(2) break;
case 0x81: idx STA CYC(6) break;
case 0x82: $ IMM NOP CYC(2) break;
case 0x83: $ NOP CYC(2) break;
case 0x84: ZPG STY CYC(3) break;
case 0x85: ZPG STA CYC(3) break;
case 0x86: ZPG STX CYC(3) break;
case 0x87: $ NOP CYC(2) break;
case 0x88: DEY CYC(2) break;
case 0x89: IMM BITI CYC(2) break;
case 0x8A: TXA CYC(2) break;
case 0x8B: $ NOP CYC(2) break;
case 0x8C: ABS STY CYC(4) break;
case 0x8D: ABS STA CYC(4) break;
case 0x8E: ABS STX CYC(4) break;
case 0x8F: $ NOP CYC(2) break;
case 0x90: REL BCC CYC(2) break;
case 0x91: idy STA CYC(6) break;
case 0x92: izp STA CYC(5) break;
case 0x93: $ NOP CYC(2) break;
case 0x94: zpx STY CYC(4) break;
case 0x95: zpx STA CYC(4) break;
case 0x96: zpy STX CYC(4) break;
case 0x97: $ NOP CYC(2) break;
case 0x98: TYA CYC(2) break;
case 0x99: aby STA CYC(5) break;
case 0x9A: TXS CYC(2) break;
case 0x9B: $ NOP CYC(2) break;
case 0x9C: ABS STZ CYC(4) break;
case 0x9D: abx STA CYC(5) break;
case 0x9E: abx STZ CYC(5) break;
case 0x9F: $ NOP CYC(2) break;
case 0xA0: IMM LDY CYC(2) break;
case 0xA1: idx LDA CYC(6) break;
case 0xA2: IMM LDX CYC(2) break;
case 0xA3: $ NOP CYC(2) break;
case 0xA4: ZPG LDY CYC(3) break;
case 0xA5: ZPG LDA CYC(3) break;
case 0xA6: ZPG LDX CYC(3) break;
case 0xA7: $ NOP CYC(2) break;
case 0xA8: TAY CYC(2) break;
case 0xA9: IMM LDA CYC(2) break;
case 0xAA: TAX CYC(2) break;
case 0xAB: $ NOP CYC(2) break;
case 0xAC: ABS LDY CYC(4) break;
case 0xAD: ABS LDA CYC(4) break;
case 0xAE: ABS LDX CYC(4) break;
case 0xAF: $ NOP CYC(2) break;
case 0xB0: REL BCS CYC(2) break;
case 0xB1: idy LDA CYC(5) break;
case 0xB2: izp LDA CYC(5) break;
case 0xB3: $ NOP CYC(2) break;
case 0xB4: zpx LDY CYC(4) break;
case 0xB5: zpx LDA CYC(4) break;
case 0xB6: zpy LDX CYC(4) break;
case 0xB7: $ NOP CYC(2) break;
case 0xB8: CLV CYC(2) break;
case 0xB9: aby LDA CYC(4) break;
case 0xBA: TSX CYC(2) break;
case 0xBB: $ NOP CYC(2) break;
case 0xBC: abx LDY CYC(4) break;
case 0xBD: abx LDA CYC(4) break;
case 0xBE: aby LDX CYC(4) break;
case 0xBF: $ NOP CYC(2) break;
case 0xC0: IMM CPY CYC(2) break;
case 0xC1: idx CMP CYC(6) break;
case 0xC2: $ IMM NOP CYC(2) break;
case 0xC3: $ NOP CYC(2) break;
case 0xC4: ZPG CPY CYC(3) break;
case 0xC5: ZPG CMP CYC(3) break;
case 0xC6: ZPG DECc CYC(5) break;
case 0xC7: $ NOP CYC(2) break;
case 0xC8: INY CYC(2) break;
case 0xC9: IMM CMP CYC(2) break;
case 0xCA: DEX CYC(2) break;
case 0xCB: $ NOP CYC(2) break;
case 0xCC: ABS CPY CYC(4) break;
case 0xCD: ABS CMP CYC(4) break;
case 0xCE: ABS DECc CYC(5) break;
case 0xCF: $ NOP CYC(2) break;
case 0xD0: REL BNE CYC(2) break;
case 0xD1: idy CMP CYC(5) break;
case 0xD2: izp CMP CYC(5) break;
case 0xD3: $ NOP CYC(2) break;
case 0xD4: $ zpx NOP CYC(4) break;
case 0xD5: zpx CMP CYC(4) break;
case 0xD6: zpx DECc CYC(6) break;
case 0xD7: $ NOP CYC(2) break;
case 0xD8: CLD CYC(2) break;
case 0xD9: aby CMP CYC(4) break;
case 0xDA: PHX CYC(3) break;
case 0xDB: $ NOP CYC(2) break;
case 0xDC: $ abx NOP CYC(4) break;
case 0xDD: abx CMP CYC(4) break;
case 0xDE: abx DECc CYC(6) break;
case 0xDF: $ NOP CYC(2) break;
case 0xE0: IMM CPX CYC(2) break;
case 0xE1: idx SBCc CYC(6) break;
case 0xE2: $ IMM NOP CYC(2) break;
case 0xE3: $ NOP CYC(2) break;
case 0xE4: ZPG CPX CYC(3) break;
case 0xE5: ZPG SBCc CYC(3) break;
case 0xE6: ZPG INCc CYC(5) break;
case 0xE7: $ NOP CYC(2) break;
case 0xE8: INX CYC(2) break;
case 0xE9: IMM SBCc CYC(2) break;
case 0xEA: NOP CYC(2) break;
case 0xEB: $ NOP CYC(2) break;
case 0xEC: ABS CPX CYC(4) break;
case 0xED: ABS SBCc CYC(4) break;
case 0xEE: ABS INCc CYC(6) break;
case 0xEF: $ NOP CYC(2) break;
case 0xF0: REL BEQ CYC(2) break;
case 0xF1: idy SBCc CYC(5) break;
case 0xF2: izp SBCc CYC(5) break;
case 0xF3: $ NOP CYC(2) break;
case 0xF4: $ zpx NOP CYC(4) break;
case 0xF5: zpx SBCc CYC(4) break;
case 0xF6: zpx INCc CYC(6) break;
case 0xF7: $ NOP CYC(2) break;
case 0xF8: SED CYC(2) break;
case 0xF9: aby SBCc CYC(4) break;
case 0xFA: PLX CYC(4) break;
case 0xFB: $ NOP CYC(2) break;
case 0xFC: $ abx NOP CYC(4) break;
case 0xFD: abx SBCc CYC(4) break;
case 0xFE: abx INCc CYC(6) break;
case 0xFF: $ NOP CYC(2) break;
}
#undef $
}
CheckInterruptSources(uExecutedCycles);
NMI(uExecutedCycles, uExtraCycles, flagc, flagn, flagv, flagz);
IRQ(uExecutedCycles, uExtraCycles, flagc, flagn, flagv, flagz);
if (bBreakOnInvalid)
if( IsDebugBreakpointHit() )
break;
} while (uExecutedCycles < uTotalCycles);
EF_TO_AF
EF_TO_AF // Emulator Flags to Apple Flags
if( g_bDebugBreakpointHit )
if ((g_nAppMode != MODE_DEBUG) && (g_nAppMode != MODE_STEPPING)) // Running at full speed? (debugger not running)
RequestDebugger();
return uExecutedCycles;
}

View File

@ -1,7 +1,7 @@
/*
AppleWin : An Apple //e emulator for Windows
Copyright (C) 2010, Tom Charlesworth, Michael Pohoreski
Copyright (C) 2010-2011, Tom Charlesworth, Michael Pohoreski
AppleWin is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -84,6 +84,9 @@ inline u8 ReadByte( u16 addr, int uExecutedCycles )
// Based on Modified 65C02
static DWORD Cpu65D02 (DWORD uTotalCycles)
{
// Optimisation:
// . Copy the global /regs/ vars to stack-based local vars
// (Oliver Schmidt says this gives a performance gain, see email - The real deal: "1.10.5")
WORD addr;
BOOL flagc; // must always be 0 or 1, no other values allowed
BOOL flagn; // must always be 0 or 0x80.
@ -96,13 +99,21 @@ static DWORD Cpu65D02 (DWORD uTotalCycles)
ULONG uExecutedCycles = 0;
BOOL bSlowerOnPagecross = 0; // Set if opcode writes to memory (eg. ASL, STA)
WORD base;
bool bBreakOnInvalid = false;
g_bDebugBreakpointHit = 0;
do
{
UINT uExtraCycles = 0;
BYTE iOpcode;
#ifdef SUPPORT_CPM
if (g_ActiveCPU == CPU_Z80)
{
const UINT uZ80Cycles = z80_mainloop(uTotalCycles, uExecutedCycles); CYC(uZ80Cycles)
}
else
#endif
if (!Fetch(iOpcode, uExecutedCycles))
break;
@ -643,10 +654,16 @@ static DWORD Cpu65D02 (DWORD uTotalCycles)
NMI(uExecutedCycles, uExtraCycles, flagc, flagn, flagv, flagz);
IRQ(uExecutedCycles, uExtraCycles, flagc, flagn, flagv, flagz);
if (bBreakOnInvalid)
if( IsDebugBreakpointHit() )
break;
} while (uExecutedCycles < uTotalCycles);
EF_TO_AF
EF_TO_AF // Emulator Flags to Apple Flags
if( g_bDebugBreakpointHit )
if ((g_nAppMode != MODE_DEBUG) && (g_nAppMode != MODE_STEPPING)) // // Running at full speed? (debugger not running)
RequestDebugger();
return uExecutedCycles;
}

View File

@ -31,9 +31,9 @@ enum AppMode_e
{
MODE_LOGO = 0
, MODE_PAUSED
, MODE_RUNNING
, MODE_DEBUG
, MODE_STEPPING
, MODE_RUNNING // 6502 is running at normal speed (Debugger breakpoints may or may not be active)
, MODE_DEBUG // 6502 is paused
, MODE_STEPPING // 6502 is running at full speed (Debugger breakpoints always active)
};
#define SPEED_MIN 0

View File

@ -36,7 +36,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#define ALLOW_INPUT_LOWERCASE 1
// See /docs/Debugger_Changelog.txt for full details
const int DEBUGGER_VERSION = MAKE_VERSION(2,7,0,17);
const int DEBUGGER_VERSION = MAKE_VERSION(2,7,0,21);
// Public _________________________________________________________________________________________
@ -51,10 +51,18 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// Breakpoints ________________________________________________________________
// Full-Speed debugging
int g_nDebugOnBreakInvalid = 0;
int g_iDebugOnOpcode = 0;
bool g_bDebugDelayBreakCheck = false;
// MODE_RUNNING // Normal Speed Breakpoints: Shift-F7 exit debugger, keep breakpoints active, enter run state at NORMAL speed
bool g_bDebugNormalSpeedBreakpoints = 0;
// MODE_STEPPING // Full Speed Breakpoints
// Any Speed Breakpoints
int g_nDebugBreakOnInvalid = 0; // Bit Flags of Invalid Opcode to break on: // iOpcodeType = AM_IMPLIED (BRK), AM_1, AM_2, AM_3
int g_iDebugBreakOnOpcode = 0;
bool g_bDebugBreakDelayCheck = false; // If exiting the debugger, allow at least one instruction to execute so we don't trigger on the same invalid opcode
int g_bDebugBreakpointHit = 0; // See: BreakpointHit_t
int g_nBreakpoints = 0;
Breakpoint_t g_aBreakpoints[ MAX_BREAKPOINTS ];
@ -318,8 +326,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
void _BWZ_ListAll ( const Breakpoint_t * aBreakWatchZero, const int nMax );
// bool CheckBreakpoint (WORD address, BOOL memory);
bool CheckBreakpointsIO ();
bool CheckBreakpointsReg ();
bool _CmdBreakpointAddReg ( Breakpoint_t *pBP, BreakpointSource_t iSrc, BreakpointOperator_t iCmp, WORD nAddress, int nLen, bool bIsTempBreakpoint );
int _CmdBreakpointAddCommonArg ( int iArg, int nArg, BreakpointSource_t iSrc, BreakpointOperator_t iCmp, bool bIsTempBreakpoint=false );
void _BWZ_Clear( Breakpoint_t * aBreakWatchZero, int iSlot );
@ -707,7 +713,7 @@ Update_t CmdBenchmarkStop (int nArgs)
{
g_bBenchmarking = false;
DebugEnd();
g_nAppMode = MODE_RUNNING;
FrameRefreshStatus(DRAW_TITLE);
VideoRedrawScreen();
DWORD currtime = GetTickCount();
@ -807,13 +813,19 @@ _Help:
//===========================================================================
Update_t CmdBreakInvalid (int nArgs) // Breakpoint IFF Full-speed!
{
if ((nArgs > 2) || (nArgs == 0))
if (nArgs > 2) // || (nArgs == 0))
goto _Help;
int iType = 0; // default to BRK
int iType = AM_IMPLIED; // default to BRK
int nActive = 0;
// if (nArgs == 2)
if (nArgs == 0)
{
nArgs = 1;
g_aArgs[ 1 ].nValue = AM_IMPLIED;
g_aArgs[ 1 ].sArg[0] = 0;
}
iType = g_aArgs[ 1 ].nValue;
// Cases:
@ -847,10 +859,10 @@ Update_t CmdBreakInvalid (int nArgs) // Breakpoint IFF Full-speed!
{
if (! nFound) // bValidParam) // case 1a or 1c
{
if ((iType < 0) || (iType > AM_3))
if ((iType < AM_IMPLIED) || (iType > AM_3))
goto _Help;
if (IsDebugBreakOnInvalid( iType ))
if ( IsDebugBreakOnInvalid( iType ) )
iParam = PARAM_ON;
else
iParam = PARAM_OFF;
@ -910,31 +922,31 @@ Update_t CmdBreakOpcode (int nArgs) // Breakpoint IFF Full-speed!
if (nArgs == 1)
{
int iOpcode = g_aArgs[ 1] .nValue;
g_iDebugOnOpcode = iOpcode & 0xFF;
g_iDebugBreakOnOpcode = iOpcode & 0xFF;
_tcscpy( sAction, TEXT("Setting") );
if (iOpcode >= NUM_OPCODES)
{
wsprintf( sText, TEXT("Warning: clamping opcode: %02X"), g_iDebugOnOpcode );
wsprintf( sText, TEXT("Warning: clamping opcode: %02X"), g_iDebugBreakOnOpcode );
ConsoleBufferPush( sText );
return ConsoleUpdate();
}
}
if (g_iDebugOnOpcode == 0)
if (g_iDebugBreakOnOpcode == 0)
// Show what the current break opcode is
wsprintf( sText, TEXT("%s full speed Break on Opcode: None")
, sAction
, g_iDebugOnOpcode
, g_aOpcodes65C02[ g_iDebugOnOpcode ].sMnemonic
, g_iDebugBreakOnOpcode
, g_aOpcodes65C02[ g_iDebugBreakOnOpcode ].sMnemonic
);
else
// Show what the current break opcode is
wsprintf( sText, TEXT("%s full speed Break on Opcode: %02X %s")
, sAction
, g_iDebugOnOpcode
, g_aOpcodes65C02[ g_iDebugOnOpcode ].sMnemonic
, g_iDebugBreakOnOpcode
, g_aOpcodes65C02[ g_iDebugBreakOnOpcode ].sMnemonic
);
ConsoleBufferPush( sText );
@ -1031,7 +1043,7 @@ bool _CheckBreakpointValue( Breakpoint_t *pBP, int nVal )
//===========================================================================
bool CheckBreakpointsIO ()
int CheckBreakpointsIO ()
{
const int NUM_TARGETS = 2;
@ -1041,7 +1053,7 @@ bool CheckBreakpointsIO ()
NO_6502_TARGET
};
int nBytes;
bool bStatus = false;
bool bBreakpointHit = 0;
int iTarget;
int nAddress;
@ -1064,7 +1076,7 @@ bool CheckBreakpointsIO ()
{
if (_CheckBreakpointValue( pBP, nAddress ))
{
return true;
return BP_HIT_MEM;
}
}
}
@ -1072,14 +1084,14 @@ bool CheckBreakpointsIO ()
}
}
}
return bStatus;
return bBreakpointHit;
}
// Returns true if a register breakpoint is triggered
//===========================================================================
bool CheckBreakpointsReg ()
int CheckBreakpointsReg ()
{
bool bStatus = false;
int bBreakpointHit = 0;
for (int iBreakpoint = 0; iBreakpoint < MAX_BREAKPOINTS; iBreakpoint++)
{
@ -1090,30 +1102,31 @@ bool CheckBreakpointsReg ()
switch (pBP->eSource)
{
case BP_SRC_REG_PC:
bStatus = _CheckBreakpointValue( pBP, regs.pc );
case BP_SRC_REG_PC:
bBreakpointHit = _CheckBreakpointValue( pBP, regs.pc );
break;
case BP_SRC_REG_A:
bStatus = _CheckBreakpointValue( pBP, regs.a );
bBreakpointHit = _CheckBreakpointValue( pBP, regs.a );
break;
case BP_SRC_REG_X:
bStatus = _CheckBreakpointValue( pBP, regs.x );
bBreakpointHit = _CheckBreakpointValue( pBP, regs.x );
break;
case BP_SRC_REG_Y:
bStatus = _CheckBreakpointValue( pBP, regs.y );
bBreakpointHit = _CheckBreakpointValue( pBP, regs.y );
break;
case BP_SRC_REG_P:
bStatus = _CheckBreakpointValue( pBP, regs.ps );
bBreakpointHit = _CheckBreakpointValue( pBP, regs.ps );
break;
case BP_SRC_REG_S:
bStatus = _CheckBreakpointValue( pBP, regs.sp );
bBreakpointHit = _CheckBreakpointValue( pBP, regs.sp );
break;
default:
break;
}
if (bStatus)
if (bBreakpointHit)
{
bBreakpointHit = BP_HIT_REG;
if (pBP->bTemp)
_BWZ_Clear(pBP, iBreakpoint);
@ -1121,7 +1134,7 @@ bool CheckBreakpointsReg ()
}
}
return bStatus;
return bBreakpointHit;
}
void ClearTempBreakpoints ()
@ -1234,7 +1247,7 @@ Update_t CmdBreakpointAddReg (int nArgs)
}
}
if ((! bHaveSrc) && (! bHaveCmp))
if ((! bHaveSrc) && (! bHaveCmp)) // Inverted/Convoluted logic: didn't find BOTH this pass, so we must have already found them.
{
int dArgs = _CmdBreakpointAddCommonArg( iArg, nArgs, iSrc, iCmp );
if (!dArgs)
@ -1389,7 +1402,8 @@ Update_t CmdBreakpointAddPC (int nArgs)
//===========================================================================
Update_t CmdBreakpointAddIO (int nArgs)
{
return UPDATE_CONSOLE_DISPLAY;
return CmdBreakpointAddMem( nArgs );
// return UPDATE_BREAKPOINTS | UPDATE_CONSOLE_DISPLAY;
}
@ -7168,13 +7182,13 @@ void DebugContinueStepping ()
{
if ((regs.pc >= g_nDebugSkipStart) && (regs.pc < (g_nDebugSkipStart + g_nDebugSkipLen)))
{
// Enter turbo debugger g_nAppMode -- UI not updated, etc.
// Enter turbo debugger mode -- UI not updated, etc.
g_nDebugSteps = -1;
g_nAppMode = MODE_STEPPING;
}
else
{
// Enter normal debugger g_nAppMode -- UI updated every instruction, etc.
// Enter normal debugger mode -- UI updated every instruction, etc.
g_nDebugSteps = 1;
g_nAppMode = MODE_STEPPING;
}
@ -7188,12 +7202,9 @@ void DebugContinueStepping ()
InternalSingleStep();
bool bBreak = CheckBreakpointsIO();
_IsDebugBreakpointHit(); // Updates g_bDebugBreakpointHit
if (CheckBreakpointsReg())
bBreak = true;
if ((regs.pc == g_nDebugStepUntil) || bBreak)
if ((regs.pc == g_nDebugStepUntil) || g_bDebugBreakpointHit)
g_nDebugSteps = 0;
else if (g_nDebugSteps > 0)
g_nDebugSteps--;
@ -7203,7 +7214,7 @@ void DebugContinueStepping ()
{
if (!((++nStepsTaken) & 0xFFFF))
{
if (nStepsTaken == 0x10000)
if (nStepsTaken == 0x10000) // HACK_MAGIC_NUM
VideoRedrawScreen();
else
VideoRefreshScreen();
@ -7215,32 +7226,11 @@ void DebugContinueStepping ()
FrameRefreshStatus(DRAW_TITLE);
// BUG: PageUp, Trace - doesn't center cursor
// if ((g_nDebugStepStart < regs.pc) && (g_nDebugStepStart+3 >= regs.pc))
// Still within current disasm "window"?
/*
if ((regs.pc >= g_nDisasmTopAddress) && (regs.pc <= g_nDisasmBotAddress))
{
int eMode = g_aOpcodes[*(mem+g_nDisasmCurAddress)].addrmode;
int nBytes = g_aOpmodes[ eMode ]._nBytes;
g_nDisasmCurAddress += nBytes;
// g_nDisasmTopAddress += nBytes;
// g_nDisasmBotAddress += nBytes;
}
else
*/
{
g_nDisasmCurAddress = regs.pc;
}
g_nDisasmCurAddress = regs.pc;
DisasmCalcTopBotAddress();
// g_nDisasmCurAddress += g_aOpmodes[g_aOpcodes[*(mem+g_nDisasmCurAddress)].addrmode]._nBytes;
// DisasmCalcTopBotAddress();
Update_t bUpdate = UPDATE_ALL;
// if (nStepsTaken >= 0x10000) // HACK_MAGIC_NUM
// bUpdate = UPDATE_ALL;
UpdateDisplay( bUpdate ); // nStepsTaken >= 0x10000);
nStepsTaken = 0;
}
@ -7297,6 +7287,8 @@ void DebugEnd ()
}
g_vMemorySearchResults.erase( g_vMemorySearchResults.begin(), g_vMemorySearchResults.end() );
g_nAppMode = MODE_RUNNING;
}

View File

@ -30,16 +30,33 @@ using namespace std;
// extern vector<int> g_aBookmarks;
// Breakpoints
enum BreakpointHit_t
{
BP_HIT_NONE = 0
,BP_HIT_INVALID = (1 << 0)
,BP_HIT_OPCODE = (1 << 1)
,BP_HIT_REG = (1 << 2)
,BP_HIT_MEM = (1 << 3)
};
extern int g_nBreakpoints;
extern Breakpoint_t g_aBreakpoints[ MAX_BREAKPOINTS ];
extern const char *g_aBreakpointSource [ NUM_BREAKPOINT_SOURCES ];
extern const TCHAR *g_aBreakpointSymbols[ NUM_BREAKPOINT_OPERATORS ];
// Full-Speed debugging
extern int g_nDebugOnBreakInvalid;
extern int g_iDebugOnOpcode ;
extern bool g_bDebugDelayBreakCheck;
// MODE_RUNNING // Normal Speed Breakpoints
extern bool g_bDebugNormalSpeedBreakpoints;
// MODE_STEPPING // Full Speed Breakpoints
// Any Speed Breakpoints
extern int g_nDebugBreakOnInvalid ;
extern int g_iDebugBreakOnOpcode ;
// Breakpoint Status
extern bool g_bDebugBreakDelayCheck;
extern int g_bDebugBreakpointHit ;
// Commands
void VerifyDebuggerCommandTable();
@ -133,23 +150,69 @@ using namespace std;
bool Bookmark_Find( const WORD nAddress );
// Breakpoints
int CheckBreakpointsIO ();
int CheckBreakpointsReg ();
bool GetBreakpointInfo ( WORD nOffset, bool & bBreakpointActive_, bool & bBreakpointEnable_ );
// 0 = Brk, 1 = Invalid1, .. 3 = Invalid 3
inline bool IsDebugBreakOnInvalid( int iOpcodeType )
inline int _IsDebugBreakpointHit()
{
bool bActive = (g_nDebugOnBreakInvalid >> iOpcodeType) & 1;
return bActive;
g_bDebugBreakpointHit |= CheckBreakpointsIO() || CheckBreakpointsReg();
return g_bDebugBreakpointHit;
}
inline int _IsDebugBreakOnOpcode( int iOpcode )
{
if (g_iDebugBreakOnOpcode == iOpcode)
g_bDebugBreakpointHit |= BP_HIT_OPCODE;
return g_bDebugBreakpointHit;
}
// iOpcodeType = AM_IMPLIED (BRK), AM_1, AM_2, AM_3
inline int IsDebugBreakOnInvalid( int iOpcodeType )
{
g_bDebugBreakpointHit |= ((g_nDebugBreakOnInvalid >> iOpcodeType) & 1) ? BP_HIT_INVALID : 0;
return g_bDebugBreakpointHit;
}
// iOpcodeType = AM_IMPLIED (BRK), AM_1, AM_2, AM_3
inline void SetDebugBreakOnInvalid( int iOpcodeType, int nValue )
{
if (iOpcodeType <= AM_3)
{
g_nDebugOnBreakInvalid &= ~ ( 1 << iOpcodeType);
g_nDebugOnBreakInvalid |= ((nValue & 1) << iOpcodeType);
g_nDebugBreakOnInvalid &= ~ ( 1 << iOpcodeType);
g_nDebugBreakOnInvalid |= ((nValue & 1) << iOpcodeType);
}
}
//
// CPU checks the Debugger breakpoints
// a) at opcode fetch
// b) after opcode execution
//
inline int IsDebugBreakOpcode( int iOpcode )
{
if (g_bDebugBreakDelayCheck)
{
g_bDebugBreakDelayCheck = false;
return false;
}
if (! iOpcode )
IsDebugBreakOnInvalid( AM_IMPLIED );
if (g_iDebugBreakOnOpcode ) // User wants to enter debugger on specific opcode?
_IsDebugBreakOnOpcode(iOpcode);
return g_bDebugBreakpointHit;
}
//
inline int IsDebugBreakpointHit()
{
if ( !g_bDebugNormalSpeedBreakpoints )
return false;
return _IsDebugBreakpointHit();
}
// Source Level Debugging
int FindSourceLine( WORD nAddress );

View File

@ -40,8 +40,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// CPU (Main)
{TEXT(".") , CmdCursorJumpPC , CMD_CURSOR_JUMP_PC , "Locate the cursor in the disasm window" }, // centered
{TEXT("=") , CmdCursorSetPC , CMD_CURSOR_SET_PC , "Sets the PC to the current instruction" },
{TEXT("BRK") , CmdBreakInvalid , CMD_BREAK_INVALID , "Enter debugger on BRK or INVALID" },
{TEXT("BRKOP") , CmdBreakOpcode , CMD_BREAK_OPCODE , "Enter debugger on opcode" },
{TEXT("G") , CmdGo , CMD_GO , "Run [until PC = address]" },
{TEXT("IN") , CmdIn , CMD_IN , "Input byte from IO $C0xx" },
{TEXT("KEY") , CmdKey , CMD_INPUT_KEY , "Feed key into emulator" },
@ -73,6 +71,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// {TEXT("BMLOAD") , CmdBookmarkLoad , CMD_BOOKMARK_LOAD , "Load bookmarks" },
{TEXT("BMSAVE") , CmdBookmarkSave , CMD_BOOKMARK_SAVE , "Save bookmarks" },
// Breakpoints
{TEXT("BRK") , CmdBreakInvalid , CMD_BREAK_INVALID , "Enter debugger on BRK or INVALID" },
{TEXT("BRKOP") , CmdBreakOpcode , CMD_BREAK_OPCODE , "Enter debugger on opcode" },
{TEXT("BP") , CmdBreakpoint , CMD_BREAKPOINT , "Alias for BPR (Breakpoint Register Add)" },
{TEXT("BPA") , CmdBreakpointAddSmart, CMD_BREAKPOINT_ADD_SMART , "Add (smart) breakpoint" },
// {TEXT("BPP") , CmdBreakpointAddFlag , CMD_BREAKPOINT_ADD_FLAG , "Add breakpoint on flags" },

View File

@ -512,7 +512,7 @@ Update_t CmdHelpSpecific (int nArgs)
switch( iParam )
{
case PARAM_CAT_BOOKMARKS : iCmdBegin = CMD_BOOKMARK ; iCmdEnd = CMD_BOOKMARK_SAVE ; break;
case PARAM_CAT_BREAKPOINTS: iCmdBegin = CMD_BREAKPOINT ; iCmdEnd = CMD_BREAKPOINT_SAVE ; break;
case PARAM_CAT_BREAKPOINTS: iCmdBegin = CMD_BREAK_INVALID ; iCmdEnd = CMD_BREAKPOINT_SAVE ; break;
case PARAM_CAT_CONFIG : iCmdBegin = CMD_BENCHMARK ; iCmdEnd = CMD_CONFIG_SAVE ; break;
case PARAM_CAT_CPU : iCmdBegin = CMD_ASSEMBLE ; iCmdEnd = CMD_UNASSEMBLE ; break;
case PARAM_CAT_FLAGS :
@ -895,6 +895,24 @@ Update_t CmdHelpSpecific (int nArgs)
case CMD_BOOKMARK_SAVE:
break;
// Breakpoints
case CMD_BREAK_INVALID:
sprintf( sTemp, TEXT(" Usage: [%s%s | %s%s] | [ # | # %s%s | # %s%s ]")
, CHC_COMMAND
, g_aParameters[ PARAM_ON ].m_sName
, CHC_COMMAND
, g_aParameters[ PARAM_OFF ].m_sName
, CHC_COMMAND
, g_aParameters[ PARAM_ON ].m_sName
, CHC_COMMAND
, g_aParameters[ PARAM_OFF ].m_sName
);
Colorize( sText, sTemp );
ConsolePrint( sText );
sprintf( sTemp, TEXT("Where: # is 0=BRK, 1=Invalid Opcode_1, 2=Invalid Opcode_2, 3=Invalid Opcode_3"));
Colorize( sText, sTemp );
ConsolePrint( sText );
break;
// case CMD_BREAK_OPCODE:
case CMD_BREAKPOINT:
sprintf( sTemp, TEXT(" Usage: [%s%s | %s%s | %s%s]")
, CHC_COMMAND

View File

@ -280,8 +280,6 @@
// CPU
, CMD_CURSOR_JUMP_PC // Shift
, CMD_CURSOR_SET_PC // Ctrl
, CMD_BREAK_INVALID
, CMD_BREAK_OPCODE
, CMD_GO
, CMD_IN
, CMD_INPUT_KEY
@ -313,6 +311,8 @@
, CMD_BOOKMARK_GOTO
, CMD_BOOKMARK_SAVE
// Breakpoints
, CMD_BREAK_INVALID
, CMD_BREAK_OPCODE
, CMD_BREAKPOINT
, CMD_BREAKPOINT_ADD_SMART // smart breakpoint
, CMD_BREAKPOINT_ADD_REG // break on: PC == Address (fetch/execute)

View File

@ -972,7 +972,7 @@ LRESULT CALLBACK FrameWndProc (
}
else if (g_nAppMode == MODE_DEBUG)
{
DebuggerProcessKey(wparam);
DebuggerProcessKey(wparam); // Debugger already active, re-direct key to debugger
}
if (wparam == VK_F10)
@ -1468,19 +1468,13 @@ void ProcessButtonClick (int button)
ResetMachineState();
g_nAppMode = MODE_RUNNING;
}
if ((g_nAppMode == MODE_DEBUG) || (g_nAppMode == MODE_STEPPING))
if ((g_nAppMode == MODE_DEBUG) || (g_nAppMode == MODE_STEPPING)) // exit debugger
{
// If any breakpoints active,
if (g_nBreakpoints)
{
// switch to MODE_STEPPING
CmdGo( 0 );
}
// If any breakpoints active and ! we are not running at normal speed
if (g_nBreakpoints && !g_bDebugNormalSpeedBreakpoints)
CmdGo( 0 ); // 6502 runs at full speed, switch to MODE_STEPPNIG
else
{
DebugEnd();
g_nAppMode = MODE_RUNNING;
}
DebugEnd(); // 6502 runs at normal speed, switch to MODE_RUNNING
}
DrawStatusArea((HDC)0,DRAW_TITLE);
VideoRedrawScreen();
@ -1510,10 +1504,7 @@ void ProcessButtonClick (int button)
{
ResetMachineState();
}
// bug/feature: allow F7 to enter debugger even though emulator isn't "running"
//else
// Allow F7 to enter debugger even though emulator isn't "running"
if (g_nAppMode == MODE_STEPPING)
{
DebuggerInputConsoleChar( DEBUG_EXIT_KEY );
@ -1521,8 +1512,13 @@ void ProcessButtonClick (int button)
else
if (g_nAppMode == MODE_DEBUG)
{
g_bDebugDelayBreakCheck = true;
ProcessButtonClick(BTN_RUN);
if (KeybGetShiftStatus())
g_bDebugNormalSpeedBreakpoints = true; // MODE_RUNNING // Normal Speed Breakpoints: Shift-F7 exit debugger, keep breakpoints active, enter run state at NORMAL speed
else
g_bDebugNormalSpeedBreakpoints = false; // MODE_STEPPING // Full Speed Breakpoints
g_bDebugBreakDelayCheck = true;
ProcessButtonClick(BTN_RUN); // Exit debugger, switch to MODE_RUNNING or MODE_STEPPING
// TODO: DD Full-Screen Palette
// exiting debugger using wrong palette, but this makes problem worse...