From 1395f270b7ab9a5586d8eb0b16ccbc10194b337a Mon Sep 17 00:00:00 2001 From: IstvanV Date: Fri, 23 Dec 2016 22:26:12 +0100 Subject: [PATCH] New function to add/delete a single breakpoint, removed setNoBreakOnDataRead() --- plus4lib/plus4api.cpp | 8 ++-- plus4lib/plus4emu.h | 10 +++-- src/plus4vm.cpp | 91 +++++++++++++++++++++++-------------------- src/plus4vm.hpp | 19 ++++++--- src/script.cpp | 11 ++---- src/vm.cpp | 14 ++++--- src/vm.hpp | 20 ++++++---- 7 files changed, 98 insertions(+), 75 deletions(-) diff --git a/plus4lib/plus4api.cpp b/plus4lib/plus4api.cpp index e4db4c9..494c654 100644 --- a/plus4lib/plus4api.cpp +++ b/plus4lib/plus4api.cpp @@ -1063,9 +1063,7 @@ extern "C" PLUS4EMU_EXPORT Plus4Emu_Error Plus4VM_AddBreakPoint( Plus4VM *vm, int bpType, uint16_t bpAddr, int bpPriority) { try { - Plus4Emu::BreakPointList bpList; - bpList.addBreakPoint(bpType, bpAddr, bpPriority); - vm->getVM().setBreakPoints(bpList); + vm->getVM().setBreakPoint(bpType, bpAddr, bpPriority); } catch (std::exception& e) { vm->setLastErrorMessage(e.what()); @@ -1089,7 +1087,9 @@ extern "C" PLUS4EMU_EXPORT void Plus4VM_SetBPPriorityThreshold( extern "C" PLUS4EMU_EXPORT void Plus4VM_SetNoBreakOnDataRead(Plus4VM *vm, int n) { - vm->getVM().setNoBreakOnDataRead(bool(n)); + // deprecated function, has no effect + (void) vm; + (void) n; } extern "C" PLUS4EMU_EXPORT void Plus4VM_SetSingleStepMode(Plus4VM *vm, int mode) diff --git a/plus4lib/plus4emu.h b/plus4lib/plus4emu.h index 3bbfa5b..a28ade2 100644 --- a/plus4lib/plus4emu.h +++ b/plus4lib/plus4emu.h @@ -583,12 +583,14 @@ PLUS4EMU_EXPORT int Plus4VM_GetDebugContext(Plus4VM *vm); /*! * Add new breakpoint with the specified type, address, and priority (0 to 3). * The allowed values for 'bpType' are: - * 0: memory read/write + * 0: any memory access (read, write or CPU opcode read) * 1: memory read * 2: memory write - * 3: memory read/write + * 3: any memory access, same as bpType == 0 * 4: video (address bits 7..15 for Y, bits 0..6 for X) * 5: ignore other breakpoints if the program counter is at this address + * 6: CPU opcode read + * A negative priority value deletes any existing breakpoint at 'bpAddr'. */ PLUS4EMU_EXPORT Plus4Emu_Error Plus4VM_AddBreakPoint( Plus4VM *vm, int bpType, uint16_t bpAddr, int bpPriority); @@ -602,7 +604,9 @@ PLUS4EMU_EXPORT void Plus4VM_ClearBreakPoints(Plus4VM *vm); */ PLUS4EMU_EXPORT void Plus4VM_SetBPPriorityThreshold(Plus4VM *vm, int n); /*! - * If 'n' is non-zero, read breakpoints will only be triggered on opcode reads. + * (DEPRECATED) If 'n' is non-zero, read breakpoints will only be triggered on + * opcode reads. NOTE: this function no longer has any effect, use execute + * breakpoints instead. */ PLUS4EMU_EXPORT void Plus4VM_SetNoBreakOnDataRead(Plus4VM *vm, int n); /*! diff --git a/src/plus4vm.cpp b/src/plus4vm.cpp index 8b93e99..70ce55e 100644 --- a/src/plus4vm.cpp +++ b/src/plus4vm.cpp @@ -121,8 +121,6 @@ namespace Plus4 { void Plus4VM::TED7360_::breakPointCallback(int type, uint16_t addr, uint8_t value) { - if (vm.noBreakOnDataRead && type == 1) - return; vm.breakPointCallback(vm.breakPointCallbackUserData, 0, type, addr, value); } @@ -1500,7 +1498,6 @@ namespace Plus4 { ted->getBreakPointPriorityThreshold()); p->setBreakOnInvalidOpcode(ted->getIsBreakOnInvalidOpcode()); } - printer_->setNoBreakOnDataRead(noBreakOnDataRead); } } @@ -1800,7 +1797,6 @@ namespace Plus4 { ted->getBreakPointPriorityThreshold()); p->setBreakOnInvalidOpcode(ted->getIsBreakOnInvalidOpcode()); } - floppyDrive->setNoBreakOnDataRead(noBreakOnDataRead); } if (serialDevices[n] != (SerialDevice *) 0) { reinterpret_cast(serialDevices[n])->setDiskImageFile( @@ -2016,40 +2012,61 @@ namespace Plus4 { } } - void Plus4VM::setBreakPoints(const Plus4Emu::BreakPointList& bpList) + void Plus4VM::setBreakPoint(int bpType, uint16_t bpAddr, int bpPriority) { - for (size_t i = 0; i < bpList.getBreakPointCnt(); i++) { - const Plus4Emu::BreakPoint& bp = bpList.getBreakPoint(i); - if (bp.type() == 4 && currentDebugContext != 0) + bpPriority = (bpPriority < 3 ? bpPriority : 3); + if (bpType == 4) { + if (currentDebugContext != 0) { throw Plus4Emu::Exception("video breakpoints can only be set " "for the main CPU"); - } - M7501 *p = getDebugCPU(); - if (p) { - for (size_t i = 0; i < bpList.getBreakPointCnt(); i++) { - const Plus4Emu::BreakPoint& bp = bpList.getBreakPoint(i); - if (bp.type() != 4) { - p->setBreakPoint(bp.type(), bp.addr(), bp.priority()); - } - else { - if (videoBreakPointCnt == 0) { - if (!videoBreakPoints) { - videoBreakPoints = new uint8_t[65536]; - for (size_t j = 0; j <= 0xFFFF; j++) - videoBreakPoints[j] = 0; - } - ted->setCallback(&videoBreakPointCheckCallback, this, 3); + } + // correct video position for FF1E read delay + uint16_t addrX = (bpAddr + 1) & 0x7F; + bpAddr = bpAddr & 0xFF80; + if (addrX != 114) + bpAddr = bpAddr | addrX; + if (bpPriority >= 0) { + if (videoBreakPointCnt == 0) { + if (!videoBreakPoints) { + videoBreakPoints = new uint8_t[65536]; + for (size_t j = 0; j <= 0xFFFF; j++) + videoBreakPoints[j] = 0; } - // correct video position for FF1E read delay - uint16_t addr = bp.addr(); - uint16_t addrX = (addr & 0x7F) + 1; - addr = addr & 0xFF80; - if (addrX != 114) - addr = addr | (addrX & 0x7F); - videoBreakPoints[addr] = uint8_t(bp.priority() + 1); + ted->setCallback(&videoBreakPointCheckCallback, this, 3); + } + if (!videoBreakPoints[bpAddr]) videoBreakPointCnt++; + if (bpPriority >= int(videoBreakPoints[bpAddr])) + videoBreakPoints[bpAddr] = uint8_t(bpPriority + 1); + } + else if (videoBreakPoints) { + if (videoBreakPoints[bpAddr]) { + videoBreakPoints[bpAddr] = 0; + videoBreakPointCnt--; + if (!videoBreakPointCnt) + ted->setCallback(&videoBreakPointCheckCallback, this, 0); } } + return; + } + M7501 *p = getDebugCPU(); + if (!p) + return; + if (bpType < 0 || bpType > 6) { + bpType = 0; + } + else { + bpType = ((bpType == 0 || bpType == 3) ? + 7 : (bpType == 6 ? 4 : (bpType == 5 ? 8 : bpType))); + } + p->setBreakPoint(bpType, bpAddr, bpPriority); + } + + void Plus4VM::setBreakPoints(const Plus4Emu::BreakPointList& bpList) + { + for (size_t i = 0; i < bpList.getBreakPointCnt(); i++) { + const Plus4Emu::BreakPoint& bp = bpList.getBreakPoint(i); + setBreakPoint(bp.type(), bp.addr(), bp.priority()); } } @@ -2058,7 +2075,7 @@ namespace Plus4 { M7501 *p = getDebugCPU(); if (p) p->clearBreakPoints(); - if (currentDebugContext == 0 && videoBreakPointCnt != 0) { + if (currentDebugContext == 0 && videoBreakPoints) { ted->setCallback(&videoBreakPointCheckCallback, this, 0); videoBreakPointCnt = 0; delete[] videoBreakPoints; @@ -2079,16 +2096,6 @@ namespace Plus4 { } } - void Plus4VM::setNoBreakOnDataRead(bool n) - { - noBreakOnDataRead = n; - for (int i = 0; i < 5; i++) { - int tmp = (i < 4 ? (i + 8) : printerDeviceNumber); - if (serialDevices[tmp] != (SerialDevice *) 0) - serialDevices[tmp]->setNoBreakOnDataRead(n); - } - } - void Plus4VM::setSingleStepMode(int mode_) { M7501 *p = getDebugCPU(); diff --git a/src/plus4vm.hpp b/src/plus4vm.hpp index 44cf6e7..158f203 100644 --- a/src/plus4vm.hpp +++ b/src/plus4vm.hpp @@ -474,6 +474,19 @@ namespace Plus4 { * 5: printer */ virtual void setDebugContext(int n); + /*! + * Add new breakpoint with the specified type, address, and priority + * (0 to 3). The allowed values for 'bpType' are: + * 0: any memory access (read, write or CPU opcode read) + * 1: memory read + * 2: memory write + * 3: any memory access, same as bpType == 0 + * 4: video (address bits 7..15 for Y, bits 0..6 for X) + * 5: ignore other breakpoints if the program counter is at this address + * 6: CPU opcode read + * A negative priority value deletes any existing breakpoint at 'bpAddr'. + */ + virtual void setBreakPoint(int bpType, uint16_t bpAddr, int bpPriority); /*! * Add breakpoints from the specified breakpoint list (see also * bplist.hpp). @@ -488,12 +501,6 @@ namespace Plus4 { * priority less than this value will not trigger a break. */ virtual void setBreakPointPriorityThreshold(int n); - /*! - * If 'n' is true, breakpoints will not be triggered on reads from - * any memory address other than the current value of the program - * counter. - */ - virtual void setNoBreakOnDataRead(bool n); /*! * Set if the breakpoint callback should be called whenever the first byte * of a CPU instruction is read from memory. 'mode_' can be one of the diff --git a/src/script.cpp b/src/script.cpp index 52b1977..abd62c2 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -1,7 +1,7 @@ // plus4emu -- portable Commodore Plus/4 emulator // Copyright (C) 2003-2016 Istvan Varga -// http://sourceforge.net/projects/plus4emu/ +// https://github.com/istvan-v/plus4emu/ // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -20,7 +20,6 @@ #include "plus4emu.hpp" #include "vm.hpp" #include "plus4vm.hpp" -#include "bplist.hpp" #include "script.hpp" #ifdef HAVE_LUA_H @@ -198,11 +197,9 @@ namespace Plus4Emu { return 0; } try { - BreakPointList bpList; - bpList.addBreakPoint(int(lua_tointeger(lst, 1)), - uint16_t(lua_tointeger(lst, 2) & 0xFFFF), - int(lua_tointeger(lst, 3))); - this_.vm.setBreakPoints(bpList); + this_.vm.setBreakPoint(int(lua_tointeger(lst, 1)), + uint16_t(lua_tointeger(lst, 2) & 0xFFFF), + int(lua_tointeger(lst, 3))); } catch (std::exception& e) { this_.luaError(e.what()); diff --git a/src/vm.cpp b/src/vm.cpp index 9787e64..0a0fa50 100644 --- a/src/vm.cpp +++ b/src/vm.cpp @@ -119,7 +119,6 @@ namespace Plus4Emu { breakPointCallback(&defaultBreakPointCallback), breakPointCallbackUserData((void *) 0), currentDebugContext(0), - noBreakOnDataRead(false), #ifndef WIN32 fileIOWorkingDirectory("./"), #else @@ -671,6 +670,14 @@ namespace Plus4Emu { return currentDebugContext; } + void VirtualMachine::setBreakPoint(int bpType, uint16_t bpAddr, + int bpPriority) + { + (void) bpType; + (void) bpAddr; + (void) bpPriority; + } + void VirtualMachine::setBreakPoints(const BreakPointList& bpList) { (void) bpList; @@ -685,11 +692,6 @@ namespace Plus4Emu { (void) n; } - void VirtualMachine::setNoBreakOnDataRead(bool n) - { - noBreakOnDataRead = n; - } - void VirtualMachine::setSingleStepMode(int mode_) { (void) mode_; diff --git a/src/vm.hpp b/src/vm.hpp index 17fd048..392ab3a 100644 --- a/src/vm.hpp +++ b/src/vm.hpp @@ -66,7 +66,6 @@ namespace Plus4Emu { uint16_t addr, uint8_t value); void *breakPointCallbackUserData; int currentDebugContext; - bool noBreakOnDataRead; private: std::string fileIOWorkingDirectory; void (*fileNameCallback)(void *userData, std::string& fileName); @@ -511,6 +510,19 @@ namespace Plus4Emu { * Returns the current debugging context (CPU number). */ virtual int getDebugContext() const; + /*! + * Add new breakpoint with the specified type, address, and priority + * (0 to 3). The allowed values for 'bpType' are: + * 0: any memory access (read, write or CPU opcode read) + * 1: memory read + * 2: memory write + * 3: any memory access, same as bpType == 0 + * 4: video (address bits 7..15 for Y, bits 0..6 for X) + * 5: ignore other breakpoints if the program counter is at this address + * 6: CPU opcode read + * A negative priority value deletes any existing breakpoint at 'bpAddr'. + */ + virtual void setBreakPoint(int bpType, uint16_t bpAddr, int bpPriority); /*! * Add breakpoints from the specified breakpoint list (see also * bplist.hpp). @@ -525,12 +537,6 @@ namespace Plus4Emu { * priority less than this value will not trigger a break. */ virtual void setBreakPointPriorityThreshold(int n); - /*! - * If 'n' is true, breakpoints will not be triggered on reads from - * any memory address other than the current value of the program - * counter. - */ - virtual void setNoBreakOnDataRead(bool n); /*! * Set if the breakpoint callback should be called whenever the first byte * of a CPU instruction is read from memory. 'mode_' can be one of the