add detection of audio data in DiStella (see #596)

This commit is contained in:
thrust26 2020-03-29 10:51:16 +02:00
parent c09b6167a1
commit 09fb69f397
9 changed files with 223 additions and 150 deletions

View File

@ -22,7 +22,7 @@
* Added displaying last write address in debugger. (TOOD: Doc) * Added displaying last write address in debugger. (TOOD: Doc)
* Added detection of color data in DiStella. (TOOD: Doc) * Added detection of color and audio data in DiStella. (TOOD: Doc)
6.0.2 to 6.1: (March 22, 2020) 6.0.2 to 6.1: (March 22, 2020)

View File

@ -916,6 +916,11 @@ string CartDebug::loadConfigFile()
buf >> hex >> start >> hex >> end; buf >> hex >> start >> hex >> end;
addDirective(Device::BCOL, start, end, currentbank); addDirective(Device::BCOL, start, end, currentbank);
} }
else if(BSPF::startsWithIgnoreCase(directive, "Device::AUD"))
{
buf >> hex >> start >> hex >> end;
addDirective(Device::AUD, start, end, currentbank);
}
else if(BSPF::startsWithIgnoreCase(directive, "Device::DATA")) else if(BSPF::startsWithIgnoreCase(directive, "Device::DATA"))
{ {
buf >> hex >> start >> hex >> end; buf >> hex >> start >> hex >> end;
@ -1070,57 +1075,54 @@ string CartDebug::saveDisassembly()
switch(tag.type) switch(tag.type)
{ {
case Device::CODE: case Device::CODE:
{
buf << ALIGN(32) << tag.disasm << tag.ccount.substr(0, 5) << tag.ctotal << tag.ccount.substr(5, 2); buf << ALIGN(32) << tag.disasm << tag.ccount.substr(0, 5) << tag.ctotal << tag.ccount.substr(5, 2);
if (tag.disasm.find("WSYNC") != std::string::npos) if (tag.disasm.find("WSYNC") != std::string::npos)
buf << "\n;---------------------------------------"; buf << "\n;---------------------------------------";
break; break;
}
case Device::ROW: case Device::ROW:
{
buf << ".byte " << ALIGN(32) << tag.disasm.substr(6, 8*4-1) << "; $" << Base::HEX4 << tag.address << " (*)"; buf << ".byte " << ALIGN(32) << tag.disasm.substr(6, 8*4-1) << "; $" << Base::HEX4 << tag.address << " (*)";
break; break;
}
case Device::GFX: case Device::GFX:
{
buf << ".byte " << (settings.gfxFormat == Base::Fmt::_2 ? "%" : "$") buf << ".byte " << (settings.gfxFormat == Base::Fmt::_2 ? "%" : "$")
<< tag.bytes << " ; |"; << tag.bytes << " ; |";
for(int c = 12; c < 20; ++c) for(int c = 12; c < 20; ++c)
buf << ((tag.disasm[c] == '\x1e') ? "#" : " "); buf << ((tag.disasm[c] == '\x1e') ? "#" : " ");
buf << ALIGN(13) << "|" << "$" << Base::HEX4 << tag.address << " (G)"; buf << ALIGN(13) << "|" << "$" << Base::HEX4 << tag.address << " (G)";
break; break;
}
case Device::PGFX: case Device::PGFX:
{
buf << ".byte " << (settings.gfxFormat == Base::Fmt::_2 ? "%" : "$") buf << ".byte " << (settings.gfxFormat == Base::Fmt::_2 ? "%" : "$")
<< tag.bytes << " ; |"; << tag.bytes << " ; |";
for(int c = 12; c < 20; ++c) for(int c = 12; c < 20; ++c)
buf << ((tag.disasm[c] == '\x1f') ? "*" : " "); buf << ((tag.disasm[c] == '\x1f') ? "*" : " ");
buf << ALIGN(13) << "|" << "$" << Base::HEX4 << tag.address << " (P)"; buf << ALIGN(13) << "|" << "$" << Base::HEX4 << tag.address << " (P)";
break; break;
}
case Device::COL: case Device::COL:
buf << ".byte " << ALIGN(32) << tag.disasm.substr(6, 12) << "; $" << Base::HEX4 << tag.address << " (Px)"; buf << ".byte " << ALIGN(32) << tag.disasm.substr(6, 12) << "; $" << Base::HEX4 << tag.address << " (C)";
break; break;
case Device::PCOL: case Device::PCOL:
buf << ".byte " << ALIGN(32) << tag.disasm.substr(6, 12) << "; $" << Base::HEX4 << tag.address << " (PF)"; buf << ".byte " << ALIGN(32) << tag.disasm.substr(6, 12) << "; $" << Base::HEX4 << tag.address << " (CP)";
break; break;
case Device::BCOL: case Device::BCOL:
buf << ".byte " << ALIGN(32) << tag.disasm.substr(6, 12) << "; $" << Base::HEX4 << tag.address << " (BK)"; buf << ".byte " << ALIGN(32) << tag.disasm.substr(6, 12) << "; $" << Base::HEX4 << tag.address << " (CB)";
break;
case Device::AUD:
buf << ".byte " << ALIGN(32) << tag.disasm.substr(6, 8 * 4 - 1) << "; $" << Base::HEX4 << tag.address << " (A)";
break; break;
case Device::DATA: case Device::DATA:
{
buf << ".byte " << ALIGN(32) << tag.disasm.substr(6, 8 * 4 - 1) << "; $" << Base::HEX4 << tag.address << " (D)"; buf << ".byte " << ALIGN(32) << tag.disasm.substr(6, 8 * 4 - 1) << "; $" << Base::HEX4 << tag.address << " (D)";
break; break;
}
case Device::NONE: case Device::NONE:
default: default:
{
break; break;
}
} // switch } // switch
buf << "\n"; buf << "\n";
} }
@ -1134,14 +1136,18 @@ string CartDebug::saveDisassembly()
<< "; ROM properties name : " << myConsole.properties().get(PropType::Cart_Name) << "\n" << "; ROM properties name : " << myConsole.properties().get(PropType::Cart_Name) << "\n"
<< "; ROM properties MD5 : " << myConsole.properties().get(PropType::Cart_MD5) << "\n" << "; ROM properties MD5 : " << myConsole.properties().get(PropType::Cart_MD5) << "\n"
<< "; Bankswitch type : " << myConsole.cartridge().about() << "\n;\n" << "; Bankswitch type : " << myConsole.cartridge().about() << "\n;\n"
<< "; Legend: * = Device::CODE not yet run (tentative code)\n" << "; Legend: * = Device::CODE not yet run (tentative code)\n"
<< "; D = Device::DATA directive (referenced in some way)\n" << "; D = Device::DATA directive (referenced in some way)\n"
<< "; G = Device::GFX directive, shown as '#' (stored in player, missile, ball)\n" << "; G = Device::GFX directive, shown as '#' (stored in player, missile, ball)\n"
<< "; P = Device::PGFX directive, shown as '*' (stored in playfield)\n" << "; P = Device::PGFX directive, shown as '*' (stored in playfield)\n"
<< "; i = indexed accessed only\n" << "; C = Device::COL directive, shown as '*' (stored in player color)\n"
<< "; c = used by code executed in RAM\n" << "; CP = Device::PCOL directive, shown as '*' (stored in playfield color)\n"
<< "; s = used by stack\n" << "; CB = Device::BCOL directive, shown as '*' (stored in background color)\n"
<< "; ! = page crossed, 1 cycle penalty\n" << "; A = Device::AUD directive, shown as '*' (stored in audio registers)\n"
<< "; i = indexed accessed only\n"
<< "; c = used by code executed in RAM\n"
<< "; s = used by stack\n"
<< "; ! = page crossed, 1 cycle penalty\n"
<< "\n processor 6502\n\n"; << "\n processor 6502\n\n";
out << "\n;-----------------------------------------------------------\n" out << "\n;-----------------------------------------------------------\n"
@ -1478,6 +1484,8 @@ Device::AccessType CartDebug::accessTypeAbsolute(Device::AccessFlags flags) cons
return Device::PCOL; return Device::PCOL;
else if(flags & Device::BCOL) else if(flags & Device::BCOL)
return Device::BCOL; return Device::BCOL;
else if(flags & Device::AUD)
return Device::AUD;
else if(flags & Device::DATA) else if(flags & Device::DATA)
return Device::DATA; return Device::DATA;
else if(flags & Device::ROW) else if(flags & Device::ROW)
@ -1498,6 +1506,7 @@ void CartDebug::AccessTypeAsString(ostream& buf, Device::AccessType type) const
case Device::COL: buf << "Device::COL"; break; case Device::COL: buf << "Device::COL"; break;
case Device::PCOL: buf << "Device::PCOL"; break; case Device::PCOL: buf << "Device::PCOL"; break;
case Device::BCOL: buf << "Device::BCOL"; break; case Device::BCOL: buf << "Device::BCOL"; break;
case Device::AUD: buf << "Device::AUD"; break;
case Device::DATA: buf << "Device::DATA"; break; case Device::DATA: buf << "Device::DATA"; break;
case Device::ROW: buf << "Device::ROW"; break; case Device::ROW: buf << "Device::ROW"; break;
case Device::REFERENCED: case Device::REFERENCED:
@ -1525,6 +1534,8 @@ void CartDebug::AccessTypeAsString(ostream& buf, Device::AccessFlags flags) cons
buf << "Device::PCOL "; buf << "Device::PCOL ";
if(flags & Device::BCOL) if(flags & Device::BCOL)
buf << "Device::BCOL "; buf << "Device::BCOL ";
if(flags & Device::AUD)
buf << "Device::AUD ";
if(flags & Device::DATA) if(flags & Device::DATA)
buf << "Device::DATA "; buf << "Device::DATA ";
if(flags & Device::ROW) if(flags & Device::ROW)

View File

@ -142,7 +142,7 @@ class CartDebug : public DebuggerSystem
things can't be automatically determined. For now, these directives things can't be automatically determined. For now, these directives
have exactly the same syntax as in a distella configuration file. have exactly the same syntax as in a distella configuration file.
@param type Currently, CODE/DATA/GFX are supported @param type Currently, CODE/DATA/GFX/PGFX/COL/PCOL/BCOL/AUD/ROW are supported
@param start The start address (inclusive) to mark with the given type @param start The start address (inclusive) to mark with the given type
@param end The end address (inclusive) to mark with the given type @param end The end address (inclusive) to mark with the given type
@param bank Bank to which these directive apply (0 indicated current bank) @param bank Bank to which these directive apply (0 indicated current bank)

View File

@ -117,57 +117,73 @@ void DiStella::disasm(uInt32 distart, int pass)
/* pc=myAppData.start; */ /* pc=myAppData.start; */
myPC = distart - myOffset; myPC = distart - myOffset;
while (myPC <= myAppData.end) { while(myPC <= myAppData.end)
{
// since -1 is used in m6502.m4 for clearing the last peek // since -1 is used in m6502.m4 for clearing the last peek
// and this results into an access at e.g. 0xffff, // and this results into an access at e.g. 0xffff,
// we have to fix the consequences here (ugly!). // we have to fix the consequences here (ugly!).
if(myPC == myAppData.end) if(myPC == myAppData.end)
goto FIX_LAST; goto FIX_LAST;
if (checkBits(myPC, Device::GFX | Device::PGFX, if(checkBits(myPC, Device::GFX | Device::PGFX,
Device::CODE)) Device::CODE))
{ {
if (pass == 2) if(pass == 2)
mark(myPC + myOffset, Device::VALID_ENTRY); mark(myPC + myOffset, Device::VALID_ENTRY);
if (pass == 3) if(pass == 3)
outputGraphics(); outputGraphics();
++myPC; ++myPC;
} else if (checkBits(myPC, Device::COL | Device::PCOL | Device::BCOL, }
Device::CODE | Device::GFX | Device::PGFX)) else if(checkBits(myPC, Device::COL | Device::PCOL | Device::BCOL,
Device::CODE | Device::GFX | Device::PGFX))
{ {
if (pass == 2) if(pass == 2)
mark(myPC + myOffset, Device::VALID_ENTRY); mark(myPC + myOffset, Device::VALID_ENTRY);
if (pass == 3) if(pass == 3)
outputColors(); outputColors();
++myPC; ++myPC;
} else if (checkBits(myPC, Device::DATA, }
Device::CODE | Device::GFX | Device::PGFX | else if(checkBits(myPC, Device::AUD,
Device::COL | Device::PCOL | Device::BCOL)) Device::CODE | Device::GFX | Device::PGFX |
Device::COL | Device::PCOL | Device::BCOL))
{ {
if (pass == 2) if(pass == 2)
mark(myPC + myOffset, Device::VALID_ENTRY); mark(myPC + myOffset, Device::VALID_ENTRY);
if (pass == 3) if(pass == 3)
outputBytes(Device::AUD);
else
++myPC;
}
else if(checkBits(myPC, Device::DATA,
Device::CODE | Device::GFX | Device::PGFX |
Device::COL | Device::PCOL | Device::BCOL |
Device::AUD))
{
if(pass == 2)
mark(myPC + myOffset, Device::VALID_ENTRY);
if(pass == 3)
outputBytes(Device::DATA); outputBytes(Device::DATA);
else else
++myPC; ++myPC;
} else if (checkBits(myPC, Device::ROW, }
Device::CODE | else if(checkBits(myPC, Device::ROW,
Device::DATA | Device::GFX | Device::PGFX | Device::CODE | Device::GFX | Device::PGFX |
Device::COL | Device::PCOL | Device::BCOL)) { Device::COL | Device::PCOL | Device::BCOL |
FIX_LAST: Device::AUD | Device::DATA)) {
if (pass == 2) FIX_LAST:
if(pass == 2)
mark(myPC + myOffset, Device::VALID_ENTRY); mark(myPC + myOffset, Device::VALID_ENTRY);
if (pass == 3) if(pass == 3)
outputBytes(Device::ROW); outputBytes(Device::ROW);
else else
++myPC; ++myPC;
} else { }
// The following sections must be CODE else {
// The following sections must be CODE
// add extra spacing line when switching from non-code to code // add extra spacing line when switching from non-code to code
if (pass == 3 && mySegType != Device::CODE && mySegType != Device::NONE) { if(pass == 3 && mySegType != Device::CODE && mySegType != Device::NONE) {
myDisasmBuf << " ' ' "; myDisasmBuf << " ' ' ";
addEntry(Device::NONE); addEntry(Device::NONE);
mark(myPC + myOffset, Device::REFERENCED); // add label when switching mark(myPC + myOffset, Device::REFERENCED); // add label when switching
@ -175,7 +191,7 @@ FIX_LAST:
mySegType = Device::CODE; mySegType = Device::CODE;
/* version 2.1 bug fix */ /* version 2.1 bug fix */
if (pass == 2) if(pass == 2)
mark(myPC + myOffset, Device::VALID_ENTRY); mark(myPC + myOffset, Device::VALID_ENTRY);
// get opcode // get opcode
@ -183,8 +199,8 @@ FIX_LAST:
// get address mode for opcode // get address mode for opcode
addrMode = ourLookup[opcode].addr_mode; addrMode = ourLookup[opcode].addr_mode;
if (pass == 3) { if(pass == 3) {
if (checkBit(myPC, Device::REFERENCED)) if(checkBit(myPC, Device::REFERENCED))
myDisasmBuf << Base::HEX4 << myPC + myOffset << "'L" << Base::HEX4 << myPC + myOffset << "'"; myDisasmBuf << Base::HEX4 << myPC + myOffset << "'L" << Base::HEX4 << myPC + myOffset << "'";
else else
myDisasmBuf << Base::HEX4 << myPC + myOffset << "' '"; myDisasmBuf << Base::HEX4 << myPC + myOffset << "' '";
@ -193,16 +209,16 @@ FIX_LAST:
// detect labels inside instructions (e.g. BIT masks) // detect labels inside instructions (e.g. BIT masks)
labelFound = AddressType::INVALID; labelFound = AddressType::INVALID;
for (Uint8 i = 0; i < ourLookup[opcode].bytes - 1; i++) { for(Uint8 i = 0; i < ourLookup[opcode].bytes - 1; i++) {
if (checkBit(myPC + i, Device::REFERENCED)) { if(checkBit(myPC + i, Device::REFERENCED)) {
labelFound = AddressType::ROM; labelFound = AddressType::ROM;
break; break;
} }
} }
if (labelFound != AddressType::INVALID) { if(labelFound != AddressType::INVALID) {
if (myOffset >= 0x1000) { if(myOffset >= 0x1000) {
// the opcode's operand address matches a label address // the opcode's operand address matches a label address
if (pass == 3) { if(pass == 3) {
// output the byte of the opcode incl. cycles // output the byte of the opcode incl. cycles
Uint8 nextOpcode = Debugger::debugger().peek(myPC + myOffset); Uint8 nextOpcode = Debugger::debugger().peek(myPC + myOffset);
@ -221,8 +237,9 @@ FIX_LAST:
} }
// continue with the label's opcode // continue with the label's opcode
continue; continue;
} else { }
if (pass == 3) { else {
if(pass == 3) {
// TODO // TODO
} }
} }
@ -230,18 +247,18 @@ FIX_LAST:
// Undefined opcodes start with a '.' // Undefined opcodes start with a '.'
// These are undefined wrt DASM // These are undefined wrt DASM
if (ourLookup[opcode].mnemonic[0] == '.' && pass == 3) { if(ourLookup[opcode].mnemonic[0] == '.' && pass == 3) {
nextLine << ".byte $" << Base::HEX2 << int(opcode) << " ;"; nextLine << ".byte $" << Base::HEX2 << int(opcode) << " ;";
} }
if (pass == 3) { if(pass == 3) {
nextLine << ourLookup[opcode].mnemonic; nextLine << ourLookup[opcode].mnemonic;
nextLineBytes << Base::HEX2 << int(opcode) << " "; nextLineBytes << Base::HEX2 << int(opcode) << " ";
} }
// Add operand(s) for PC values outside the app data range // Add operand(s) for PC values outside the app data range
if (myPC >= myAppData.end) { if(myPC >= myAppData.end) {
switch (addrMode) { switch(addrMode) {
case AddressingMode::ABSOLUTE: case AddressingMode::ABSOLUTE:
case AddressingMode::ABSOLUTE_X: case AddressingMode::ABSOLUTE_X:
case AddressingMode::ABSOLUTE_Y: case AddressingMode::ABSOLUTE_Y:
@ -249,7 +266,7 @@ FIX_LAST:
case AddressingMode::INDIRECT_Y: case AddressingMode::INDIRECT_Y:
case AddressingMode::ABS_INDIRECT: case AddressingMode::ABS_INDIRECT:
{ {
if (pass == 3) { if(pass == 3) {
/* Line information is already printed; append .byte since last /* Line information is already printed; append .byte since last
instruction will put recompilable object larger that original instruction will put recompilable object larger that original
binary file */ binary file */
@ -258,8 +275,8 @@ FIX_LAST:
<< Base::HEX2 << int(opcode); << Base::HEX2 << int(opcode);
addEntry(Device::DATA); addEntry(Device::DATA);
if (myPC == myAppData.end) { if(myPC == myAppData.end) {
if (checkBit(myPC, Device::REFERENCED)) if(checkBit(myPC, Device::REFERENCED))
myDisasmBuf << Base::HEX4 << myPC + myOffset << "'L" << Base::HEX4 << myPC + myOffset << "'"; myDisasmBuf << Base::HEX4 << myPC + myOffset << "'L" << Base::HEX4 << myPC + myOffset << "'";
else else
myDisasmBuf << Base::HEX4 << myPC + myOffset << "' '"; myDisasmBuf << Base::HEX4 << myPC + myOffset << "' '";
@ -281,7 +298,7 @@ FIX_LAST:
case AddressingMode::ZERO_PAGE_Y: case AddressingMode::ZERO_PAGE_Y:
case AddressingMode::RELATIVE: case AddressingMode::RELATIVE:
{ {
if (pass == 3) { if(pass == 3) {
/* Line information is already printed, but we can remove the /* Line information is already printed, but we can remove the
Instruction (i.e. BMI) by simply clearing the buffer to print */ Instruction (i.e. BMI) by simply clearing the buffer to print */
myDisasmBuf << ".byte $" << Base::HEX2 << int(opcode); myDisasmBuf << ".byte $" << Base::HEX2 << int(opcode);
@ -302,10 +319,10 @@ FIX_LAST:
// Add operand(s) // Add operand(s)
ad = d1 = 0; // not WSYNC by default! ad = d1 = 0; // not WSYNC by default!
/* Version 2.1 added the extensions to mnemonics */ /* Version 2.1 added the extensions to mnemonics */
switch (addrMode) { switch(addrMode) {
case AddressingMode::ACCUMULATOR: case AddressingMode::ACCUMULATOR:
{ {
if (pass == 3 && mySettings.aFlag) if(pass == 3 && mySettings.aFlag)
nextLine << " A"; nextLine << " A";
break; break;
} }
@ -314,25 +331,28 @@ FIX_LAST:
{ {
ad = Debugger::debugger().dpeek(myPC + myOffset); myPC += 2; ad = Debugger::debugger().dpeek(myPC + myOffset); myPC += 2;
labelFound = mark(ad, Device::REFERENCED); labelFound = mark(ad, Device::REFERENCED);
if (pass == 3) { if(pass == 3) {
if (ad < 0x100 && mySettings.fFlag) if(ad < 0x100 && mySettings.fFlag)
nextLine << ".w "; nextLine << ".w ";
else else
nextLine << " "; nextLine << " ";
if (labelFound == AddressType::ROM) { if(labelFound == AddressType::ROM) {
LABEL_A12_HIGH(ad); LABEL_A12_HIGH(ad);
nextLineBytes << Base::HEX2 << int(ad & 0xff) << " " << Base::HEX2 << int(ad >> 8); nextLineBytes << Base::HEX2 << int(ad & 0xff) << " " << Base::HEX2 << int(ad >> 8);
} else if (labelFound == AddressType::ROM_MIRROR) { }
if (mySettings.rFlag) { else if(labelFound == AddressType::ROM_MIRROR) {
if(mySettings.rFlag) {
int tmp = (ad & myAppData.end) + myOffset; int tmp = (ad & myAppData.end) + myOffset;
LABEL_A12_HIGH(tmp); LABEL_A12_HIGH(tmp);
nextLineBytes << Base::HEX2 << int(tmp & 0xff) << " " << Base::HEX2 << int(tmp >> 8); nextLineBytes << Base::HEX2 << int(tmp & 0xff) << " " << Base::HEX2 << int(tmp >> 8);
} else { }
else {
nextLine << "$" << Base::HEX4 << ad; nextLine << "$" << Base::HEX4 << ad;
nextLineBytes << Base::HEX2 << int(ad & 0xff) << " " << Base::HEX2 << int(ad >> 8); nextLineBytes << Base::HEX2 << int(ad & 0xff) << " " << Base::HEX2 << int(ad >> 8);
} }
} else { }
else {
LABEL_A12_LOW(ad); LABEL_A12_LOW(ad);
nextLineBytes << Base::HEX2 << int(ad & 0xff) << " " << Base::HEX2 << int(ad >> 8); nextLineBytes << Base::HEX2 << int(ad & 0xff) << " " << Base::HEX2 << int(ad >> 8);
} }
@ -344,7 +364,7 @@ FIX_LAST:
{ {
d1 = Debugger::debugger().peek(myPC + myOffset); ++myPC; d1 = Debugger::debugger().peek(myPC + myOffset); ++myPC;
labelFound = mark(d1, Device::REFERENCED); labelFound = mark(d1, Device::REFERENCED);
if (pass == 3) { if(pass == 3) {
nextLine << " "; nextLine << " ";
LABEL_A12_LOW(int(d1)); LABEL_A12_LOW(int(d1));
nextLineBytes << Base::HEX2 << int(d1); nextLineBytes << Base::HEX2 << int(d1);
@ -355,7 +375,7 @@ FIX_LAST:
case AddressingMode::IMMEDIATE: case AddressingMode::IMMEDIATE:
{ {
d1 = Debugger::debugger().peek(myPC + myOffset); ++myPC; d1 = Debugger::debugger().peek(myPC + myOffset); ++myPC;
if (pass == 3) { if(pass == 3) {
nextLine << " #$" << Base::HEX2 << int(d1) << " "; nextLine << " #$" << Base::HEX2 << int(d1) << " ";
nextLineBytes << Base::HEX2 << int(d1); nextLineBytes << Base::HEX2 << int(d1);
} }
@ -366,33 +386,37 @@ FIX_LAST:
{ {
ad = Debugger::debugger().dpeek(myPC + myOffset); myPC += 2; ad = Debugger::debugger().dpeek(myPC + myOffset); myPC += 2;
labelFound = mark(ad, Device::REFERENCED); labelFound = mark(ad, Device::REFERENCED);
if (pass == 2 && !checkBit(ad & myAppData.end, Device::CODE)) { if(pass == 2 && !checkBit(ad & myAppData.end, Device::CODE)) {
// Since we can't know what address is being accessed unless we also // Since we can't know what address is being accessed unless we also
// know the current X value, this is marked as ROW instead of DATA // know the current X value, this is marked as ROW instead of DATA
// The processing is left here, however, in case future versions of // The processing is left here, however, in case future versions of
// the code can somehow track access to CPU registers // the code can somehow track access to CPU registers
mark(ad, Device::ROW); mark(ad, Device::ROW);
} else if (pass == 3) { }
if (ad < 0x100 && mySettings.fFlag) else if(pass == 3) {
if(ad < 0x100 && mySettings.fFlag)
nextLine << ".wx "; nextLine << ".wx ";
else else
nextLine << " "; nextLine << " ";
if (labelFound == AddressType::ROM) { if(labelFound == AddressType::ROM) {
LABEL_A12_HIGH(ad); LABEL_A12_HIGH(ad);
nextLine << ",x"; nextLine << ",x";
nextLineBytes << Base::HEX2 << int(ad & 0xff) << " " << Base::HEX2 << int(ad >> 8); nextLineBytes << Base::HEX2 << int(ad & 0xff) << " " << Base::HEX2 << int(ad >> 8);
} else if (labelFound == AddressType::ROM_MIRROR) { }
if (mySettings.rFlag) { else if(labelFound == AddressType::ROM_MIRROR) {
if(mySettings.rFlag) {
int tmp = (ad & myAppData.end) + myOffset; int tmp = (ad & myAppData.end) + myOffset;
LABEL_A12_HIGH(tmp); LABEL_A12_HIGH(tmp);
nextLine << ",x"; nextLine << ",x";
nextLineBytes << Base::HEX2 << int(tmp & 0xff) << " " << Base::HEX2 << int(tmp >> 8); nextLineBytes << Base::HEX2 << int(tmp & 0xff) << " " << Base::HEX2 << int(tmp >> 8);
} else { }
else {
nextLine << "$" << Base::HEX4 << ad << ",x"; nextLine << "$" << Base::HEX4 << ad << ",x";
nextLineBytes << Base::HEX2 << int(ad & 0xff) << " " << Base::HEX2 << int(ad >> 8); nextLineBytes << Base::HEX2 << int(ad & 0xff) << " " << Base::HEX2 << int(ad >> 8);
} }
} else { }
else {
LABEL_A12_LOW(ad); LABEL_A12_LOW(ad);
nextLine << ",x"; nextLine << ",x";
nextLineBytes << Base::HEX2 << int(ad & 0xff) << " " << Base::HEX2 << int(ad >> 8); nextLineBytes << Base::HEX2 << int(ad & 0xff) << " " << Base::HEX2 << int(ad >> 8);
@ -405,33 +429,37 @@ FIX_LAST:
{ {
ad = Debugger::debugger().dpeek(myPC + myOffset); myPC += 2; ad = Debugger::debugger().dpeek(myPC + myOffset); myPC += 2;
labelFound = mark(ad, Device::REFERENCED); labelFound = mark(ad, Device::REFERENCED);
if (pass == 2 && !checkBit(ad & myAppData.end, Device::CODE)) { if(pass == 2 && !checkBit(ad & myAppData.end, Device::CODE)) {
// Since we can't know what address is being accessed unless we also // Since we can't know what address is being accessed unless we also
// know the current Y value, this is marked as ROW instead of DATA // know the current Y value, this is marked as ROW instead of DATA
// The processing is left here, however, in case future versions of // The processing is left here, however, in case future versions of
// the code can somehow track access to CPU registers // the code can somehow track access to CPU registers
mark(ad, Device::ROW); mark(ad, Device::ROW);
} else if (pass == 3) { }
if (ad < 0x100 && mySettings.fFlag) else if(pass == 3) {
if(ad < 0x100 && mySettings.fFlag)
nextLine << ".wy "; nextLine << ".wy ";
else else
nextLine << " "; nextLine << " ";
if (labelFound == AddressType::ROM) { if(labelFound == AddressType::ROM) {
LABEL_A12_HIGH(ad); LABEL_A12_HIGH(ad);
nextLine << ",y"; nextLine << ",y";
nextLineBytes << Base::HEX2 << int(ad & 0xff) << " " << Base::HEX2 << int(ad >> 8); nextLineBytes << Base::HEX2 << int(ad & 0xff) << " " << Base::HEX2 << int(ad >> 8);
} else if (labelFound == AddressType::ROM_MIRROR) { }
if (mySettings.rFlag) { else if(labelFound == AddressType::ROM_MIRROR) {
if(mySettings.rFlag) {
int tmp = (ad & myAppData.end) + myOffset; int tmp = (ad & myAppData.end) + myOffset;
LABEL_A12_HIGH(tmp); LABEL_A12_HIGH(tmp);
nextLine << ",y"; nextLine << ",y";
nextLineBytes << Base::HEX2 << int(tmp & 0xff) << " " << Base::HEX2 << int(tmp >> 8); nextLineBytes << Base::HEX2 << int(tmp & 0xff) << " " << Base::HEX2 << int(tmp >> 8);
} else { }
else {
nextLine << "$" << Base::HEX4 << ad << ",y"; nextLine << "$" << Base::HEX4 << ad << ",y";
nextLineBytes << Base::HEX2 << int(ad & 0xff) << " " << Base::HEX2 << int(ad >> 8); nextLineBytes << Base::HEX2 << int(ad & 0xff) << " " << Base::HEX2 << int(ad >> 8);
} }
} else { }
else {
LABEL_A12_LOW(ad); LABEL_A12_LOW(ad);
nextLine << ",y"; nextLine << ",y";
nextLineBytes << Base::HEX2 << int(ad & 0xff) << " " << Base::HEX2 << int(ad >> 8); nextLineBytes << Base::HEX2 << int(ad & 0xff) << " " << Base::HEX2 << int(ad >> 8);
@ -443,7 +471,7 @@ FIX_LAST:
case AddressingMode::INDIRECT_X: case AddressingMode::INDIRECT_X:
{ {
d1 = Debugger::debugger().peek(myPC + myOffset); ++myPC; d1 = Debugger::debugger().peek(myPC + myOffset); ++myPC;
if (pass == 3) { if(pass == 3) {
labelFound = mark(d1, 0); // dummy call to get address type labelFound = mark(d1, 0); // dummy call to get address type
nextLine << " ("; nextLine << " (";
LABEL_A12_LOW(d1); LABEL_A12_LOW(d1);
@ -456,7 +484,7 @@ FIX_LAST:
case AddressingMode::INDIRECT_Y: case AddressingMode::INDIRECT_Y:
{ {
d1 = Debugger::debugger().peek(myPC + myOffset); ++myPC; d1 = Debugger::debugger().peek(myPC + myOffset); ++myPC;
if (pass == 3) { if(pass == 3) {
labelFound = mark(d1, 0); // dummy call to get address type labelFound = mark(d1, 0); // dummy call to get address type
nextLine << " ("; nextLine << " (";
LABEL_A12_LOW(d1); LABEL_A12_LOW(d1);
@ -470,7 +498,7 @@ FIX_LAST:
{ {
d1 = Debugger::debugger().peek(myPC + myOffset); ++myPC; d1 = Debugger::debugger().peek(myPC + myOffset); ++myPC;
labelFound = mark(d1, Device::REFERENCED); labelFound = mark(d1, Device::REFERENCED);
if (pass == 3) { if(pass == 3) {
nextLine << " "; nextLine << " ";
LABEL_A12_LOW(d1); LABEL_A12_LOW(d1);
nextLine << ",x"; nextLine << ",x";
@ -483,7 +511,7 @@ FIX_LAST:
{ {
d1 = Debugger::debugger().peek(myPC + myOffset); ++myPC; d1 = Debugger::debugger().peek(myPC + myOffset); ++myPC;
labelFound = mark(d1, Device::REFERENCED); labelFound = mark(d1, Device::REFERENCED);
if (pass == 3) { if(pass == 3) {
nextLine << " "; nextLine << " ";
LABEL_A12_LOW(d1); LABEL_A12_LOW(d1);
nextLine << ",y"; nextLine << ",y";
@ -501,11 +529,12 @@ FIX_LAST:
ad = ((myPC + Int8(d1)) & 0xfff) + myOffset; ad = ((myPC + Int8(d1)) & 0xfff) + myOffset;
labelFound = mark(ad, Device::REFERENCED); labelFound = mark(ad, Device::REFERENCED);
if (pass == 3) { if(pass == 3) {
if (labelFound == AddressType::ROM) { if(labelFound == AddressType::ROM) {
nextLine << " "; nextLine << " ";
LABEL_A12_HIGH(ad); LABEL_A12_HIGH(ad);
} else }
else
nextLine << " $" << Base::HEX4 << ad; nextLine << " $" << Base::HEX4 << ad;
nextLineBytes << Base::HEX2 << int(d1); nextLineBytes << Base::HEX2 << int(d1);
@ -517,29 +546,31 @@ FIX_LAST:
{ {
ad = Debugger::debugger().dpeek(myPC + myOffset); myPC += 2; ad = Debugger::debugger().dpeek(myPC + myOffset); myPC += 2;
labelFound = mark(ad, Device::REFERENCED); labelFound = mark(ad, Device::REFERENCED);
if (pass == 2 && !checkBit(ad & myAppData.end, Device::CODE)) { if(pass == 2 && !checkBit(ad & myAppData.end, Device::CODE)) {
// Since we can't know what address is being accessed unless we also // Since we can't know what address is being accessed unless we also
// know the current X value, this is marked as ROW instead of DATA // know the current X value, this is marked as ROW instead of DATA
// The processing is left here, however, in case future versions of // The processing is left here, however, in case future versions of
// the code can somehow track access to CPU registers // the code can somehow track access to CPU registers
mark(ad, Device::ROW); mark(ad, Device::ROW);
} else if (pass == 3) { }
if (ad < 0x100 && mySettings.fFlag) else if(pass == 3) {
if(ad < 0x100 && mySettings.fFlag)
nextLine << ".ind "; nextLine << ".ind ";
else else
nextLine << " "; nextLine << " ";
} }
if (labelFound == AddressType::ROM) { if(labelFound == AddressType::ROM) {
nextLine << "("; nextLine << "(";
LABEL_A12_HIGH(ad); LABEL_A12_HIGH(ad);
nextLine << ")"; nextLine << ")";
} }
else if (labelFound == AddressType::ROM_MIRROR) { else if(labelFound == AddressType::ROM_MIRROR) {
nextLine << "("; nextLine << "(";
if (mySettings.rFlag) { if(mySettings.rFlag) {
int tmp = (ad & myAppData.end) + myOffset; int tmp = (ad & myAppData.end) + myOffset;
LABEL_A12_HIGH(tmp); LABEL_A12_HIGH(tmp);
} else { }
else {
LABEL_A12_LOW(ad); LABEL_A12_LOW(ad);
} }
nextLine << ")"; nextLine << ")";
@ -558,26 +589,27 @@ FIX_LAST:
break; break;
} // end switch } // end switch
if (pass == 3) { if(pass == 3) {
cycles += int(ourLookup[opcode].cycles); cycles += int(ourLookup[opcode].cycles);
// A complete line of disassembly (text, cycle count, and bytes) // A complete line of disassembly (text, cycle count, and bytes)
myDisasmBuf << nextLine.str() << "'" myDisasmBuf << nextLine.str() << "'"
<< ";" << std::dec << int(ourLookup[opcode].cycles) << ";" << std::dec << int(ourLookup[opcode].cycles)
<< (addrMode == AddressingMode::RELATIVE ? (ad & 0xf00) != ((myPC + myOffset) & 0xf00) ? "/3!" : "/3 " : " "); << (addrMode == AddressingMode::RELATIVE ? (ad & 0xf00) != ((myPC + myOffset) & 0xf00) ? "/3!" : "/3 " : " ");
if ((opcode == 0x40 || opcode == 0x60 || opcode == 0x4c || opcode == 0x00 // code block end if((opcode == 0x40 || opcode == 0x60 || opcode == 0x4c || opcode == 0x00 // code block end
|| checkBit(myPC, Device::REFERENCED) // referenced address || checkBit(myPC, Device::REFERENCED) // referenced address
|| (ourLookup[opcode].rw_mode == RWMode::WRITE && d1 == WSYNC)) // strobe WSYNC || (ourLookup[opcode].rw_mode == RWMode::WRITE && d1 == WSYNC)) // strobe WSYNC
&& cycles > 0) { && cycles > 0) {
// output cycles for previous code block // output cycles for previous code block
myDisasmBuf << "'= " << std::setw(3) << std::setfill(' ') << std::dec << cycles; myDisasmBuf << "'= " << std::setw(3) << std::setfill(' ') << std::dec << cycles;
cycles = 0; cycles = 0;
} else { }
else {
myDisasmBuf << "' "; myDisasmBuf << "' ";
} }
myDisasmBuf << "'" << nextLineBytes.str(); myDisasmBuf << "'" << nextLineBytes.str();
addEntry(Device::CODE); addEntry(Device::CODE);
if (opcode == 0x40 || opcode == 0x60 || opcode == 0x4c || opcode == 0x00) { if(opcode == 0x40 || opcode == 0x60 || opcode == 0x4c || opcode == 0x00) {
myDisasmBuf << " ' ' "; myDisasmBuf << " ' ' ";
addEntry(Device::NONE); addEntry(Device::NONE);
mySegType = Device::NONE; // prevent extra lines if data follows mySegType = Device::NONE; // prevent extra lines if data follows
@ -586,8 +618,8 @@ FIX_LAST:
nextLine.str(""); nextLine.str("");
nextLineBytes.str(""); nextLineBytes.str("");
} }
} } // CODE
} /* while loop */ } /* while loop */
/* Just in case we are disassembling outside of the address range, force the myPCEnd to EOF */ /* Just in case we are disassembling outside of the address range, force the myPCEnd to EOF */
myPCEnd = myAppData.end + myOffset; myPCEnd = myAppData.end + myOffset;
@ -630,7 +662,7 @@ void DiStella::disasmPass1(CartDebug::AddressList& debuggerAddresses)
// Therefore, we stop at the first such address encountered // Therefore, we stop at the first such address encountered
for (uInt32 k = pcBeg; k <= myPCEnd; ++k) { for (uInt32 k = pcBeg; k <= myPCEnd; ++k) {
if (checkBits(k, Device::Device::DATA | Device::GFX | Device::PGFX | if (checkBits(k, Device::Device::DATA | Device::GFX | Device::PGFX |
Device::COL | Device::PCOL | Device::BCOL, Device::COL | Device::PCOL | Device::BCOL | Device::AUD,
Device::CODE)) { Device::CODE)) {
//if (Debugger::debugger().getAccessFlags(k) & //if (Debugger::debugger().getAccessFlags(k) &
// (Device::DATA | Device::GFX | Device::PGFX)) { // (Device::DATA | Device::GFX | Device::PGFX)) {
@ -692,7 +724,7 @@ void DiStella::disasmPass1(CartDebug::AddressList& debuggerAddresses)
// Must be ROW / unused bytes // Must be ROW / unused bytes
if (!checkBit(k, Device::CODE | Device::GFX | Device::PGFX | if (!checkBit(k, Device::CODE | Device::GFX | Device::PGFX |
Device::COL | Device::PCOL | Device::BCOL | Device::COL | Device::PCOL | Device::BCOL | Device::AUD |
Device::DATA)) Device::DATA))
mark(k + myOffset, Device::ROW); mark(k + myOffset, Device::ROW);
} }
@ -711,7 +743,7 @@ void DiStella::disasmFromAddress(uInt32 distart)
// abort when we reach non-code areas // abort when we reach non-code areas
if (checkBits(myPC, Device::Device::DATA | Device::GFX | Device::PGFX | if (checkBits(myPC, Device::Device::DATA | Device::GFX | Device::PGFX |
Device::COL | Device::PCOL | Device::BCOL, Device::COL | Device::PCOL | Device::BCOL | Device::AUD,
Device::CODE)) { Device::CODE)) {
myPCEnd = (myPC - 1) + myOffset; myPCEnd = (myPC - 1) + myOffset;
return; return;
@ -1037,18 +1069,11 @@ void DiStella::addEntry(Device::AccessType type)
case Device::GFX: case Device::GFX:
case Device::PGFX: case Device::PGFX:
getline(myDisasmBuf, tag.disasm, '\'');
getline(myDisasmBuf, tag.bytes);
break;
case Device::COL: case Device::COL:
case Device::PCOL: case Device::PCOL:
case Device::BCOL: case Device::BCOL:
getline(myDisasmBuf, tag.disasm, '\'');
getline(myDisasmBuf, tag.bytes);
break;
case Device::DATA: case Device::DATA:
case Device::AUD:
getline(myDisasmBuf, tag.disasm, '\''); getline(myDisasmBuf, tag.disasm, '\'');
getline(myDisasmBuf, tag.bytes); getline(myDisasmBuf, tag.bytes);
break; break;
@ -1213,7 +1238,7 @@ void DiStella::outputBytes(Device::AccessType type)
isType = checkBits(myPC, type, isType = checkBits(myPC, type,
Device::CODE | (type != Device::DATA ? Device::DATA : 0) | Device::CODE | (type != Device::DATA ? Device::DATA : 0) |
Device::GFX | Device::PGFX | Device::GFX | Device::PGFX |
Device::COL | Device::PCOL | Device::BCOL); Device::COL | Device::PCOL | Device::BCOL | Device::AUD);
referenced = checkBit(myPC, Device::REFERENCED); referenced = checkBit(myPC, Device::REFERENCED);
} }
if (!lineEmpty) if (!lineEmpty)

View File

@ -46,13 +46,14 @@ class Device : public Serializable
// debugger, or specified in a Distella cfg file, and are listed in order // debugger, or specified in a Distella cfg file, and are listed in order
// of decreasing hierarchy // of decreasing hierarchy
// //
CODE = 1 << 10, // 0x400, disassemble-able code segments CODE = 1 << 11, // 0x800, disassemble-able code segments
TCODE = 1 << 9, // 0x200, (tentative) disassemble-able code segments TCODE = 1 << 10, // 0x400, (tentative) disassemble-able code segments
GFX = 1 << 8, // 0x100, addresses loaded into GRPx registers GFX = 1 << 9, // 0x200, addresses loaded into GRPx registers
PGFX = 1 << 7, // 0x080, addresses loaded into PFx registers PGFX = 1 << 8, // 0x100, addresses loaded into PFx registers
COL = 1 << 6, // 0x040, addresses loaded into COLUPx registers COL = 1 << 7, // 0x080, addresses loaded into COLUPx registers
PCOL = 1 << 5, // 0x010, addresses loaded into COLUPF register PCOL = 1 << 6, // 0x040, addresses loaded into COLUPF register
BCOL = 1 << 4, // 0x010, addresses loaded into COLUBK register BCOL = 1 << 5, // 0x020, addresses loaded into COLUBK register
AUD = 1 << 4, // 0x010, addresses loaded into audio registers
DATA = 1 << 3, // 0x008, addresses loaded into registers other than GRPx / PFx DATA = 1 << 3, // 0x008, addresses loaded into registers other than GRPx / PFx
ROW = 1 << 2, // 0x004, all other addresses ROW = 1 << 2, // 0x004, all other addresses
// special type for poke() // special type for poke()

View File

@ -23,21 +23,15 @@
// Flags for access types // Flags for access types
#define DISASM_CODE Device::CODE #define DISASM_CODE Device::CODE
// #define DISASM_GFX Device::GFX
// #define DISASM_PGFX Device::PGFX
#define DISASM_DATA Device::DATA #define DISASM_DATA Device::DATA
// #define DISASM_ROW Device::ROW
#define DISASM_WRITE Device::WRITE #define DISASM_WRITE Device::WRITE
#define DISASM_NONE 0 #define DISASM_NONE Device::NONE
#else #else
// Flags for access types // Flags for access types
#define DISASM_CODE 0 #define DISASM_CODE 0
// #define DISASM_GFX 0
// #define DISASM_PGFX 0
#define DISASM_DATA 0 #define DISASM_DATA 0
// #define DISASM_ROW 0
#define DISASM_NONE 0
#define DISASM_WRITE 0 #define DISASM_WRITE 0
#define DISASM_NONE 0
#endif #endif
#include "Settings.hxx" #include "Settings.hxx"
#include "Vec.hxx" #include "Vec.hxx"

View File

@ -534,8 +534,8 @@ void Settings::usage() const
<< " Arguments are more fully explained in the manual\n" << " Arguments are more fully explained in the manual\n"
<< endl << endl
<< " -dis.resolve <1|0> Attempt to resolve code sections in disassembler\n" << " -dis.resolve <1|0> Attempt to resolve code sections in disassembler\n"
<< " -dis.gfxformat <2|16> Set base to use for displaying GFX sections in\n" << " -dis.gfxformat <2|16> Set base to use for displaying (P)GFX sections\n"
<< " disassembler\n" << " in disassembler\n"
<< " -dis.showaddr <1|0> Show opcode addresses in disassembler\n" << " -dis.showaddr <1|0> Show opcode addresses in disassembler\n"
<< " -dis.relocate <1|0> Relocate calls out of address range in\n" << " -dis.relocate <1|0> Relocate calls out of address range in\n"
<< " disassembler\n" << " disassembler\n"

View File

@ -234,7 +234,7 @@ class System : public Serializable
/** /**
Access and modify the access type flags for the given Access and modify the access type flags for the given
address. Note that while any flag can be used, the disassembly address. Note that while any flag can be used, the disassembly
only really acts on CODE/GFX/PGFX/COL/PCOL/BCOL/DATA/ROW. only really acts on CODE/GFX/PGFX/COL/PCOL/BCOL/AUD/DATA/ROW.
*/ */
Device::AccessFlags getAccessFlags(uInt16 address) const; Device::AccessFlags getAccessFlags(uInt16 address) const;
void setAccessFlags(uInt16 address, Device::AccessFlags flags); void setAccessFlags(uInt16 address, Device::AccessFlags flags);

View File

@ -530,34 +530,76 @@ bool TIA::poke(uInt16 address, uInt8 value)
break; break;
case AUDV0: case AUDV0:
{
myAudio.channel0().audv(value); myAudio.channel0().audv(value);
myShadowRegisters[address] = value; myShadowRegisters[address] = value;
#ifdef DEBUGGER_SUPPORT
uInt16 dataAddr = mySystem->m6502().lastDataAddressForPoke();
if(dataAddr)
mySystem->setAccessFlags(dataAddr, Device::AUD);
#endif
break; break;
}
case AUDV1: case AUDV1:
{
myAudio.channel1().audv(value); myAudio.channel1().audv(value);
myShadowRegisters[address] = value; myShadowRegisters[address] = value;
#ifdef DEBUGGER_SUPPORT
uInt16 dataAddr = mySystem->m6502().lastDataAddressForPoke();
if(dataAddr)
mySystem->setAccessFlags(dataAddr, Device::AUD);
#endif
break; break;
}
case AUDF0: case AUDF0:
{
myAudio.channel0().audf(value); myAudio.channel0().audf(value);
myShadowRegisters[address] = value; myShadowRegisters[address] = value;
#ifdef DEBUGGER_SUPPORT
uInt16 dataAddr = mySystem->m6502().lastDataAddressForPoke();
if(dataAddr)
mySystem->setAccessFlags(dataAddr, Device::AUD);
#endif
break; break;
}
case AUDF1: case AUDF1:
{
myAudio.channel1().audf(value); myAudio.channel1().audf(value);
myShadowRegisters[address] = value; myShadowRegisters[address] = value;
#ifdef DEBUGGER_SUPPORT
uInt16 dataAddr = mySystem->m6502().lastDataAddressForPoke();
if(dataAddr)
mySystem->setAccessFlags(dataAddr, Device::AUD);
#endif
break; break;
}
case AUDC0: case AUDC0:
{
myAudio.channel0().audc(value); myAudio.channel0().audc(value);
myShadowRegisters[address] = value; myShadowRegisters[address] = value;
#ifdef DEBUGGER_SUPPORT
uInt16 dataAddr = mySystem->m6502().lastDataAddressForPoke();
if(dataAddr)
mySystem->setAccessFlags(dataAddr, Device::AUD);
#endif
break; break;
}
case AUDC1: case AUDC1:
{
myAudio.channel1().audc(value); myAudio.channel1().audc(value);
myShadowRegisters[address] = value; myShadowRegisters[address] = value;
#ifdef DEBUGGER_SUPPORT
uInt16 dataAddr = mySystem->m6502().lastDataAddressForPoke();
if(dataAddr)
mySystem->setAccessFlags(dataAddr, Device::AUD);
#endif
break; break;
}
case HMOVE: case HMOVE:
myDelayQueue.push(HMOVE, value, Delay::hmove); myDelayQueue.push(HMOVE, value, Delay::hmove);