mirror of https://github.com/stella-emu/stella.git
Implemented solution for #396
This commit is contained in:
parent
a7f8d67211
commit
ecb6c7a508
|
@ -163,6 +163,9 @@ void CartDebug::triggerReadFromWritePort(uInt16 addr)
|
|||
{
|
||||
myRWPortAddress = addr;
|
||||
mySystem.setDirtyPage(addr);
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
mySystem.m6502().setReadFromWritePort(addr);
|
||||
#endif // DEBUGGER_SUPPORT
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -73,7 +73,9 @@ M6502::M6502(const Settings& settings)
|
|||
myOnHaltCallback(nullptr),
|
||||
myHaltRequested(false),
|
||||
myGhostReadsTrap(true),
|
||||
myStepStateByInstruction(false)
|
||||
myStepStateByInstruction(false),
|
||||
myReadFromWritePortBreak(false),
|
||||
myReadFromWritePortAddr(0)
|
||||
{
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
myDebugger = nullptr;
|
||||
|
@ -120,6 +122,7 @@ void M6502::reset()
|
|||
|
||||
myHaltRequested = false;
|
||||
myGhostReadsTrap = mySettings.getBool("dbg.ghostreadstrap");
|
||||
myReadFromWritePortBreak = mySettings.getBool(devSettings ? "dev.rwportbreak" : "plr.rwportbreak");
|
||||
|
||||
myLastBreakCycle = ULLONG_MAX;
|
||||
}
|
||||
|
@ -289,6 +292,18 @@ inline void M6502::_execute(uInt64 cycles, DispatchResult& result)
|
|||
result.setDebugger(currentCycles, msg.str());
|
||||
return;
|
||||
}
|
||||
|
||||
int rwAddr = readFromWritePort();
|
||||
if(rwAddr)
|
||||
{
|
||||
stringstream msg;
|
||||
msg << "RWP[@ $" << Common::Base::HEX4 << rwAddr << "]: ";
|
||||
|
||||
myLastBreakCycle = mySystem->cycles();
|
||||
|
||||
result.setDebugger(currentCycles, msg.str(), PC);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int cond = evalCondSaveStates();
|
||||
|
@ -437,6 +452,8 @@ bool M6502::save(Serializer& out) const
|
|||
out.putBool(myHaltRequested);
|
||||
out.putBool(myStepStateByInstruction);
|
||||
out.putBool(myGhostReadsTrap);
|
||||
out.putBool(myReadFromWritePortBreak);
|
||||
out.putInt(myReadFromWritePortAddr);
|
||||
out.putLong(myLastBreakCycle);
|
||||
}
|
||||
catch(...)
|
||||
|
@ -485,7 +502,8 @@ bool M6502::load(Serializer& in)
|
|||
myHaltRequested = in.getBool();
|
||||
myStepStateByInstruction = in.getBool();
|
||||
myGhostReadsTrap = in.getBool();
|
||||
|
||||
myReadFromWritePortBreak = in.getBool();
|
||||
myReadFromWritePortAddr = in.getInt();
|
||||
myLastBreakCycle = in.getLong();
|
||||
}
|
||||
catch(...)
|
||||
|
@ -635,4 +653,21 @@ void M6502::updateStepStateByInstruction()
|
|||
myTrapConds.size();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
int M6502::readFromWritePort()
|
||||
{
|
||||
uInt16 addr = myReadFromWritePortAddr;
|
||||
myReadFromWritePortAddr = 0;
|
||||
|
||||
// A read from the write port occurs when the read is actually in the write
|
||||
// port address space AND the last access was actually a read (the latter
|
||||
// differentiates between reads that are normally part of a write cycle vs.
|
||||
// ones that are illegal)
|
||||
if(myReadFromWritePortBreak && lastReadAddress() &&
|
||||
(mySystem->getPageAccessType(addr) & System::PA_WRITE) == System::PA_WRITE)
|
||||
return addr;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // DEBUGGER_SUPPORT
|
||||
|
|
|
@ -242,6 +242,9 @@ class M6502 : public Serializable
|
|||
const StringList& getCondTrapNames() const;
|
||||
|
||||
void setGhostReadsTrap(bool enable) { myGhostReadsTrap = enable; }
|
||||
void setReadFromWritePortBreak(bool enable) { myReadFromWritePortBreak = enable; }
|
||||
void setReadFromWritePort(uInt16 addr) { myReadFromWritePortAddr = addr; };
|
||||
int readFromWritePort();
|
||||
#endif // DEBUGGER_SUPPORT
|
||||
|
||||
private:
|
||||
|
@ -461,6 +464,8 @@ class M6502 : public Serializable
|
|||
// in save states, they cannot be conditionally compiled
|
||||
bool myGhostReadsTrap; // trap on ghost reads
|
||||
bool myStepStateByInstruction;
|
||||
bool myReadFromWritePortBreak;
|
||||
uInt16 myReadFromWritePortAddr;
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
|
|
|
@ -149,6 +149,8 @@ Settings::Settings(OSystem& osystem)
|
|||
setInternal("dis.gfxformat", "2");
|
||||
setInternal("dis.showaddr", "true");
|
||||
setInternal("dis.relocate", "false");
|
||||
setInternal("plr.rwportbreak", "false");
|
||||
setInternal("dev.rwportbreak", "true");
|
||||
#endif
|
||||
|
||||
// player settings
|
||||
|
@ -620,6 +622,9 @@ void Settings::usage() const
|
|||
<< " -plr.tv.jitter_recovery <1-20> Set recovery time for TV jitter effect\n"
|
||||
<< " -plr.tiadriven <1|0> Drive unused TIA pins randomly on a\n"
|
||||
<< " read/peek\n"
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
<< " -plr.rwportbreak <1|0> Debugger breaks on reads from write ports\n"
|
||||
#endif
|
||||
<< " -plr.thumb.trapfatal <1|0> Determines whether errors in ARM emulation\n"
|
||||
<< " throw an exception\n"
|
||||
<< " -plr.eepromaccess <1|0> Enable messages for AtariVox/SaveKey access\n"
|
||||
|
@ -639,6 +644,9 @@ void Settings::usage() const
|
|||
<< " -dev.tv.jitter_recovery <1-20> Set recovery time for TV jitter effect\n"
|
||||
<< " -dev.tiadriven <1|0> Drive unused TIA pins randomly on a\n"
|
||||
<< " read/peek\n"
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
<< " -dev.rwportbreak <1|0> Debugger breaks on reads from write ports\n"
|
||||
#endif
|
||||
<< " -dev.thumb.trapfatal <1|0> Determines whether errors in ARM emulation\n"
|
||||
<< " throw an exception\n"
|
||||
<< " -dev.eepromaccess <1|0> Enable messages for AtariVox/SaveKey access\n"
|
||||
|
|
|
@ -151,6 +151,11 @@ void DeveloperDialog::addEmulationTab(const GUI::Font& font)
|
|||
wid.push_back(myUndrivenPinsWidget);
|
||||
ypos += lineHeight + VGAP;
|
||||
|
||||
myRWPortBreakWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1,
|
||||
"Break on reads from write ports");
|
||||
wid.push_back(myRWPortBreakWidget);
|
||||
ypos += lineHeight + VGAP;
|
||||
|
||||
// Thumb ARM emulation exception
|
||||
myThumbExceptionWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1,
|
||||
"Fatal ARM emulation error throws exception");
|
||||
|
@ -445,7 +450,7 @@ void DeveloperDialog::addDebuggerTab(const GUI::Font& font)
|
|||
ypos += lineHeight + VGAP * 4;
|
||||
|
||||
myGhostReadsTrapWidget = new CheckboxWidget(myTab, font, HBORDER, ypos + 1,
|
||||
"Trap on 'ghost' reads", kGhostReads);
|
||||
"Trap on 'ghost' reads");
|
||||
wid.push_back(myGhostReadsTrapWidget);
|
||||
|
||||
// Add message concerning usage
|
||||
|
@ -487,6 +492,8 @@ void DeveloperDialog::loadSettings(SettingsSet set)
|
|||
myRandomizeCPU[set] = instance().settings().getString(prefix + "cpurandom");
|
||||
// Undriven TIA pins
|
||||
myUndrivenPins[set] = instance().settings().getBool(prefix + "tiadriven");
|
||||
// Read from write ports break
|
||||
myRWPortBreak[set] = instance().settings().getBool(prefix + "rwportbreak");
|
||||
// Thumb ARM emulation exception
|
||||
myThumbException[set] = instance().settings().getBool(prefix + "thumb.trapfatal");
|
||||
// AtariVox/SaveKey EEPROM access
|
||||
|
@ -521,6 +528,8 @@ void DeveloperDialog::saveSettings(SettingsSet set)
|
|||
instance().settings().setValue(prefix + "cpurandom", myRandomizeCPU[set]);
|
||||
// Undriven TIA pins
|
||||
instance().settings().setValue(prefix + "tiadriven", myUndrivenPins[set]);
|
||||
// Read from write ports break
|
||||
instance().settings().setValue(prefix + "rwportbreak", myRWPortBreak[set]);
|
||||
// Thumb ARM emulation exception
|
||||
instance().settings().setValue(prefix + "thumb.trapfatal", myThumbException[set]);
|
||||
// AtariVox/SaveKey EEPROM access
|
||||
|
@ -558,6 +567,8 @@ void DeveloperDialog::getWidgetStates(SettingsSet set)
|
|||
myRandomizeCPU[set] = cpurandom;
|
||||
// Undriven TIA pins
|
||||
myUndrivenPins[set] = myUndrivenPinsWidget->getState();
|
||||
// Read from write ports break
|
||||
myRWPortBreak[set] = myRWPortBreakWidget->getState();
|
||||
// Thumb ARM emulation exception
|
||||
myThumbException[set] = myThumbExceptionWidget->getState();
|
||||
// AtariVox/SaveKey EEPROM access
|
||||
|
@ -595,6 +606,8 @@ void DeveloperDialog::setWidgetStates(SettingsSet set)
|
|||
myRandomizeCPUWidget[i]->setState(BSPF::containsIgnoreCase(cpurandom, cpuregs[i]));
|
||||
// Undriven TIA pins
|
||||
myUndrivenPinsWidget->setState(myUndrivenPins[set]);
|
||||
// Read from write ports break
|
||||
myRWPortBreakWidget->setState(myRWPortBreak[set]);
|
||||
// Thumb ARM emulation exception
|
||||
myThumbExceptionWidget->setState(myThumbException[set]);
|
||||
// AtariVox/SaveKey EEPROM access
|
||||
|
@ -682,6 +695,10 @@ void DeveloperDialog::saveConfig()
|
|||
saveSettings(SettingsSet::player);
|
||||
saveSettings(SettingsSet::developer);
|
||||
|
||||
// Read from write ports break
|
||||
if(instance().hasConsole())
|
||||
instance().console().system().m6502().setReadFromWritePortBreak(myRWPortBreakWidget->getState());
|
||||
|
||||
// activate the current settings
|
||||
instance().frameBuffer().showFrameStats(myFrameStatsWidget->getState());
|
||||
// jitter
|
||||
|
@ -743,6 +760,8 @@ void DeveloperDialog::setDefaults()
|
|||
myRandomizeCPU[set] = devSettings ? "SAXYP" : "AXYP";
|
||||
// Undriven TIA pins
|
||||
myUndrivenPins[set] = devSettings ? true : false;
|
||||
// Reads from write ports
|
||||
myRWPortBreak[set] = devSettings ? true : false;
|
||||
// Thumb ARM emulation exception
|
||||
myThumbException[set] = devSettings ? true : false;
|
||||
// AtariVox/SaveKey EEPROM access
|
||||
|
|
|
@ -75,7 +75,6 @@ class DeveloperDialog : public Dialog
|
|||
kBLColourChangedCmd = 'GObl',
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
kDFontSizeChanged = 'UIfs',
|
||||
kGhostReads = 'Dbgh'
|
||||
#endif
|
||||
};
|
||||
enum SettingsSet
|
||||
|
@ -101,6 +100,9 @@ class DeveloperDialog : public Dialog
|
|||
StaticTextWidget* myRandomizeCPULabel;
|
||||
CheckboxWidget* myRandomizeCPUWidget[5];
|
||||
CheckboxWidget* myUndrivenPinsWidget;
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
CheckboxWidget* myRWPortBreakWidget;
|
||||
#endif
|
||||
CheckboxWidget* myThumbExceptionWidget;
|
||||
CheckboxWidget* myEEPROMAccessWidget;
|
||||
|
||||
|
@ -143,6 +145,9 @@ class DeveloperDialog : public Dialog
|
|||
int myTVJitterRec[2];
|
||||
bool myDebugColors[2];
|
||||
bool myUndrivenPins[2];
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
bool myRWPortBreak[2];
|
||||
#endif
|
||||
bool myThumbException[2];
|
||||
bool myEEPROMAccess[2];
|
||||
// States sets
|
||||
|
|
Loading…
Reference in New Issue