added user defined timers to debugger (TODO: screenshots)

This commit is contained in:
Thomas Jentzsch 2022-10-06 16:55:00 +02:00
parent d8ed1d1d13
commit 3de6002c46
13 changed files with 381 additions and 10 deletions

View File

@ -15,7 +15,8 @@
6.7 to 7.0 (XXXXX XX, 202X)
* Enhanced ROM launcher to allow multiple images per ROM
(TODO: controller support, doc)
* Made heaps of additional images available for the ROM launcher
* Added searching by filename for ROM launcher images
@ -31,6 +32,8 @@
* Fixed broken 7800 pause key support
* Added user defined CPU cycle timers to debugger (TODO: screenshots)
-Have fun!

View File

@ -45,6 +45,7 @@
<li><a href="#PseudoRegisters">Pseudo-Registers</a></li>
<li><a href="#Watches">Watches</a></li>
<li><a href="#Traps">Traps</a></li>
<li><a href="#Timers">Timers</a></li>
</ul>
</li>
<li><a href="#SaveWork">Save your work!</a></li>
@ -858,6 +859,23 @@ can remove a trap with "delTrap number", where the number comes from
"listTraps" or by entering the identical trap again. You can get rid of
all traps at once with the "clearTraps" command.</p></p>
<h4><a name="Timers">Timers</a></h4>
<p>Timers are used to measure cycles used between two timer points. They
measure the minimum, maximum and average cycles executed between their two
timer points. Start and end points can be set via prompt command or ROM
Disassembly settings dialog.</p>
<p>Timer points can be defined with or without a bank. With a bank, they
are triggered in the given bank only, using all mirror addresses too. Without
a bank, the timer points are triggered in all bank, using the given adress
only.</p>
<p>All timers can be shown in detail with "listTimers", a single timer
with "printTimer number". "resetTimers" allows resetting all timer statistics,
"delTimer number" removes a single timer. All timers can be deleted with the
"clearTimers" command.</p>
</br>
<h3><a name="SaveWork">Save your work!</a></h3>
<p>Stella offers several commands to save your work inside the debugger for
@ -945,6 +963,7 @@ Type "help 'cmd'" to see extended information about the given command.</p>
clearConfig - Clear DiStella config directives [bank xx]
clearHistory - Clear the prompt history
clearSaveStateIfs - Clear all saveState points
clearTimers - Clear all timers
clearTraps - Clear all traps
clearWatches - Clear all watches
cls - Clear prompt area of text
@ -959,6 +978,7 @@ clearSaveStateIfs - Clear all saveState points
delFunction - Delete function with label xx
delSaveStateIf - Delete conditional saveState point &lt;xx&gt;
delTrap - Delete trap &lt;xx&gt;
delTimer - Delete timer &lt;xx&gt;
delWatch - Delete watch &lt;xx&gt;
disAsm - Disassemble address xx [yy lines] (default=PC)
dump - Dump data at address &lt;xx&gt; [to yy] [1: memory; 2: CPU state; 4: input regs] [?]
@ -994,8 +1014,10 @@ clearSaveStateIfs - Clear all saveState points
pCol - Mark 'PCOL' range in disassembly
pGfx - Mark 'PGFX' range in disassembly
print - Evaluate/print expression xx in hex/dec/binary
printTimer - Print details of timer xx
ram - Show ZP RAM, or set address xx to yy1 [yy2 ...]
reset - Reset system to power-on state
resetTimers - Reset all timers' statistics
rewind - Rewind state by one or [xx] steps/traces/scanlines/frames...
riot - Show RIOT timer/input status
rom - Set ROM address xx to yy1 [yy2 ...]
@ -1017,8 +1039,9 @@ clearSaveStateIfs - Clear all saveState points
scanLine - Advance emulation by &lt;xx&gt; scanlines (default=1)
step - Single step CPU [with count xx]
stepWhile - Single step CPU while &lt;condition&gt; is true
swchb - Set SWCHB to value xx
swchb - Set SWCHB to value xx
tia - Show TIA state
timer - Set a timer point
trace - Single step CPU over subroutines [with count xx]
trap - Trap read/write access to address(es) xx [yy]
trapIf - On &lt;condition&gt; trap R/W access to address(es) xx [yy]
@ -1563,6 +1586,9 @@ matches the address of the disassembly line where the mouse was clicked.</li>
<li><b>Disassemble @ current line</b>: Disassemble from the disassembly line where the mouse was clicked.
This allows to fill gaps in the disassembly and is most useful for bankswitched ROMs.</li>
<li><b>Set timer @ current line</b>: Set a timer point using the current
disassembly line's address and bank</li>
<li><b>Show tentative code</b>: Allow DiStella to do a static analysis/disassembly.</li>
<li><b>Show PC addresses</b>: Show Program Counter addresses as labels (where there

View File

@ -577,6 +577,83 @@ const string& DebuggerParser::cartName() const
return debugger.myOSystem.console().properties().get(PropType::Cart_Name);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DebuggerParser::printTimer(uInt32 idx, bool showHeader)
{
if(idx >= debugger.m6502().numTimers())
{
commandResult << red("invalid timer");
return;
}
const TimerMap::Timer& timer = debugger.m6502().getTimer(idx);
const bool banked = debugger.cartDebug().romBankCount() > 1;
ostringstream buf;
if(!debugger.cartDebug().getLabel(buf, timer.from.addr, true))
buf << " $" << setw(4) << Base::HEX4 << timer.from.addr;
string labelFrom = buf.str();
buf.str("");
if(!debugger.cartDebug().getLabel(buf, timer.to.addr, true))
buf << " $" << setw(4) << Base::HEX4 << timer.to.addr;
string labelTo = buf.str();
labelFrom = (labelFrom + " ").substr(0, banked ? 12 : 15);
labelTo = (labelTo + " ").substr(0, banked ? 12 : 15);
if(showHeader)
{
if(banked)
commandResult << " #| From /Bk| To /Bk| Execs| Avg. | Min. | Max. |";
else
commandResult << " #| From | To | Execs| Avg. | Min. | Max. |";
}
commandResult << endl << Base::toString(idx) << "|" << labelFrom;
if(banked)
{
commandResult << "/" << setw(2) << setfill(' ');
if(timer.from.bank == TimerMap::ANY_BANK)
commandResult << "-";
else
commandResult << dec << static_cast<uInt16>(timer.from.bank);
}
commandResult << "|";
if(timer.isPartial)
commandResult << (banked ? " - " : " - ")
<< "| -| -| -| -|";
else
{
commandResult << labelTo;
if(banked)
{
commandResult << "/" << setw(2) << setfill(' ');
if(timer.to.bank == TimerMap::ANY_BANK)
commandResult << "-";
else
commandResult << dec << static_cast<uInt16>(timer.to.bank);
}
commandResult << "|"
<< setw(6) << setfill(' ') << dec << timer.execs << "|";
if(!timer.execs)
commandResult << " -| -| -|";
else
commandResult
<< setw(6) << dec << timer.averageCycles() << "|"
<< setw(6) << dec << timer.minCycles << "|"
<< setw(6) << dec << timer.maxCycles << "|";
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DebuggerParser::listTimers()
{
commandResult << "timers:" << endl;
for(uInt32 i = 0; i < debugger.m6502().numTimers(); ++i)
printTimer(i, i == 0);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DebuggerParser::listTraps(bool listCond)
{
@ -973,6 +1050,14 @@ void DebuggerParser::executeClearSaveStateIfs()
commandResult << "all saveState points cleared";
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "clearTimers"
void DebuggerParser::executeClearTimers()
{
debugger.m6502().clearTimers();
commandResult << "all timers cleared";
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "clearTraps"
void DebuggerParser::executeClearTraps()
@ -1085,6 +1170,17 @@ void DebuggerParser::executeDelSaveStateIf()
commandResult << red("no such saveStateIf");
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "delTimer"
void DebuggerParser::executeDelTimer()
{
const int index = args[0];
if(debugger.m6502().delTimer(index))
commandResult << "removed timer " << Base::toString(index);
else
commandResult << red("no such timer");
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "delTrap"
void DebuggerParser::executeDelTrap()
@ -1623,6 +1719,16 @@ void DebuggerParser::executeListSaveStateIfs()
commandResult << "no savestateifs defined";
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "listTimers"
void DebuggerParser::executeListTimers()
{
if(debugger.m6502().numTimers())
listTimers();
else
commandResult << "no timers set";
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "listTraps"
void DebuggerParser::executeListTraps()
@ -1732,6 +1838,13 @@ void DebuggerParser::executePrint()
commandResult << eval();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "printTimer"
void DebuggerParser::executePrintTimer()
{
printTimer(args[0]);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "ram"
void DebuggerParser::executeRam()
@ -1757,6 +1870,14 @@ void DebuggerParser::executeReset()
commandResult << "reset system";
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "resetTimers"
void DebuggerParser::executeResetTimers()
{
debugger.m6502().resetTimers();
commandResult << "all timers reset";
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "rewind"
void DebuggerParser::executeRewind()
@ -2169,6 +2290,65 @@ void DebuggerParser::executeTia()
commandResult << debugger.tiaDebug().toString();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "timer"
void DebuggerParser::executeTimer()
{
const uInt32 romBankCount = debugger.cartDebug().romBankCount();
if(argCount < 2)
{
const uInt16 addr = !argCount ? debugger.cpuDebug().pc() : args[0];
const uInt8 bank = !argCount ? debugger.cartDebug().getBank(addr) : TimerMap::ANY_BANK;
const uInt32 idx = debugger.m6502().addTimer(addr, bank);
commandResult << "set timer " << dec << idx << " "
<< (debugger.m6502().getTimer(idx).isPartial ? "start" : "end");
if(!argCount)
commandResult << " at $" << Base::HEX4 << (addr & TimerMap::ADDRESS_MASK);
if(romBankCount > 1 && !argCount)
commandResult << " + mirrors in bank #" << std::dec << static_cast<int>(bank);
return;
}
else if(argCount > 4)
{
outputCommandError("too many arguments", myCommand);
return;
}
// Detect if 2nd parameter is bank
if(argCount == 2 && args[0] >= 0x1000 && args[1] <= TimerMap::ANY_BANK)
{
const uInt16 addr = args[0];
const uInt8 bank = args[1];
if(bank >= romBankCount && bank != TimerMap::ANY_BANK)
{
commandResult << red("invalid bank");
return;
}
const uInt32 idx = debugger.m6502().addTimer(addr, bank);
commandResult << "set timer " << dec << idx << " "
<< (debugger.m6502().getTimer(idx).isPartial ? "start" : "end");
return;
}
else
{
const uInt8 bankFrom = argCount >= 3 ? args[2] : TimerMap::ANY_BANK;
if(bankFrom >= romBankCount && bankFrom != TimerMap::ANY_BANK)
{
commandResult << red("invalid bank");
return;
}
const uInt8 bankTo = argCount == 4 ? args[3] : bankFrom;
if(bankTo >= romBankCount && bankTo != TimerMap::ANY_BANK)
{
commandResult << red("invalid bank");
return;
}
const uInt32 idx = debugger.m6502().addTimer(args[0], args[1], bankFrom, bankTo);
commandResult << "timer " << idx << " added";
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "trace"
void DebuggerParser::executeTrace()
@ -2648,6 +2828,16 @@ DebuggerParser::CommandArray DebuggerParser::commands = { {
std::mem_fn(&DebuggerParser::executeClearSaveStateIfs)
},
{
"clearTimers",
"Clear all timers",
"All timers cleared\nExample: clearTimers (no parameters)",
false,
false,
{ Parameters::ARG_END_ARGS },
std::mem_fn(&DebuggerParser::executeClearTimers)
},
{
"clearTraps",
"Clear all traps",
@ -2778,6 +2968,16 @@ DebuggerParser::CommandArray DebuggerParser::commands = { {
std::mem_fn(&DebuggerParser::executeDelSaveStateIf)
},
{
"delTimer",
"Delete timer <xx>",
"Example: delTimer 0",
true,
false,
{ Parameters::ARG_WORD, Parameters::ARG_END_ARGS },
std::mem_fn(&DebuggerParser::executeDelTimer)
},
{
"delTrap",
"Delete trap <xx>",
@ -3035,6 +3235,16 @@ DebuggerParser::CommandArray DebuggerParser::commands = { {
std::mem_fn(&DebuggerParser::executeListSaveStateIfs)
},
{
"listTimers",
"List timers",
"Lists all timers\nExample: listTimers (no parameters)",
false,
false,
{ Parameters::ARG_END_ARGS },
std::mem_fn(&DebuggerParser::executeListTimers)
},
{
"listTraps",
"List traps",
@ -3146,6 +3356,16 @@ DebuggerParser::CommandArray DebuggerParser::commands = { {
std::mem_fn(&DebuggerParser::executePrint)
},
{
"printTimer",
"Print statistics for timer <xx>",
"Example: printTimer 0",
true,
false,
{ Parameters::ARG_WORD, Parameters::ARG_END_ARGS },
std::mem_fn(&DebuggerParser::executePrintTimer)
},
{
"ram",
"Show ZP RAM, or set address xx to yy1 [yy2 ...]",
@ -3166,6 +3386,16 @@ DebuggerParser::CommandArray DebuggerParser::commands = { {
std::mem_fn(&DebuggerParser::executeReset)
},
{
"resetTimers",
"Reset all timers' statistics" ,
"All timers resetted\nExample: resetTimers (no parameters)",
false,
false,
{ Parameters::ARG_END_ARGS },
std::mem_fn(&DebuggerParser::executeResetTimers)
},
{
"rewind",
"Rewind state by one or [xx] steps/traces/scanlines/frames...",
@ -3404,6 +3634,16 @@ DebuggerParser::CommandArray DebuggerParser::commands = { {
std::mem_fn(&DebuggerParser::executeTia)
},
{
"timer",
"Set a cycle counting timer from addresses xx to yy [banks aa bb]",
"Example: timer, timer 1000, timer 3000 3100, timer f000 f800 1",
false,
true,
{ Parameters::ARG_WORD, Parameters::ARG_MULTI_BYTE },
std::mem_fn(&DebuggerParser::executeTimer)
},
{
"trace",
"Single step CPU over subroutines [with count xx]",

View File

@ -101,7 +101,7 @@ class DebuggerParser
std::array<Parameters, 10> parms;
std::function<void (DebuggerParser*)> executor;
};
using CommandArray = std::array<Command, 104>;
using CommandArray = std::array<Command, 110>;
static CommandArray commands;
struct Trap
@ -142,6 +142,9 @@ class DebuggerParser
void listTraps(bool listCond);
string trapStatus(const Trap& trap);
void printTimer(uInt32 idx,bool showHeader = true);
void listTimers();
// output the error with the example provided for the command
void outputCommandError(const string& errorMsg, int command);
@ -162,6 +165,7 @@ class DebuggerParser
void executeClearConfig();
void executeClearHistory();
void executeClearSaveStateIfs();
void executeClearTimers();
void executeClearTraps();
void executeClearWatches();
void executeCls();
@ -175,6 +179,7 @@ class DebuggerParser
void executeDelBreakIf();
void executeDelFunction();
void executeDelSaveStateIf();
void executeDelTimer();
void executeDelTrap();
void executeDelWatch();
void executeDisAsm();
@ -200,6 +205,7 @@ class DebuggerParser
void executeListConfig();
void executeListFunctions();
void executeListSaveStateIfs();
void executeListTimers();
void executeListTraps();
void executeLoadAllStates();
void executeLoadConfig();
@ -211,8 +217,10 @@ class DebuggerParser
void executePCol();
void executePGfx();
void executePrint();
void executePrintTimer();
void executeRam();
void executeReset();
void executeResetTimers();
void executeRewind();
void executeRiot();
void executeRom();
@ -236,6 +244,7 @@ class DebuggerParser
void executeStepWhile();
void executeSwchb();
void executeTia();
void executeTimer();
void executeTrace();
void executeTrap();
void executeTrapIf();

View File

@ -48,6 +48,13 @@ RomListSettings::RomListSettings(GuiObject* boss, const GUI::Font& font)
"RunTo PC @ current line", RomListWidget::kRuntoPCCmd);
wid.push_back(runtoPC);
// Toggle timer
ypos += buttonHeight + 4;
auto* setTimer =
new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight,
"Set timer @ current line", RomListWidget::kSetTimerCmd);
wid.push_back(setTimer);
// Re-disassemble
ypos += buttonHeight + 4;
auto* disasm =
@ -154,6 +161,11 @@ void RomListSettings::handleCommand(CommandSender* sender, int cmd, int data, in
sendCommand(cmd, _item, -1);
break;
}
case RomListWidget::kSetTimerCmd:
{
sendCommand(cmd, _item, -1);
break;
}
case RomListWidget::kDisassembleCmd:
{
sendCommand(cmd, _item, -1);

View File

@ -37,6 +37,7 @@ class RomListWidget : public EditableWidget
// 'id' will be the Base::Format of the data
kSetPCCmd = 'STpc', // 'data' will be disassembly line number
kRuntoPCCmd = 'RTpc', // 'data' will be disassembly line number
kSetTimerCmd = 'STtm',
kDisassembleCmd = 'REds',
kTentativeCodeCmd = 'TEcd', // 'data' will be boolean
kPCAddressesCmd = 'PCad', // 'data' will be boolean

View File

@ -105,6 +105,11 @@ void RomWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
runtoPC(data);
break;
case RomListWidget::kSetTimerCmd:
// 'data' is the line in the disassemblylist to be accessed
setTimer(data);
break;
case RomListWidget::kDisassembleCmd:
// 'data' is the line in the disassemblylist to be accessed
disassemble(data);
@ -196,6 +201,20 @@ void RomWidget::runtoPC(int disasm_line)
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RomWidget::setTimer(int disasm_line)
{
const uInt16 address = getAddress(disasm_line);
if(address != 0)
{
ostringstream command;
command << "timer #" << address << " " << instance().debugger().cartDebug().getBank(address);
const string& msg = instance().debugger().run(command.str());
instance().frameBuffer().showTextMessage(msg);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RomWidget::disassemble(int disasm_line)
{

View File

@ -51,6 +51,7 @@ class RomWidget : public Widget, public CommandSender
void toggleBreak(int disasm_line);
void setPC(int disasm_line);
void runtoPC(int disasm_line);
void setTimer(int disasm_line);
void disassemble(int disasm_line);
void patchROM(int disasm_line, const string& bytes,
Common::Base::Fmt base);

View File

@ -9,6 +9,7 @@ MODULE_OBJS := \
src/debugger/DiStella.o \
src/debugger/RiotDebug.o \
src/debugger/TIADebug.o
src/debugger/TimerMap.o \
MODULE_DIRS += \
src/debugger

View File

@ -264,8 +264,10 @@ inline void M6502::_execute(uInt64 cycles, DispatchResult& result)
if(myBreakPoints.check(PC, bank))
{
myLastBreakCycle = mySystem->cycles();
const uInt32 flags = myBreakPoints.get(PC, bank);
// disable a one-shot breakpoint
if(myBreakPoints.get(PC, bank) & BreakpointMap::ONE_SHOT)
if(flags & BreakpointMap::ONE_SHOT)
{
myBreakPoints.erase(PC, bank);
return;
@ -292,6 +294,9 @@ inline void M6502::_execute(uInt64 cycles, DispatchResult& result)
}
}
if(myTimer.isInitialized())
myTimer.update(PC, mySystem->cart().getBank(PC), mySystem->cycles());
const int cond = evalCondBreaks();
if(cond > -1)
{
@ -656,12 +661,12 @@ uInt32 M6502::addCondTrap(Expression* e, const string& name)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool M6502::delCondTrap(uInt32 brk)
bool M6502::delCondTrap(uInt32 idx)
{
if(brk < myTrapConds.size())
if(idx < myTrapConds.size())
{
Vec::removeAt(myTrapConds, brk);
Vec::removeAt(myTrapCondNames, brk);
Vec::removeAt(myTrapConds, idx);
Vec::removeAt(myTrapCondNames, idx);
updateStepStateByInstruction();
@ -691,4 +696,36 @@ void M6502::updateStepStateByInstruction()
myStepStateByInstruction =
!myCondBreaks.empty() || !myCondSaveStates.empty() || !myTrapConds.empty();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 M6502::addTimer(const uInt16 fromAddr, const uInt16 toAddr,
const uInt8 fromBank, const uInt8 toBank)
{
return myTimer.add(fromAddr, toAddr, fromBank, toBank);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 M6502::addTimer(const uInt16 addr, const uInt8 bank)
{
return myTimer.add(addr, bank);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool M6502::delTimer(const uInt32 idx)
{
return myTimer.erase(idx);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void M6502::clearTimers()
{
myTimer.clear();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void M6502::resetTimers()
{
myTimer.reset();
}
#endif // DEBUGGER_SUPPORT

View File

@ -31,6 +31,7 @@ class DispatchResult;
#include "Expression.hxx"
#include "TrapArray.hxx"
#include "BreakpointMap.hxx"
#include "TimerMap.hxx"
#endif
#include "bspf.hxx"
@ -248,15 +249,25 @@ class M6502 : public Serializable
// methods for 'trapif' handling
uInt32 addCondTrap(Expression* e, const string& name);
bool delCondTrap(uInt32 brk);
bool delCondTrap(uInt32 idx);
void clearCondTraps();
const StringList& getCondTrapNames() const;
// methods for 'timer' handling:
uInt32 addTimer(uInt16 fromAddr, uInt16 toAddr,
uInt8 fromBank, uInt8 toBank);
uInt32 addTimer(uInt16 addr, uInt8 bank);
bool delTimer(uInt32 idx);
void clearTimers();
void resetTimers();
uInt32 numTimers() const { return myTimer.size(); }
const TimerMap::Timer& getTimer(uInt32 idx) const { return myTimer.get(idx); };
void setGhostReadsTrap(bool enable) { myGhostReadsTrap = enable; }
void setReadFromWritePortBreak(bool enable) { myReadFromWritePortBreak = enable; }
void setWriteToReadPortBreak(bool enable) { myWriteToReadPortBreak = enable; }
void setLogBreaks(bool enable) { myLogBreaks = enable; }
bool getLogBreaks() { return myLogBreaks; }
bool getLogBreaks() const { return myLogBreaks; }
#endif // DEBUGGER_SUPPORT
private:
@ -465,6 +476,9 @@ class M6502 : public Serializable
StringList myCondSaveStateNames;
vector<unique_ptr<Expression>> myTrapConds;
StringList myTrapCondNames;
TimerMap myTimer;
#endif // DEBUGGER_SUPPORT
bool myGhostReadsTrap{false}; // trap on ghost reads

View File

@ -856,6 +856,7 @@
<ClCompile Include="..\..\debugger\gui\TrakBallWidget.cxx">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\debugger\TimerMap.cxx" />
<ClCompile Include="..\..\emucore\Bankswitch.cxx" />
<ClCompile Include="..\..\emucore\Cart3EPlus.cxx" />
<ClCompile Include="..\..\emucore\Cart3EX.cxx" />
@ -2051,6 +2052,7 @@
<ClInclude Include="..\..\debugger\gui\TrakBallWidget.hxx">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="..\..\debugger\TimerMap.hxx" />
<ClInclude Include="..\..\debugger\TrapArray.hxx">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
</ClInclude>

View File

@ -1194,6 +1194,9 @@
<ClCompile Include="..\..\common\sdl_blitter\QisBlitter.cxx">
<Filter>Source Files\sdl_blitter</Filter>
</ClCompile>
<ClCompile Include="..\..\debugger\TimerMap.cxx">
<Filter>Source Files\debugger</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\common\bspf.hxx">
@ -2435,6 +2438,9 @@
<ClInclude Include="..\..\common\smartmod.hxx">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\debugger\TimerMap.hxx">
<Filter>Header Files\debugger</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="stella.ico">