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 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)

View File

@ -916,6 +916,11 @@ string CartDebug::loadConfigFile()
buf >> hex >> start >> hex >> end;
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"))
{
buf >> hex >> start >> hex >> end;
@ -1070,57 +1075,54 @@ string CartDebug::saveDisassembly()
switch(tag.type)
{
case Device::CODE:
{
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)
buf << "\n;---------------------------------------";
break;
}
case Device::ROW:
{
buf << ".byte " << ALIGN(32) << tag.disasm.substr(6, 8*4-1) << "; $" << Base::HEX4 << tag.address << " (*)";
break;
}
case Device::GFX:
{
buf << ".byte " << (settings.gfxFormat == Base::Fmt::_2 ? "%" : "$")
<< tag.bytes << " ; |";
for(int c = 12; c < 20; ++c)
buf << ((tag.disasm[c] == '\x1e') ? "#" : " ");
buf << ALIGN(13) << "|" << "$" << Base::HEX4 << tag.address << " (G)";
break;
}
case Device::PGFX:
{
buf << ".byte " << (settings.gfxFormat == Base::Fmt::_2 ? "%" : "$")
<< tag.bytes << " ; |";
for(int c = 12; c < 20; ++c)
buf << ((tag.disasm[c] == '\x1f') ? "*" : " ");
buf << ALIGN(13) << "|" << "$" << Base::HEX4 << tag.address << " (P)";
break;
}
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;
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;
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;
case Device::DATA:
{
buf << ".byte " << ALIGN(32) << tag.disasm.substr(6, 8 * 4 - 1) << "; $" << Base::HEX4 << tag.address << " (D)";
break;
}
case Device::NONE:
default:
{
break;
}
} // switch
buf << "\n";
}
@ -1134,14 +1136,18 @@ string CartDebug::saveDisassembly()
<< "; ROM properties name : " << myConsole.properties().get(PropType::Cart_Name) << "\n"
<< "; ROM properties MD5 : " << myConsole.properties().get(PropType::Cart_MD5) << "\n"
<< "; Bankswitch type : " << myConsole.cartridge().about() << "\n;\n"
<< "; Legend: * = Device::CODE not yet run (tentative code)\n"
<< "; D = Device::DATA directive (referenced in some way)\n"
<< "; G = Device::GFX directive, shown as '#' (stored in player, missile, ball)\n"
<< "; P = Device::PGFX directive, shown as '*' (stored in playfield)\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"
<< "; Legend: * = Device::CODE not yet run (tentative code)\n"
<< "; D = Device::DATA directive (referenced in some way)\n"
<< "; G = Device::GFX directive, shown as '#' (stored in player, missile, ball)\n"
<< "; P = Device::PGFX directive, shown as '*' (stored in playfield)\n"
<< "; C = Device::COL directive, shown as '*' (stored in player color)\n"
<< "; CP = Device::PCOL directive, shown as '*' (stored in playfield color)\n"
<< "; CB = Device::BCOL directive, shown as '*' (stored in background color)\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";
out << "\n;-----------------------------------------------------------\n"
@ -1478,6 +1484,8 @@ Device::AccessType CartDebug::accessTypeAbsolute(Device::AccessFlags flags) cons
return Device::PCOL;
else if(flags & Device::BCOL)
return Device::BCOL;
else if(flags & Device::AUD)
return Device::AUD;
else if(flags & Device::DATA)
return Device::DATA;
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::PCOL: buf << "Device::PCOL"; break;
case Device::BCOL: buf << "Device::BCOL"; break;
case Device::AUD: buf << "Device::AUD"; break;
case Device::DATA: buf << "Device::DATA"; break;
case Device::ROW: buf << "Device::ROW"; break;
case Device::REFERENCED:
@ -1525,6 +1534,8 @@ void CartDebug::AccessTypeAsString(ostream& buf, Device::AccessFlags flags) cons
buf << "Device::PCOL ";
if(flags & Device::BCOL)
buf << "Device::BCOL ";
if(flags & Device::AUD)
buf << "Device::AUD ";
if(flags & Device::DATA)
buf << "Device::DATA ";
if(flags & Device::ROW)

View File

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

View File

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

View File

@ -534,8 +534,8 @@ void Settings::usage() const
<< " Arguments are more fully explained in the manual\n"
<< endl
<< " -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"
<< " disassembler\n"
<< " -dis.gfxformat <2|16> Set base to use for displaying (P)GFX sections\n"
<< " 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"
<< " disassembler\n"

View File

@ -234,7 +234,7 @@ class System : public Serializable
/**
Access and modify the access type flags for the given
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;
void setAccessFlags(uInt16 address, Device::AccessFlags flags);

View File

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