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
saveOldState(false);
// Force a re-disassemble
myRom->invalidate();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -92,8 +92,6 @@ class Debugger : public DialogContainer
virtual ~Debugger();
public:
OSystem *getOSystem() { return myOSystem; }
/**
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. */
int peek(int addr) { return mySystem->peek(addr); }
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);

View File

@ -746,7 +746,7 @@ void DebuggerParser::executeCheat()
for(int arg = 0; arg < argCount; 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())
commandResult << "Cheat code " << cheat << " enabled" << endl;
else
@ -1043,6 +1043,34 @@ void DebuggerParser::executeJump()
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"
void DebuggerParser::executeListbreaks()
@ -1269,7 +1297,7 @@ void DebuggerParser::executeRunTo()
ostringstream buf;
buf << "RunTo searching through " << max_iterations << " disassembled instructions";
ProgressDialog progress(debugger->myBaseDialog,
debugger->getOSystem()->consoleFont(), buf.str());
debugger->myOSystem->consoleFont(), buf.str());
progress.setRange(0, max_iterations, 5);
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"
void DebuggerParser::executeUndef()
@ -1779,6 +1834,42 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = {
&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",
"List breakpoints",
@ -2058,6 +2149,15 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = {
&DebuggerParser::executeTrapwrite
},
{
"type",
"Show disassemly type for address xx",
true,
false,
{ kARG_WORD, kARG_END_ARGS },
&DebuggerParser::executeType
},
{
"undef",
"Undefine label xx (if defined)",

View File

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

View File

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

View File

@ -24,7 +24,7 @@
#include "TIA.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,

View File

@ -92,10 +92,6 @@ void CartridgeDPC::install(System& system)
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
access.type = System::PA_READWRITE;
for(uInt32 j = 0x1000; j < 0x1080; j += (1 << shift))
@ -422,10 +418,16 @@ bool CartridgeDPC::bank(uInt16 bank)
uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask();
// Setup the page access methods for the current bank
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);
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
access.directPeekBase = 0;
access.codeAccessBase = 0;
access.codeAccessBase = &myCodeAccessBase[8128];
access.type = System::PA_READ;
for(uInt32 j = (0x1FE0 & ~mask); j < 0x2000; j += (1 << shift))
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
memcpy(myImage, image, 16384);
createCodeAccessBase(16384 + 1024);
createCodeAccessBase(16384 + 2048);
// This cart can address a 1024 byte bank of RAM @ 0x1000
// and 256 bytes @ 0x1800
@ -79,7 +79,10 @@ void CartridgeE7::install(System& system)
// Set the page accessing methods for the hot spots
for(uInt32 i = (0x1FE0 & ~mask); i < 0x2000; i += (1 << shift))
{
access.codeAccessBase = &myCodeAccessBase[8128];
mySystem->setPageAccess(i >> shift, access);
}
// Setup the second segment to always point to the last ROM slice
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))
{
access.directPokeBase = &myRAM[1024 + offset + (j & 0x00FF)];
access.codeAccessBase = &myCodeAccessBase[8192 + 1024 + offset + (j & 0x00FF)];
mySystem->setPageAccess(j >> shift, access);
}
@ -188,7 +192,7 @@ void CartridgeE7::bankRAM(uInt16 bank)
for(uInt32 k = 0x1900; k < 0x1A00; k += (1 << shift))
{
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);
}
myBankChanged = true;
@ -225,6 +229,7 @@ bool CartridgeE7::bank(uInt16 slice)
for(uInt32 j = 0x1000; j < 0x1400; j += (1 << shift))
{
access.directPokeBase = &myRAM[j & 0x03FF];
access.codeAccessBase = &myCodeAccessBase[8192 + (j & 0x03FF)];
mySystem->setPageAccess(j >> shift, access);
}

View File

@ -51,17 +51,9 @@ void CartridgeEF::reset()
void CartridgeEF::install(System& 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
assert((0x1000 & mask) == 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);
assert((0x1000 & mySystem->pageMask()) == 0);
// Install pages for the startup bank
bank(myStartBank);
@ -102,10 +94,16 @@ bool CartridgeEF::bank(uInt16 bank)
uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask();
// Setup the page access methods for the current bank
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);
address += (1 << shift))
{

View File

@ -69,15 +69,12 @@ void CartridgeEFSC::install(System& system)
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
access.type = System::PA_WRITE;
for(uInt32 j = 0x1000; j < 0x1080; j += (1 << shift))
{
access.directPokeBase = &myRAM[j & 0x007F];
access.codeAccessBase = &myCodeAccessBase[j & 0x007F];
mySystem->setPageAccess(j >> shift, access);
}
@ -148,10 +145,16 @@ bool CartridgeEFSC::bank(uInt16 bank)
uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask();
// Setup the page access methods for the current bank
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);
address += (1 << shift))
{

View File

@ -52,17 +52,9 @@ void CartridgeF0::reset()
void CartridgeF0::install(System& 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
assert((0x1000 & mask) == 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);
assert((0x1000 & mySystem->pageMask()) == 0);
// Install pages for bank 1
myCurrentBank = 0;
@ -105,10 +97,16 @@ void CartridgeF0::incbank()
uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask();
// Setup the page access methods for the current bank
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);
address += (1 << shift))
{

View File

@ -52,17 +52,9 @@ void CartridgeF4::reset()
void CartridgeF4::install(System& 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
assert((0x1000 & mask) == 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);
assert((0x1000 & mySystem->pageMask()) == 0);
// Install pages for the startup bank
bank(myStartBank);
@ -107,10 +99,16 @@ bool CartridgeF4::bank(uInt16 bank)
uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask();
// Setup the page access methods for the current bank
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);
address += (1 << shift))
{

View File

@ -69,15 +69,12 @@ void CartridgeF4SC::install(System& system)
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
access.type = System::PA_WRITE;
for(uInt32 j = 0x1000; j < 0x1080; j += (1 << shift))
{
access.directPokeBase = &myRAM[j & 0x007F];
access.codeAccessBase = &myCodeAccessBase[j & 0x007F];
mySystem->setPageAccess(j >> shift, access);
}
@ -151,10 +148,16 @@ bool CartridgeF4SC::bank(uInt16 bank)
uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask();
// Setup the page access methods for the current bank
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);
address += (1 << shift))
{

View File

@ -51,17 +51,9 @@ void CartridgeF6::reset()
void CartridgeF6::install(System& 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
assert((0x1000 & mask) == 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);
assert((0x1000 & mySystem->pageMask()) == 0);
// Upon install we'll setup the startup bank
bank(myStartBank);
@ -147,10 +139,16 @@ bool CartridgeF6::bank(uInt16 bank)
uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask();
// Setup the page access methods for the current bank
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);
address += (1 << shift))
{

View File

@ -69,15 +69,12 @@ void CartridgeF6SC::install(System& system)
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
access.type = System::PA_WRITE;
for(uInt32 j = 0x1000; j < 0x1080; j += (1 << shift))
{
access.directPokeBase = &myRAM[j & 0x007F];
access.codeAccessBase = &myCodeAccessBase[j & 0x007F];
mySystem->setPageAccess(j >> shift, access);
}
@ -194,10 +191,16 @@ bool CartridgeF6SC::bank(uInt16 bank)
uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask();
// Setup the page access methods for the current bank
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);
address += (1 << shift))
{

View File

@ -58,17 +58,9 @@ void CartridgeF8::reset()
void CartridgeF8::install(System& 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
assert((0x1000 & mask) == 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);
assert((0x1000 & mySystem->pageMask()) == 0);
// Install pages for the startup bank
bank(myStartBank);
@ -134,10 +126,16 @@ bool CartridgeF8::bank(uInt16 bank)
uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask();
// Setup the page access methods for the current bank
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);
address += (1 << shift))
{

View File

@ -69,15 +69,12 @@ void CartridgeF8SC::install(System& system)
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
access.type = System::PA_WRITE;
for(uInt32 j = 0x1000; j < 0x1080; j += (1 << shift))
{
access.directPokeBase = &myRAM[j & 0x007F];
access.codeAccessBase = &myCodeAccessBase[j & 0x007F];
mySystem->setPageAccess(j >> shift, access);
}
@ -174,10 +171,16 @@ bool CartridgeF8SC::bank(uInt16 bank)
uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask();
// Setup the page access methods for the current bank
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);
address += (1 << shift))
{

View File

@ -69,15 +69,12 @@ void CartridgeFA::install(System& system)
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
access.type = System::PA_WRITE;
for(uInt32 j = 0x1000; j < 0x1100; j += (1 << shift))
{
access.directPokeBase = &myRAM[j & 0x00FF];
access.codeAccessBase = &myCodeAccessBase[j & 0x00FF];
mySystem->setPageAccess(j >> shift, access);
}
@ -184,10 +181,16 @@ bool CartridgeFA::bank(uInt16 bank)
uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask();
// Setup the page access methods for the current bank
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);
address += (1 << shift))
{

View File

@ -23,6 +23,23 @@
#ifdef DEBUGGER_SUPPORT
#include "Debugger.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
#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)
{
@ -170,7 +187,7 @@ inline uInt8 M6502::peek(uInt16 address, bool isCode)
}
#endif
uInt8 result = mySystem->peek(address, isCode);
uInt8 result = mySystem->peek(address, flags);
myLastAccessWasRead = true;
myLastPeekAddress = address;
return result;
@ -245,9 +262,10 @@ bool M6502::execute(uInt32 number)
myLastPeekAddress = myLastPokeAddress = 0;
// 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
if(PC >= 0xfafe && PC <= 0xfb10)
debugStream << ::hex << setw(2) << (int)A << " "
<< ::hex << setw(2) << (int)X << " "
<< ::hex << setw(2) << (int)Y << " "

View File

@ -211,11 +211,12 @@ class M6502 : public Serializable
find them itself.
@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
*/
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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@ -256,11 +256,12 @@ class System : public Serializable
the address.
@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
*/
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.
@ -290,11 +291,12 @@ class System : public Serializable
void unlockDataBus();
/**
Answer whether or not the given address has ever been used as
code. That is, it has ever been stored in either the IR or the PC,
or otherwise been executed.
Access and modify the disassembly type flags for the given
address. Note that while any flag can be used, the disassembly
only really acts on SKIP/CODE/GFX/DATA/ROW.
*/
bool isCode(uInt16 address);
uInt8 getAddressDisasmType(uInt16 address);
void setAddressDisasmType(uInt16 address, uInt8 flags);
public:
/**