mirror of https://github.com/stella-emu/stella.git
added mirrors
This commit is contained in:
parent
7b8b121ee5
commit
d15690f5f1
|
@ -171,7 +171,7 @@ int CartDebug::readFromWritePort()
|
||||||
// port address space AND the last access was actually a read (the latter
|
// 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.
|
// differentiates between reads that are normally part of a write cycle vs.
|
||||||
// ones that are illegal)
|
// ones that are illegal)
|
||||||
if(mySystem.m6502().lastRealReadAddress() &&
|
if(mySystem.m6502().lastReadAddress() &&
|
||||||
(mySystem.getPageAccessType(addr) & System::PA_WRITE) == System::PA_WRITE)
|
(mySystem.getPageAccessType(addr) & System::PA_WRITE) == System::PA_WRITE)
|
||||||
return addr;
|
return addr;
|
||||||
else
|
else
|
||||||
|
|
|
@ -128,10 +128,10 @@ class CartDebug : public DebuggerSystem
|
||||||
// write port area.
|
// write port area.
|
||||||
int readFromWritePort();
|
int readFromWritePort();
|
||||||
|
|
||||||
// Return the address of the last CPU read
|
// Return the base (= non-mirrored) address of the last CPU read
|
||||||
int lastReadAddress() { return mySystem.m6502().lastReadAddress(); }
|
int lastReadBaseAddress() { return mySystem.m6502().lastReadBaseAddress(); }
|
||||||
// Return the address of the last CPU write
|
// Return the base (= non-mirrored) address of the last CPU write
|
||||||
int lastWriteAddress() { return mySystem.m6502().lastWriteAddress(); }
|
int lastWriteBaseAddress() { return mySystem.m6502().lastWriteBaseAddress(); }
|
||||||
|
|
||||||
// The following two methods are meant to be used together
|
// The following two methods are meant to be used together
|
||||||
// First, a call is made to disassemble(), which updates the disassembly
|
// First, a call is made to disassemble(), which updates the disassembly
|
||||||
|
|
|
@ -441,38 +441,47 @@ bool Debugger::writeTrap(uInt16 t)
|
||||||
return writeTraps().isInitialized() && writeTraps().isSet(t);
|
return writeTraps().isInitialized() && writeTraps().isSet(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void Debugger::toggleReadTrapIf(uInt16 t)
|
|
||||||
{
|
|
||||||
readTrapIfs().initialize();
|
|
||||||
readTrapIfs().toggle(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Debugger::toggleWriteTrapIf(uInt16 t)
|
uInt32 Debugger::getBaseAddress(uInt32 addr, bool read)
|
||||||
{
|
{
|
||||||
writeTrapIfs().initialize();
|
if((addr & 0x1080) == 0x0000) // (addr & 0b 0001 0000 1000 0000) == 0b 0000 0000 0000 0000
|
||||||
writeTrapIfs().toggle(t);
|
if(read)
|
||||||
}
|
// ADDR_TIA read (%xxx0 xxxx 0xxx ????)
|
||||||
|
return addr & 0x000f; // 0b 0000 0000 0000 1111
|
||||||
|
else
|
||||||
|
// ADDR_TIA write (%xxx0 xxxx 0x?? ????)
|
||||||
|
return addr & 0x003f; // 0b 0000 0000 0011 1111
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// ADDR_ZPRAM (%xxx0 xx0x 1??? ????)
|
||||||
void Debugger::toggleTrapIf(uInt16 t)
|
if((addr & 0x1280) == 0x0080) // (addr & 0b 0001 0010 1000 0000) == 0b 0000 0000 1000 0000
|
||||||
{
|
return addr & 0x00ff; // 0b 0000 0000 1111 1111
|
||||||
toggleReadTrapIf(t);
|
|
||||||
toggleWriteTrapIf(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// ADDR_ROM
|
||||||
bool Debugger::readTrapIf(uInt16 t)
|
if(addr & 0x1000)
|
||||||
{
|
return addr & 0x1fff; // 0b 0001 1111 1111 1111
|
||||||
return readTrapIfs().isInitialized() && readTrapIfs().isSet(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// ADDR_IO read/write I/O registers (%xxx0 xx1x 1xxx x0??)
|
||||||
bool Debugger::writeTrapIf(uInt16 t)
|
if((addr & 0x1284) == 0x0280) // (addr & 0b 0001 0010 1000 0100) == 0b 0000 0010 1000 0000
|
||||||
{
|
return addr & 0x0283; // 0b 0000 0010 1000 0011
|
||||||
return writeTrapIfs().isInitialized() && writeTrapIfs().isSet(t);
|
|
||||||
}*/
|
// ADDR_IO write timers (%xxx0 xx1x 1xx1 ?1??)
|
||||||
|
if(!read && (addr & 0x1294) == 0x0294) // (addr & 0b 0001 0010 1001 0100) == 0b 0000 0010 1001 0100
|
||||||
|
return addr & 0x029f; // 0b 0000 0010 1001 1111
|
||||||
|
|
||||||
|
// ADDR_IO read timers (%xxx0 xx1x 1xxx ?1x0)
|
||||||
|
if(read && (addr & 0x1285) == 0x0284) // (addr & 0b 0001 0010 1000 0101) == 0b 0000 0010 1000 0100
|
||||||
|
return addr & 0x028c; // 0b 0000 0010 1000 1100
|
||||||
|
|
||||||
|
// ADDR_IO read timer/PA7 interrupt (%xxx0 xx1x 1xxx x1x1)
|
||||||
|
if(read && (addr & 0x1285) == 0x0285) // (addr & 0b 0001 0010 1000 0101) == 0b 0000 0010 1000 0101
|
||||||
|
return addr & 0x0285; // 0b 0000 0010 1000 0101
|
||||||
|
|
||||||
|
// ADDR_IO write PA7 edge control (%xxx0 xx1x 1xx0 x1??)
|
||||||
|
if(!read && (addr & 0x1294) == 0x0284) // (addr & 0b 0001 0010 1001 0100) == 0b 0000 0010 1000 0100
|
||||||
|
return addr & 0x0287; // 0b 0000 0010 1000 0111
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Debugger::nextScanline(int lines)
|
void Debugger::nextScanline(int lines)
|
||||||
|
|
|
@ -216,6 +216,7 @@ class Debugger : public DialogContainer
|
||||||
{ mySystem.setAccessFlags(addr, flags); }
|
{ mySystem.setAccessFlags(addr, flags); }
|
||||||
|
|
||||||
void setBreakPoint(uInt16 bp, bool set);
|
void setBreakPoint(uInt16 bp, bool set);
|
||||||
|
uInt32 getBaseAddress(uInt32 addr, bool read);
|
||||||
|
|
||||||
bool patchROM(uInt16 addr, uInt8 value);
|
bool patchROM(uInt16 addr, uInt8 value);
|
||||||
|
|
||||||
|
|
|
@ -1144,6 +1144,13 @@ void DebuggerParser::executeListfunctions()
|
||||||
void DebuggerParser::executeListtraps()
|
void DebuggerParser::executeListtraps()
|
||||||
{
|
{
|
||||||
StringList names = debugger.cpuDebug().m6502().getCondTrapNames();
|
StringList names = debugger.cpuDebug().m6502().getCondTrapNames();
|
||||||
|
|
||||||
|
if(myTraps.size() != names.size())
|
||||||
|
{
|
||||||
|
commandResult << "Internal error! Different trap sizes.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (names.size() > 0)
|
if (names.size() > 0)
|
||||||
{
|
{
|
||||||
for(uInt32 i = 0; i < names.size(); i++)
|
for(uInt32 i = 0; i < names.size(); i++)
|
||||||
|
@ -1579,6 +1586,11 @@ void DebuggerParser::executeTraps(bool read, bool write, string command, bool ha
|
||||||
int ofs = hasCond ? 1 : 0;
|
int ofs = hasCond ? 1 : 0;
|
||||||
uInt32 begin = args[ofs];
|
uInt32 begin = args[ofs];
|
||||||
uInt32 end = argCount == ofs + 2 ? args[ofs + 1] : begin;
|
uInt32 end = argCount == ofs + 2 ? args[ofs + 1] : begin;
|
||||||
|
// mirrors
|
||||||
|
uInt32 beginRead = debugger.getBaseAddress(begin, true);
|
||||||
|
uInt32 endRead = debugger.getBaseAddress(end, true);
|
||||||
|
uInt32 beginWrite = debugger.getBaseAddress(begin, false);
|
||||||
|
uInt32 endWrite = debugger.getBaseAddress(end, false);
|
||||||
|
|
||||||
if(begin > 0xFFFF || end > 0xFFFF || begin > end)
|
if(begin > 0xFFFF || end > 0xFFFF || begin > end)
|
||||||
{
|
{
|
||||||
|
@ -1591,26 +1603,22 @@ void DebuggerParser::executeTraps(bool read, bool write, string command, bool ha
|
||||||
if(hasCond)
|
if(hasCond)
|
||||||
parserBuf << "(" << argStrings[0] << ")&&(";
|
parserBuf << "(" << argStrings[0] << ")&&(";
|
||||||
|
|
||||||
// TODO: mirrors
|
|
||||||
//begin = getBaseMirror(begin);
|
|
||||||
//end = getBaseMirror(eng);
|
|
||||||
|
|
||||||
// add address range condition(s) to provided condition
|
// add address range condition(s) to provided condition
|
||||||
if(read)
|
if(read)
|
||||||
{
|
{
|
||||||
if(begin != end)
|
if(beginRead != endRead)
|
||||||
parserBuf << "_lastread>=" << Base::toString(begin) << "&&_lastread<=" << Base::toString(end);
|
parserBuf << "_lastread>=" << Base::toString(beginRead) << "&&_lastread<=" << Base::toString(endRead);
|
||||||
else
|
else
|
||||||
parserBuf << "_lastread==" << Base::toString(begin);
|
parserBuf << "_lastread==" << Base::toString(beginRead);
|
||||||
}
|
}
|
||||||
if(read && write)
|
if(read && write)
|
||||||
parserBuf << "||";
|
parserBuf << "||";
|
||||||
if(write)
|
if(write)
|
||||||
{
|
{
|
||||||
if(begin != end)
|
if(beginWrite != endWrite)
|
||||||
parserBuf << "_lastwrite>=" << Base::toString(begin) << "&&_lastwrite<=" << Base::toString(end);
|
parserBuf << "_lastwrite>=" << Base::toString(beginWrite) << "&&_lastwrite<=" << Base::toString(endWrite);
|
||||||
else
|
else
|
||||||
parserBuf << "_lastwrite==" << Base::toString(begin);
|
parserBuf << "_lastwrite==" << Base::toString(beginWrite);
|
||||||
}
|
}
|
||||||
// parenthesize provided condition (end)
|
// parenthesize provided condition (end)
|
||||||
if(hasCond)
|
if(hasCond)
|
||||||
|
@ -1660,47 +1668,6 @@ void DebuggerParser::executeTraps(bool read, bool write, string command, bool ha
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uInt32 getBaseAddress(uInt32 addr, bool read)
|
|
||||||
{
|
|
||||||
// ADDR_TIA write (%xxx0 xxxx 0x?? ????)
|
|
||||||
if(!read && (addr & 0x1080) == 0x0000) // (addr & 0b 0001 0000 1000 0000) == 0b 0000 0000 0000 0000
|
|
||||||
return addr & 0x003f; // 0b 0000 0000 0011 1111
|
|
||||||
|
|
||||||
// ADDR_TIA read (%xxx0 xxxx 0xxx ????)
|
|
||||||
if(read && (addr & 0x1080) == 0x0000) // (addr & 0b 0001 0000 1000 0000) == 0b 0000 0000 0000 0000
|
|
||||||
return addr & 0x000f; // 0b 0000 0000 0000 1111
|
|
||||||
|
|
||||||
// ADDR_ZPRAM (%xxx0 xx0x 1??? ????)
|
|
||||||
if((addr & 0x1280) == 0x0080) // (addr & 0b 0001 0010 1000 0000) == 0b 0000 0000 1000 0000
|
|
||||||
return addr & 0x00ff; // 0b 0000 0000 1111 1111
|
|
||||||
|
|
||||||
// ADDR_ROM
|
|
||||||
if(addr & 0x1000)
|
|
||||||
return addr & 0x1fff; // 0b 0001 1111 1111 1111
|
|
||||||
|
|
||||||
// ADDR_IO read/write I/O registers (%xxx0 xx1x 1xxx x0??)
|
|
||||||
if((addr & 0x1284) == 0x0280) // (addr & 0b 0001 0010 1000 0100) == 0b 0000 0010 1000 0000
|
|
||||||
return addr & 0x0283; // 0b 0000 0010 1000 0011
|
|
||||||
|
|
||||||
// ADDR_IO write timers (%xxx0 xx1x 1xx1 ?1??)
|
|
||||||
if(!read && (addr & 0x1294) == 0x0294) // (addr & 0b 0001 0010 1001 0100) == 0b 0000 0010 1001 0100
|
|
||||||
return addr & 0x029f; // 0b 0000 0010 1001 1111
|
|
||||||
|
|
||||||
// ADDR_IO read timers (%xxx0 xx1x 1xxx ?1x0)
|
|
||||||
if(read && (addr & 0x1285) == 0x0284) // (addr & 0b 0001 0010 1000 0101) == 0b 0000 0010 1000 0100
|
|
||||||
return addr & 0x028c; // 0b 0000 0010 1000 1100
|
|
||||||
|
|
||||||
// ADDR_IO read timer/PA7 interrupt (%xxx0 xx1x 1xxx x1x1)
|
|
||||||
if(read && (addr & 0x1285) == 0x0285) // (addr & 0b 0001 0010 1000 0101) == 0b 0000 0010 1000 0101
|
|
||||||
return addr & 0x0285; // 0b 0000 0010 1000 0101
|
|
||||||
|
|
||||||
// ADDR_IO write PA7 edge control (%xxx0 xx1x 1xx0 x1??)
|
|
||||||
if(!read && (addr & 0x1294) == 0x0284) // (addr & 0b 0001 0010 1001 0100) == 0b 0000 0010 1000 0100
|
|
||||||
return addr & 0x0287; // 0b 0000 0010 1000 0111
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
// wrapper function for trap(if)/trapread(if)/trapwrite(if) commands
|
// wrapper function for trap(if)/trapread(if)/trapwrite(if) commands
|
||||||
void DebuggerParser::executeTrapRW(uInt32 addr, bool read, bool write, bool add)
|
void DebuggerParser::executeTrapRW(uInt32 addr, bool read, bool write, bool add)
|
||||||
|
|
|
@ -126,7 +126,7 @@ inline uInt8 M6502::peek(uInt16 address, uInt8 flags)
|
||||||
#ifdef DEBUGGER_SUPPORT
|
#ifdef DEBUGGER_SUPPORT
|
||||||
if(myReadTraps.isInitialized() && myReadTraps.isSet(address))
|
if(myReadTraps.isInitialized() && myReadTraps.isSet(address))
|
||||||
{
|
{
|
||||||
//TODO: myLastPeekBaseAddress = baseAddress(myLastPeekAddress); // mirror handling
|
myLastPeekBaseAddress = myDebugger->getBaseAddress(myLastPeekAddress, true); // mirror handling
|
||||||
int cond = evalCondTraps();
|
int cond = evalCondTraps();
|
||||||
if(cond > -1)
|
if(cond > -1)
|
||||||
{
|
{
|
||||||
|
@ -159,7 +159,7 @@ inline void M6502::poke(uInt16 address, uInt8 value, uInt8 flags)
|
||||||
#ifdef DEBUGGER_SUPPORT
|
#ifdef DEBUGGER_SUPPORT
|
||||||
if(myWriteTraps.isInitialized() && myWriteTraps.isSet(address))
|
if(myWriteTraps.isInitialized() && myWriteTraps.isSet(address))
|
||||||
{
|
{
|
||||||
//TODO: myLastPokeBaseAddress = baseAddress(myLastPokeAddress); // mirror handling
|
myLastPokeBaseAddress = myDebugger->getBaseAddress(myLastPokeAddress, false); // mirror handling
|
||||||
int cond = evalCondTraps();
|
int cond = evalCondTraps();
|
||||||
if(cond > -1)
|
if(cond > -1)
|
||||||
{
|
{
|
||||||
|
|
|
@ -145,7 +145,7 @@ class M6502 : public Serializable
|
||||||
|
|
||||||
@return The address of the last read
|
@return The address of the last read
|
||||||
*/
|
*/
|
||||||
uInt16 lastRealReadAddress() const {
|
uInt16 lastReadAddress() const {
|
||||||
return myLastPokeAddress ?
|
return myLastPokeAddress ?
|
||||||
(myLastPokeAddress != myLastPeekAddress ? myLastPeekAddress : 0) :
|
(myLastPokeAddress != myLastPeekAddress ? myLastPeekAddress : 0) :
|
||||||
myLastPeekAddress;
|
myLastPeekAddress;
|
||||||
|
@ -156,14 +156,14 @@ class M6502 : public Serializable
|
||||||
|
|
||||||
@return The address of the last read
|
@return The address of the last read
|
||||||
*/
|
*/
|
||||||
uInt16 lastReadAddress() const { return myLastPeekAddress; }
|
uInt16 lastReadBaseAddress() const { return myLastPeekBaseAddress; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Return the last address that was part of a write/poke.
|
Return the last address that was part of a write/poke.
|
||||||
|
|
||||||
@return The address of the last write
|
@return The address of the last write
|
||||||
*/
|
*/
|
||||||
uInt16 lastWriteAddress() const { return myLastPokeAddress; }
|
uInt16 lastWriteBaseAddress() const { return myLastPokeBaseAddress; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Return the source of the address that was used for a write/poke.
|
Return the source of the address that was used for a write/poke.
|
||||||
|
@ -355,6 +355,9 @@ class M6502 : public Serializable
|
||||||
/// Indicates the last address which was accessed specifically
|
/// Indicates the last address which was accessed specifically
|
||||||
/// by a peek or poke command
|
/// by a peek or poke command
|
||||||
uInt16 myLastPeekAddress, myLastPokeAddress;
|
uInt16 myLastPeekAddress, myLastPokeAddress;
|
||||||
|
/// Indicates the last base (= non-mirrored) address which was
|
||||||
|
/// accessed specifically by a peek or poke command
|
||||||
|
uInt16 myLastPeekBaseAddress, myLastPokeBaseAddress;
|
||||||
|
|
||||||
/// Indicates the last address used to access data by a peek command
|
/// Indicates the last address used to access data by a peek command
|
||||||
/// for the CPU registers (S/A/X/Y)
|
/// for the CPU registers (S/A/X/Y)
|
||||||
|
|
|
@ -207,9 +207,9 @@ CartMethod getCartSpecial(char* ch)
|
||||||
else if(BSPF::equalsIgnoreCase(ch, "_rwport"))
|
else if(BSPF::equalsIgnoreCase(ch, "_rwport"))
|
||||||
return &CartDebug::readFromWritePort;
|
return &CartDebug::readFromWritePort;
|
||||||
else if(BSPF::equalsIgnoreCase(ch, "_lastread"))
|
else if(BSPF::equalsIgnoreCase(ch, "_lastread"))
|
||||||
return &CartDebug::lastReadAddress;
|
return &CartDebug::lastReadBaseAddress;
|
||||||
else if(BSPF::equalsIgnoreCase(ch, "_lastwrite"))
|
else if(BSPF::equalsIgnoreCase(ch, "_lastwrite"))
|
||||||
return &CartDebug::lastWriteAddress;
|
return &CartDebug::lastWriteBaseAddress;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue