The emulation core now tracks access to DATA areas (currently, any address

used as a peek operand).  Still TODO is deal with poke areas, which would
be relevant in carts with extended RAM.

The interaction between the internal tracking and Distella is now much
tighter, in that knowledge gained by Distella is used in the core code,
and vice versa.  This allows the best of both worlds, where the internal
tracking finds stuff at runtime (that couldn't be found in a static
analysis), and Distella tracks potential paths (that haven't occurred at
runtime yet).

Added 'type' debugger prompt command, which basically queries an address
for its disassembly type (CODE/GFX/DATA, etc).

Added debugger commands to query the last address used in an operation
for various registers, but they're only stubs at the moment.

Updated the bankswitch schemes to deal with accesses in and around the
hotspot areas.  Previously, peek accesses in these areas weren't being
recorded as DATA areas.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2145 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2010-10-10 20:24:22 +00:00
parent 5d0b25cd48
commit 5624d30d93
25 changed files with 1111 additions and 917 deletions

View File

@ -613,6 +613,9 @@ void Debugger::setStartState()
// Save initial state, but don't add it to the rewind list // Save initial state, but don't add it to the rewind list
saveOldState(false); saveOldState(false);
// Force a re-disassemble
myRom->invalidate();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -92,8 +92,6 @@ class Debugger : public DialogContainer
virtual ~Debugger(); virtual ~Debugger();
public: public:
OSystem *getOSystem() { return myOSystem; }
/** /**
Updates the basedialog to be of the type defined for this derived class. Updates the basedialog to be of the type defined for this derived class.
*/ */
@ -284,7 +282,10 @@ class Debugger : public DialogContainer
/* These are now exposed so Expressions can use them. */ /* These are now exposed so Expressions can use them. */
int peek(int addr) { return mySystem->peek(addr); } int peek(int addr) { return mySystem->peek(addr); }
int dpeek(int addr) { return mySystem->peek(addr) | (mySystem->peek(addr+1) << 8); } int dpeek(int addr) { return mySystem->peek(addr) | (mySystem->peek(addr+1) << 8); }
int isCode(int addr) { return mySystem->isCode(addr); } inline int getAddressDisasmType(uInt16 addr)
{ return mySystem->getAddressDisasmType(addr); }
inline void setAddressDisasmType(uInt16 addr, uInt8 flags)
{ mySystem->setAddressDisasmType(addr, flags); }
void setBreakPoint(int bp, bool set); void setBreakPoint(int bp, bool set);

View File

@ -746,7 +746,7 @@ void DebuggerParser::executeCheat()
for(int arg = 0; arg < argCount; arg++) for(int arg = 0; arg < argCount; arg++)
{ {
const string& cheat = argStrings[arg]; const string& cheat = argStrings[arg];
const Cheat* c = debugger->getOSystem()->cheat().add("DBG", cheat); const Cheat* c = debugger->myOSystem->cheat().add("DBG", cheat);
if(c && c->enabled()) if(c && c->enabled())
commandResult << "Cheat code " << cheat << " enabled" << endl; commandResult << "Cheat code " << cheat << " enabled" << endl;
else else
@ -1043,6 +1043,34 @@ void DebuggerParser::executeJump()
commandResult << "address $" << HEX4 << args[0] << " doesn't exist"; commandResult << "address $" << HEX4 << args[0] << " doesn't exist";
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "lastaddr"
void DebuggerParser::executeLastAddress()
{
commandResult << red("not implemented yet");
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "lasta"
void DebuggerParser::executeLastAccAddress()
{
commandResult << red("not implemented yet");
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "lastx"
void DebuggerParser::executeLastXAddress()
{
commandResult << red("not implemented yet");
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "lasty"
void DebuggerParser::executeLastYAddress()
{
commandResult << red("not implemented yet");
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "listbreaks" // "listbreaks"
void DebuggerParser::executeListbreaks() void DebuggerParser::executeListbreaks()
@ -1269,7 +1297,7 @@ void DebuggerParser::executeRunTo()
ostringstream buf; ostringstream buf;
buf << "RunTo searching through " << max_iterations << " disassembled instructions"; buf << "RunTo searching through " << max_iterations << " disassembled instructions";
ProgressDialog progress(debugger->myBaseDialog, ProgressDialog progress(debugger->myBaseDialog,
debugger->getOSystem()->consoleFont(), buf.str()); debugger->myOSystem->consoleFont(), buf.str());
progress.setRange(0, max_iterations, 5); progress.setRange(0, max_iterations, 5);
bool done = false; bool done = false;
@ -1468,6 +1496,33 @@ void DebuggerParser::executeTrapwrite()
} }
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "type"
void DebuggerParser::executeType()
{
uInt8 flags = debugger->getAddressDisasmType(args[0]);
if(flags)
{
commandResult << Debugger::to_bin_8(flags) << ": ";
if(flags & CartDebug::SKIP)
commandResult << "SKIP ";
if(flags & CartDebug::CODE)
commandResult << "CODE ";
if(flags & CartDebug::GFX)
commandResult << "GFX ";
if(flags & CartDebug::DATA)
commandResult << "DATA ";
if(flags & CartDebug::ROW)
commandResult << "ROW ";
if(flags & CartDebug::REFERENCED)
commandResult << "*REFERENCED ";
if(flags & CartDebug::VALID_ENTRY)
commandResult << "*VALID_ENTRY ";
}
else
commandResult << "no flags set";
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "undef" // "undef"
void DebuggerParser::executeUndef() void DebuggerParser::executeUndef()
@ -1779,6 +1834,42 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = {
&DebuggerParser::executeJump &DebuggerParser::executeJump
}, },
{
"lastaddr",
"Show last accessed address",
false,
false,
{ kARG_END_ARGS },
&DebuggerParser::executeLastAddress
},
{
"lasta",
"Show last accessed address for accumulator",
false,
false,
{ kARG_END_ARGS },
&DebuggerParser::executeLastAccAddress
},
{
"lastx",
"Show last accessed address for register X",
false,
false,
{ kARG_END_ARGS },
&DebuggerParser::executeLastXAddress
},
{
"lasty",
"Show last accessed address for register Y",
false,
false,
{ kARG_END_ARGS },
&DebuggerParser::executeLastYAddress
},
{ {
"listbreaks", "listbreaks",
"List breakpoints", "List breakpoints",
@ -2058,6 +2149,15 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = {
&DebuggerParser::executeTrapwrite &DebuggerParser::executeTrapwrite
}, },
{
"type",
"Show disassemly type for address xx",
true,
false,
{ kARG_WORD, kARG_END_ARGS },
&DebuggerParser::executeType
},
{ {
"undef", "undef",
"Undefine label xx (if defined)", "Undefine label xx (if defined)",

View File

@ -83,7 +83,7 @@ class DebuggerParser
private: private:
enum { enum {
kNumCommands = 65, kNumCommands = 70,
kMAX_ARG_TYPES = 10 kMAX_ARG_TYPES = 10
}; };
@ -162,6 +162,10 @@ class DebuggerParser
void executeGfx(); void executeGfx();
void executeHelp(); void executeHelp();
void executeJump(); void executeJump();
void executeLastAddress();
void executeLastAccAddress();
void executeLastXAddress();
void executeLastYAddress();
void executeListbreaks(); void executeListbreaks();
void executeListconfig(); void executeListconfig();
void executeListfunctions(); void executeListfunctions();
@ -193,6 +197,7 @@ class DebuggerParser
void executeTrap(); void executeTrap();
void executeTrapread(); void executeTrapread();
void executeTrapwrite(); void executeTrapwrite();
void executeType();
void executeUndef(); void executeUndef();
void executeV(); void executeV();
void executeWatch(); void executeWatch();

View File

@ -100,8 +100,9 @@ DiStella::DiStella(const CartDebug& dbg, CartDebug::DisassemblyList& list,
myPCBeg = myPC; myPCBeg = myPC;
myAddressQueue.pop(); myAddressQueue.pop();
disasm(myPC, 1); disasm(myPC, 1);
for (uInt16 k = myPCBeg; k <= myPCEnd; k++) if(myPCBeg <= myPCEnd)
mark(k, CartDebug::CODE); for (uInt32 k = myPCBeg; k <= myPCEnd; k++)
mark(k, CartDebug::CODE);
// When we get to this point, all addresses have been processed // When we get to this point, all addresses have been processed
// starting from the initial one in the address list // starting from the initial one in the address list
@ -138,8 +139,8 @@ cerr << "(list) marking " << HEX4 << addr << " as CODE\n";
// been referenced as CODE // been referenced as CODE
while(it == addresses.end() && codeAccessPoint <= myAppData.end) while(it == addresses.end() && codeAccessPoint <= myAppData.end)
{ {
if(Debugger::debugger().isCode(codeAccessPoint+myOffset) && if((Debugger::debugger().getAddressDisasmType(codeAccessPoint+myOffset) & CartDebug::CODE)
!check_bit(codeAccessPoint, CartDebug::CODE)) && !(labels[codeAccessPoint & myAppData.end] & CartDebug::CODE))
{ {
cerr << "(emul) marking " << HEX4 << (codeAccessPoint+myOffset) << " as CODE\n"; cerr << "(emul) marking " << HEX4 << (codeAccessPoint+myOffset) << " as CODE\n";
myAddressQueue.push(codeAccessPoint+myOffset); myAddressQueue.push(codeAccessPoint+myOffset);
@ -153,7 +154,7 @@ cerr << "(emul) marking " << HEX4 << (codeAccessPoint+myOffset) << " as CODE\n";
for (int k = 0; k <= myAppData.end; k++) for (int k = 0; k <= myAppData.end; k++)
{ {
if (!check_bit(k, CartDebug::CODE)) if (!check_bit(k, CartDebug::SKIP|CartDebug::CODE|CartDebug::GFX|CartDebug::DATA))
mark(k+myOffset, CartDebug::ROW); mark(k+myOffset, CartDebug::ROW);
} }
} }
@ -178,9 +179,9 @@ void DiStella::disasm(uInt32 distart, int pass)
if(l != EmptyString) nextline << pre << l << post; \ if(l != EmptyString) nextline << pre << l << post; \
else nextline << pre << "L" << HEX4 << address << post; else nextline << pre << "L" << HEX4 << address << post;
uInt8 op, d1, opsrc; uInt8 op, d1;
uInt16 ad; uInt16 ad;
short amode; AddressingMode addr_mode;
int bytes=0, labfound=0, addbranch=0; int bytes=0, labfound=0, addbranch=0;
stringstream nextline, nextlinebytes; stringstream nextline, nextlinebytes;
myDisasmBuf.str(""); myDisasmBuf.str("");
@ -189,8 +190,7 @@ void DiStella::disasm(uInt32 distart, int pass)
myPC = distart - myOffset; myPC = distart - myOffset;
while(myPC <= myAppData.end) while(myPC <= myAppData.end)
{ {
if(check_bit(myPC, CartDebug::GFX)) if(check_bit(myPC, CartDebug::GFX) && !check_bit(myPC, CartDebug::CODE))
/* && !check_bit(myPC, CartDebug::CODE))*/
{ {
if (pass == 2) if (pass == 2)
mark(myPC+myOffset, CartDebug::VALID_ENTRY); mark(myPC+myOffset, CartDebug::VALID_ENTRY);
@ -230,13 +230,12 @@ void DiStella::disasm(uInt32 distart, int pass)
myDisasmBuf << ".byte $" << HEX2 << (int)byte << " $" myDisasmBuf << ".byte $" << HEX2 << (int)byte << " $"
<< HEX4 << myPC+myOffset << "'" << HEX4 << myPC+myOffset << "'"
<< HEX2 << (int)byte; << HEX2 << (int)byte;
cerr << myDisasmBuf.str() << endl;
addEntry(CartDebug::DATA); addEntry(CartDebug::DATA);
} }
myPC++; myPC++;
} }
else if (check_bit(myPC, CartDebug::ROW) && !check_bit(myPC, CartDebug::GFX)) else if (check_bit(myPC, CartDebug::ROW) &&
/* && !check_bit(myPC, CartDebug::CODE)) { */ !check_bit(myPC, CartDebug::CODE|CartDebug::DATA|CartDebug::GFX))
{ {
mark(myPC+myOffset, CartDebug::VALID_ENTRY); mark(myPC+myOffset, CartDebug::VALID_ENTRY);
if (pass == 3) if (pass == 3)
@ -248,7 +247,7 @@ cerr << myDisasmBuf.str() << endl;
myPC++; myPC++;
while (check_bit(myPC, CartDebug::ROW) && while (check_bit(myPC, CartDebug::ROW) &&
!check_bit(myPC, CartDebug::REFERENCED|CartDebug::DATA|CartDebug::GFX) !check_bit(myPC, CartDebug::CODE|CartDebug::DATA|CartDebug::GFX)
&& pass == 3 && myPC <= myAppData.end) && pass == 3 && myPC <= myAppData.end)
{ {
bytes++; bytes++;
@ -271,8 +270,10 @@ cerr << myDisasmBuf.str() << endl;
addEntry(CartDebug::NONE); addEntry(CartDebug::NONE);
} }
} }
else else // The following sections must be SKIP or CODE
{ {
// Add label (if any)
//
op = Debugger::debugger().peek(myPC+myOffset); op = Debugger::debugger().peek(myPC+myOffset);
/* version 2.1 bug fix */ /* version 2.1 bug fix */
if (pass == 2) if (pass == 2)
@ -285,26 +286,36 @@ cerr << myDisasmBuf.str() << endl;
myDisasmBuf << HEX4 << myPC+myOffset << "' '"; myDisasmBuf << HEX4 << myPC+myOffset << "' '";
} }
amode = ourLookup[op].addr_mode; // Add opcode mneumonic
//
addr_mode = ourLookup[op].addr_mode;
myPC++; myPC++;
#if 0
// FIXME - the following condition is never true
if (ourLookup[op].mnemonic[0] == '.') if (ourLookup[op].mnemonic[0] == '.')
{ {
amode = IMPLIED; addr_mode = IMPLIED;
if (pass == 3) if (pass == 3)
nextline << ".byte $" << HEX2 << (int)op << " ;"; nextline << ".byte $" << HEX2 << (int)op << " ;";
} }
#endif
if (pass == 1) if (pass == 1)
{ {
opsrc = ourLookup[op].source;
/* M_REL covers BPL, BMI, BVC, BVS, BCC, BCS, BNE, BEQ /* M_REL covers BPL, BMI, BVC, BVS, BCC, BCS, BNE, BEQ
M_ADDR = JMP $NNNN, JSR $NNNN M_ADDR = JMP $NNNN, JSR $NNNN
M_AIND = JMP Abs, Indirect */ M_AIND = JMP Abs, Indirect */
if ((opsrc == M_REL) || (opsrc == M_ADDR) || (opsrc == M_AIND)) switch(ourLookup[op].source)
addbranch = 1; {
else case M_REL:
addbranch = 0; case M_ADDR:
case M_AIND:
addbranch = 1;
break;
default:
addbranch = 0;
break;
}
} }
else if (pass == 3) else if (pass == 3)
{ {
@ -312,9 +323,11 @@ cerr << myDisasmBuf.str() << endl;
nextlinebytes << HEX2 << (int)op << " "; nextlinebytes << HEX2 << (int)op << " ";
} }
// Add operand(s) for PC values outside the app data range
//
if (myPC >= myAppData.end) if (myPC >= myAppData.end)
{ {
switch(amode) switch(addr_mode)
{ {
case ABSOLUTE: case ABSOLUTE:
case ABSOLUTE_X: case ABSOLUTE_X:
@ -325,10 +338,13 @@ cerr << myDisasmBuf.str() << endl;
{ {
if (pass == 3) if (pass == 3)
{ {
/* Line information is already printed; append .byte since last instruction will /* Line information is already printed; append .byte since last
put recompilable object larger that original binary file */ instruction will put recompilable object larger that original
myDisasmBuf << ".byte $" << HEX2 << (int)op; binary file */
addEntry(CartDebug::ROW); myDisasmBuf << ".byte $" << HEX2 << (int)op << " $"
<< HEX4 << myPC+myOffset << "'"
<< HEX2 << (int)op;
addEntry(CartDebug::DATA);
if (myPC == myAppData.end) if (myPC == myAppData.end)
{ {
@ -338,8 +354,10 @@ cerr << myDisasmBuf.str() << endl;
myDisasmBuf << HEX4 << myPC+myOffset << "' '"; myDisasmBuf << HEX4 << myPC+myOffset << "' '";
op = Debugger::debugger().peek(myPC+myOffset); myPC++; op = Debugger::debugger().peek(myPC+myOffset); myPC++;
myDisasmBuf << ".byte $" << HEX2 << (int)op; myDisasmBuf << ".byte $" << HEX2 << (int)op << " $"
addEntry(CartDebug::ROW); << HEX4 << myPC+myOffset << "'"
<< HEX2 << (int)op;
addEntry(CartDebug::DATA);
} }
} }
myPCEnd = myAppData.end + myOffset; myPCEnd = myAppData.end + myOffset;
@ -371,11 +389,13 @@ cerr << myDisasmBuf.str() << endl;
default: default:
break; break;
} } // end switch(addr_mode)
} }
// Add operand(s)
//
/* Version 2.1 added the extensions to mnemonics */ /* Version 2.1 added the extensions to mnemonics */
switch(amode) switch(addr_mode)
{ {
#if 0 #if 0
case IMPLIED: case IMPLIED:
@ -399,13 +419,18 @@ cerr << myDisasmBuf.str() << endl;
labfound = mark(ad, CartDebug::REFERENCED); labfound = mark(ad, CartDebug::REFERENCED);
if (pass == 1) if (pass == 1)
{ {
if ((addbranch) && !check_bit(ad & myAppData.end, CartDebug::CODE)) if (addbranch)
{ {
if (ad > 0xfff) if (!check_bit(ad & myAppData.end, CartDebug::CODE))
myAddressQueue.push((ad & myAppData.end) + myOffset); {
if (ad > 0xfff)
myAddressQueue.push((ad & myAppData.end) + myOffset);
mark(ad, CartDebug::CODE); mark(ad, CartDebug::CODE);
}
} }
else if(ad > 0xfff)
mark(ad, CartDebug::DATA);
} }
else if (pass == 3) else if (pass == 3)
{ {
@ -471,7 +496,11 @@ cerr << myDisasmBuf.str() << endl;
{ {
ad = Debugger::debugger().dpeek(myPC+myOffset); myPC+=2; ad = Debugger::debugger().dpeek(myPC+myOffset); myPC+=2;
labfound = mark(ad, CartDebug::REFERENCED); labfound = mark(ad, CartDebug::REFERENCED);
if (pass == 3) if (pass == 2 && !check_bit(ad & myAppData.end, CartDebug::CODE))
{
mark(ad, CartDebug::DATA);
}
else if (pass == 3)
{ {
if (ad < 0x100) if (ad < 0x100)
nextline << ".wx "; nextline << ".wx ";
@ -507,7 +536,11 @@ cerr << myDisasmBuf.str() << endl;
{ {
ad = Debugger::debugger().dpeek(myPC+myOffset); myPC+=2; ad = Debugger::debugger().dpeek(myPC+myOffset); myPC+=2;
labfound = mark(ad, CartDebug::REFERENCED); labfound = mark(ad, CartDebug::REFERENCED);
if (pass == 3) if (pass == 2 && !check_bit(ad & myAppData.end, CartDebug::CODE))
{
mark(ad, CartDebug::DATA);
}
else if (pass == 3)
{ {
if (ad < 0x100) if (ad < 0x100)
nextline << ".wy "; nextline << ".wy ";
@ -630,7 +663,11 @@ cerr << myDisasmBuf.str() << endl;
{ {
ad = Debugger::debugger().dpeek(myPC+myOffset); myPC+=2; ad = Debugger::debugger().dpeek(myPC+myOffset); myPC+=2;
labfound = mark(ad, CartDebug::REFERENCED); labfound = mark(ad, CartDebug::REFERENCED);
if (pass == 3) if (pass == 2 && !check_bit(ad & myAppData.end, CartDebug::CODE))
{
mark(ad, CartDebug::DATA);
}
else if (pass == 3)
{ {
if (ad < 0x100) if (ad < 0x100)
nextline << ".ind "; nextline << ".ind ";
@ -649,6 +686,9 @@ cerr << myDisasmBuf.str() << endl;
nextlinebytes << HEX2 << (int)(ad&0xff) << " " << HEX2 << (int)(ad>>8); nextlinebytes << HEX2 << (int)(ad&0xff) << " " << HEX2 << (int)(ad>>8);
break; break;
} }
default:
break;
} // end switch } // end switch
if (pass == 1) if (pass == 1)
@ -715,21 +755,21 @@ int DiStella::mark(uInt16 address, uInt8 mask)
with the appropriate bit; return 2. with the appropriate bit; return 2.
$0280-$0297 = system equates (INPT0, etc...); mark the array's element $0280-$0297 = system equates (INPT0, etc...); mark the array's element
with the appropriate bit; return 3. with the appropriate bit; return 3.
$1000-$1FFF = CartDebug::CODE/CartDebug::ROW, mark the code/data array for the mirrored address $1000-$1FFF = mark the code/data array for the mirrored address
with the appropriate bit; return 4. with the appropriate bit; return 4.
$3000-$3FFF = CartDebug::CODE/CartDebug::ROW, mark the code/data array for the mirrored address $3000-$3FFF = mark the code/data array for the mirrored address
with the appropriate bit; return 4. with the appropriate bit; return 4.
$5000-$5FFF = CartDebug::CODE/CartDebug::ROW, mark the code/data array for the mirrored address $5000-$5FFF = mark the code/data array for the mirrored address
with the appropriate bit; return 4. with the appropriate bit; return 4.
$7000-$7FFF = CartDebug::CODE/CartDebug::ROW, mark the code/data array for the mirrored address $7000-$7FFF = mark the code/data array for the mirrored address
with the appropriate bit; return 4. with the appropriate bit; return 4.
$9000-$9FFF = CartDebug::CODE/CartDebug::ROW, mark the code/data array for the mirrored address $9000-$9FFF = mark the code/data array for the mirrored address
with the appropriate bit; return 4. with the appropriate bit; return 4.
$B000-$BFFF = CartDebug::CODE/CartDebug::ROW, mark the code/data array for the mirrored address $B000-$BFFF = mark the code/data array for the mirrored address
with the appropriate bit; return 4. with the appropriate bit; return 4.
$D000-$DFFF = CartDebug::CODE/CartDebug::ROW, mark the code/data array for the mirrored address $D000-$DFFF = mark the code/data array for the mirrored address
with the appropriate bit; return 4. with the appropriate bit; return 4.
$F000-$FFFF = CartDebug::CODE/CartDebug::ROW, mark the code/data array for the address $F000-$FFFF = mark the code/data array for the address
with the appropriate bit; return 1. with the appropriate bit; return 1.
Anything else = invalid, return 0. Anything else = invalid, return 0.
=========================================================== ===========================================================
@ -737,6 +777,7 @@ int DiStella::mark(uInt16 address, uInt8 mask)
if (address >= myOffset && address <= myAppData.end + myOffset) if (address >= myOffset && address <= myAppData.end + myOffset)
{ {
Debugger::debugger().setAddressDisasmType(address | myOffset, mask);
labels[address-myOffset] = labels[address-myOffset] | mask; labels[address-myOffset] = labels[address-myOffset] | mask;
return 1; return 1;
} }
@ -751,6 +792,7 @@ int DiStella::mark(uInt16 address, uInt8 mask)
else if (address > 0x1000) else if (address > 0x1000)
{ {
/* 2K & 4K case */ /* 2K & 4K case */
Debugger::debugger().setAddressDisasmType(address | myOffset, mask);
labels[address & myAppData.end] = labels[address & myAppData.end] | mask; labels[address & myAppData.end] = labels[address & myAppData.end] | mask;
return 4; return 4;
} }
@ -761,7 +803,10 @@ int DiStella::mark(uInt16 address, uInt8 mask)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool DiStella::check_bit(uInt16 address, uInt8 mask) const bool DiStella::check_bit(uInt16 address, uInt8 mask) const
{ {
return (labels[address] & mask) == mask; if(Debugger::debugger().getAddressDisasmType(address | myOffset) & mask)
return true;
else
return labels[address & myAppData.end] & mask;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -816,7 +861,7 @@ void DiStella::addEntry(CartDebug::DisasmType type)
{ {
if(myDisasmBuf.peek() != ' ') if(myDisasmBuf.peek() != ' ')
getline(myDisasmBuf, tag.label, '\''); getline(myDisasmBuf, tag.label, '\'');
else if(settings.show_addresses) else if(settings.show_addresses && tag.type == CartDebug::CODE)
{ {
// Have addresses indented, to differentiate from actual labels // Have addresses indented, to differentiate from actual labels
char address[8]; char address[8];

View File

@ -24,7 +24,7 @@
#include "TIA.hxx" #include "TIA.hxx"
#include "Cart3E.hxx" #include "Cart3E.hxx"
// TODO - add support for code stored in RAM // TODO (2010-10-10) - support CodeAccessBase functionality somehow
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cartridge3E::Cartridge3E(const uInt8* image, uInt32 size, Cartridge3E::Cartridge3E(const uInt8* image, uInt32 size,

View File

@ -92,10 +92,6 @@ void CartridgeDPC::install(System& system)
System::PageAccess access(0, 0, 0, this, System::PA_READ); System::PageAccess access(0, 0, 0, this, System::PA_READ);
// Set the page accessing methods for the hot spots
for(uInt32 i = (0x1FF8 & ~mask); i < 0x2000; i += (1 << shift))
mySystem->setPageAccess(i >> shift, access);
// Set the page accessing method for the DPC reading & writing pages // Set the page accessing method for the DPC reading & writing pages
access.type = System::PA_READWRITE; access.type = System::PA_READWRITE;
for(uInt32 j = 0x1000; j < 0x1080; j += (1 << shift)) for(uInt32 j = 0x1000; j < 0x1080; j += (1 << shift))
@ -422,10 +418,16 @@ bool CartridgeDPC::bank(uInt16 bank)
uInt16 shift = mySystem->pageShift(); uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask(); uInt16 mask = mySystem->pageMask();
// Setup the page access methods for the current bank
System::PageAccess access(0, 0, 0, this, System::PA_READ); System::PageAccess access(0, 0, 0, this, System::PA_READ);
// Map Program ROM image into the system // Set the page accessing methods for the hot spots
for(uInt32 i = (0x1FF8 & ~mask); i < 0x2000; i += (1 << shift))
{
access.codeAccessBase = &myCodeAccessBase[offset + (i & 0x0FFF)];
mySystem->setPageAccess(i >> shift, access);
}
// Setup the page access methods for the current bank
for(uInt32 address = 0x1080; address < (0x1FF8U & ~mask); for(uInt32 address = 0x1080; address < (0x1FF8U & ~mask);
address += (1 << shift)) address += (1 << shift))
{ {

View File

@ -72,7 +72,7 @@ void CartridgeE0::install(System& system)
// Set the page accessing methods for the hot spots in the last segment // Set the page accessing methods for the hot spots in the last segment
access.directPeekBase = 0; access.directPeekBase = 0;
access.codeAccessBase = 0; access.codeAccessBase = &myCodeAccessBase[8128];
access.type = System::PA_READ; access.type = System::PA_READ;
for(uInt32 j = (0x1FE0 & ~mask); j < 0x2000; j += (1 << shift)) for(uInt32 j = (0x1FE0 & ~mask); j < 0x2000; j += (1 << shift))
mySystem->setPageAccess(j >> shift, access); mySystem->setPageAccess(j >> shift, access);

View File

@ -29,7 +29,7 @@ CartridgeE7::CartridgeE7(const uInt8* image, const Settings& settings)
{ {
// Copy the ROM image into my buffer // Copy the ROM image into my buffer
memcpy(myImage, image, 16384); memcpy(myImage, image, 16384);
createCodeAccessBase(16384 + 1024); createCodeAccessBase(16384 + 2048);
// This cart can address a 1024 byte bank of RAM @ 0x1000 // This cart can address a 1024 byte bank of RAM @ 0x1000
// and 256 bytes @ 0x1800 // and 256 bytes @ 0x1800
@ -79,7 +79,10 @@ void CartridgeE7::install(System& system)
// Set the page accessing methods for the hot spots // Set the page accessing methods for the hot spots
for(uInt32 i = (0x1FE0 & ~mask); i < 0x2000; i += (1 << shift)) for(uInt32 i = (0x1FE0 & ~mask); i < 0x2000; i += (1 << shift))
{
access.codeAccessBase = &myCodeAccessBase[8128];
mySystem->setPageAccess(i >> shift, access); mySystem->setPageAccess(i >> shift, access);
}
// Setup the second segment to always point to the last ROM slice // Setup the second segment to always point to the last ROM slice
for(uInt32 j = 0x1A00; j < (0x1FE0U & ~mask); j += (1 << shift)) for(uInt32 j = 0x1A00; j < (0x1FE0U & ~mask); j += (1 << shift))
@ -179,6 +182,7 @@ void CartridgeE7::bankRAM(uInt16 bank)
for(uInt32 j = 0x1800; j < 0x1900; j += (1 << shift)) for(uInt32 j = 0x1800; j < 0x1900; j += (1 << shift))
{ {
access.directPokeBase = &myRAM[1024 + offset + (j & 0x00FF)]; access.directPokeBase = &myRAM[1024 + offset + (j & 0x00FF)];
access.codeAccessBase = &myCodeAccessBase[8192 + 1024 + offset + (j & 0x00FF)];
mySystem->setPageAccess(j >> shift, access); mySystem->setPageAccess(j >> shift, access);
} }
@ -188,7 +192,7 @@ void CartridgeE7::bankRAM(uInt16 bank)
for(uInt32 k = 0x1900; k < 0x1A00; k += (1 << shift)) for(uInt32 k = 0x1900; k < 0x1A00; k += (1 << shift))
{ {
access.directPeekBase = &myRAM[1024 + offset + (k & 0x00FF)]; access.directPeekBase = &myRAM[1024 + offset + (k & 0x00FF)];
access.codeAccessBase = &myCodeAccessBase[k & 0x0FFF]; access.codeAccessBase = &myCodeAccessBase[8192 + 1024 + offset + (k & 0x00FF)];
mySystem->setPageAccess(k >> shift, access); mySystem->setPageAccess(k >> shift, access);
} }
myBankChanged = true; myBankChanged = true;
@ -225,6 +229,7 @@ bool CartridgeE7::bank(uInt16 slice)
for(uInt32 j = 0x1000; j < 0x1400; j += (1 << shift)) for(uInt32 j = 0x1000; j < 0x1400; j += (1 << shift))
{ {
access.directPokeBase = &myRAM[j & 0x03FF]; access.directPokeBase = &myRAM[j & 0x03FF];
access.codeAccessBase = &myCodeAccessBase[8192 + (j & 0x03FF)];
mySystem->setPageAccess(j >> shift, access); mySystem->setPageAccess(j >> shift, access);
} }

View File

@ -51,17 +51,9 @@ void CartridgeEF::reset()
void CartridgeEF::install(System& system) void CartridgeEF::install(System& system)
{ {
mySystem = &system; mySystem = &system;
uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask();
// Make sure the system we're being installed in has a page size that'll work // Make sure the system we're being installed in has a page size that'll work
assert((0x1000 & mask) == 0); assert((0x1000 & mySystem->pageMask()) == 0);
System::PageAccess access(0, 0, 0, this, System::PA_READ);
// Set the page accessing methods for the hot spots
for(uInt32 i = (0x1FE0 & ~mask); i < 0x2000; i += (1 << shift))
mySystem->setPageAccess(i >> shift, access);
// Install pages for the startup bank // Install pages for the startup bank
bank(myStartBank); bank(myStartBank);
@ -102,10 +94,16 @@ bool CartridgeEF::bank(uInt16 bank)
uInt16 shift = mySystem->pageShift(); uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask(); uInt16 mask = mySystem->pageMask();
// Setup the page access methods for the current bank
System::PageAccess access(0, 0, 0, this, System::PA_READ); System::PageAccess access(0, 0, 0, this, System::PA_READ);
// Map ROM image into the system // Set the page accessing methods for the hot spots
for(uInt32 i = (0x1FE0 & ~mask); i < 0x2000; i += (1 << shift))
{
access.codeAccessBase = &myCodeAccessBase[offset + (i & 0x0FFF)];
mySystem->setPageAccess(i >> shift, access);
}
// Setup the page access methods for the current bank
for(uInt32 address = 0x1000; address < (0x1FE0U & ~mask); for(uInt32 address = 0x1000; address < (0x1FE0U & ~mask);
address += (1 << shift)) address += (1 << shift))
{ {

View File

@ -69,15 +69,12 @@ void CartridgeEFSC::install(System& system)
System::PageAccess access(0, 0, 0, this, System::PA_READ); System::PageAccess access(0, 0, 0, this, System::PA_READ);
// Set the page accessing methods for the hot spots
for(uInt32 i = (0x1FE0 & ~mask); i < 0x2000; i += (1 << shift))
mySystem->setPageAccess(i >> shift, access);
// Set the page accessing method for the RAM writing pages // Set the page accessing method for the RAM writing pages
access.type = System::PA_WRITE; access.type = System::PA_WRITE;
for(uInt32 j = 0x1000; j < 0x1080; j += (1 << shift)) for(uInt32 j = 0x1000; j < 0x1080; j += (1 << shift))
{ {
access.directPokeBase = &myRAM[j & 0x007F]; access.directPokeBase = &myRAM[j & 0x007F];
access.codeAccessBase = &myCodeAccessBase[j & 0x007F];
mySystem->setPageAccess(j >> shift, access); mySystem->setPageAccess(j >> shift, access);
} }
@ -148,10 +145,16 @@ bool CartridgeEFSC::bank(uInt16 bank)
uInt16 shift = mySystem->pageShift(); uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask(); uInt16 mask = mySystem->pageMask();
// Setup the page access methods for the current bank
System::PageAccess access(0, 0, 0, this, System::PA_READ); System::PageAccess access(0, 0, 0, this, System::PA_READ);
// Map ROM image into the system // Set the page accessing methods for the hot spots
for(uInt32 i = (0x1FE0 & ~mask); i < 0x2000; i += (1 << shift))
{
access.codeAccessBase = &myCodeAccessBase[offset + (i & 0x0FFF)];
mySystem->setPageAccess(i >> shift, access);
}
// Setup the page access methods for the current bank
for(uInt32 address = 0x1100; address < (0x1FE0U & ~mask); for(uInt32 address = 0x1100; address < (0x1FE0U & ~mask);
address += (1 << shift)) address += (1 << shift))
{ {

View File

@ -52,17 +52,9 @@ void CartridgeF0::reset()
void CartridgeF0::install(System& system) void CartridgeF0::install(System& system)
{ {
mySystem = &system; mySystem = &system;
uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask();
// Make sure the system we're being installed in has a page size that'll work // Make sure the system we're being installed in has a page size that'll work
assert((0x1000 & mask) == 0); assert((0x1000 & mySystem->pageMask()) == 0);
System::PageAccess access(0, 0, 0, this, System::PA_READ);
// Set the page accessing methods for the hot spots
for(uInt32 i = (0x1FF0 & ~mask); i < 0x2000; i += (1 << shift))
mySystem->setPageAccess(i >> shift, access);
// Install pages for bank 1 // Install pages for bank 1
myCurrentBank = 0; myCurrentBank = 0;
@ -105,10 +97,16 @@ void CartridgeF0::incbank()
uInt16 shift = mySystem->pageShift(); uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask(); uInt16 mask = mySystem->pageMask();
// Setup the page access methods for the current bank
System::PageAccess access(0, 0, 0, this, System::PA_READ); System::PageAccess access(0, 0, 0, this, System::PA_READ);
// Map ROM image into the system // Set the page accessing methods for the hot spots
for(uInt32 i = (0x1FF0 & ~mask); i < 0x2000; i += (1 << shift))
{
access.codeAccessBase = &myCodeAccessBase[offset + (i & 0x0FFF)];
mySystem->setPageAccess(i >> shift, access);
}
// Setup the page access methods for the current bank
for(uInt32 address = 0x1000; address < (0x1FF0U & ~mask); for(uInt32 address = 0x1000; address < (0x1FF0U & ~mask);
address += (1 << shift)) address += (1 << shift))
{ {

View File

@ -52,17 +52,9 @@ void CartridgeF4::reset()
void CartridgeF4::install(System& system) void CartridgeF4::install(System& system)
{ {
mySystem = &system; mySystem = &system;
uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask();
// Make sure the system we're being installed in has a page size that'll work // Make sure the system we're being installed in has a page size that'll work
assert((0x1000 & mask) == 0); assert((0x1000 & mySystem->pageMask()) == 0);
System::PageAccess access(0, 0, 0, this, System::PA_READ);
// Set the page accessing methods for the hot spots
for(uInt32 i = (0x1FF4 & ~mask); i < 0x2000; i += (1 << shift))
mySystem->setPageAccess(i >> shift, access);
// Install pages for the startup bank // Install pages for the startup bank
bank(myStartBank); bank(myStartBank);
@ -107,10 +99,16 @@ bool CartridgeF4::bank(uInt16 bank)
uInt16 shift = mySystem->pageShift(); uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask(); uInt16 mask = mySystem->pageMask();
// Setup the page access methods for the current bank
System::PageAccess access(0, 0, 0, this, System::PA_READ); System::PageAccess access(0, 0, 0, this, System::PA_READ);
// Map ROM image into the system // Set the page accessing methods for the hot spots
for(uInt32 i = (0x1FF4 & ~mask); i < 0x2000; i += (1 << shift))
{
access.codeAccessBase = &myCodeAccessBase[offset + (i & 0x0FFF)];
mySystem->setPageAccess(i >> shift, access);
}
// Setup the page access methods for the current bank
for(uInt32 address = 0x1000; address < (0x1FF4U & ~mask); for(uInt32 address = 0x1000; address < (0x1FF4U & ~mask);
address += (1 << shift)) address += (1 << shift))
{ {

View File

@ -69,15 +69,12 @@ void CartridgeF4SC::install(System& system)
System::PageAccess access(0, 0, 0, this, System::PA_READ); System::PageAccess access(0, 0, 0, this, System::PA_READ);
// Set the page accessing methods for the hot spots
for(uInt32 i = (0x1FF4 & ~mask); i < 0x2000; i += (1 << shift))
mySystem->setPageAccess(i >> shift, access);
// Set the page accessing method for the RAM writing pages // Set the page accessing method for the RAM writing pages
access.type = System::PA_WRITE; access.type = System::PA_WRITE;
for(uInt32 j = 0x1000; j < 0x1080; j += (1 << shift)) for(uInt32 j = 0x1000; j < 0x1080; j += (1 << shift))
{ {
access.directPokeBase = &myRAM[j & 0x007F]; access.directPokeBase = &myRAM[j & 0x007F];
access.codeAccessBase = &myCodeAccessBase[j & 0x007F];
mySystem->setPageAccess(j >> shift, access); mySystem->setPageAccess(j >> shift, access);
} }
@ -151,10 +148,16 @@ bool CartridgeF4SC::bank(uInt16 bank)
uInt16 shift = mySystem->pageShift(); uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask(); uInt16 mask = mySystem->pageMask();
// Setup the page access methods for the current bank
System::PageAccess access(0, 0, 0, this, System::PA_READ); System::PageAccess access(0, 0, 0, this, System::PA_READ);
// Map ROM image into the system // Set the page accessing methods for the hot spots
for(uInt32 i = (0x1FF4 & ~mask); i < 0x2000; i += (1 << shift))
{
access.codeAccessBase = &myCodeAccessBase[offset + (i & 0x0FFF)];
mySystem->setPageAccess(i >> shift, access);
}
// Setup the page access methods for the current bank
for(uInt32 address = 0x1100; address < (0x1FF4U & ~mask); for(uInt32 address = 0x1100; address < (0x1FF4U & ~mask);
address += (1 << shift)) address += (1 << shift))
{ {

View File

@ -51,17 +51,9 @@ void CartridgeF6::reset()
void CartridgeF6::install(System& system) void CartridgeF6::install(System& system)
{ {
mySystem = &system; mySystem = &system;
uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask();
// Make sure the system we're being installed in has a page size that'll work // Make sure the system we're being installed in has a page size that'll work
assert((0x1000 & mask) == 0); assert((0x1000 & mySystem->pageMask()) == 0);
System::PageAccess access(0, 0, 0, this, System::PA_READ);
// Set the page accessing methods for the hot spots
for(uInt32 i = (0x1FF6 & ~mask); i < 0x2000; i += (1 << shift))
mySystem->setPageAccess(i >> shift, access);
// Upon install we'll setup the startup bank // Upon install we'll setup the startup bank
bank(myStartBank); bank(myStartBank);
@ -147,10 +139,16 @@ bool CartridgeF6::bank(uInt16 bank)
uInt16 shift = mySystem->pageShift(); uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask(); uInt16 mask = mySystem->pageMask();
// Setup the page access methods for the current bank
System::PageAccess access(0, 0, 0, this, System::PA_READ); System::PageAccess access(0, 0, 0, this, System::PA_READ);
// Map ROM image into the system // Set the page accessing methods for the hot spots
for(uInt32 i = (0x1FF6 & ~mask); i < 0x2000; i += (1 << shift))
{
access.codeAccessBase = &myCodeAccessBase[offset + (i & 0x0FFF)];
mySystem->setPageAccess(i >> shift, access);
}
// Setup the page access methods for the current bank
for(uInt32 address = 0x1000; address < (0x1FF6U & ~mask); for(uInt32 address = 0x1000; address < (0x1FF6U & ~mask);
address += (1 << shift)) address += (1 << shift))
{ {

View File

@ -69,15 +69,12 @@ void CartridgeF6SC::install(System& system)
System::PageAccess access(0, 0, 0, this, System::PA_READ); System::PageAccess access(0, 0, 0, this, System::PA_READ);
// Set the page accessing methods for the hot spots
for(uInt32 i = (0x1FF6 & ~mask); i < 0x2000; i += (1 << shift))
mySystem->setPageAccess(i >> shift, access);
// Set the page accessing method for the RAM writing pages // Set the page accessing method for the RAM writing pages
access.type = System::PA_WRITE; access.type = System::PA_WRITE;
for(uInt32 j = 0x1000; j < 0x1080; j += (1 << shift)) for(uInt32 j = 0x1000; j < 0x1080; j += (1 << shift))
{ {
access.directPokeBase = &myRAM[j & 0x007F]; access.directPokeBase = &myRAM[j & 0x007F];
access.codeAccessBase = &myCodeAccessBase[j & 0x007F];
mySystem->setPageAccess(j >> shift, access); mySystem->setPageAccess(j >> shift, access);
} }
@ -194,10 +191,16 @@ bool CartridgeF6SC::bank(uInt16 bank)
uInt16 shift = mySystem->pageShift(); uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask(); uInt16 mask = mySystem->pageMask();
// Setup the page access methods for the current bank
System::PageAccess access(0, 0, 0, this, System::PA_READ); System::PageAccess access(0, 0, 0, this, System::PA_READ);
// Map ROM image into the system // Set the page accessing methods for the hot spots
for(uInt32 i = (0x1FF6 & ~mask); i < 0x2000; i += (1 << shift))
{
access.codeAccessBase = &myCodeAccessBase[offset + (i & 0x0FFF)];
mySystem->setPageAccess(i >> shift, access);
}
// Setup the page access methods for the current bank
for(uInt32 address = 0x1100; address < (0x1FF6U & ~mask); for(uInt32 address = 0x1100; address < (0x1FF6U & ~mask);
address += (1 << shift)) address += (1 << shift))
{ {

View File

@ -58,17 +58,9 @@ void CartridgeF8::reset()
void CartridgeF8::install(System& system) void CartridgeF8::install(System& system)
{ {
mySystem = &system; mySystem = &system;
uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask();
// Make sure the system we're being installed in has a page size that'll work // Make sure the system we're being installed in has a page size that'll work
assert((0x1000 & mask) == 0); assert((0x1000 & mySystem->pageMask()) == 0);
System::PageAccess access(0, 0, 0, this, System::PA_READ);
// Set the page accessing methods for the hot spots
for(uInt32 i = (0x1FF8 & ~mask); i < 0x2000; i += (1 << shift))
mySystem->setPageAccess(i >> shift, access);
// Install pages for the startup bank // Install pages for the startup bank
bank(myStartBank); bank(myStartBank);
@ -134,10 +126,16 @@ bool CartridgeF8::bank(uInt16 bank)
uInt16 shift = mySystem->pageShift(); uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask(); uInt16 mask = mySystem->pageMask();
// Setup the page access methods for the current bank
System::PageAccess access(0, 0, 0, this, System::PA_READ); System::PageAccess access(0, 0, 0, this, System::PA_READ);
// Map ROM image into the system // Set the page accessing methods for the hot spots
for(uInt32 i = (0x1FF8 & ~mask); i < 0x2000; i += (1 << shift))
{
access.codeAccessBase = &myCodeAccessBase[offset + (i & 0x0FFF)];
mySystem->setPageAccess(i >> shift, access);
}
// Setup the page access methods for the current bank
for(uInt32 address = 0x1000; address < (0x1FF8U & ~mask); for(uInt32 address = 0x1000; address < (0x1FF8U & ~mask);
address += (1 << shift)) address += (1 << shift))
{ {

View File

@ -69,15 +69,12 @@ void CartridgeF8SC::install(System& system)
System::PageAccess access(0, 0, 0, this, System::PA_READ); System::PageAccess access(0, 0, 0, this, System::PA_READ);
// Set the page accessing methods for the hot spots
for(uInt32 i = (0x1FF8 & ~mask); i < 0x2000; i += (1 << shift))
mySystem->setPageAccess(i >> shift, access);
// Set the page accessing method for the RAM writing pages // Set the page accessing method for the RAM writing pages
access.type = System::PA_WRITE; access.type = System::PA_WRITE;
for(uInt32 j = 0x1000; j < 0x1080; j += (1 << shift)) for(uInt32 j = 0x1000; j < 0x1080; j += (1 << shift))
{ {
access.directPokeBase = &myRAM[j & 0x007F]; access.directPokeBase = &myRAM[j & 0x007F];
access.codeAccessBase = &myCodeAccessBase[j & 0x007F];
mySystem->setPageAccess(j >> shift, access); mySystem->setPageAccess(j >> shift, access);
} }
@ -174,10 +171,16 @@ bool CartridgeF8SC::bank(uInt16 bank)
uInt16 shift = mySystem->pageShift(); uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask(); uInt16 mask = mySystem->pageMask();
// Setup the page access methods for the current bank
System::PageAccess access(0, 0, 0, this, System::PA_READ); System::PageAccess access(0, 0, 0, this, System::PA_READ);
// Map ROM image into the system // Set the page accessing methods for the hot spots
for(uInt32 i = (0x1FF8 & ~mask); i < 0x2000; i += (1 << shift))
{
access.codeAccessBase = &myCodeAccessBase[offset + (i & 0x0FFF)];
mySystem->setPageAccess(i >> shift, access);
}
// Setup the page access methods for the current bank
for(uInt32 address = 0x1100; address < (0x1FF8U & ~mask); for(uInt32 address = 0x1100; address < (0x1FF8U & ~mask);
address += (1 << shift)) address += (1 << shift))
{ {

View File

@ -69,15 +69,12 @@ void CartridgeFA::install(System& system)
System::PageAccess access(0, 0, 0, this, System::PA_READ); System::PageAccess access(0, 0, 0, this, System::PA_READ);
// Set the page accessing methods for the hot spots
for(uInt32 i = (0x1FF8 & ~mask); i < 0x2000; i += (1 << shift))
mySystem->setPageAccess(i >> shift, access);
// Set the page accessing method for the RAM writing pages // Set the page accessing method for the RAM writing pages
access.type = System::PA_WRITE; access.type = System::PA_WRITE;
for(uInt32 j = 0x1000; j < 0x1100; j += (1 << shift)) for(uInt32 j = 0x1000; j < 0x1100; j += (1 << shift))
{ {
access.directPokeBase = &myRAM[j & 0x00FF]; access.directPokeBase = &myRAM[j & 0x00FF];
access.codeAccessBase = &myCodeAccessBase[j & 0x00FF];
mySystem->setPageAccess(j >> shift, access); mySystem->setPageAccess(j >> shift, access);
} }
@ -184,10 +181,16 @@ bool CartridgeFA::bank(uInt16 bank)
uInt16 shift = mySystem->pageShift(); uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask(); uInt16 mask = mySystem->pageMask();
// Setup the page access methods for the current bank
System::PageAccess access(0, 0, 0, this, System::PA_READ); System::PageAccess access(0, 0, 0, this, System::PA_READ);
// Map ROM image into the system // Set the page accessing methods for the hot spots
for(uInt32 i = (0x1FF8 & ~mask); i < 0x2000; i += (1 << shift))
{
access.codeAccessBase = &myCodeAccessBase[offset + (i & 0x0FFF)];
mySystem->setPageAccess(i >> shift, access);
}
// Setup the page access methods for the current bank
for(uInt32 address = 0x1200; address < (0x1FF8U & ~mask); for(uInt32 address = 0x1200; address < (0x1FF8U & ~mask);
address += (1 << shift)) address += (1 << shift))
{ {

View File

@ -23,6 +23,23 @@
#ifdef DEBUGGER_SUPPORT #ifdef DEBUGGER_SUPPORT
#include "Debugger.hxx" #include "Debugger.hxx"
#include "Expression.hxx" #include "Expression.hxx"
#include "CartDebug.hxx"
// Flags for disassembly types
#define DISASM_SKIP CartDebug::SKIP
#define DISASM_CODE CartDebug::CODE
#define DISASM_GFX CartDebug::GFX
#define DISASM_DATA CartDebug::DATA
#define DISASM_ROW CartDebug::ROW
#define DISASM_NONE 0
#else
// Flags for disassembly types
#define DISASM_SKIP 0
#define DISASM_CODE 0
#define DISASM_GFX 0
#define DISASM_DATA 0
#define DISASM_ROW 0
#define DISASM_NONE 0
#endif #endif
#include "M6502.hxx" #include "M6502.hxx"
@ -152,7 +169,7 @@ void M6502::PS(uInt8 ps)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
inline uInt8 M6502::peek(uInt16 address, bool isCode) inline uInt8 M6502::peek(uInt16 address, uInt8 flags)
{ {
if(address != myLastAddress) if(address != myLastAddress)
{ {
@ -170,7 +187,7 @@ inline uInt8 M6502::peek(uInt16 address, bool isCode)
} }
#endif #endif
uInt8 result = mySystem->peek(address, isCode); uInt8 result = mySystem->peek(address, flags);
myLastAccessWasRead = true; myLastAccessWasRead = true;
myLastPeekAddress = address; myLastPeekAddress = address;
return result; return result;
@ -245,9 +262,10 @@ bool M6502::execute(uInt32 number)
myLastPeekAddress = myLastPokeAddress = 0; myLastPeekAddress = myLastPokeAddress = 0;
// Fetch instruction at the program counter // Fetch instruction at the program counter
IR = peek(PC++, true); // This address represents a code section IR = peek(PC++, DISASM_CODE); // This address represents a code section
#ifdef DEBUG_OUTPUT #ifdef DEBUG_OUTPUT
if(PC >= 0xfafe && PC <= 0xfb10)
debugStream << ::hex << setw(2) << (int)A << " " debugStream << ::hex << setw(2) << (int)A << " "
<< ::hex << setw(2) << (int)X << " " << ::hex << setw(2) << (int)X << " "
<< ::hex << setw(2) << (int)Y << " " << ::hex << setw(2) << (int)Y << " "

View File

@ -211,11 +211,12 @@ class M6502 : public Serializable
find them itself. find them itself.
@param address The address from which the value should be loaded @param address The address from which the value should be loaded
@param isCode Indicates that this address is part of an instruction @param flags Indicates that this address has the given flags
for type of access (CODE, DATA, GFX, etc)
@return The byte at the specified address @return The byte at the specified address
*/ */
inline uInt8 peek(uInt16 address, bool isCode); inline uInt8 peek(uInt16 address, uInt8 flags);
/** /**
Change the byte at the specified address to the given value and Change the byte at the specified address to the given value and

File diff suppressed because it is too large Load Diff

View File

@ -32,197 +32,197 @@
#endif #endif
define(M6502_IMPLIED, `{ define(M6502_IMPLIED, `{
peek(PC, false); peek(PC, DISASM_NONE);
}') }')
define(M6502_IMMEDIATE_READ, `{ define(M6502_IMMEDIATE_READ, `{
operand = peek(PC++, true); operand = peek(PC++, DISASM_CODE);
}') }')
define(M6502_ABSOLUTE_READ, `{ define(M6502_ABSOLUTE_READ, `{
uInt16 address = peek(PC++, true); uInt16 address = peek(PC++, DISASM_CODE);
address |= ((uInt16)peek(PC++, true) << 8); address |= ((uInt16)peek(PC++, DISASM_CODE) << 8);
operand = peek(address, false); operand = peek(address, DISASM_DATA);
}') }')
define(M6502_ABSOLUTE_WRITE, `{ define(M6502_ABSOLUTE_WRITE, `{
operandAddress = peek(PC++, true); operandAddress = peek(PC++, DISASM_CODE);
operandAddress |= ((uInt16)peek(PC++, true) << 8); operandAddress |= ((uInt16)peek(PC++, DISASM_CODE) << 8);
}') }')
define(M6502_ABSOLUTE_READMODIFYWRITE, `{ define(M6502_ABSOLUTE_READMODIFYWRITE, `{
operandAddress = peek(PC++, true); operandAddress = peek(PC++, DISASM_CODE);
operandAddress |= ((uInt16)peek(PC++, true) << 8); operandAddress |= ((uInt16)peek(PC++, DISASM_CODE) << 8);
operand = peek(operandAddress, false); operand = peek(operandAddress, DISASM_DATA);
poke(operandAddress, operand); poke(operandAddress, operand);
}') }')
define(M6502_ABSOLUTEX_READ, `{ define(M6502_ABSOLUTEX_READ, `{
uInt16 low = peek(PC++, true); uInt16 low = peek(PC++, DISASM_CODE);
uInt16 high = ((uInt16)peek(PC++, true) << 8); uInt16 high = ((uInt16)peek(PC++, DISASM_CODE) << 8);
operand = peek(high | (uInt8)(low + X), false); operand = peek(high | (uInt8)(low + X), DISASM_DATA);
if((low + X) > 0xFF) if((low + X) > 0xFF)
operand = peek((high | low) + X, false); operand = peek((high | low) + X, DISASM_DATA);
}') }')
define(M6502_ABSOLUTEX_WRITE, `{ define(M6502_ABSOLUTEX_WRITE, `{
uInt16 low = peek(PC++, true); uInt16 low = peek(PC++, DISASM_CODE);
uInt16 high = ((uInt16)peek(PC++, true) << 8); uInt16 high = ((uInt16)peek(PC++, DISASM_CODE) << 8);
peek(high | (uInt8)(low + X), false); peek(high | (uInt8)(low + X), DISASM_DATA);
operandAddress = (high | low) + X; operandAddress = (high | low) + X;
}') }')
define(M6502_ABSOLUTEX_READMODIFYWRITE, `{ define(M6502_ABSOLUTEX_READMODIFYWRITE, `{
uInt16 low = peek(PC++, true); uInt16 low = peek(PC++, DISASM_CODE);
uInt16 high = ((uInt16)peek(PC++, true) << 8); uInt16 high = ((uInt16)peek(PC++, DISASM_CODE) << 8);
peek(high | (uInt8)(low + X), false); peek(high | (uInt8)(low + X), DISASM_DATA);
operandAddress = (high | low) + X; operandAddress = (high | low) + X;
operand = peek(operandAddress, false); operand = peek(operandAddress, DISASM_DATA);
poke(operandAddress, operand); poke(operandAddress, operand);
}') }')
define(M6502_ABSOLUTEY_READ, `{ define(M6502_ABSOLUTEY_READ, `{
uInt16 low = peek(PC++, true); uInt16 low = peek(PC++, DISASM_CODE);
uInt16 high = ((uInt16)peek(PC++, true) << 8); uInt16 high = ((uInt16)peek(PC++, DISASM_CODE) << 8);
operand = peek(high | (uInt8)(low + Y), false); operand = peek(high | (uInt8)(low + Y), DISASM_DATA);
if((low + Y) > 0xFF) if((low + Y) > 0xFF)
operand = peek((high | low) + Y, false); operand = peek((high | low) + Y, DISASM_DATA);
}') }')
define(M6502_ABSOLUTEY_WRITE, `{ define(M6502_ABSOLUTEY_WRITE, `{
uInt16 low = peek(PC++, true); uInt16 low = peek(PC++, DISASM_CODE);
uInt16 high = ((uInt16)peek(PC++, true) << 8); uInt16 high = ((uInt16)peek(PC++, DISASM_CODE) << 8);
peek(high | (uInt8)(low + Y), false); peek(high | (uInt8)(low + Y), DISASM_DATA);
operandAddress = (high | low) + Y; operandAddress = (high | low) + Y;
}') }')
define(M6502_ABSOLUTEY_READMODIFYWRITE, `{ define(M6502_ABSOLUTEY_READMODIFYWRITE, `{
uInt16 low = peek(PC++, true); uInt16 low = peek(PC++, DISASM_CODE);
uInt16 high = ((uInt16)peek(PC++, true) << 8); uInt16 high = ((uInt16)peek(PC++, DISASM_CODE) << 8);
peek(high | (uInt8)(low + Y), false); peek(high | (uInt8)(low + Y), DISASM_DATA);
operandAddress = (high | low) + Y; operandAddress = (high | low) + Y;
operand = peek(operandAddress, false); operand = peek(operandAddress, DISASM_DATA);
poke(operandAddress, operand); poke(operandAddress, operand);
}') }')
define(M6502_ZERO_READ, `{ define(M6502_ZERO_READ, `{
operand = peek(peek(PC++, true), false); operand = peek(peek(PC++, DISASM_CODE), DISASM_DATA);
}') }')
define(M6502_ZERO_WRITE, `{ define(M6502_ZERO_WRITE, `{
operandAddress = peek(PC++, true); operandAddress = peek(PC++, DISASM_CODE);
}') }')
define(M6502_ZERO_READMODIFYWRITE, `{ define(M6502_ZERO_READMODIFYWRITE, `{
operandAddress = peek(PC++, true); operandAddress = peek(PC++, DISASM_CODE);
operand = peek(operandAddress, false); operand = peek(operandAddress, DISASM_DATA);
poke(operandAddress, operand); poke(operandAddress, operand);
}') }')
define(M6502_ZEROX_READ, `{ define(M6502_ZEROX_READ, `{
uInt8 address = peek(PC++, true); uInt8 address = peek(PC++, DISASM_CODE);
peek(address, false); peek(address, DISASM_DATA);
address += X; address += X;
operand = peek(address, false); operand = peek(address, DISASM_DATA);
}') }')
define(M6502_ZEROX_WRITE, `{ define(M6502_ZEROX_WRITE, `{
operandAddress = peek(PC++, true); operandAddress = peek(PC++, DISASM_CODE);
peek(operandAddress, false); peek(operandAddress, DISASM_DATA);
operandAddress = (operandAddress + X) & 0xFF; operandAddress = (operandAddress + X) & 0xFF;
}') }')
define(M6502_ZEROX_READMODIFYWRITE, `{ define(M6502_ZEROX_READMODIFYWRITE, `{
operandAddress = peek(PC++, true); operandAddress = peek(PC++, DISASM_CODE);
peek(operandAddress, false); peek(operandAddress, DISASM_DATA);
operandAddress = (operandAddress + X) & 0xFF; operandAddress = (operandAddress + X) & 0xFF;
operand = peek(operandAddress, false); operand = peek(operandAddress, DISASM_DATA);
poke(operandAddress, operand); poke(operandAddress, operand);
}') }')
define(M6502_ZEROY_READ, `{ define(M6502_ZEROY_READ, `{
uInt8 address = peek(PC++, true); uInt8 address = peek(PC++, DISASM_CODE);
peek(address, false); peek(address, DISASM_DATA);
address += Y; address += Y;
operand = peek(address, false); operand = peek(address, DISASM_DATA);
}') }')
define(M6502_ZEROY_WRITE, `{ define(M6502_ZEROY_WRITE, `{
operandAddress = peek(PC++, true); operandAddress = peek(PC++, DISASM_CODE);
peek(operandAddress, false); peek(operandAddress, DISASM_DATA);
operandAddress = (operandAddress + Y) & 0xFF; operandAddress = (operandAddress + Y) & 0xFF;
}') }')
define(M6502_ZEROY_READMODIFYWRITE, `{ define(M6502_ZEROY_READMODIFYWRITE, `{
operandAddress = peek(PC++, true); operandAddress = peek(PC++, DISASM_CODE);
peek(operandAddress, false); peek(operandAddress, DISASM_DATA);
operandAddress = (operandAddress + Y) & 0xFF; operandAddress = (operandAddress + Y) & 0xFF;
operand = peek(operandAddress, false); operand = peek(operandAddress, DISASM_DATA);
poke(operandAddress, operand); poke(operandAddress, operand);
}') }')
define(M6502_INDIRECT, `{ define(M6502_INDIRECT, `{
uInt16 addr = peek(PC++, true); uInt16 addr = peek(PC++, DISASM_CODE);
addr |= ((uInt16)peek(PC++, true) << 8); addr |= ((uInt16)peek(PC++, DISASM_CODE) << 8);
// Simulate the error in the indirect addressing mode! // Simulate the error in the indirect addressing mode!
uInt16 high = NOTSAMEPAGE(addr, addr + 1) ? (addr & 0xff00) : (addr + 1); uInt16 high = NOTSAMEPAGE(addr, addr + 1) ? (addr & 0xff00) : (addr + 1);
operandAddress = peek(addr, false); operandAddress = peek(addr, DISASM_DATA);
operandAddress |= ((uInt16)peek(high, false) << 8); operandAddress |= ((uInt16)peek(high, DISASM_DATA) << 8);
}') }')
define(M6502_INDIRECTX_READ, `{ define(M6502_INDIRECTX_READ, `{
uInt8 pointer = peek(PC++, true); uInt8 pointer = peek(PC++, DISASM_CODE);
peek(pointer, false); peek(pointer, DISASM_DATA);
pointer += X; pointer += X;
uInt16 address = peek(pointer++, false); uInt16 address = peek(pointer++, DISASM_DATA);
address |= ((uInt16)peek(pointer, false) << 8); address |= ((uInt16)peek(pointer, DISASM_DATA) << 8);
operand = peek(address, false); operand = peek(address, DISASM_DATA);
}') }')
define(M6502_INDIRECTX_WRITE, `{ define(M6502_INDIRECTX_WRITE, `{
uInt8 pointer = peek(PC++, true); uInt8 pointer = peek(PC++, DISASM_CODE);
peek(pointer, false); peek(pointer, DISASM_DATA);
pointer += X; pointer += X;
operandAddress = peek(pointer++, false); operandAddress = peek(pointer++, DISASM_DATA);
operandAddress |= ((uInt16)peek(pointer, false) << 8); operandAddress |= ((uInt16)peek(pointer, DISASM_DATA) << 8);
}') }')
define(M6502_INDIRECTX_READMODIFYWRITE, `{ define(M6502_INDIRECTX_READMODIFYWRITE, `{
uInt8 pointer = peek(PC++, true); uInt8 pointer = peek(PC++, DISASM_CODE);
peek(pointer, false); peek(pointer, DISASM_DATA);
pointer += X; pointer += X;
operandAddress = peek(pointer++, false); operandAddress = peek(pointer++, DISASM_DATA);
operandAddress |= ((uInt16)peek(pointer, false) << 8); operandAddress |= ((uInt16)peek(pointer, DISASM_DATA) << 8);
operand = peek(operandAddress, false); operand = peek(operandAddress, DISASM_DATA);
poke(operandAddress, operand); poke(operandAddress, operand);
}') }')
define(M6502_INDIRECTY_READ, `{ define(M6502_INDIRECTY_READ, `{
uInt8 pointer = peek(PC++, true); uInt8 pointer = peek(PC++, DISASM_CODE);
uInt16 low = peek(pointer++, false); uInt16 low = peek(pointer++, DISASM_DATA);
uInt16 high = ((uInt16)peek(pointer, false) << 8); uInt16 high = ((uInt16)peek(pointer, DISASM_DATA) << 8);
operand = peek(high | (uInt8)(low + Y), false); operand = peek(high | (uInt8)(low + Y), DISASM_DATA);
if((low + Y) > 0xFF) if((low + Y) > 0xFF)
operand = peek((high | low) + Y, false); operand = peek((high | low) + Y, DISASM_DATA);
}') }')
define(M6502_INDIRECTY_WRITE, `{ define(M6502_INDIRECTY_WRITE, `{
uInt8 pointer = peek(PC++, true); uInt8 pointer = peek(PC++, DISASM_CODE);
uInt16 low = peek(pointer++, false); uInt16 low = peek(pointer++, DISASM_DATA);
uInt16 high = ((uInt16)peek(pointer, false) << 8); uInt16 high = ((uInt16)peek(pointer, DISASM_DATA) << 8);
peek(high | (uInt8)(low + Y), false); peek(high | (uInt8)(low + Y), DISASM_DATA);
operandAddress = (high | low) + Y; operandAddress = (high | low) + Y;
}') }')
define(M6502_INDIRECTY_READMODIFYWRITE, `{ define(M6502_INDIRECTY_READMODIFYWRITE, `{
uInt8 pointer = peek(PC++, true); uInt8 pointer = peek(PC++, DISASM_CODE);
uInt16 low = peek(pointer++, false); uInt16 low = peek(pointer++, DISASM_DATA);
uInt16 high = ((uInt16)peek(pointer, false) << 8); uInt16 high = ((uInt16)peek(pointer, DISASM_DATA) << 8);
peek(high | (uInt8)(low + Y), false); peek(high | (uInt8)(low + Y), DISASM_DATA);
operandAddress = (high | low) + Y; operandAddress = (high | low) + Y;
operand = peek(operandAddress, false); operand = peek(operandAddress, DISASM_DATA);
poke(operandAddress, operand); poke(operandAddress, operand);
}') }')
@ -230,10 +230,10 @@ define(M6502_INDIRECTY_READMODIFYWRITE, `{
define(M6502_BCC, `{ define(M6502_BCC, `{
if(!C) if(!C)
{ {
peek(PC, false); peek(PC, DISASM_NONE);
uInt16 address = PC + (Int8)operand; uInt16 address = PC + (Int8)operand;
if(NOTSAMEPAGE(PC, address)) if(NOTSAMEPAGE(PC, address))
peek((PC & 0xFF00) | (address & 0x00FF), false); peek((PC & 0xFF00) | (address & 0x00FF), DISASM_DATA);
PC = address; PC = address;
} }
}') }')
@ -241,10 +241,10 @@ define(M6502_BCC, `{
define(M6502_BCS, `{ define(M6502_BCS, `{
if(C) if(C)
{ {
peek(PC, false); peek(PC, DISASM_NONE);
uInt16 address = PC + (Int8)operand; uInt16 address = PC + (Int8)operand;
if(NOTSAMEPAGE(PC, address)) if(NOTSAMEPAGE(PC, address))
peek((PC & 0xFF00) | (address & 0x00FF), false); peek((PC & 0xFF00) | (address & 0x00FF), DISASM_DATA);
PC = address; PC = address;
} }
}') }')
@ -252,10 +252,10 @@ define(M6502_BCS, `{
define(M6502_BEQ, `{ define(M6502_BEQ, `{
if(!notZ) if(!notZ)
{ {
peek(PC, false); peek(PC, DISASM_NONE);
uInt16 address = PC + (Int8)operand; uInt16 address = PC + (Int8)operand;
if(NOTSAMEPAGE(PC, address)) if(NOTSAMEPAGE(PC, address))
peek((PC & 0xFF00) | (address & 0x00FF), false); peek((PC & 0xFF00) | (address & 0x00FF), DISASM_DATA);
PC = address; PC = address;
} }
}') }')
@ -263,10 +263,10 @@ define(M6502_BEQ, `{
define(M6502_BMI, `{ define(M6502_BMI, `{
if(N) if(N)
{ {
peek(PC, false); peek(PC, DISASM_NONE);
uInt16 address = PC + (Int8)operand; uInt16 address = PC + (Int8)operand;
if(NOTSAMEPAGE(PC, address)) if(NOTSAMEPAGE(PC, address))
peek((PC & 0xFF00) | (address & 0x00FF), false); peek((PC & 0xFF00) | (address & 0x00FF), DISASM_DATA);
PC = address; PC = address;
} }
}') }')
@ -274,10 +274,10 @@ define(M6502_BMI, `{
define(M6502_BNE, `{ define(M6502_BNE, `{
if(notZ) if(notZ)
{ {
peek(PC, false); peek(PC, DISASM_NONE);
uInt16 address = PC + (Int8)operand; uInt16 address = PC + (Int8)operand;
if(NOTSAMEPAGE(PC, address)) if(NOTSAMEPAGE(PC, address))
peek((PC & 0xFF00) | (address & 0x00FF), false); peek((PC & 0xFF00) | (address & 0x00FF), DISASM_DATA);
PC = address; PC = address;
} }
}') }')
@ -285,10 +285,10 @@ define(M6502_BNE, `{
define(M6502_BPL, `{ define(M6502_BPL, `{
if(!N) if(!N)
{ {
peek(PC, false); peek(PC, DISASM_NONE);
uInt16 address = PC + (Int8)operand; uInt16 address = PC + (Int8)operand;
if(NOTSAMEPAGE(PC, address)) if(NOTSAMEPAGE(PC, address))
peek((PC & 0xFF00) | (address & 0x00FF), false); peek((PC & 0xFF00) | (address & 0x00FF), DISASM_DATA);
PC = address; PC = address;
} }
}') }')
@ -296,10 +296,10 @@ define(M6502_BPL, `{
define(M6502_BVC, `{ define(M6502_BVC, `{
if(!V) if(!V)
{ {
peek(PC, false); peek(PC, DISASM_NONE);
uInt16 address = PC + (Int8)operand; uInt16 address = PC + (Int8)operand;
if(NOTSAMEPAGE(PC, address)) if(NOTSAMEPAGE(PC, address))
peek((PC & 0xFF00) | (address & 0x00FF), false); peek((PC & 0xFF00) | (address & 0x00FF), DISASM_DATA);
PC = address; PC = address;
} }
}') }')
@ -307,10 +307,10 @@ define(M6502_BVC, `{
define(M6502_BVS, `{ define(M6502_BVS, `{
if(V) if(V)
{ {
peek(PC, false); peek(PC, DISASM_NONE);
uInt16 address = PC + (Int8)operand; uInt16 address = PC + (Int8)operand;
if(NOTSAMEPAGE(PC, address)) if(NOTSAMEPAGE(PC, address))
peek((PC & 0xFF00) | (address & 0x00FF), false); peek((PC & 0xFF00) | (address & 0x00FF), DISASM_DATA);
PC = address; PC = address;
} }
}') }')
@ -449,7 +449,7 @@ define(M6502_BIT, `{
}') }')
define(M6502_BRK, `{ define(M6502_BRK, `{
peek(PC++, true); peek(PC++, DISASM_CODE);
B = true; B = true;
@ -459,8 +459,8 @@ define(M6502_BRK, `{
I = true; I = true;
PC = peek(0xfffe, false); PC = peek(0xfffe, DISASM_NONE);
PC |= ((uInt16)peek(0xffff, false) << 8); PC |= ((uInt16)peek(0xffff, DISASM_NONE) << 8);
}') }')
define(M6502_CLC, `{ define(M6502_CLC, `{
@ -598,8 +598,8 @@ define(M6502_JMP, `{
}') }')
define(M6502_JSR, `{ define(M6502_JSR, `{
uInt8 low = peek(PC++, true); uInt8 low = peek(PC++, DISASM_CODE);
peek(0x0100 + SP, false); peek(0x0100 + SP, DISASM_DATA);
// It seems that the 650x does not push the address of the next instruction // It seems that the 650x does not push the address of the next instruction
// on the stack it actually pushes the address of the next instruction // on the stack it actually pushes the address of the next instruction
@ -607,7 +607,7 @@ define(M6502_JSR, `{
poke(0x0100 + SP--, PC >> 8); poke(0x0100 + SP--, PC >> 8);
poke(0x0100 + SP--, PC & 0xff); poke(0x0100 + SP--, PC & 0xff);
PC = low | ((uInt16)peek(PC++, true) << 8); PC = low | ((uInt16)peek(PC++, DISASM_CODE) << 8);
}') }')
define(M6502_LAS, `{ define(M6502_LAS, `{
@ -689,15 +689,15 @@ define(M6502_PHP, `{
}') }')
define(M6502_PLA, `{ define(M6502_PLA, `{
peek(0x0100 + SP++, false); peek(0x0100 + SP++, DISASM_NONE);
A = peek(0x0100 + SP, false); A = peek(0x0100 + SP, DISASM_NONE);
notZ = A; notZ = A;
N = A & 0x80; N = A & 0x80;
}') }')
define(M6502_PLP, `{ define(M6502_PLP, `{
peek(0x0100 + SP++, false); peek(0x0100 + SP++, DISASM_NONE);
PS(peek(0x0100 + SP, false)); PS(peek(0x0100 + SP, DISASM_NONE));
}') }')
define(M6502_RLA, `{ define(M6502_RLA, `{
@ -800,17 +800,17 @@ define(M6502_RRA, `{
}') }')
define(M6502_RTI, `{ define(M6502_RTI, `{
peek(0x0100 + SP++, false); peek(0x0100 + SP++, DISASM_DATA);
PS(peek(0x0100 + SP++, false)); PS(peek(0x0100 + SP++, DISASM_DATA));
PC = peek(0x0100 + SP++, false); PC = peek(0x0100 + SP++, DISASM_CODE);
PC |= ((uInt16)peek(0x0100 + SP, false) << 8); PC |= ((uInt16)peek(0x0100 + SP, DISASM_CODE) << 8);
}') }')
define(M6502_RTS, `{ define(M6502_RTS, `{
peek(0x0100 + SP++, false); peek(0x0100 + SP++, DISASM_DATA);
PC = peek(0x0100 + SP++, false); PC = peek(0x0100 + SP++, DISASM_CODE);
PC |= ((uInt16)peek(0x0100 + SP, false) << 8); PC |= ((uInt16)peek(0x0100 + SP, DISASM_CODE) << 8);
peek(PC++, true); peek(PC++, DISASM_CODE);
}') }')
define(M6502_SAX, `{ define(M6502_SAX, `{

View File

@ -19,7 +19,7 @@
#include <cassert> #include <cassert>
#include <iostream> #include <iostream>
#include "Debugger.hxx"
#include "Device.hxx" #include "Device.hxx"
#include "M6502.hxx" #include "M6502.hxx"
#include "M6532.hxx" #include "M6532.hxx"
@ -212,13 +212,16 @@ void System::clearDirtyPages()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 System::peek(uInt16 addr, bool isCode) uInt8 System::peek(uInt16 addr, uInt8 flags)
{ {
PageAccess& access = myPageAccessTable[(addr & myAddressMask) >> myPageShift]; PageAccess& access = myPageAccessTable[(addr & myAddressMask) >> myPageShift];
uInt8 result; // Set access type
if(access.codeAccessBase)
*(access.codeAccessBase + (addr & myPageMask)) |= flags;
// See if this page uses direct accessing or not // See if this page uses direct accessing or not
uInt8 result;
if(access.directPeekBase) if(access.directPeekBase)
{ {
result = *(access.directPeekBase + (addr & myPageMask)); result = *(access.directPeekBase + (addr & myPageMask));
@ -230,15 +233,8 @@ uInt8 System::peek(uInt16 addr, bool isCode)
#ifdef DEBUGGER_SUPPORT #ifdef DEBUGGER_SUPPORT
if(!myDataBusLocked) if(!myDataBusLocked)
{
if(access.codeAccessBase)
*(access.codeAccessBase + (addr & myPageMask)) = isCode;
myDataBusState = result;
}
#else
myDataBusState = result;
#endif #endif
myDataBusState = result;
return result; return result;
} }
@ -269,17 +265,28 @@ void System::poke(uInt16 addr, uInt8 value)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool System::isCode(uInt16 addr) uInt8 System::getAddressDisasmType(uInt16 addr)
{ {
#ifdef DEBUGGER_SUPPORT #ifdef DEBUGGER_SUPPORT
PageAccess& access = myPageAccessTable[(addr & myAddressMask) >> myPageShift]; PageAccess& access = myPageAccessTable[(addr & myAddressMask) >> myPageShift];
if(access.codeAccessBase) if(access.codeAccessBase)
return *(access.codeAccessBase + (addr & myPageMask)) ? true : false; return *(access.codeAccessBase + (addr & myPageMask));
else else
return false; return 0;
#else #else
return false; return 0;
#endif
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void System::setAddressDisasmType(uInt16 addr, uInt8 flags)
{
#ifdef DEBUGGER_SUPPORT
PageAccess& access = myPageAccessTable[(addr & myAddressMask) >> myPageShift];
if(access.codeAccessBase)
*(access.codeAccessBase + (addr & myPageMask)) |= flags;
#endif #endif
} }

View File

@ -256,11 +256,12 @@ class System : public Serializable
the address. the address.
@param address The address from which the value should be loaded @param address The address from which the value should be loaded
@param isCode Indicates that this address is part of an instruction @param flags Indicates that this address has the given flags
for type of access (CODE, DATA, GFX, etc)
@return The byte at the specified address @return The byte at the specified address
*/ */
uInt8 peek(uInt16 address, bool isCode = false); uInt8 peek(uInt16 address, uInt8 flags = 0);
/** /**
Change the byte at the specified address to the given value. Change the byte at the specified address to the given value.
@ -290,11 +291,12 @@ class System : public Serializable
void unlockDataBus(); void unlockDataBus();
/** /**
Answer whether or not the given address has ever been used as Access and modify the disassembly type flags for the given
code. That is, it has ever been stored in either the IR or the PC, address. Note that while any flag can be used, the disassembly
or otherwise been executed. only really acts on SKIP/CODE/GFX/DATA/ROW.
*/ */
bool isCode(uInt16 address); uInt8 getAddressDisasmType(uInt16 address);
void setAddressDisasmType(uInt16 address, uInt8 flags);
public: public:
/** /**