From 195775b703069723f971aacff82eb4b4e5018f4a Mon Sep 17 00:00:00 2001 From: mpohoreski Date: Mon, 21 Feb 2011 23:54:09 +0000 Subject: [PATCH] .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 --- AppleWin/docs/Debugger_Changelog.txt | 4 + AppleWin/source/CPU.cpp | 28 +- AppleWin/source/CPU/cpu6502.h | 12 +- AppleWin/source/CPU/cpu65C02.h | 536 +++++++++--------- AppleWin/source/CPU/cpu65d02.h | 25 +- AppleWin/source/Common.h | 6 +- AppleWin/source/Debugger/Debug.cpp | 126 ++-- AppleWin/source/Debugger/Debug.h | 83 ++- .../source/Debugger/Debugger_Commands.cpp | 4 +- AppleWin/source/Debugger/Debugger_Help.cpp | 20 +- AppleWin/source/Debugger/Debugger_Types.h | 4 +- AppleWin/source/Frame.cpp | 32 +- 12 files changed, 478 insertions(+), 402 deletions(-) diff --git a/AppleWin/docs/Debugger_Changelog.txt b/AppleWin/docs/Debugger_Changelog.txt index 9b5181da..cb96ce8b 100644 --- a/AppleWin/docs/Debugger_Changelog.txt +++ b/AppleWin/docs/Debugger_Changelog.txt @@ -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 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. diff --git a/AppleWin/source/CPU.cpp b/AppleWin/source/CPU.cpp index 3cd2d1a1..f12a1846 100644 --- a/AppleWin/source/CPU.cpp +++ b/AppleWin/source/CPU.cpp @@ -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 //=========================================================================== diff --git a/AppleWin/source/CPU/cpu6502.h b/AppleWin/source/CPU/cpu6502.h index 4c21f3d1..c196f115 100644 --- a/AppleWin/source/CPU/cpu6502.h +++ b/AppleWin/source/CPU/cpu6502.h @@ -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; } diff --git a/AppleWin/source/CPU/cpu65C02.h b/AppleWin/source/CPU/cpu65C02.h index aaa63c0c..58897c7e 100644 --- a/AppleWin/source/CPU/cpu65C02.h +++ b/AppleWin/source/CPU/cpu65C02.h @@ -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; } diff --git a/AppleWin/source/CPU/cpu65d02.h b/AppleWin/source/CPU/cpu65d02.h index 6b31273e..08953da9 100644 --- a/AppleWin/source/CPU/cpu65d02.h +++ b/AppleWin/source/CPU/cpu65d02.h @@ -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; } diff --git a/AppleWin/source/Common.h b/AppleWin/source/Common.h index 1869b366..e5ecff5d 100644 --- a/AppleWin/source/Common.h +++ b/AppleWin/source/Common.h @@ -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 diff --git a/AppleWin/source/Debugger/Debug.cpp b/AppleWin/source/Debugger/Debug.cpp index 062021ca..7b1e18ac 100644 --- a/AppleWin/source/Debugger/Debug.cpp +++ b/AppleWin/source/Debugger/Debug.cpp @@ -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; } diff --git a/AppleWin/source/Debugger/Debug.h b/AppleWin/source/Debugger/Debug.h index f2218269..78f07f0b 100644 --- a/AppleWin/source/Debugger/Debug.h +++ b/AppleWin/source/Debugger/Debug.h @@ -30,16 +30,33 @@ using namespace std; // extern vector 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 ); diff --git a/AppleWin/source/Debugger/Debugger_Commands.cpp b/AppleWin/source/Debugger/Debugger_Commands.cpp index 7db33525..97bd58da 100644 --- a/AppleWin/source/Debugger/Debugger_Commands.cpp +++ b/AppleWin/source/Debugger/Debugger_Commands.cpp @@ -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" }, diff --git a/AppleWin/source/Debugger/Debugger_Help.cpp b/AppleWin/source/Debugger/Debugger_Help.cpp index 21a44240..fd81dede 100644 --- a/AppleWin/source/Debugger/Debugger_Help.cpp +++ b/AppleWin/source/Debugger/Debugger_Help.cpp @@ -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 diff --git a/AppleWin/source/Debugger/Debugger_Types.h b/AppleWin/source/Debugger/Debugger_Types.h index 464c4dd9..d3eb3f8a 100644 --- a/AppleWin/source/Debugger/Debugger_Types.h +++ b/AppleWin/source/Debugger/Debugger_Types.h @@ -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) diff --git a/AppleWin/source/Frame.cpp b/AppleWin/source/Frame.cpp index 6a6efa96..8b787a62 100644 --- a/AppleWin/source/Frame.cpp +++ b/AppleWin/source/Frame.cpp @@ -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...