From e85738978c5a18aa4351684c921139988c3759ee Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sun, 29 Mar 2020 10:51:16 +0200 Subject: [PATCH] add detection of audio data in DiStella (see #596) --- Changes.txt | 2 +- src/debugger/CartDebug.cxx | 57 +++++---- src/debugger/CartDebug.hxx | 2 +- src/debugger/DiStella.cxx | 239 ++++++++++++++++++++----------------- src/emucore/Device.hxx | 15 +-- src/emucore/M6502.cxx | 10 +- src/emucore/Settings.cxx | 4 +- src/emucore/System.hxx | 2 +- src/emucore/tia/TIA.cxx | 42 +++++++ 9 files changed, 223 insertions(+), 150 deletions(-) diff --git a/Changes.txt b/Changes.txt index 5dbc6047e..9daaf6f42 100644 --- a/Changes.txt +++ b/Changes.txt @@ -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) diff --git a/src/debugger/CartDebug.cxx b/src/debugger/CartDebug.cxx index 0552b2d65..d9750629e 100644 --- a/src/debugger/CartDebug.cxx +++ b/src/debugger/CartDebug.cxx @@ -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) diff --git a/src/debugger/CartDebug.hxx b/src/debugger/CartDebug.hxx index e52389974..dda0906cb 100644 --- a/src/debugger/CartDebug.hxx +++ b/src/debugger/CartDebug.hxx @@ -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) diff --git a/src/debugger/DiStella.cxx b/src/debugger/DiStella.cxx index a53143668..547a75933 100644 --- a/src/debugger/DiStella.cxx +++ b/src/debugger/DiStella.cxx @@ -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) diff --git a/src/emucore/Device.hxx b/src/emucore/Device.hxx index 205de10ac..d60ec7054 100644 --- a/src/emucore/Device.hxx +++ b/src/emucore/Device.hxx @@ -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() diff --git a/src/emucore/M6502.cxx b/src/emucore/M6502.cxx index 6f7392326..86b050dfb 100644 --- a/src/emucore/M6502.cxx +++ b/src/emucore/M6502.cxx @@ -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" diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx index 68747896a..d4cdb81e8 100644 --- a/src/emucore/Settings.cxx +++ b/src/emucore/Settings.cxx @@ -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" diff --git a/src/emucore/System.hxx b/src/emucore/System.hxx index 1a6dcff68..2e7c158a9 100644 --- a/src/emucore/System.hxx +++ b/src/emucore/System.hxx @@ -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); diff --git a/src/emucore/tia/TIA.cxx b/src/emucore/tia/TIA.cxx index 58eb8c8ea..c5896c3aa 100644 --- a/src/emucore/tia/TIA.cxx +++ b/src/emucore/tia/TIA.cxx @@ -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);