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

This commit is contained in:
thrust26 2020-03-26 22:22:52 +01:00
parent 193e8a1a46
commit d01aa94161
25 changed files with 318 additions and 89 deletions

2
.gitignore vendored
View File

@ -31,3 +31,5 @@ src/**/*.psess
src/**/*.vspx src/**/*.vspx
src/**/**.pdb src/**/**.pdb
Stella.xcscheme Stella.xcscheme
src/tools/fonts/*

View File

@ -13,11 +13,16 @@
=========================================================================== ===========================================================================
6.1 to 6.2: (??? ??, 2020) 6.1 to 6.2: (??? ??, 2020)
* Paddle centering and sensitivity can be adjusted now
* High scores: Score addresses, game variation etc. can be defined for a * Added that paddle centering and sensitivity can be adjusted now (TOOD: Doc)
game. This allows the user to save high scores for these games. For each
game and variation, the top 10 scores can be saved. * Added high scores: Score addresses, game variation etc. can be defined for
a game. This allows the user to save high scores for these games. For each
game and variation, the top 10 scores can be saved. (TOOD: Doc)
* Added displaying last write address in debugger. (TOOD: Doc)
* Added detection of color 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

@ -84,6 +84,7 @@ using ByteArray = std::vector<uInt8>;
using ShortArray = std::vector<uInt16>; using ShortArray = std::vector<uInt16>;
using StringList = std::vector<std::string>; using StringList = std::vector<std::string>;
using ByteBuffer = std::unique_ptr<uInt8[]>; // NOLINT using ByteBuffer = std::unique_ptr<uInt8[]>; // NOLINT
using WordBuffer = std::unique_ptr<uInt16[]>; // NOLINT
// We use KB a lot; let's make a literal for it // We use KB a lot; let's make a literal for it
constexpr uInt32 operator "" _KB(unsigned long long size) constexpr uInt32 operator "" _KB(unsigned long long size)

View File

@ -900,6 +900,21 @@ string CartDebug::loadConfigFile()
buf >> hex >> start >> hex >> end; buf >> hex >> start >> hex >> end;
addDirective(CartDebug::PGFX, start, end, currentbank); addDirective(CartDebug::PGFX, start, end, currentbank);
} }
else if(BSPF::startsWithIgnoreCase(directive, "COL"))
{
buf >> hex >> start >> hex >> end;
addDirective(CartDebug::COL, start, end, currentbank);
}
else if(BSPF::startsWithIgnoreCase(directive, "PCOL"))
{
buf >> hex >> start >> hex >> end;
addDirective(CartDebug::PCOL, start, end, currentbank);
}
else if(BSPF::startsWithIgnoreCase(directive, "BCOL"))
{
buf >> hex >> start >> hex >> end;
addDirective(CartDebug::BCOL, start, end, currentbank);
}
else if(BSPF::startsWithIgnoreCase(directive, "DATA")) else if(BSPF::startsWithIgnoreCase(directive, "DATA"))
{ {
buf >> hex >> start >> hex >> end; buf >> hex >> start >> hex >> end;
@ -966,6 +981,25 @@ string CartDebug::saveConfigFile()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string CartDebug::saveDisassembly() string CartDebug::saveDisassembly()
{ {
string NTSC_COLOR[16] = {
"BLACK", "YELLOW", "BROWN", "ORANGE",
"RED", "MAUVE", "VIOLET", "PURPLE",
"BLUE", "BLUE_CYAN", "CYAN", "CYAN_GREEN",
"GREEN", "GREEN_YELLOW", "GREEN_BEIGE", "BEIGE"
};
string PAL_COLOR[16] = {
"BLACK0", "BLACK1", "YELLOW", "GREEN_YELLOW",
"ORANGE", "GREEN", "RED", "CYAN_GREEN",
"MAUVE", "CYAN", "VIOLET", "BLUE_CYAN",
"PURPLE", "BLUE", "BLACKE", "BLACKF"
};
string SECAM_COLOR[8] = {
"BLACK", "BLUE", "RED", "PURPLE",
"GREEN", "CYAN", "YELLOW", "WHITE"
};
bool isNTSC = myConsole.timing() == ConsoleTiming::ntsc;
bool isPAL = myConsole.timing() == ConsoleTiming::pal;
if(myDisasmFile == "") if(myDisasmFile == "")
{ {
const string& propsname = const string& propsname =
@ -1064,6 +1098,18 @@ string CartDebug::saveDisassembly()
buf << ALIGN(13) << "|" << "$" << Base::HEX4 << tag.address << " (P)"; buf << ALIGN(13) << "|" << "$" << Base::HEX4 << tag.address << " (P)";
break; break;
} }
case CartDebug::COL:
buf << ".byte " << ALIGN(32) << tag.disasm.substr(6, 12) << "; $" << Base::HEX4 << tag.address << " (Px)";
break;
case CartDebug::PCOL:
buf << ".byte " << ALIGN(32) << tag.disasm.substr(6, 12) << "; $" << Base::HEX4 << tag.address << " (PF)";
break;
case CartDebug::BCOL:
buf << ".byte " << ALIGN(32) << tag.disasm.substr(6, 12) << "; $" << Base::HEX4 << tag.address << " (BK)";
break;
case CartDebug::DATA: case CartDebug::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)";
@ -1097,6 +1143,27 @@ string CartDebug::saveDisassembly()
<< "; ! = page crossed, 1 cycle penalty\n" << "; ! = page crossed, 1 cycle penalty\n"
<< "\n processor 6502\n\n"; << "\n processor 6502\n\n";
out << "\n;-----------------------------------------------------------\n"
<< "; Color constants\n"
<< ";-----------------------------------------------------------\n\n";
if(isNTSC)
{
for(int i = 0; i < 16; ++i)
out << ALIGN(16) << NTSC_COLOR[i] << " = $" << Base::HEX2 << (i << 4) << "\n";
}
else if(isPAL)
{
for(int i = 0; i < 16; ++i)
out << ALIGN(16) << PAL_COLOR[i] << " = $" << Base::HEX2 << (i << 4) << "\n";
}
else
{
for(int i = 0; i < 8; ++i)
out << ALIGN(16) << SECAM_COLOR[i] << " = $" << Base::HEX1 << (i << 1) << "\n";
}
out << "\n";
bool addrUsed = false; bool addrUsed = false;
for(uInt16 addr = 0x00; addr <= 0x0F; ++addr) for(uInt16 addr = 0x00; addr <= 0x0F; ++addr)
addrUsed = addrUsed || myReserved.TIARead[addr] || (mySystem.getAccessFlags(addr) & WRITE); addrUsed = addrUsed || myReserved.TIARead[addr] || (mySystem.getAccessFlags(addr) & WRITE);
@ -1104,6 +1171,7 @@ string CartDebug::saveDisassembly()
addrUsed = addrUsed || myReserved.TIAWrite[addr] || (mySystem.getAccessFlags(addr) & DATA); addrUsed = addrUsed || myReserved.TIAWrite[addr] || (mySystem.getAccessFlags(addr) & DATA);
for(uInt16 addr = 0x00; addr <= 0x17; ++addr) for(uInt16 addr = 0x00; addr <= 0x17; ++addr)
addrUsed = addrUsed || myReserved.IOReadWrite[addr]; addrUsed = addrUsed || myReserved.IOReadWrite[addr];
if(addrUsed) if(addrUsed)
{ {
out << "\n;-----------------------------------------------------------\n" out << "\n;-----------------------------------------------------------\n"
@ -1393,7 +1461,7 @@ void CartDebug::addressTypeAsString(ostream& buf, uInt16 addr) const
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CartDebug::DisasmType CartDebug::disasmTypeAbsolute(uInt8 flags) const CartDebug::DisasmType CartDebug::disasmTypeAbsolute(uInt16 flags) const
{ {
if(flags & CartDebug::CODE) if(flags & CartDebug::CODE)
return CartDebug::CODE; return CartDebug::CODE;
@ -1403,6 +1471,12 @@ CartDebug::DisasmType CartDebug::disasmTypeAbsolute(uInt8 flags) const
return CartDebug::GFX; return CartDebug::GFX;
else if(flags & CartDebug::PGFX) else if(flags & CartDebug::PGFX)
return CartDebug::PGFX; return CartDebug::PGFX;
else if(flags & CartDebug::COL)
return CartDebug::COL;
else if(flags & CartDebug::PCOL)
return CartDebug::PCOL;
else if(flags & CartDebug::BCOL)
return CartDebug::BCOL;
else if(flags & CartDebug::DATA) else if(flags & CartDebug::DATA)
return CartDebug::DATA; return CartDebug::DATA;
else if(flags & CartDebug::ROW) else if(flags & CartDebug::ROW)
@ -1420,6 +1494,9 @@ void CartDebug::disasmTypeAsString(ostream& buf, DisasmType type) const
case CartDebug::TCODE: buf << "TCODE"; break; case CartDebug::TCODE: buf << "TCODE"; break;
case CartDebug::GFX: buf << "GFX"; break; case CartDebug::GFX: buf << "GFX"; break;
case CartDebug::PGFX: buf << "PGFX"; break; case CartDebug::PGFX: buf << "PGFX"; break;
case CartDebug::COL: buf << "COL"; break;
case CartDebug::PCOL: buf << "PCOL"; break;
case CartDebug::BCOL: buf << "BCOL"; break;
case CartDebug::DATA: buf << "DATA"; break; case CartDebug::DATA: buf << "DATA"; break;
case CartDebug::ROW: buf << "ROW"; break; case CartDebug::ROW: buf << "ROW"; break;
case CartDebug::REFERENCED: case CartDebug::REFERENCED:
@ -1429,7 +1506,7 @@ void CartDebug::disasmTypeAsString(ostream& buf, DisasmType type) const
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartDebug::disasmTypeAsString(ostream& buf, uInt8 flags) const void CartDebug::disasmTypeAsString(ostream& buf, uInt16 flags) const
{ {
if(flags) if(flags)
{ {
@ -1441,6 +1518,12 @@ void CartDebug::disasmTypeAsString(ostream& buf, uInt8 flags) const
buf << "GFX "; buf << "GFX ";
if(flags & CartDebug::PGFX) if(flags & CartDebug::PGFX)
buf << "PGFX "; buf << "PGFX ";
if(flags & CartDebug::COL)
buf << "COL ";
if(flags & CartDebug::PCOL)
buf << "PCOL ";
if(flags & CartDebug::BCOL)
buf << "BCOL ";
if(flags & CartDebug::DATA) if(flags & CartDebug::DATA)
buf << "DATA "; buf << "DATA ";
if(flags & CartDebug::ROW) if(flags & CartDebug::ROW)

View File

@ -60,14 +60,17 @@ class CartDebug : public DebuggerSystem
// 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 << 7, // 0x80, disassemble-able code segments CODE = 1 << 10, // 0x400, disassemble-able code segments
TCODE = 1 << 6, // 0x40, (tentative) disassemble-able code segments TCODE = 1 << 9, // 0x200, (tentative) disassemble-able code segments
GFX = 1 << 5, // 0x20, addresses loaded into GRPx registers GFX = 1 << 8, // 0x100, addresses loaded into GRPx registers
PGFX = 1 << 4, // 0x10, addresses loaded into PFx registers PGFX = 1 << 7, // 0x080, addresses loaded into PFx registers
DATA = 1 << 3, // 0x08, addresses loaded into registers other than GRPx / PFx COL = 1 << 6, // 0x040, addresses loaded into COLUPx registers
ROW = 1 << 2, // 0x04, all other addresses PCOL = 1 << 5, // 0x010, addresses loaded into COLUPF register
BCOL = 1 << 4, // 0x010, addresses loaded into COLUBK register
DATA = 1 << 3, // 0x008, addresses loaded into registers other than GRPx / PFx
ROW = 1 << 2, // 0x004, all other addresses
// special type for poke() // special type for poke()
WRITE = TCODE // 0x40, address written to WRITE = TCODE // 0x200, address written to
}; };
struct DisassemblyTag { struct DisassemblyTag {
DisasmType type{NONE}; DisasmType type{NONE};
@ -263,7 +266,7 @@ class CartDebug : public DebuggerSystem
using LabelToAddr = std::map<string, uInt16, using LabelToAddr = std::map<string, uInt16,
std::function<bool(const string&, const string&)>>; std::function<bool(const string&, const string&)>>;
using AddrTypeArray = std::array<uInt8, 0x1000>; using AddrTypeArray = std::array<uInt16, 0x1000>;
struct DirectiveTag { struct DirectiveTag {
DisasmType type{NONE}; DisasmType type{NONE};
@ -305,14 +308,14 @@ class CartDebug : public DebuggerSystem
void getBankDirectives(ostream& buf, BankInfo& info) const; void getBankDirectives(ostream& buf, BankInfo& info) const;
// Get disassembly enum type from 'flags', taking precendence into account // Get disassembly enum type from 'flags', taking precendence into account
DisasmType disasmTypeAbsolute(uInt8 flags) const; DisasmType disasmTypeAbsolute(uInt16 flags) const;
// Convert disassembly enum type to corresponding string and append to buf // Convert disassembly enum type to corresponding string and append to buf
void disasmTypeAsString(ostream& buf, DisasmType type) const; void disasmTypeAsString(ostream& buf, DisasmType type) const;
// Convert all disassembly types in 'flags' to corresponding string and // Convert all disassembly types in 'flags' to corresponding string and
// append to buf // append to buf
void disasmTypeAsString(ostream& buf, uInt8 flags) const; void disasmTypeAsString(ostream& buf, uInt16 flags) const;
private: private:
const OSystem& myOSystem; const OSystem& myOSystem;

View File

@ -440,19 +440,19 @@ bool Debugger::writeTrap(uInt16 t)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 Debugger::peek(uInt16 addr, uInt8 flags) uInt8 Debugger::peek(uInt16 addr, uInt16 flags)
{ {
return mySystem.peek(addr, flags); return mySystem.peek(addr, flags);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt16 Debugger::dpeek(uInt16 addr, uInt8 flags) uInt16 Debugger::dpeek(uInt16 addr, uInt16 flags)
{ {
return uInt16(mySystem.peek(addr, flags) | (mySystem.peek(addr+1, flags) << 8)); return uInt16(mySystem.peek(addr, flags) | (mySystem.peek(addr+1, flags) << 8));
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::poke(uInt16 addr, uInt8 value, uInt8 flags) void Debugger::poke(uInt16 addr, uInt8 value, uInt16 flags)
{ {
mySystem.poke(addr, value, flags); mySystem.poke(addr, value, flags);
} }
@ -464,13 +464,13 @@ M6502& Debugger::m6502() const
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int Debugger::peekAsInt(int addr, uInt8 flags) int Debugger::peekAsInt(int addr, uInt16 flags)
{ {
return mySystem.peek(uInt16(addr), flags); return mySystem.peek(uInt16(addr), flags);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int Debugger::dpeekAsInt(int addr, uInt8 flags) int Debugger::dpeekAsInt(int addr, uInt16 flags)
{ {
return mySystem.peek(uInt16(addr), flags) | return mySystem.peek(uInt16(addr), flags) |
(mySystem.peek(uInt16(addr+1), flags) << 8); (mySystem.peek(uInt16(addr+1), flags) << 8);
@ -483,7 +483,7 @@ int Debugger::getAccessFlags(uInt16 addr) const
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::setAccessFlags(uInt16 addr, uInt8 flags) void Debugger::setAccessFlags(uInt16 addr, uInt16 flags)
{ {
mySystem.setAccessFlags(addr, flags); mySystem.setAccessFlags(addr, flags);
} }

View File

@ -243,18 +243,18 @@ class Debugger : public DialogContainer
static Debugger& debugger() { return *myStaticDebugger; } static Debugger& debugger() { return *myStaticDebugger; }
/** Convenience methods to access peek/poke from System */ /** Convenience methods to access peek/poke from System */
uInt8 peek(uInt16 addr, uInt8 flags = 0); uInt8 peek(uInt16 addr, uInt16 flags = 0);
uInt16 dpeek(uInt16 addr, uInt8 flags = 0); uInt16 dpeek(uInt16 addr, uInt16 flags = 0);
void poke(uInt16 addr, uInt8 value, uInt8 flags = 0); void poke(uInt16 addr, uInt8 value, uInt16 flags = 0);
/** Convenience method to access the 6502 from System */ /** Convenience method to access the 6502 from System */
M6502& m6502() const; M6502& m6502() const;
/** These are now exposed so Expressions can use them. */ /** These are now exposed so Expressions can use them. */
int peekAsInt(int addr, uInt8 flags = 0); int peekAsInt(int addr, uInt16 flags = 0);
int dpeekAsInt(int addr, uInt8 flags = 0); int dpeekAsInt(int addr, uInt16 flags = 0);
int getAccessFlags(uInt16 addr) const; int getAccessFlags(uInt16 addr) const;
void setAccessFlags(uInt16 addr, uInt8 flags); void setAccessFlags(uInt16 addr, uInt16 flags);
uInt32 getBaseAddress(uInt32 addr, bool read); uInt32 getBaseAddress(uInt32 addr, bool read);

View File

@ -125,14 +125,25 @@ void DiStella::disasm(uInt32 distart, int pass)
goto FIX_LAST; goto FIX_LAST;
if (checkBits(myPC, CartDebug::GFX | CartDebug::PGFX, if (checkBits(myPC, CartDebug::GFX | CartDebug::PGFX,
CartDebug::CODE)) { CartDebug::CODE))
{
if (pass == 2) if (pass == 2)
mark(myPC + myOffset, CartDebug::VALID_ENTRY); mark(myPC + myOffset, CartDebug::VALID_ENTRY);
if (pass == 3) if (pass == 3)
outputGraphics(); outputGraphics();
++myPC; ++myPC;
} else if (checkBits(myPC, CartDebug::COL | CartDebug::PCOL | CartDebug::BCOL,
CartDebug::CODE | CartDebug::GFX | CartDebug::PGFX))
{
if (pass == 2)
mark(myPC + myOffset, CartDebug::VALID_ENTRY);
if (pass == 3)
outputColors();
++myPC;
} else if (checkBits(myPC, CartDebug::DATA, } else if (checkBits(myPC, CartDebug::DATA,
CartDebug::CODE | CartDebug::GFX | CartDebug::PGFX)) { CartDebug::CODE | CartDebug::GFX | CartDebug::PGFX |
CartDebug::COL | CartDebug::PCOL | CartDebug::BCOL))
{
if (pass == 2) if (pass == 2)
mark(myPC + myOffset, CartDebug::VALID_ENTRY); mark(myPC + myOffset, CartDebug::VALID_ENTRY);
if (pass == 3) if (pass == 3)
@ -140,7 +151,9 @@ void DiStella::disasm(uInt32 distart, int pass)
else else
++myPC; ++myPC;
} else if (checkBits(myPC, CartDebug::ROW, } else if (checkBits(myPC, CartDebug::ROW,
CartDebug::CODE | CartDebug::DATA | CartDebug::GFX | CartDebug::PGFX)) { CartDebug::CODE |
CartDebug::DATA | CartDebug::GFX | CartDebug::PGFX |
CartDebug::COL | CartDebug::PCOL | CartDebug::BCOL)) {
FIX_LAST: FIX_LAST:
if (pass == 2) if (pass == 2)
mark(myPC + myOffset, CartDebug::VALID_ENTRY); mark(myPC + myOffset, CartDebug::VALID_ENTRY);
@ -606,12 +619,13 @@ void DiStella::disasmPass1(CartDebug::AddressList& debuggerAddresses)
// in the emulation core indicate that the CODE range has finished // in the emulation core indicate that the CODE range has finished
// 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, CartDebug::CartDebug::DATA | CartDebug::GFX | CartDebug::PGFX, if (checkBits(k, CartDebug::CartDebug::DATA | CartDebug::GFX | CartDebug::PGFX |
CartDebug::CODE)) { CartDebug::COL | CartDebug::PCOL | CartDebug::BCOL,
CartDebug::CODE)) {
//if (Debugger::debugger().getAccessFlags(k) & //if (Debugger::debugger().getAccessFlags(k) &
// (CartDebug::DATA | CartDebug::GFX | CartDebug::PGFX)) { // (CartDebug::DATA | CartDebug::GFX | CartDebug::PGFX)) {
// TODO: this should never happen, remove when we are sure // TODO: this should never happen, remove when we are sure
// TODO: NOT USED: uInt8 flags = Debugger::debugger().getAccessFlags(k); // TODO: NOT USED: uInt16 flags = Debugger::debugger().getAccessFlags(k);
myPCEnd = k - 1; myPCEnd = k - 1;
break; break;
} }
@ -667,8 +681,9 @@ void DiStella::disasmPass1(CartDebug::AddressList& debuggerAddresses)
} }
// Must be ROW / unused bytes // Must be ROW / unused bytes
if (!checkBit(k, CartDebug::CODE | CartDebug::GFX | if (!checkBit(k, CartDebug::CODE | CartDebug::GFX | CartDebug::PGFX |
CartDebug::PGFX | CartDebug::DATA)) CartDebug::COL | CartDebug::PCOL | CartDebug::BCOL |
CartDebug::DATA))
mark(k + myOffset, CartDebug::ROW); mark(k + myOffset, CartDebug::ROW);
} }
} }
@ -685,7 +700,9 @@ void DiStella::disasmFromAddress(uInt32 distart)
while (myPC <= myAppData.end) { while (myPC <= myAppData.end) {
// abort when we reach non-code areas // abort when we reach non-code areas
if (checkBits(myPC, CartDebug::CartDebug::DATA | CartDebug::GFX | CartDebug::PGFX, CartDebug::CODE)) { if (checkBits(myPC, CartDebug::CartDebug::DATA | CartDebug::GFX | CartDebug::PGFX |
CartDebug::COL | CartDebug::PCOL | CartDebug::BCOL,
CartDebug::CODE)) {
myPCEnd = (myPC - 1) + myOffset; myPCEnd = (myPC - 1) + myOffset;
return; return;
} }
@ -823,7 +840,7 @@ void DiStella::disasmFromAddress(uInt32 distart)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int DiStella::mark(uInt32 address, uInt8 mask, bool directive) int DiStella::mark(uInt32 address, uInt16 mask, bool directive)
{ {
/*----------------------------------------------------------------------- /*-----------------------------------------------------------------------
For any given offset and code range... For any given offset and code range...
@ -896,16 +913,16 @@ int DiStella::mark(uInt32 address, uInt8 mask, bool directive)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool DiStella::checkBit(uInt16 address, uInt8 mask, bool useDebugger) const bool DiStella::checkBit(uInt16 address, uInt16 mask, bool useDebugger) const
{ {
// The REFERENCED and VALID_ENTRY flags are needed for any inspection of // The REFERENCED and VALID_ENTRY flags are needed for any inspection of
// an address // an address
// Since they're set only in the labels array (as the lower two bits), // Since they're set only in the labels array (as the lower two bits),
// they must be included in the other bitfields // they must be included in the other bitfields
uInt8 label = myLabels[address & myAppData.end], uInt16 label = myLabels[address & myAppData.end],
lastbits = label & 0x03, lastbits = label & 0x03,
directive = myDirectives[address & myAppData.end] & 0xFC, directive = myDirectives[address & myAppData.end] & ~0x03,
debugger = Debugger::debugger().getAccessFlags(address | myOffset) & 0xFC; debugger = Debugger::debugger().getAccessFlags(address | myOffset) & ~0x03;
// Any address marked by a manual directive always takes priority // Any address marked by a manual directive always takes priority
if (directive) if (directive)
@ -918,11 +935,18 @@ bool DiStella::checkBit(uInt16 address, uInt8 mask, bool useDebugger) const
return label & mask; return label & mask;
} }
bool DiStella::checkBits(uInt16 address, uInt8 mask, uInt8 notMask, bool useDebugger) const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool DiStella::checkBits(uInt16 address, uInt16 mask, uInt16 notMask, bool useDebugger) const
{ {
return checkBit(address, mask, useDebugger) && !checkBit(address, notMask, useDebugger); return checkBit(address, mask, useDebugger) && !checkBit(address, notMask, useDebugger);
} }
/*bool DiStella::isType(uInt16 address) const
{
return checkBits(address, CartDebug::GFX | CartDebug::PGFX |
CartDebug::COL | CartDebug::PCOL | CartDebug::BCOL);
}*/
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool DiStella::check_range(uInt16 beg, uInt16 end) const bool DiStella::check_range(uInt16 beg, uInt16 end) const
{ {
@ -999,18 +1023,29 @@ void DiStella::addEntry(CartDebug::DisasmType type)
Debugger::debugger().setAccessFlags(tag.address, CartDebug::TCODE); Debugger::debugger().setAccessFlags(tag.address, CartDebug::TCODE);
} }
break; break;
case CartDebug::GFX: case CartDebug::GFX:
case CartDebug::PGFX: case CartDebug::PGFX:
getline(myDisasmBuf, tag.disasm, '\''); getline(myDisasmBuf, tag.disasm, '\'');
getline(myDisasmBuf, tag.bytes); getline(myDisasmBuf, tag.bytes);
break; break;
case CartDebug::COL:
case CartDebug::PCOL:
case CartDebug::BCOL:
getline(myDisasmBuf, tag.disasm, '\'');
getline(myDisasmBuf, tag.bytes);
break;
case CartDebug::DATA: case CartDebug::DATA:
getline(myDisasmBuf, tag.disasm, '\''); getline(myDisasmBuf, tag.disasm, '\'');
getline(myDisasmBuf, tag.bytes); getline(myDisasmBuf, tag.bytes);
break; break;
case CartDebug::ROW: case CartDebug::ROW:
getline(myDisasmBuf, tag.disasm); getline(myDisasmBuf, tag.disasm);
break; break;
case CartDebug::NONE: case CartDebug::NONE:
default: // should never happen default: // should never happen
tag.disasm = " "; tag.disasm = " ";
@ -1044,7 +1079,7 @@ void DiStella::outputGraphics()
myDisasmBuf << ".byte $" << Base::HEX2 << int(byte) << " |"; myDisasmBuf << ".byte $" << Base::HEX2 << int(byte) << " |";
for (uInt8 i = 0, c = byte; i < 8; ++i, c <<= 1) for (uInt8 i = 0, c = byte; i < 8; ++i, c <<= 1)
myDisasmBuf << ((c > 127) ? bitString : " "); myDisasmBuf << ((c > 127) ? bitString : " ");
myDisasmBuf << "| $" << Base::HEX4 << myPC + myOffset << "'"; myDisasmBuf << "| $" << Base::HEX4 << myPC + myOffset << "'";
if (mySettings.gfxFormat == Base::Fmt::_2) if (mySettings.gfxFormat == Base::Fmt::_2)
myDisasmBuf << Base::toString(byte, Base::Fmt::_2_8); myDisasmBuf << Base::toString(byte, Base::Fmt::_2_8);
else else
@ -1053,6 +1088,74 @@ void DiStella::outputGraphics()
addEntry(isPGfx ? CartDebug::PGFX : CartDebug::GFX); addEntry(isPGfx ? CartDebug::PGFX : CartDebug::GFX);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DiStella::outputColors()
{
string NTSC_COLOR[16] = {
"BLACK", "YELLOW", "BROWN", "ORANGE",
"RED", "MAUVE", "VIOLET", "PURPLE",
"BLUE", "BLUE_CYAN", "CYAN", "CYAN_GREEN",
"GREEN", "GREEN_YELLOW", "GREEN_BEIGE", "BEIGE"
};
string PAL_COLOR[16] = {
"BLACK0", "BLACK1", "YELLOW", "GREEN_YELLOW",
"ORANGE", "GREEN", "RED", "CYAN_GREEN",
"MAUVE", "CYAN", "VIOLET", "BLUE_CYAN",
"PURPLE", "BLUE", "BLACKE", "BLACKF"
};
string SECAM_COLOR[8] = {
"BLACK", "BLUE", "RED", "PURPLE",
"GREEN", "CYAN", "YELLOW", "WHITE"
};
uInt8 byte = Debugger::debugger().peek(myPC + myOffset);
// add extra spacing line when switching from non-colors to colors
if(mySegType != CartDebug::COL && mySegType != CartDebug::NONE)
{
myDisasmBuf << " ' ' ";
addEntry(CartDebug::NONE);
}
mySegType = CartDebug::COL;
// output label/address
if(checkBit(myPC, CartDebug::REFERENCED))
myDisasmBuf << Base::HEX4 << myPC + myOffset << "'L" << Base::HEX4 << myPC + myOffset << "'";
else
myDisasmBuf << Base::HEX4 << myPC + myOffset << "' '";
// output color
string color;
myDisasmBuf << ".byte ";
if(myDbg.myConsole.timing() == ConsoleTiming::ntsc)
{
color = NTSC_COLOR[byte >> 4];
myDisasmBuf << color << "|$" << Base::HEX1 << (byte & 0xf);
}
else if(myDbg.myConsole.timing() == ConsoleTiming::pal)
{
color = PAL_COLOR[byte >> 4];
myDisasmBuf << color << "|$" << Base::HEX1 << (byte & 0xf);
}
else
{
color = SECAM_COLOR[(byte >> 1) & 0x7];
myDisasmBuf << "$" << Base::HEX1 << (byte >> 4) << "|" << color;
}
myDisasmBuf << std::setw(16 - color.length()) << std::setfill(' ');
// output address
myDisasmBuf << "; $" << Base::HEX4 << myPC + myOffset << " "
<< (checkBit(myPC, CartDebug::COL) ? "(Px)" : checkBit(myPC, CartDebug::PCOL) ? "(PF)" : "(BK)");
// output color value
myDisasmBuf << "'" << Base::HEX2 << int(byte);
addEntry(checkBit(myPC, CartDebug::COL) ? CartDebug::COL :
checkBit(myPC, CartDebug::PCOL) ? CartDebug::PCOL : CartDebug::BCOL);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DiStella::outputBytes(CartDebug::DisasmType type) void DiStella::outputBytes(CartDebug::DisasmType type)
{ {
@ -1097,7 +1200,9 @@ void DiStella::outputBytes(CartDebug::DisasmType type)
++myPC; ++myPC;
} }
isType = checkBits(myPC, type, isType = checkBits(myPC, type,
CartDebug::CODE | (type != CartDebug::DATA ? CartDebug::DATA : 0) | CartDebug::GFX | CartDebug::PGFX); CartDebug::CODE | (type != CartDebug::DATA ? CartDebug::DATA : 0) |
CartDebug::GFX | CartDebug::PGFX |
CartDebug::COL | CartDebug::PCOL | CartDebug::BCOL);
referenced = checkBit(myPC, CartDebug::REFERENCED); referenced = checkBit(myPC, CartDebug::REFERENCED);
} }
if (!lineEmpty) if (!lineEmpty)

View File

@ -87,11 +87,12 @@ class DiStella
void disasmFromAddress(uInt32 distart); void disasmFromAddress(uInt32 distart);
bool check_range(uInt16 start, uInt16 end) const; bool check_range(uInt16 start, uInt16 end) const;
int mark(uInt32 address, uInt8 mask, bool directive = false); int mark(uInt32 address, uInt16 mask, bool directive = false);
bool checkBit(uInt16 address, uInt8 mask, bool useDebugger = true) const; bool checkBit(uInt16 address, uInt16 mask, bool useDebugger = true) const;
bool checkBits(uInt16 address, uInt16 mask, uInt16 notMask, bool useDebugger = true) const;
bool checkBits(uInt16 address, uInt8 mask, uInt8 notMask, bool useDebugger = true) const; //bool isType(uInt16 address) const;
void outputGraphics(); void outputGraphics();
void outputColors();
void outputBytes(CartDebug::DisasmType type); void outputBytes(CartDebug::DisasmType type);
// Convenience methods to generate appropriate labels // Convenience methods to generate appropriate labels

View File

@ -511,7 +511,8 @@ void RomListWidget::drawWidget(bool hilite)
// Bytes are only editable if they represent code, graphics, or accessible data // Bytes are only editable if they represent code, graphics, or accessible data
// Otherwise, the disassembly should get all remaining space // Otherwise, the disassembly should get all remaining space
if(dlist[pos].type & (CartDebug::CODE|CartDebug::GFX|CartDebug::PGFX|CartDebug::DATA)) if(dlist[pos].type & (CartDebug::CODE|CartDebug::GFX|CartDebug::PGFX|
CartDebug::COL|CartDebug::PCOL|CartDebug::BCOL|CartDebug::DATA))
{ {
if(dlist[pos].type == CartDebug::CODE) if(dlist[pos].type == CartDebug::CODE)
{ {

View File

@ -117,7 +117,7 @@ void Cartridge::pokeRAM(uInt8& dest, uInt16 address, uInt8 value)
void Cartridge::createCodeAccessBase(size_t size) void Cartridge::createCodeAccessBase(size_t size)
{ {
#ifdef DEBUGGER_SUPPORT #ifdef DEBUGGER_SUPPORT
myCodeAccessBase = make_unique<uInt8[]>(size); myCodeAccessBase = make_unique<uInt16[]>(size);
std::fill_n(myCodeAccessBase.get(), size, CartDebug::ROW); std::fill_n(myCodeAccessBase.get(), size, CartDebug::ROW);
#else #else
myCodeAccessBase = nullptr; myCodeAccessBase = nullptr;

View File

@ -322,7 +322,7 @@ class Cartridge : public Device
// The array containing information about every byte of ROM indicating // The array containing information about every byte of ROM indicating
// whether it is used as code. // whether it is used as code.
ByteBuffer myCodeAccessBase; WordBuffer myCodeAccessBase;
// Contains address of illegal RAM write access or 0 // Contains address of illegal RAM write access or 0
uInt16 myRamWriteAccess{0}; uInt16 myRamWriteAccess{0};

View File

@ -182,7 +182,7 @@ bool Cartridge4A50::poke(uInt16 address, uInt8 value)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 Cartridge4A50::getAccessFlags(uInt16 address) const uInt16 Cartridge4A50::getAccessFlags(uInt16 address) const
{ {
if((address & 0x1800) == 0x1000) // 2K region from 0x1000 - 0x17ff if((address & 0x1800) == 0x1000) // 2K region from 0x1000 - 0x17ff
{ {
@ -214,7 +214,7 @@ uInt8 Cartridge4A50::getAccessFlags(uInt16 address) const
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Cartridge4A50::setAccessFlags(uInt16 address, uInt8 flags) void Cartridge4A50::setAccessFlags(uInt16 address, uInt16 flags)
{ {
if((address & 0x1800) == 0x1000) // 2K region from 0x1000 - 0x17ff if((address & 0x1800) == 0x1000) // 2K region from 0x1000 - 0x17ff
{ {

View File

@ -158,14 +158,14 @@ class Cartridge4A50 : public Cartridge
@param address The address to query @param address The address to query
*/ */
uInt8 getAccessFlags(uInt16 address) const override; uInt16 getAccessFlags(uInt16 address) const override;
/** /**
Change the given address to use the given disassembly flags. Change the given address to use the given disassembly flags.
@param address The address to modify @param address The address to modify
@param flags A bitfield of DisasmType directives for the given address @param flags A bitfield of DisasmType directives for the given address
*/ */
void setAccessFlags(uInt16 address, uInt8 flags) override; void setAccessFlags(uInt16 address, uInt16 flags) override;
/** /**
Check all possible hotspots Check all possible hotspots

View File

@ -191,14 +191,14 @@ bool CartridgeAR::poke(uInt16 addr, uInt8)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 CartridgeAR::getAccessFlags(uInt16 address) const uInt16 CartridgeAR::getAccessFlags(uInt16 address) const
{ {
return myCodeAccessBase[(address & 0x07FF) + return myCodeAccessBase[(address & 0x07FF) +
myImageOffset[(address & 0x0800) ? 1 : 0]]; myImageOffset[(address & 0x0800) ? 1 : 0]];
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeAR::setAccessFlags(uInt16 address, uInt8 flags) void CartridgeAR::setAccessFlags(uInt16 address, uInt16 flags)
{ {
myCodeAccessBase[(address & 0x07FF) + myCodeAccessBase[(address & 0x07FF) +
myImageOffset[(address & 0x0800) ? 1 : 0]] |= flags; myImageOffset[(address & 0x0800) ? 1 : 0]] |= flags;

View File

@ -164,14 +164,14 @@ class CartridgeAR : public Cartridge
@param address The address to query @param address The address to query
*/ */
uInt8 getAccessFlags(uInt16 address) const override; uInt16 getAccessFlags(uInt16 address) const override;
/** /**
Change the given address to use the given disassembly flags. Change the given address to use the given disassembly flags.
@param address The address to modify @param address The address to modify
@param flags A bitfield of DisasmType directives for the given address @param flags A bitfield of DisasmType directives for the given address
*/ */
void setAccessFlags(uInt16 address, uInt8 flags) override; void setAccessFlags(uInt16 address, uInt16 flags) override;
// Handle a change to the bank configuration // Handle a change to the bank configuration
bool bankConfiguration(uInt8 configuration); bool bankConfiguration(uInt8 configuration);

View File

@ -102,7 +102,7 @@ class Device : public Serializable
@param address The address to modify @param address The address to modify
*/ */
virtual uInt8 getAccessFlags(uInt16 address) const { return 0; } virtual uInt16 getAccessFlags(uInt16 address) const { return 0; }
/** /**
Change the given address type to use the given disassembly flags Change the given address type to use the given disassembly flags
@ -110,7 +110,7 @@ class Device : public Serializable
@param address The address to modify @param address The address to modify
@param flags A bitfield of DisasmType directives for the given address @param flags A bitfield of DisasmType directives for the given address
*/ */
virtual void setAccessFlags(uInt16 address, uInt8 flags) { } virtual void setAccessFlags(uInt16 address, uInt16 flags) { }
protected: protected:
/// Pointer to the system the device is installed in or the null pointer /// Pointer to the system the device is installed in or the null pointer

View File

@ -104,7 +104,7 @@ void M6502::reset()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
inline uInt8 M6502::peek(uInt16 address, uInt8 flags) inline uInt8 M6502::peek(uInt16 address, uInt16 flags)
{ {
handleHalt(); handleHalt();
@ -144,7 +144,7 @@ inline uInt8 M6502::peek(uInt16 address, uInt8 flags)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
inline void M6502::poke(uInt16 address, uInt8 value, uInt8 flags) inline void M6502::poke(uInt16 address, uInt8 value, uInt16 flags)
{ {
//////////////////////////////////////////////// ////////////////////////////////////////////////
// TODO - move this logic directly into CartAR // TODO - move this logic directly into CartAR

View File

@ -269,7 +269,7 @@ class M6502 : public Serializable
@return The byte at the specified address @return The byte at the specified address
*/ */
uInt8 peek(uInt16 address, uInt8 flags); uInt8 peek(uInt16 address, uInt16 flags);
/** /**
Change the byte at the specified address to the given value and Change the byte at the specified address to the given value and
@ -278,7 +278,7 @@ class M6502 : public Serializable
@param address The address where the value should be stored @param address The address where the value should be stored
@param value The value to be stored at the address @param value The value to be stored at the address
*/ */
void poke(uInt16 address, uInt8 value, uInt8 flags = 0); void poke(uInt16 address, uInt8 value, uInt16 flags = 0);
/** /**
Get the 8-bit value of the Processor Status register. Get the 8-bit value of the Processor Status register.
@ -391,7 +391,7 @@ class M6502 : public Serializable
/// accessed specifically by a peek or poke command /// accessed specifically by a peek or poke command
uInt16 myLastPeekBaseAddress{0}, myLastPokeBaseAddress{0}; uInt16 myLastPeekBaseAddress{0}, myLastPokeBaseAddress{0};
// Indicates the type of the last access // Indicates the type of the last access
uInt8 myFlags{0}; uInt16 myFlags{0};
/// Indicates the last address used to access data by a peek command /// Indicates the last address used to access data by a peek command
/// for the CPU registers (S/A/X/Y) /// for the CPU registers (S/A/X/Y)

View File

@ -467,7 +467,7 @@ void M6532::createAccessBases()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 M6532::getAccessFlags(uInt16 address) const uInt16 M6532::getAccessFlags(uInt16 address) const
{ {
if (address & IO_BIT) if (address & IO_BIT)
return myIOAccessBase[address & IO_MASK]; return myIOAccessBase[address & IO_MASK];
@ -478,7 +478,7 @@ uInt8 M6532::getAccessFlags(uInt16 address) const
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void M6532::setAccessFlags(uInt16 address, uInt8 flags) void M6532::setAccessFlags(uInt16 address, uInt16 flags)
{ {
// ignore none flag // ignore none flag
if (flags != CartDebug::NONE) { if (flags != CartDebug::NONE) {

View File

@ -151,14 +151,14 @@ class M6532 : public Device
@param address The address to query @param address The address to query
*/ */
uInt8 getAccessFlags(uInt16 address) const override; uInt16 getAccessFlags(uInt16 address) const override;
/** /**
Change the given address to use the given disassembly flags. Change the given address to use the given disassembly flags.
@param address The address to modify @param address The address to modify
@param flags A bitfield of DisasmType directives for the given address @param flags A bitfield of DisasmType directives for the given address
*/ */
void setAccessFlags(uInt16 address, uInt8 flags) override; void setAccessFlags(uInt16 address, uInt16 flags) override;
#endif // DEBUGGER_SUPPORT #endif // DEBUGGER_SUPPORT
private: private:
@ -225,9 +225,9 @@ class M6532 : public Device
// The arrays containing information about every byte of RIOT // The arrays containing information about every byte of RIOT
// indicating whether and how (RW) it is used. // indicating whether and how (RW) it is used.
std::array<uInt8, RAM_SIZE> myRAMAccessBase; std::array<uInt16, RAM_SIZE> myRAMAccessBase;
std::array<uInt8, STACK_SIZE> myStackAccessBase; std::array<uInt16, STACK_SIZE> myStackAccessBase;
std::array<uInt8, IO_SIZE> myIOAccessBase; std::array<uInt16, IO_SIZE> myIOAccessBase;
// The array used to skip the first ZP access tracking // The array used to skip the first ZP access tracking
std::array<uInt8, RAM_SIZE> myZPAccessDelay; std::array<uInt8, RAM_SIZE> myZPAccessDelay;
#endif // DEBUGGER_SUPPORT #endif // DEBUGGER_SUPPORT

View File

@ -99,7 +99,7 @@ void System::clearDirtyPages()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 System::peek(uInt16 addr, uInt8 flags) uInt8 System::peek(uInt16 addr, uInt16 flags)
{ {
const PageAccess& access = getPageAccess(addr); const PageAccess& access = getPageAccess(addr);
@ -127,7 +127,7 @@ uInt8 System::peek(uInt16 addr, uInt8 flags)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void System::poke(uInt16 addr, uInt8 value, uInt8 flags) void System::poke(uInt16 addr, uInt8 value, uInt16 flags)
{ {
uInt16 page = (addr & ADDRESS_MASK) >> PAGE_SHIFT; uInt16 page = (addr & ADDRESS_MASK) >> PAGE_SHIFT;
const PageAccess& access = myPageAccessTable[page]; const PageAccess& access = myPageAccessTable[page];
@ -160,7 +160,7 @@ void System::poke(uInt16 addr, uInt8 value, uInt8 flags)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 System::getAccessFlags(uInt16 addr) const uInt16 System::getAccessFlags(uInt16 addr) const
{ {
#ifdef DEBUGGER_SUPPORT #ifdef DEBUGGER_SUPPORT
const PageAccess& access = getPageAccess(addr); const PageAccess& access = getPageAccess(addr);
@ -175,7 +175,7 @@ uInt8 System::getAccessFlags(uInt16 addr) const
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void System::setAccessFlags(uInt16 addr, uInt8 flags) void System::setAccessFlags(uInt16 addr, uInt16 flags)
{ {
#ifdef DEBUGGER_SUPPORT #ifdef DEBUGGER_SUPPORT
const PageAccess& access = getPageAccess(addr); const PageAccess& access = getPageAccess(addr);

View File

@ -202,7 +202,7 @@ class System : public Serializable
@return The byte at the specified address @return The byte at the specified address
*/ */
uInt8 peek(uInt16 address, uInt8 flags = 0); uInt8 peek(uInt16 address, uInt16 flags = 0);
/** /**
Change the byte at the specified address to the given value. Change the byte at the specified address to the given value.
@ -217,7 +217,7 @@ class System : public Serializable
@param address The address where the value should be stored @param address The address where the value should be stored
@param value The value to be stored at the address @param value The value to be stored at the address
*/ */
void poke(uInt16 address, uInt8 value, uInt8 flags = 0); void poke(uInt16 address, uInt8 value, uInt16 flags = 0);
/** /**
Lock/unlock the data bus. When the bus is locked, peek() and Lock/unlock the data bus. When the bus is locked, peek() and
@ -236,8 +236,8 @@ class System : public Serializable
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/DATA/ROW. only really acts on CODE/GFX/PGFX/DATA/ROW.
*/ */
uInt8 getAccessFlags(uInt16 address) const; uInt16 getAccessFlags(uInt16 address) const;
void setAccessFlags(uInt16 address, uInt8 flags); void setAccessFlags(uInt16 address, uInt16 flags);
public: public:
/** /**
@ -277,7 +277,7 @@ class System : public Serializable
conclusively determine if a section of address space is CODE, even conclusively determine if a section of address space is CODE, even
if the disassembler failed to mark it as such. if the disassembler failed to mark it as such.
*/ */
uInt8* codeAccessBase{nullptr}; uInt16* codeAccessBase{nullptr};
/** /**
Pointer to the device associated with this page or to the system's Pointer to the device associated with this page or to the system's

View File

@ -568,26 +568,47 @@ bool TIA::poke(uInt16 address, uInt8 value)
break; break;
case COLUBK: case COLUBK:
{
value &= 0xFE; value &= 0xFE;
myBackground.setColor(value); myBackground.setColor(value);
myShadowRegisters[address] = value; myShadowRegisters[address] = value;
#ifdef DEBUGGER_SUPPORT
uInt16 dataAddr = mySystem->m6502().lastDataAddressForPoke();
if(dataAddr)
mySystem->setAccessFlags(dataAddr, CartDebug::BCOL);
#endif
break; break;
}
case COLUP0: case COLUP0:
{
value &= 0xFE; value &= 0xFE;
myPlayfield.setColorP0(value); myPlayfield.setColorP0(value);
myMissile0.setColor(value); myMissile0.setColor(value);
myPlayer0.setColor(value); myPlayer0.setColor(value);
myShadowRegisters[address] = value; myShadowRegisters[address] = value;
#ifdef DEBUGGER_SUPPORT
uInt16 dataAddr = mySystem->m6502().lastDataAddressForPoke();
if(dataAddr)
mySystem->setAccessFlags(dataAddr, CartDebug::COL);
#endif
break; break;
}
case COLUP1: case COLUP1:
{
value &= 0xFE; value &= 0xFE;
myPlayfield.setColorP1(value); myPlayfield.setColorP1(value);
myMissile1.setColor(value); myMissile1.setColor(value);
myPlayer1.setColor(value); myPlayer1.setColor(value);
myShadowRegisters[address] = value; myShadowRegisters[address] = value;
#ifdef DEBUGGER_SUPPORT
uInt16 dataAddr = mySystem->m6502().lastDataAddressForPoke();
if(dataAddr)
mySystem->setAccessFlags(dataAddr, CartDebug::COL);
#endif
break; break;
}
case CTRLPF: case CTRLPF:
flushLineCache(); flushLineCache();
@ -599,9 +620,10 @@ bool TIA::poke(uInt16 address, uInt8 value)
break; break;
case COLUPF: case COLUPF:
{
flushLineCache(); flushLineCache();
value &= 0xFE; value &= 0xFE;
if (myPFColorDelay) if(myPFColorDelay)
myDelayQueue.push(COLUPF, value, 1); myDelayQueue.push(COLUPF, value, 1);
else else
{ {
@ -609,7 +631,13 @@ bool TIA::poke(uInt16 address, uInt8 value)
myBall.setColor(value); myBall.setColor(value);
myShadowRegisters[address] = value; myShadowRegisters[address] = value;
} }
#ifdef DEBUGGER_SUPPORT
uInt16 dataAddr = mySystem->m6502().lastDataAddressForPoke();
if(dataAddr)
mySystem->setAccessFlags(dataAddr, CartDebug::PCOL);
#endif
break; break;
}
case PF0: case PF0:
{ {
@ -1891,13 +1919,13 @@ void TIA::createAccessBase()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIA::getAccessFlags(uInt16 address) const uInt16 TIA::getAccessFlags(uInt16 address) const
{ {
return myAccessBase[address & TIA_MASK]; return myAccessBase[address & TIA_MASK];
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::setAccessFlags(uInt16 address, uInt8 flags) void TIA::setAccessFlags(uInt16 address, uInt16 flags)
{ {
// ignore none flag // ignore none flag
if (flags != CartDebug::NONE) { if (flags != CartDebug::NONE) {

View File

@ -685,14 +685,14 @@ class TIA : public Device
* *
* @param address The address to query * @param address The address to query
*/ */
uInt8 getAccessFlags(uInt16 address) const override; uInt16 getAccessFlags(uInt16 address) const override;
/** /**
* Change the given address to use the given disassembly flags. * Change the given address to use the given disassembly flags.
* *
* @param address The address to modify * @param address The address to modify
* @param flags A bitfield of DisasmType directives for the given address * @param flags A bitfield of DisasmType directives for the given address
*/ */
void setAccessFlags(uInt16 address, uInt8 flags) override; void setAccessFlags(uInt16 address, uInt16 flags) override;
#endif // DEBUGGER_SUPPORT #endif // DEBUGGER_SUPPORT
private: private:
@ -901,7 +901,7 @@ class TIA : public Device
#ifdef DEBUGGER_SUPPORT #ifdef DEBUGGER_SUPPORT
// The arrays containing information about every byte of TIA // The arrays containing information about every byte of TIA
// indicating whether and how (RW) it is used. // indicating whether and how (RW) it is used.
std::array<uInt8, TIA_SIZE> myAccessBase; std::array<uInt16, TIA_SIZE> myAccessBase;
// The array used to skip the first two TIA access trackings // The array used to skip the first two TIA access trackings
std::array<uInt8, TIA_SIZE> myAccessDelay; std::array<uInt8, TIA_SIZE> myAccessDelay;