mirror of https://github.com/stella-emu/stella.git
add detection of audio data in DiStella (see #596)
This commit is contained in:
parent
c09b6167a1
commit
09fb69f397
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue