mirror of https://github.com/stella-emu/stella.git
Beginning the process of more properly integrating Distella (and disassembly
in general) into the emulation core. For now, this means integrating the directive names into CartDebug, and having Distella using those same names. The new directive names were determined by discussion with Omegamatrix on AtariAge, and are listed in order of decreasing hierarchy: SKIP (the 'bit' trick to skip over sections of code) CODE (addresses accessible to the program counter) GFX (addresses where data is loaded into TIA GRPx registers) DATA (addresses referenced somewhere in the ROM) ROW (addresses never referenced at all) The next TODO item is to have the 6502 core set these values during emulation. This is currently (crudely) done with a true/false setting in System::peek, where true corresponds to CODE. This will be extended, so that false corresponds to DATA. Eventually GFX will also be detected, by watching writes to the TIA GRPx registers. Still to work out is how to detect SKIP sections. Anything not marked with one of the above directives will be marked as ROW, which essentially means ROM space that is never used. This will have the nice side effect of detecting dead ROM space, potentially leading to space optimizations. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2143 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
f51c16c54f
commit
fa3dc7cc38
|
@ -352,12 +352,6 @@ string CartDebug::disassemble(uInt16 start, uInt16 lines) const
|
|||
bool CartDebug::addDirective(CartDebug::DisasmType type,
|
||||
uInt16 start, uInt16 end, int bank)
|
||||
{
|
||||
#define PRINT_TAG(d) \
|
||||
cerr << (d.type == CartDebug::CODE ? "CODE" : \
|
||||
d.type == CartDebug::DATA ? "DATA" : \
|
||||
"GFX") \
|
||||
<< " " << hex << d.start << " - " << hex << d.end << endl;
|
||||
|
||||
#define PRINT_LIST(header) \
|
||||
cerr << header << endl; \
|
||||
for(DirectiveList::const_iterator d = list.begin(); d != list.end(); ++d) \
|
||||
|
@ -753,26 +747,32 @@ string CartDebug::loadConfigFile(string file)
|
|||
buf >> hex >> start;
|
||||
// TODO - figure out what to do with this
|
||||
}
|
||||
else if(BSPF_startsWithIgnoreCase(directive, "BLOCK"))
|
||||
else if(BSPF_startsWithIgnoreCase(directive, "SKIP"))
|
||||
{
|
||||
buf >> hex >> start;
|
||||
buf >> hex >> end;
|
||||
// addDirective(CartDebug::BLOCK, start, end, currentbank);
|
||||
// addDirective(CartDebug::SKIP, start, end, currentbank);
|
||||
}
|
||||
else if(BSPF_startsWithIgnoreCase(directive, "CODE"))
|
||||
{
|
||||
buf >> hex >> start >> hex >> end;
|
||||
addDirective(CartDebug::CODE, start, end, currentbank);
|
||||
}
|
||||
else if(BSPF_startsWithIgnoreCase(directive, "GFX"))
|
||||
{
|
||||
buf >> hex >> start >> hex >> end;
|
||||
addDirective(CartDebug::GFX, start, end, currentbank);
|
||||
}
|
||||
else if(BSPF_startsWithIgnoreCase(directive, "DATA"))
|
||||
{
|
||||
buf >> hex >> start >> hex >> end;
|
||||
addDirective(CartDebug::DATA, start, end, currentbank);
|
||||
}
|
||||
else if(BSPF_startsWithIgnoreCase(directive, "GFX"))
|
||||
else if(BSPF_startsWithIgnoreCase(directive, "ROW"))
|
||||
{
|
||||
buf >> hex >> start >> hex >> end;
|
||||
addDirective(CartDebug::GFX, start, end, currentbank);
|
||||
buf >> hex >> start;
|
||||
buf >> hex >> end;
|
||||
addDirective(CartDebug::ROW, start, end, currentbank);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1000,20 +1000,13 @@ void CartDebug::disasmTypeAsString(ostream& buf, DisasmType type) const
|
|||
{
|
||||
switch(type)
|
||||
{
|
||||
case CartDebug::BLOCK:
|
||||
buf << "BLOCK";
|
||||
break;
|
||||
case CartDebug::CODE:
|
||||
buf << "CODE";
|
||||
break;
|
||||
case CartDebug::DATA:
|
||||
buf << "DATA";
|
||||
break;
|
||||
case CartDebug::GFX:
|
||||
buf << "GFX";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case CartDebug::NONE: buf << "NONE"; break;
|
||||
case CartDebug::VALID: buf << "VALID"; break;
|
||||
case CartDebug::SKIP: buf << "SKIP"; break;
|
||||
case CartDebug::CODE: buf << "CODE"; break;
|
||||
case CartDebug::GFX: buf << "GFX"; break;
|
||||
case CartDebug::DATA: buf << "DATA"; break;
|
||||
case CartDebug::ROW: buf << "ROW"; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -54,11 +54,15 @@ class CartDebug : public DebuggerSystem
|
|||
|
||||
public:
|
||||
enum DisasmType {
|
||||
GFX = 1 << 0,
|
||||
DATA = 1 << 1,
|
||||
CODE = 1 << 2,
|
||||
BLOCK = 1 << 3,
|
||||
NONE = 1 << 4
|
||||
NONE = 0,
|
||||
VALID = 1 << 0, /* addresses that can have a label placed in front of it. A good counterexample
|
||||
would be "FF00: LDA $FE00"; $FF01 would be in the middle of a multi-byte
|
||||
instruction, and therefore cannot be labelled. */
|
||||
SKIP = 1 << 1, /* TODO - document this */
|
||||
CODE = 1 << 2, /* disassemble-able code segments */
|
||||
GFX = 1 << 3, /* addresses loaded into GRPx registers */
|
||||
DATA = 1 << 4, /* code somewhere in the program references it, i.e. LDA $F372 referenced $F372 */
|
||||
ROW = 1 << 5 /* all other addresses */
|
||||
};
|
||||
struct DisassemblyTag {
|
||||
DisasmType type;
|
||||
|
|
|
@ -100,13 +100,13 @@ DiStella::DiStella(const CartDebug& dbg, CartDebug::DisassemblyList& list,
|
|||
myPCBeg = myPC;
|
||||
myAddressQueue.pop();
|
||||
disasm(myPC, 1);
|
||||
for (uInt32 k = myPCBeg; k <= myPCEnd; k++)
|
||||
mark(k, REACHABLE);
|
||||
for (uInt16 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
|
||||
// If so, process the next one in the list that hasn't already
|
||||
// been marked as REACHABLE
|
||||
// been marked as CODE
|
||||
// If it *has* been marked, it can be removed from consideration
|
||||
// in all subsequent passes
|
||||
//
|
||||
|
@ -123,7 +123,7 @@ DiStella::DiStella(const CartDebug& dbg, CartDebug::DisassemblyList& list,
|
|||
while(it != addresses.end())
|
||||
{
|
||||
uInt16 addr = *it;
|
||||
if(!check_bit(labels[addr-myOffset], REACHABLE))
|
||||
if(!check_bit(labels[addr-myOffset], CartDebug::CODE))
|
||||
{
|
||||
cerr << "(list) marking " << HEX4 << addr << " as CODE\n";
|
||||
myAddressQueue.push(addr);
|
||||
|
@ -135,11 +135,11 @@ cerr << "(list) marking " << HEX4 << addr << " as CODE\n";
|
|||
}
|
||||
|
||||
// Stella itself can provide hints on whether an address has ever
|
||||
// been referenced as CODE
|
||||
// been referenced as CartDebug::CODE
|
||||
while(it == addresses.end() && codeAccessPoint <= myAppData.end)
|
||||
{
|
||||
if(Debugger::debugger().isCode(codeAccessPoint+myOffset) &&
|
||||
!check_bit(labels[codeAccessPoint], REACHABLE))
|
||||
!check_bit(labels[codeAccessPoint], CartDebug::CODE))
|
||||
{
|
||||
cerr << "(emul) marking " << HEX4 << (codeAccessPoint+myOffset) << " as CODE\n";
|
||||
myAddressQueue.push(codeAccessPoint+myOffset);
|
||||
|
@ -153,8 +153,8 @@ cerr << "(emul) marking " << HEX4 << (codeAccessPoint+myOffset) << " as CODE\n";
|
|||
|
||||
for (int k = 0; k <= myAppData.end; k++)
|
||||
{
|
||||
if (!check_bit(labels[k], REACHABLE))
|
||||
mark(k+myOffset, DATA);
|
||||
if (!check_bit(labels[k], CartDebug::CODE))
|
||||
mark(k+myOffset, CartDebug::ROW);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -189,14 +189,14 @@ void DiStella::disasm(uInt32 distart, int pass)
|
|||
myPC = distart - myOffset;
|
||||
while(myPC <= myAppData.end)
|
||||
{
|
||||
if(check_bit(labels[myPC], GFX))
|
||||
/* && !check_bit(labels[myPC], REACHABLE))*/
|
||||
if(check_bit(labels[myPC], CartDebug::GFX))
|
||||
/* && !check_bit(labels[myPC], CartDebug::CODE))*/
|
||||
{
|
||||
if (pass == 2)
|
||||
mark(myPC+myOffset,VALID_ENTRY);
|
||||
mark(myPC+myOffset, CartDebug::VALID);
|
||||
else if (pass == 3)
|
||||
{
|
||||
if (check_bit(labels[myPC],REFERENCED))
|
||||
if (check_bit(labels[myPC], CartDebug::DATA))
|
||||
myDisasmBuf << HEX4 << myPC+myOffset << "'L" << HEX4 << myPC+myOffset << "'";
|
||||
else
|
||||
myDisasmBuf << HEX4 << myPC+myOffset << "' '";
|
||||
|
@ -214,10 +214,10 @@ void DiStella::disasm(uInt32 distart, int pass)
|
|||
}
|
||||
myPC++;
|
||||
}
|
||||
else if (check_bit(labels[myPC], DATA) && !check_bit(labels[myPC], GFX))
|
||||
/* && !check_bit(labels[myPC],REACHABLE)) { */
|
||||
else if (check_bit(labels[myPC], CartDebug::ROW) && !check_bit(labels[myPC], CartDebug::GFX))
|
||||
/* && !check_bit(labels[myPC], CartDebug::CODE)) { */
|
||||
{
|
||||
mark(myPC+myOffset, VALID_ENTRY);
|
||||
mark(myPC+myOffset, CartDebug::VALID);
|
||||
if (pass == 3)
|
||||
{
|
||||
bytes = 1;
|
||||
|
@ -226,15 +226,15 @@ void DiStella::disasm(uInt32 distart, int pass)
|
|||
}
|
||||
myPC++;
|
||||
|
||||
while (check_bit(labels[myPC], DATA) && !check_bit(labels[myPC], REFERENCED)
|
||||
&& !check_bit(labels[myPC], GFX) && pass == 3 && myPC <= myAppData.end)
|
||||
while (check_bit(labels[myPC], CartDebug::ROW) && !check_bit(labels[myPC], CartDebug::DATA)
|
||||
&& !check_bit(labels[myPC], CartDebug::GFX) && pass == 3 && myPC <= myAppData.end)
|
||||
{
|
||||
if (pass == 3)
|
||||
{
|
||||
bytes++;
|
||||
if (bytes == 17)
|
||||
{
|
||||
addEntry(CartDebug::DATA);
|
||||
addEntry(CartDebug::ROW);
|
||||
myDisasmBuf << " ' '.byte $" << HEX2 << (int)Debugger::debugger().peek(myPC+myOffset);
|
||||
bytes = 1;
|
||||
}
|
||||
|
@ -246,7 +246,7 @@ void DiStella::disasm(uInt32 distart, int pass)
|
|||
|
||||
if (pass == 3)
|
||||
{
|
||||
addEntry(CartDebug::DATA);
|
||||
addEntry(CartDebug::ROW);
|
||||
myDisasmBuf << " ' ' ";
|
||||
addEntry(CartDebug::NONE);
|
||||
}
|
||||
|
@ -256,10 +256,10 @@ void DiStella::disasm(uInt32 distart, int pass)
|
|||
op = Debugger::debugger().peek(myPC+myOffset);
|
||||
/* version 2.1 bug fix */
|
||||
if (pass == 2)
|
||||
mark(myPC+myOffset, VALID_ENTRY);
|
||||
mark(myPC+myOffset, CartDebug::VALID);
|
||||
else if (pass == 3)
|
||||
{
|
||||
if (check_bit(labels[myPC], REFERENCED))
|
||||
if (check_bit(labels[myPC], CartDebug::DATA))
|
||||
myDisasmBuf << HEX4 << myPC+myOffset << "'L" << HEX4 << myPC+myOffset << "'";
|
||||
else
|
||||
myDisasmBuf << HEX4 << myPC+myOffset << "' '";
|
||||
|
@ -308,18 +308,18 @@ void DiStella::disasm(uInt32 distart, int pass)
|
|||
/* 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::DATA);
|
||||
addEntry(CartDebug::ROW);
|
||||
|
||||
if (myPC == myAppData.end)
|
||||
{
|
||||
if (check_bit(labels[myPC],REFERENCED))
|
||||
if (check_bit(labels[myPC], CartDebug::DATA))
|
||||
myDisasmBuf << HEX4 << myPC+myOffset << "'L" << HEX4 << myPC+myOffset << "'";
|
||||
else
|
||||
myDisasmBuf << HEX4 << myPC+myOffset << "' '";
|
||||
|
||||
op = Debugger::debugger().peek(myPC+myOffset); myPC++;
|
||||
myDisasmBuf << ".byte $" << HEX2 << (int)op;
|
||||
addEntry(CartDebug::DATA);
|
||||
addEntry(CartDebug::ROW);
|
||||
}
|
||||
}
|
||||
myPCEnd = myAppData.end + myOffset;
|
||||
|
@ -339,7 +339,7 @@ void DiStella::disasm(uInt32 distart, int pass)
|
|||
/* Line information is already printed, but we can remove the
|
||||
Instruction (i.e. BMI) by simply clearing the buffer to print */
|
||||
myDisasmBuf << ".byte $" << HEX2 << (int)op;
|
||||
addEntry(CartDebug::DATA);
|
||||
addEntry(CartDebug::ROW);
|
||||
nextline.str("");
|
||||
nextlinebytes.str("");
|
||||
}
|
||||
|
@ -376,15 +376,15 @@ void DiStella::disasm(uInt32 distart, int pass)
|
|||
case ABSOLUTE:
|
||||
{
|
||||
ad = Debugger::debugger().dpeek(myPC+myOffset); myPC+=2;
|
||||
labfound = mark(ad, REFERENCED);
|
||||
labfound = mark(ad, CartDebug::DATA);
|
||||
if (pass == 1)
|
||||
{
|
||||
if ((addbranch) && !check_bit(labels[ad & myAppData.end], REACHABLE))
|
||||
if ((addbranch) && !check_bit(labels[ad & myAppData.end], CartDebug::CODE))
|
||||
{
|
||||
if (ad > 0xfff)
|
||||
myAddressQueue.push((ad & myAppData.end) + myOffset);
|
||||
|
||||
mark(ad, REACHABLE);
|
||||
mark(ad, CartDebug::CODE);
|
||||
}
|
||||
}
|
||||
else if (pass == 3)
|
||||
|
@ -422,7 +422,7 @@ void DiStella::disasm(uInt32 distart, int pass)
|
|||
case ZERO_PAGE:
|
||||
{
|
||||
d1 = Debugger::debugger().peek(myPC+myOffset); myPC++;
|
||||
labfound = mark(d1, REFERENCED);
|
||||
labfound = mark(d1, CartDebug::DATA);
|
||||
if (pass == 3)
|
||||
{
|
||||
if (labfound == 2)
|
||||
|
@ -450,7 +450,7 @@ void DiStella::disasm(uInt32 distart, int pass)
|
|||
case ABSOLUTE_X:
|
||||
{
|
||||
ad = Debugger::debugger().dpeek(myPC+myOffset); myPC+=2;
|
||||
labfound = mark(ad, REFERENCED);
|
||||
labfound = mark(ad, CartDebug::DATA);
|
||||
if (pass == 3)
|
||||
{
|
||||
if (ad < 0x100)
|
||||
|
@ -486,7 +486,7 @@ void DiStella::disasm(uInt32 distart, int pass)
|
|||
case ABSOLUTE_Y:
|
||||
{
|
||||
ad = Debugger::debugger().dpeek(myPC+myOffset); myPC+=2;
|
||||
labfound = mark(ad, REFERENCED);
|
||||
labfound = mark(ad, CartDebug::DATA);
|
||||
if (pass == 3)
|
||||
{
|
||||
if (ad < 0x100)
|
||||
|
@ -544,7 +544,7 @@ void DiStella::disasm(uInt32 distart, int pass)
|
|||
case ZERO_PAGE_X:
|
||||
{
|
||||
d1 = Debugger::debugger().peek(myPC+myOffset); myPC++;
|
||||
labfound = mark(d1, REFERENCED);
|
||||
labfound = mark(d1, CartDebug::DATA);
|
||||
if (pass == 3)
|
||||
{
|
||||
if (labfound == 2)
|
||||
|
@ -561,7 +561,7 @@ void DiStella::disasm(uInt32 distart, int pass)
|
|||
case ZERO_PAGE_Y:
|
||||
{
|
||||
d1 = Debugger::debugger().peek(myPC+myOffset); myPC++;
|
||||
labfound = mark(d1,REFERENCED);
|
||||
labfound = mark(d1, CartDebug::DATA);
|
||||
if (pass == 3)
|
||||
{
|
||||
if (labfound == 2)
|
||||
|
@ -583,13 +583,13 @@ void DiStella::disasm(uInt32 distart, int pass)
|
|||
d1 = Debugger::debugger().peek(myPC+myOffset); myPC++;
|
||||
ad = ((myPC + (Int8)d1) & 0xfff) + myOffset;
|
||||
|
||||
labfound = mark(ad, REFERENCED);
|
||||
labfound = mark(ad, CartDebug::DATA);
|
||||
if (pass == 1)
|
||||
{
|
||||
if ((addbranch) && !check_bit(labels[ad-myOffset], REACHABLE))
|
||||
if ((addbranch) && !check_bit(labels[ad-myOffset], CartDebug::CODE))
|
||||
{
|
||||
myAddressQueue.push(ad);
|
||||
mark(ad, REACHABLE);
|
||||
mark(ad, CartDebug::CODE);
|
||||
}
|
||||
}
|
||||
else if (pass == 3)
|
||||
|
@ -609,7 +609,7 @@ void DiStella::disasm(uInt32 distart, int pass)
|
|||
case ABS_INDIRECT:
|
||||
{
|
||||
ad = Debugger::debugger().dpeek(myPC+myOffset); myPC+=2;
|
||||
labfound = mark(ad, REFERENCED);
|
||||
labfound = mark(ad, CartDebug::DATA);
|
||||
if (pass == 3)
|
||||
{
|
||||
if (ad < 0x100)
|
||||
|
@ -666,7 +666,7 @@ void DiStella::disasm(uInt32 distart, int pass)
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
int DiStella::mark(uInt32 address, MarkType bit)
|
||||
int DiStella::mark(uInt16 address, uInt8 bit)
|
||||
{
|
||||
/*-----------------------------------------------------------------------
|
||||
For any given offset and code range...
|
||||
|
@ -695,21 +695,21 @@ int DiStella::mark(uInt32 address, MarkType bit)
|
|||
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 = CODE/DATA, mark the code/data array for the mirrored address
|
||||
$1000-$1FFF = CartDebug::CODE/CartDebug::ROW, mark the code/data array for the mirrored address
|
||||
with the appropriate bit; return 4.
|
||||
$3000-$3FFF = CODE/DATA, mark the code/data array for the mirrored address
|
||||
$3000-$3FFF = CartDebug::CODE/CartDebug::ROW, mark the code/data array for the mirrored address
|
||||
with the appropriate bit; return 4.
|
||||
$5000-$5FFF = CODE/DATA, mark the code/data array for the mirrored address
|
||||
$5000-$5FFF = CartDebug::CODE/CartDebug::ROW, mark the code/data array for the mirrored address
|
||||
with the appropriate bit; return 4.
|
||||
$7000-$7FFF = CODE/DATA, mark the code/data array for the mirrored address
|
||||
$7000-$7FFF = CartDebug::CODE/CartDebug::ROW, mark the code/data array for the mirrored address
|
||||
with the appropriate bit; return 4.
|
||||
$9000-$9FFF = CODE/DATA, mark the code/data array for the mirrored address
|
||||
$9000-$9FFF = CartDebug::CODE/CartDebug::ROW, mark the code/data array for the mirrored address
|
||||
with the appropriate bit; return 4.
|
||||
$B000-$BFFF = CODE/DATA, mark the code/data array for the mirrored address
|
||||
$B000-$BFFF = CartDebug::CODE/CartDebug::ROW, mark the code/data array for the mirrored address
|
||||
with the appropriate bit; return 4.
|
||||
$D000-$DFFF = CODE/DATA, mark the code/data array for the mirrored address
|
||||
$D000-$DFFF = CartDebug::CODE/CartDebug::ROW, mark the code/data array for the mirrored address
|
||||
with the appropriate bit; return 4.
|
||||
$F000-$FFFF = CODE/DATA, mark the code/data array for the address
|
||||
$F000-$FFFF = CartDebug::CODE/CartDebug::ROW, mark the code/data array for the address
|
||||
with the appropriate bit; return 1.
|
||||
Anything else = invalid, return 0.
|
||||
===========================================================
|
||||
|
@ -739,7 +739,7 @@ int DiStella::mark(uInt32 address, MarkType bit)
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool DiStella::check_range(uInt32 beg, uInt32 end)
|
||||
bool DiStella::check_range(uInt16 beg, uInt16 end) const
|
||||
{
|
||||
if(beg > end)
|
||||
{
|
||||
|
@ -806,22 +806,25 @@ void DiStella::addEntry(CartDebug::DisasmType type)
|
|||
myDisasmBuf.seekg(11, ios::beg);
|
||||
switch(tag.type)
|
||||
{
|
||||
case CartDebug::BLOCK:
|
||||
// TODO - handle this
|
||||
case CartDebug::SKIP: // TODO - handle this
|
||||
tag.disasm = " ";
|
||||
break;
|
||||
case CartDebug::CODE:
|
||||
getline(myDisasmBuf, tag.disasm, '\'');
|
||||
getline(myDisasmBuf, tag.ccount, '\'');
|
||||
getline(myDisasmBuf, tag.bytes);
|
||||
break;
|
||||
case CartDebug::DATA:
|
||||
getline(myDisasmBuf, tag.disasm);
|
||||
break;
|
||||
case CartDebug::GFX:
|
||||
getline(myDisasmBuf, tag.disasm, '\'');
|
||||
getline(myDisasmBuf, tag.bytes);
|
||||
break;
|
||||
case CartDebug::NONE:
|
||||
case CartDebug::DATA: // TODO - handle this
|
||||
tag.disasm = " ";
|
||||
break;
|
||||
case CartDebug::ROW:
|
||||
getline(myDisasmBuf, tag.disasm);
|
||||
break;
|
||||
default: // should never happen
|
||||
tag.disasm = " ";
|
||||
break;
|
||||
}
|
||||
|
@ -833,8 +836,8 @@ DONE_WITH_ADD:
|
|||
|
||||
#if 0
|
||||
// debugging output
|
||||
cerr << (tag.type == CartDebug::CODE ? "CODE" : (tag.type == CartDebug::DATA ? "DATA" :
|
||||
(tag.type == CartDebug::GFX ? "GFX " : "NONE"))) << "|"
|
||||
cerr << (tag.type == CartDebug::CODE ? "CartDebug::CODE" : (tag.type == CartDebug::ROW ? "CartDebug::ROW" :
|
||||
(tag.type == CartDebug::GFX ? "CartDebug::GFX " : "NONE"))) << "|"
|
||||
<< hex << setw(4) << setfill('0') << tag.address << "|"
|
||||
<< tag.label << "|" << tag.disasm << "|" << tag.ccount << "|" << "|"
|
||||
<< tag.bytes << endl;
|
||||
|
@ -850,25 +853,8 @@ void DiStella::processDirectives(const CartDebug::DirectiveList& directives)
|
|||
{
|
||||
const CartDebug::DirectiveTag tag = *i;
|
||||
if(check_range(tag.start, tag.end))
|
||||
{
|
||||
MarkType type;
|
||||
switch(tag.type)
|
||||
{
|
||||
case CartDebug::DATA :
|
||||
type = DATA;
|
||||
break;
|
||||
case CartDebug::GFX :
|
||||
type = GFX;
|
||||
break;
|
||||
case CartDebug::CODE :
|
||||
type = REACHABLE;
|
||||
break;
|
||||
default:
|
||||
continue; // skip this tag
|
||||
}
|
||||
for(uInt32 k = tag.start; k <= tag.end; ++k)
|
||||
mark(k, type);
|
||||
}
|
||||
for(uInt16 k = tag.start; k <= tag.end; ++k)
|
||||
mark(k, tag.type);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -67,18 +67,10 @@ class DiStella
|
|||
static Settings settings;
|
||||
|
||||
private:
|
||||
// TODO - place this comment whereever the array is located
|
||||
// Marked bits
|
||||
// This is a reference sheet of bits that can be set for a given address, which
|
||||
// are stored in the labels[] array.
|
||||
enum MarkType {
|
||||
REFERENCED = 1 << 0, /* code somewhere in the program references it, i.e. LDA $F372 referenced $F372 */
|
||||
VALID_ENTRY = 1 << 1, /* addresses that can have a label placed in front of it. A good counterexample
|
||||
would be "FF00: LDA $FE00"; $FF01 would be in the middle of a multi-byte
|
||||
instruction, and therefore cannot be labelled. */
|
||||
DATA = 1 << 2,
|
||||
GFX = 1 << 3,
|
||||
REACHABLE = 1 << 4 /* disassemble-able code segments */
|
||||
};
|
||||
|
||||
// Indicate that a new line of disassembly has been completed
|
||||
// In the original Distella code, this indicated a new line to be printed
|
||||
|
@ -91,9 +83,9 @@ class DiStella
|
|||
|
||||
// These functions are part of the original Distella code
|
||||
void disasm(uInt32 distart, int pass);
|
||||
int mark(uInt32 address, MarkType bit);
|
||||
bool check_range(uInt32 start, uInt32 end);
|
||||
inline int check_bit(uInt8 bitflags, int i) const { return (bitflags & i); }
|
||||
int mark(uInt16 address, uInt8 bit);
|
||||
bool check_range(uInt16 start, uInt16 end) const;
|
||||
inline uInt8 check_bit(uInt8 bitflags, uInt8 i) const { return (bitflags & i); }
|
||||
|
||||
private:
|
||||
const CartDebug& myDbg;
|
||||
|
|
|
@ -387,11 +387,11 @@ bool M6502::load(Serializer& in)
|
|||
if(in.getString() != CPU)
|
||||
return false;
|
||||
|
||||
A = (uInt8) in.getByte(); // Accumulator
|
||||
X = (uInt8) in.getByte(); // X index register
|
||||
Y = (uInt8) in.getByte(); // Y index register
|
||||
SP = (uInt8) in.getByte(); // Stack Pointer
|
||||
IR = (uInt8) in.getByte(); // Instruction register
|
||||
A = (uInt8) in.getByte(); // Accumulator
|
||||
X = (uInt8) in.getByte(); // X index register
|
||||
Y = (uInt8) in.getByte(); // Y index register
|
||||
SP = (uInt8) in.getByte(); // Stack Pointer
|
||||
IR = (uInt8) in.getByte(); // Instruction register
|
||||
PC = (uInt16) in.getInt(); // Program Counter
|
||||
|
||||
N = in.getBool(); // N flag for processor status register
|
||||
|
|
Loading…
Reference in New Issue