Skip to content

Commit

Permalink
New function to add/delete a single breakpoint, removed setNoBreakOnD…
Browse files Browse the repository at this point in the history
…ataRead()
  • Loading branch information
istvan-v committed Dec 23, 2016
1 parent eed6e3c commit 1395f27
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 75 deletions.
8 changes: 4 additions & 4 deletions plus4lib/plus4api.cpp
Expand Up @@ -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());
Expand All @@ -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)
Expand Down
10 changes: 7 additions & 3 deletions plus4lib/plus4emu.h
Expand Up @@ -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);
Expand All @@ -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);
/*!
Expand Down
91 changes: 49 additions & 42 deletions src/plus4vm.cpp
Expand Up @@ -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);
}

Expand Down Expand Up @@ -1500,7 +1498,6 @@ namespace Plus4 {
ted->getBreakPointPriorityThreshold());
p->setBreakOnInvalidOpcode(ted->getIsBreakOnInvalidOpcode());
}
printer_->setNoBreakOnDataRead(noBreakOnDataRead);
}
}

Expand Down Expand Up @@ -1800,7 +1797,6 @@ namespace Plus4 {
ted->getBreakPointPriorityThreshold());
p->setBreakOnInvalidOpcode(ted->getIsBreakOnInvalidOpcode());
}
floppyDrive->setNoBreakOnDataRead(noBreakOnDataRead);
}
if (serialDevices[n] != (SerialDevice *) 0) {
reinterpret_cast<FloppyDrive *>(serialDevices[n])->setDiskImageFile(
Expand Down Expand Up @@ -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());
}
}

Expand All @@ -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;
Expand All @@ -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();
Expand Down
19 changes: 13 additions & 6 deletions src/plus4vm.hpp
Expand Up @@ -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).
Expand All @@ -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
Expand Down
11 changes: 4 additions & 7 deletions src/script.cpp
@@ -1,7 +1,7 @@

// plus4emu -- portable Commodore Plus/4 emulator
// Copyright (C) 2003-2016 Istvan Varga <istvanv@users.sourceforge.net>
// 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
Expand All @@ -20,7 +20,6 @@
#include "plus4emu.hpp"
#include "vm.hpp"
#include "plus4vm.hpp"
#include "bplist.hpp"
#include "script.hpp"

#ifdef HAVE_LUA_H
Expand Down Expand Up @@ -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());
Expand Down
14 changes: 8 additions & 6 deletions src/vm.cpp
Expand Up @@ -119,7 +119,6 @@ namespace Plus4Emu {
breakPointCallback(&defaultBreakPointCallback),
breakPointCallbackUserData((void *) 0),
currentDebugContext(0),
noBreakOnDataRead(false),
#ifndef WIN32
fileIOWorkingDirectory("./"),
#else
Expand Down Expand Up @@ -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;
Expand All @@ -685,11 +692,6 @@ namespace Plus4Emu {
(void) n;
}

void VirtualMachine::setNoBreakOnDataRead(bool n)
{
noBreakOnDataRead = n;
}

void VirtualMachine::setSingleStepMode(int mode_)
{
(void) mode_;
Expand Down
20 changes: 13 additions & 7 deletions src/vm.hpp
Expand Up @@ -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);
Expand Down Expand Up @@ -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).
Expand All @@ -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
Expand Down

0 comments on commit 1395f27

Please sign in to comment.