mirror of https://github.com/stella-emu/stella.git
Merge remote-tracking branch 'remotes/origin/refactor/cart'
This commit is contained in:
commit
5c7bea8923
|
@ -36,6 +36,10 @@
|
||||||
|
|
||||||
* Restored 'cfg' directory for Distella config files.
|
* Restored 'cfg' directory for Distella config files.
|
||||||
|
|
||||||
|
* Added 3EX bank switching type.
|
||||||
|
|
||||||
|
* Removed unused CV+ and DASH bank switching types.
|
||||||
|
|
||||||
-Have fun!
|
-Have fun!
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3808,7 +3808,9 @@ Ms Pac-Man (Stella extended codes):
|
||||||
<p>Each block in a property file consists of a set of properties for a single
|
<p>Each block in a property file consists of a set of properties for a single
|
||||||
game. Stella supports the properties described below:</p>
|
game. Stella supports the properties described below:</p>
|
||||||
|
|
||||||
<a><img src="graphics/options_gameinfo_emulation.png"></a>
|
<p>
|
||||||
|
<a><img src="graphics/options_gameinfo_emulation.png"></a>
|
||||||
|
</p>
|
||||||
<table CELLSPACING="10">
|
<table CELLSPACING="10">
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -3829,9 +3831,10 @@ Ms Pac-Man (Stella extended codes):
|
||||||
<tr><td>32IN1 ¹</td><td>64-128K Multicart (32 games) </td><td>.32N, .32N1 </td></tr>
|
<tr><td>32IN1 ¹</td><td>64-128K Multicart (32 games) </td><td>.32N, .32N1 </td></tr>
|
||||||
<tr><td>64IN1 ¹</td><td>64/128K Multicart </td><td>.64N, .64N1 </td></tr>
|
<tr><td>64IN1 ¹</td><td>64/128K Multicart </td><td>.64N, .64N1 </td></tr>
|
||||||
<tr><td>128IN1 ¹</td><td>256/512K Multicart </td><td>.128, .128N1 </td></tr>
|
<tr><td>128IN1 ¹</td><td>256/512K Multicart </td><td>.128, .128N1 </td></tr>
|
||||||
<tr><td>2K </td><td>32-2048 byte Atari </td><td>.2K </td></tr>
|
<tr><td>2K </td><td>32-2048 bytes Atari </td><td>.2K </td></tr>
|
||||||
<tr><td>3E </td><td>32K Tigervision </td><td>.3E </td></tr>
|
<tr><td>3E </td><td>512K Tigervision + 32K RAM</td><td>.3E </td></tr>
|
||||||
<tr><td>3E+ </td><td>3E+ (TJ modified DASH) </td><td>.3EP, .3E+ </td></tr>
|
<tr><td>3EX </td><td>512K Tigervision + 256K RAM</td><td>.3EX </td></tr>
|
||||||
|
<tr><td>3E+ </td><td>3E+ (TJ modified 3E) </td><td>.3EP, .3E+ </td></tr>
|
||||||
<tr><td>3F </td><td>512K Tigervision </td><td>.3F </td></tr>
|
<tr><td>3F </td><td>512K Tigervision </td><td>.3F </td></tr>
|
||||||
<tr><td>4A50 ²</td><td>64K 4A50 + RAM </td><td>.4A5, .4A50 </td></tr>
|
<tr><td>4A50 ²</td><td>64K 4A50 + RAM </td><td>.4A5, .4A50 </td></tr>
|
||||||
<tr><td>4K </td><td>4K Atari </td><td>.4K </td></tr>
|
<tr><td>4K </td><td>4K Atari </td><td>.4K </td></tr>
|
||||||
|
@ -3843,9 +3846,7 @@ Ms Pac-Man (Stella extended codes):
|
||||||
<tr><td>CDF </td><td>Chris, Darrell, Fred (includes CDFJ)</td><td>.CDF </td></tr>
|
<tr><td>CDF </td><td>Chris, Darrell, Fred (includes CDFJ)</td><td>.CDF </td></tr>
|
||||||
<tr><td>CM ¹</td><td>Spectravideo CompuMate </td><td>.CM </td></tr>
|
<tr><td>CM ¹</td><td>Spectravideo CompuMate </td><td>.CM </td></tr>
|
||||||
<tr><td>CTY ²</td><td>CDW - Chetiry </td><td>.CTY </td></tr>
|
<tr><td>CTY ²</td><td>CDW - Chetiry </td><td>.CTY </td></tr>
|
||||||
<tr><td>CV </td><td>Commavid extra RAM </td><td>.CV </td></tr>
|
<tr><td>CV </td><td>CommaVid extra RAM </td><td>.CV </td></tr>
|
||||||
<tr><td>CV+ </td><td>Extended Commavid extra RAM</td><td>.CVP </td></tr>
|
|
||||||
<tr><td>DASH </td><td>Boulder Dash 2 </td><td>.DAS, .DASH </td></tr>
|
|
||||||
<tr><td>DF </td><td>CPUWIZ 128K </td><td>.DF </td></tr>
|
<tr><td>DF </td><td>CPUWIZ 128K </td><td>.DF </td></tr>
|
||||||
<tr><td>DFSC </td><td>CPUWIZ 128K + RAM</td><td>.DFS, .DFSC </td></tr>
|
<tr><td>DFSC </td><td>CPUWIZ 128K + RAM</td><td>.DFS, .DFSC </td></tr>
|
||||||
<tr><td>DPC </td><td>Pitfall II </td><td>.DPC </td></tr>
|
<tr><td>DPC </td><td>Pitfall II </td><td>.DPC </td></tr>
|
||||||
|
@ -3867,7 +3868,7 @@ Ms Pac-Man (Stella extended codes):
|
||||||
<tr><td>FC </td><td>Amiga Power Play Aracde 16/32K </td><td>.FC </td></tr>
|
<tr><td>FC </td><td>Amiga Power Play Aracde 16/32K </td><td>.FC </td></tr>
|
||||||
<tr><td>FE </td><td>8K Decathlon </td><td>.FE </td></tr>
|
<tr><td>FE </td><td>8K Decathlon </td><td>.FE </td></tr>
|
||||||
<tr><td>MDM </td><td>Menu Driven Megacart </td><td>.MDM </td></tr>
|
<tr><td>MDM </td><td>Menu Driven Megacart </td><td>.MDM </td></tr>
|
||||||
<tr><td>SB </td><td>128-256k SUPERbanking </td><td>.SB </td></tr>
|
<tr><td>SB </td><td>128-256K SUPERbanking </td><td>.SB </td></tr>
|
||||||
<tr><td>UA </td><td>8K UA Ltd. </td><td>.UA </td></tr>
|
<tr><td>UA </td><td>8K UA Ltd. </td><td>.UA </td></tr>
|
||||||
<tr><td>UASW </td><td>8K UA Ltd. (swapped banks)</td><td>.UASW </td></tr>
|
<tr><td>UASW </td><td>8K UA Ltd. (swapped banks)</td><td>.UASW </td></tr>
|
||||||
<tr><td>WD </td><td>Wickstead Design (Pink Panther) </td><td>.WD </td></tr>
|
<tr><td>WD </td><td>Wickstead Design (Pink Panther) </td><td>.WD </td></tr>
|
||||||
|
@ -3927,11 +3928,15 @@ Ms Pac-Man (Stella extended codes):
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
|
</br>
|
||||||
<!--
|
<!--
|
||||||
<p><b>Note:</b> Items marked as '*' are deprecated, and will probably be
|
<p><b>Note:</b> Items marked as '*' are deprecated, and will probably be
|
||||||
removed in a future release.</p>
|
removed in a future release.</p>
|
||||||
-->
|
-->
|
||||||
<a><img src="graphics/options_gameinfo_console.png"></a>
|
<p>
|
||||||
|
<a><img src="graphics/options_gameinfo_console.png"></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<table CELLSPACING="10">
|
<table CELLSPACING="10">
|
||||||
<tr>
|
<tr>
|
||||||
<td VALIGN="TOP"><i>Console.TelevisionType:</i></td>
|
<td VALIGN="TOP"><i>Console.TelevisionType:</i></td>
|
||||||
|
@ -3951,8 +3956,11 @@ Ms Pac-Man (Stella extended codes):
|
||||||
right player. The value must be <b>A</b> or <b>B</b>.</td>
|
right player. The value must be <b>A</b> or <b>B</b>.</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
</br>
|
||||||
|
|
||||||
<a name="Controller"><img src="graphics/options_gameinfo_controller.png"></a>
|
<p>
|
||||||
|
<a name="Controller"><img src="graphics/options_gameinfo_controller.png"></a>
|
||||||
|
</p>
|
||||||
<table CELLSPACING="10">
|
<table CELLSPACING="10">
|
||||||
<tr>
|
<tr>
|
||||||
<td VALIGN="TOP"><i>Controller.Left:</i><br><i>Controller.Right:</i></td>
|
<td VALIGN="TOP"><i>Controller.Left:</i><br><i>Controller.Right:</i></td>
|
||||||
|
@ -4027,8 +4035,11 @@ Ms Pac-Man (Stella extended codes):
|
||||||
how to use the X/Y axis (ie, 02 is paddle0/paddle2).
|
how to use the X/Y axis (ie, 02 is paddle0/paddle2).
|
||||||
-->
|
-->
|
||||||
</table>
|
</table>
|
||||||
|
</br>
|
||||||
|
|
||||||
<a><img src="graphics/options_gameinfo_cartridge.png"></a>
|
<p>
|
||||||
|
<a><img src="graphics/options_gameinfo_cartridge.png"></a>
|
||||||
|
</p>
|
||||||
<table CELLSPACING="10">
|
<table CELLSPACING="10">
|
||||||
<tr>
|
<tr>
|
||||||
<td VALIGN="TOP"><i>Cartridge.Name:</i></td>
|
<td VALIGN="TOP"><i>Cartridge.Name:</i></td>
|
||||||
|
|
|
@ -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 DWordBuffer = std::unique_ptr<uInt32[]>; // 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)
|
||||||
|
|
|
@ -79,7 +79,10 @@ CartDebug::CartDebug(Debugger& dbg, Console& console, const OSystem& osystem)
|
||||||
|
|
||||||
BankInfo info;
|
BankInfo info;
|
||||||
info.size = std::min<size_t>(romSize, 4_KB);
|
info.size = std::min<size_t>(romSize, 4_KB);
|
||||||
for(uInt32 i = 0; i < myConsole.cartridge().bankCount(); ++i)
|
for(uInt32 i = 0; i < myConsole.cartridge().romBankCount(); ++i)
|
||||||
|
myBankInfo.push_back(info);
|
||||||
|
|
||||||
|
for(uInt32 i = 0; i < myConsole.cartridge().ramBankCount(); ++i)
|
||||||
myBankInfo.push_back(info);
|
myBankInfo.push_back(info);
|
||||||
|
|
||||||
info.size = 128; // ZP RAM
|
info.size = 128; // ZP RAM
|
||||||
|
@ -239,9 +242,10 @@ string CartDebug::toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool CartDebug::disassemble(bool force)
|
bool CartDebug::disassemblePC(bool force)
|
||||||
{
|
{
|
||||||
uInt16 PC = myDebugger.cpuDebug().pc();
|
uInt16 PC = myDebugger.cpuDebug().pc();
|
||||||
|
// ROM/RAM bank or ZP-RAM?
|
||||||
int bank = (PC & 0x1000) ? getBank(PC) : int(myBankInfo.size()) - 1;
|
int bank = (PC & 0x1000) ? getBank(PC) : int(myBankInfo.size()) - 1;
|
||||||
|
|
||||||
return disassemble(bank, PC, force);
|
return disassemble(bank, PC, force);
|
||||||
|
@ -418,7 +422,7 @@ bool CartDebug::addDirective(Device::AccessType type,
|
||||||
bank = (myDebugger.cpuDebug().pc() & 0x1000) ?
|
bank = (myDebugger.cpuDebug().pc() & 0x1000) ?
|
||||||
getBank(myDebugger.cpuDebug().pc()) : int(myBankInfo.size())-1;
|
getBank(myDebugger.cpuDebug().pc()) : int(myBankInfo.size())-1;
|
||||||
|
|
||||||
bank = std::min(bank, bankCount());
|
bank = std::min(bank, romBankCount());
|
||||||
BankInfo& info = myBankInfo[bank];
|
BankInfo& info = myBankInfo[bank];
|
||||||
DirectiveList& list = info.directiveList;
|
DirectiveList& list = info.directiveList;
|
||||||
|
|
||||||
|
@ -550,9 +554,9 @@ int CartDebug::getPCBank()
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
int CartDebug::bankCount() const
|
int CartDebug::romBankCount() const
|
||||||
{
|
{
|
||||||
return myConsole.cartridge().bankCount();
|
return myConsole.cartridge().romBankCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -959,7 +963,7 @@ string CartDebug::loadConfigFile()
|
||||||
myDebugger.rom().invalidate();
|
myDebugger.rom().invalidate();
|
||||||
|
|
||||||
stringstream retVal;
|
stringstream retVal;
|
||||||
if(myConsole.cartridge().bankCount() > 1)
|
if(myConsole.cartridge().romBankCount() > 1)
|
||||||
retVal << DebuggerParser::red("config file for multi-bank ROM not fully supported\n");
|
retVal << DebuggerParser::red("config file for multi-bank ROM not fully supported\n");
|
||||||
retVal << "config file '" << node.getShortPath() << "' loaded OK";
|
retVal << "config file '" << node.getShortPath() << "' loaded OK";
|
||||||
return retVal.str();
|
return retVal.str();
|
||||||
|
@ -994,14 +998,14 @@ string CartDebug::saveConfigFile()
|
||||||
out << "// Stella.pro: \"" << name << "\"" << endl
|
out << "// Stella.pro: \"" << name << "\"" << endl
|
||||||
<< "// MD5: " << md5 << endl
|
<< "// MD5: " << md5 << endl
|
||||||
<< endl;
|
<< endl;
|
||||||
for(uInt32 b = 0; b < myConsole.cartridge().bankCount(); ++b)
|
for(uInt32 b = 0; b < myConsole.cartridge().romBankCount(); ++b)
|
||||||
{
|
{
|
||||||
out << "[" << b << "]" << endl;
|
out << "[" << b << "]" << endl;
|
||||||
getBankDirectives(out, myBankInfo[b]);
|
getBankDirectives(out, myBankInfo[b]);
|
||||||
}
|
}
|
||||||
|
|
||||||
stringstream retVal;
|
stringstream retVal;
|
||||||
if(myConsole.cartridge().bankCount() > 1)
|
if(myConsole.cartridge().romBankCount() > 1)
|
||||||
retVal << DebuggerParser::red("config file for multi-bank ROM not fully supported\n");
|
retVal << DebuggerParser::red("config file for multi-bank ROM not fully supported\n");
|
||||||
retVal << "config file '" << cfg.getShortPath() << "' saved OK";
|
retVal << "config file '" << cfg.getShortPath() << "' saved OK";
|
||||||
return retVal.str();
|
return retVal.str();
|
||||||
|
@ -1062,14 +1066,14 @@ string CartDebug::saveDisassembly()
|
||||||
|
|
||||||
Disassembly disasm;
|
Disassembly disasm;
|
||||||
disasm.list.reserve(2048);
|
disasm.list.reserve(2048);
|
||||||
uInt16 bankCount = myConsole.cartridge().bankCount();
|
uInt16 romBankCount = myConsole.cartridge().romBankCount();
|
||||||
uInt16 oldBank = myConsole.cartridge().getBank();
|
uInt16 oldBank = myConsole.cartridge().getBank();
|
||||||
|
|
||||||
// prepare for switching banks
|
// prepare for switching banks
|
||||||
myConsole.cartridge().unlockBank();
|
myConsole.cartridge().unlockBank();
|
||||||
uInt32 origin = 0;
|
uInt32 origin = 0;
|
||||||
|
|
||||||
for(int bank = 0; bank < bankCount; ++bank)
|
for(int bank = 0; bank < romBankCount; ++bank)
|
||||||
{
|
{
|
||||||
// TODO: not every CartDebugWidget does it like that, we need a method
|
// TODO: not every CartDebugWidget does it like that, we need a method
|
||||||
myConsole.cartridge().unlockBank();
|
myConsole.cartridge().unlockBank();
|
||||||
|
@ -1086,8 +1090,8 @@ string CartDebug::saveDisassembly()
|
||||||
|
|
||||||
buf << "\n\n;***********************************************************\n"
|
buf << "\n\n;***********************************************************\n"
|
||||||
<< "; Bank " << bank;
|
<< "; Bank " << bank;
|
||||||
if (bankCount > 1)
|
if (romBankCount > 1)
|
||||||
buf << " / 0.." << bankCount - 1;
|
buf << " / 0.." << romBankCount - 1;
|
||||||
buf << "\n;***********************************************************\n\n";
|
buf << "\n;***********************************************************\n\n";
|
||||||
|
|
||||||
|
|
||||||
|
@ -1101,7 +1105,7 @@ string CartDebug::saveDisassembly()
|
||||||
|
|
||||||
buf << " SEG CODE\n";
|
buf << " SEG CODE\n";
|
||||||
|
|
||||||
if(bankCount == 1)
|
if(romBankCount == 1)
|
||||||
buf << " ORG $" << Base::HEX4 << info.offset << "\n\n";
|
buf << " ORG $" << Base::HEX4 << info.offset << "\n\n";
|
||||||
else
|
else
|
||||||
buf << " ORG $" << Base::HEX4 << origin << "\n"
|
buf << " ORG $" << Base::HEX4 << origin << "\n"
|
||||||
|
@ -1331,7 +1335,7 @@ string CartDebug::saveDisassembly()
|
||||||
out << buf.str();
|
out << buf.str();
|
||||||
|
|
||||||
stringstream retVal;
|
stringstream retVal;
|
||||||
if(myConsole.cartridge().bankCount() > 1)
|
if(myConsole.cartridge().romBankCount() > 1)
|
||||||
retVal << DebuggerParser::red("disassembly for multi-bank ROM not fully supported\n");
|
retVal << DebuggerParser::red("disassembly for multi-bank ROM not fully supported\n");
|
||||||
retVal << "saved " << node.getShortPath() << " OK";
|
retVal << "saved " << node.getShortPath() << " OK";
|
||||||
return retVal.str();
|
return retVal.str();
|
||||||
|
@ -1371,8 +1375,8 @@ string CartDebug::saveAccessFile()
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
string CartDebug::listConfig(int bank)
|
string CartDebug::listConfig(int bank)
|
||||||
{
|
{
|
||||||
uInt32 startbank = 0, endbank = bankCount();
|
uInt32 startbank = 0, endbank = romBankCount();
|
||||||
if(bank >= 0 && bank < bankCount())
|
if(bank >= 0 && bank < romBankCount())
|
||||||
{
|
{
|
||||||
startbank = bank;
|
startbank = bank;
|
||||||
endbank = startbank + 1;
|
endbank = startbank + 1;
|
||||||
|
@ -1396,7 +1400,7 @@ string CartDebug::listConfig(int bank)
|
||||||
getBankDirectives(buf, info);
|
getBankDirectives(buf, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(myConsole.cartridge().bankCount() > 1)
|
if(myConsole.cartridge().romBankCount() > 1)
|
||||||
buf << DebuggerParser::red("config file for multi-bank ROM not fully supported") << endl;
|
buf << DebuggerParser::red("config file for multi-bank ROM not fully supported") << endl;
|
||||||
|
|
||||||
return buf.str();
|
return buf.str();
|
||||||
|
@ -1405,8 +1409,8 @@ string CartDebug::listConfig(int bank)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
string CartDebug::clearConfig(int bank)
|
string CartDebug::clearConfig(int bank)
|
||||||
{
|
{
|
||||||
uInt32 startbank = 0, endbank = bankCount();
|
uInt32 startbank = 0, endbank = romBankCount();
|
||||||
if(bank >= 0 && bank < bankCount())
|
if(bank >= 0 && bank < romBankCount())
|
||||||
{
|
{
|
||||||
startbank = bank;
|
startbank = bank;
|
||||||
endbank = startbank + 1;
|
endbank = startbank + 1;
|
||||||
|
|
|
@ -95,7 +95,7 @@ class CartDebug : public DebuggerSystem
|
||||||
int lastWriteBaseAddress();
|
int lastWriteBaseAddress();
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
bool disassemble(bool force = false);
|
bool disassemblePC(bool force = false);
|
||||||
bool disassembleBank(int bank);
|
bool disassembleBank(int bank);
|
||||||
|
|
||||||
// First, a call is made to disassemble(), which updates the disassembly
|
// First, a call is made to disassemble(), which updates the disassembly
|
||||||
|
@ -159,7 +159,7 @@ class CartDebug : public DebuggerSystem
|
||||||
/**
|
/**
|
||||||
Get the total number of banks supported by the cartridge.
|
Get the total number of banks supported by the cartridge.
|
||||||
*/
|
*/
|
||||||
int bankCount() const;
|
int romBankCount() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Add a label and associated address.
|
Add a label and associated address.
|
||||||
|
|
|
@ -763,7 +763,7 @@ void DebuggerParser::executeBreak()
|
||||||
{
|
{
|
||||||
uInt16 addr;
|
uInt16 addr;
|
||||||
uInt8 bank;
|
uInt8 bank;
|
||||||
uInt32 bankCount = debugger.cartDebug().bankCount();
|
uInt32 romBankCount = debugger.cartDebug().romBankCount();
|
||||||
|
|
||||||
if(argCount == 0)
|
if(argCount == 0)
|
||||||
addr = debugger.cpuDebug().pc();
|
addr = debugger.cpuDebug().pc();
|
||||||
|
@ -775,7 +775,7 @@ void DebuggerParser::executeBreak()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bank = args[1];
|
bank = args[1];
|
||||||
if(bank >= bankCount && bank != 0xff)
|
if(bank >= romBankCount && bank != 0xff)
|
||||||
{
|
{
|
||||||
commandResult << red("invalid bank");
|
commandResult << red("invalid bank");
|
||||||
return;
|
return;
|
||||||
|
@ -791,12 +791,12 @@ void DebuggerParser::executeBreak()
|
||||||
commandResult << "cleared";
|
commandResult << "cleared";
|
||||||
|
|
||||||
commandResult << " breakpoint at $" << Base::HEX4 << addr << " + mirrors";
|
commandResult << " breakpoint at $" << Base::HEX4 << addr << " + mirrors";
|
||||||
if(bankCount > 1)
|
if(romBankCount > 1)
|
||||||
commandResult << " in bank #" << std::dec << int(bank);
|
commandResult << " in bank #" << std::dec << int(bank);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for(int i = 0; i < debugger.cartDebug().bankCount(); ++i)
|
for(int i = 0; i < debugger.cartDebug().romBankCount(); ++i)
|
||||||
{
|
{
|
||||||
bool set = debugger.toggleBreakPoint(addr, i);
|
bool set = debugger.toggleBreakPoint(addr, i);
|
||||||
|
|
||||||
|
@ -809,7 +809,7 @@ void DebuggerParser::executeBreak()
|
||||||
commandResult << "cleared";
|
commandResult << "cleared";
|
||||||
|
|
||||||
commandResult << " breakpoint at $" << Base::HEX4 << addr << " + mirrors";
|
commandResult << " breakpoint at $" << Base::HEX4 << addr << " + mirrors";
|
||||||
if(bankCount > 1)
|
if(romBankCount > 1)
|
||||||
commandResult << " in bank #" << std::dec << int(bank);
|
commandResult << " in bank #" << std::dec << int(bank);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1459,11 +1459,11 @@ void DebuggerParser::executeListbreaks()
|
||||||
{
|
{
|
||||||
stringstream buf;
|
stringstream buf;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
uInt32 bankCount = debugger.cartDebug().bankCount();
|
uInt32 romBankCount = debugger.cartDebug().romBankCount();
|
||||||
|
|
||||||
for(const auto& bp : debugger.breakPoints().getBreakpoints())
|
for(const auto& bp : debugger.breakPoints().getBreakpoints())
|
||||||
{
|
{
|
||||||
if(bankCount == 1)
|
if(romBankCount == 1)
|
||||||
{
|
{
|
||||||
buf << debugger.cartDebug().getLabel(bp.addr, true, 4) << " ";
|
buf << debugger.cartDebug().getLabel(bp.addr, true, 4) << " ";
|
||||||
if(!(++count % 8)) buf << endl;
|
if(!(++count % 8)) buf << endl;
|
||||||
|
|
|
@ -16,80 +16,25 @@
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "Cart0840.hxx"
|
#include "Cart0840.hxx"
|
||||||
#include "PopUpWidget.hxx"
|
|
||||||
#include "Cart0840Widget.hxx"
|
#include "Cart0840Widget.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Cartridge0840Widget::Cartridge0840Widget(
|
Cartridge0840Widget::Cartridge0840Widget(
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h, Cartridge0840& cart)
|
int x, int y, int w, int h, Cartridge0840& cart)
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||||
myCart(cart)
|
|
||||||
{
|
{
|
||||||
uInt16 size = 2 * 4096;
|
myHotspotDelta = 0x40;
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string Cartridge0840Widget::description()
|
||||||
|
{
|
||||||
ostringstream info;
|
ostringstream info;
|
||||||
info << "0840 ECONObanking, two 4K banks\n"
|
|
||||||
<< "Startup bank = " << cart.startBank() << "\n";
|
|
||||||
|
|
||||||
// Eventually, we should query this from the debugger/disassembler
|
info << "0840 ECONObanking, two 4K banks\n";
|
||||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0x800; i < 2;
|
info << CartridgeEnhancedWidget::description();
|
||||||
++i, offset += 0x1000, spot += 0x40)
|
|
||||||
{
|
|
||||||
uInt16 start = uInt16((cart.myImage[offset+1] << 8) | cart.myImage[offset]);
|
|
||||||
start -= start % 0x1000;
|
|
||||||
info << "Bank " << i << " @ $" << Common::Base::HEX4 << start << " - "
|
|
||||||
<< "$" << (start + 0xFFF) << " (hotspot = $" << spot << ")\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
int xpos = 2,
|
return info.str();
|
||||||
ypos = addBaseInformation(size, "Fred X. Quimby", info.str()) + myLineHeight;
|
|
||||||
|
|
||||||
VariantList items;
|
|
||||||
VarList::push_back(items, "0 ($800)");
|
|
||||||
VarList::push_back(items, "1 ($840)");
|
|
||||||
myBank =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("0 ($800)"),
|
|
||||||
myLineHeight, items, "Set bank ",
|
|
||||||
0, kBankChanged);
|
|
||||||
myBank->setTarget(this);
|
|
||||||
addFocusWidget(myBank);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void Cartridge0840Widget::loadConfig()
|
|
||||||
{
|
|
||||||
Debugger& dbg = instance().debugger();
|
|
||||||
CartDebug& cart = dbg.cartDebug();
|
|
||||||
const CartState& state = static_cast<const CartState&>(cart.getState());
|
|
||||||
const CartState& oldstate = static_cast<const CartState&>(cart.getOldState());
|
|
||||||
|
|
||||||
myBank->setSelectedIndex(myCart.getBank(), state.bank != oldstate.bank);
|
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void Cartridge0840Widget::handleCommand(CommandSender* sender,
|
|
||||||
int cmd, int data, int id)
|
|
||||||
{
|
|
||||||
if(cmd == kBankChanged)
|
|
||||||
{
|
|
||||||
myCart.unlockBank();
|
|
||||||
myCart.bank(myBank->getSelected());
|
|
||||||
myCart.lockBank();
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string Cartridge0840Widget::bankState()
|
|
||||||
{
|
|
||||||
ostringstream& buf = buffer();
|
|
||||||
|
|
||||||
static const std::array<string, 2> spot = { "$800", "$840" };
|
|
||||||
buf << "Bank = " << std::dec << myCart.getBank()
|
|
||||||
<< ", hotspot = " << spot[myCart.getBank()];
|
|
||||||
|
|
||||||
return buf.str();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,10 @@
|
||||||
#define CARTRIDGE0840_WIDGET_HXX
|
#define CARTRIDGE0840_WIDGET_HXX
|
||||||
|
|
||||||
class Cartridge0840;
|
class Cartridge0840;
|
||||||
class PopUpWidget;
|
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
#include "CartEnhancedWidget.hxx"
|
||||||
|
|
||||||
class Cartridge0840Widget : public CartDebugWidget
|
class Cartridge0840Widget : public CartridgeEnhancedWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Cartridge0840Widget(GuiObject* boss, const GUI::Font& lfont,
|
Cartridge0840Widget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
|
@ -33,17 +32,11 @@ class Cartridge0840Widget : public CartDebugWidget
|
||||||
virtual ~Cartridge0840Widget() = default;
|
virtual ~Cartridge0840Widget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Cartridge0840& myCart;
|
string manufacturer() override { return "Fred X. Quimby"; }
|
||||||
PopUpWidget* myBank{nullptr};
|
|
||||||
|
|
||||||
enum { kBankChanged = 'bkCH' };
|
string description() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void loadConfig() override;
|
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
|
||||||
|
|
||||||
string bankState() override;
|
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
Cartridge0840Widget() = delete;
|
Cartridge0840Widget() = delete;
|
||||||
Cartridge0840Widget(const Cartridge0840Widget&) = delete;
|
Cartridge0840Widget(const Cartridge0840Widget&) = delete;
|
||||||
|
|
|
@ -22,15 +22,18 @@
|
||||||
Cartridge2KWidget::Cartridge2KWidget(
|
Cartridge2KWidget::Cartridge2KWidget(
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h, Cartridge2K& cart)
|
int x, int y, int w, int h, Cartridge2K& cart)
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h)
|
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||||
{
|
{
|
||||||
// Eventually, we should query this from the debugger/disassembler
|
initialize();
|
||||||
size_t size = cart.mySize;
|
}
|
||||||
uInt16 start = (cart.myImage[size-3] << 8) | cart.myImage[size-4];
|
|
||||||
start -= start % size;
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string Cartridge2KWidget::description()
|
||||||
ostringstream info;
|
{
|
||||||
info << "Standard 2K cartridge, non-bankswitched\n"
|
ostringstream info;
|
||||||
<< "Accessible @ $" << Common::Base::HEX4 << start << " - " << "$" << (start + size - 1);
|
|
||||||
addBaseInformation(size, "Atari", info.str());
|
info << "Standard 2K cartridge, non-bankswitched\n";
|
||||||
|
info << CartridgeEnhancedWidget::description();
|
||||||
|
|
||||||
|
return info.str();
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,9 +20,9 @@
|
||||||
|
|
||||||
class Cartridge2K;
|
class Cartridge2K;
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
#include "CartEnhancedWidget.hxx"
|
||||||
|
|
||||||
class Cartridge2KWidget : public CartDebugWidget
|
class Cartridge2KWidget : public CartridgeEnhancedWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Cartridge2KWidget(GuiObject* boss, const GUI::Font& lfont,
|
Cartridge2KWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
|
@ -32,10 +32,11 @@ class Cartridge2KWidget : public CartDebugWidget
|
||||||
virtual ~Cartridge2KWidget() = default;
|
virtual ~Cartridge2KWidget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// No implementation for non-bankswitched ROMs
|
string manufacturer() override { return "Atari"; }
|
||||||
void loadConfig() override { }
|
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override { }
|
|
||||||
|
|
||||||
|
string description() override;
|
||||||
|
|
||||||
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
Cartridge2KWidget() = delete;
|
Cartridge2KWidget() = delete;
|
||||||
Cartridge2KWidget(const Cartridge2KWidget&) = delete;
|
Cartridge2KWidget(const Cartridge2KWidget&) = delete;
|
||||||
|
|
|
@ -18,121 +18,124 @@
|
||||||
#include "Cart3EPlus.hxx"
|
#include "Cart3EPlus.hxx"
|
||||||
#include "EditTextWidget.hxx"
|
#include "EditTextWidget.hxx"
|
||||||
#include "PopUpWidget.hxx"
|
#include "PopUpWidget.hxx"
|
||||||
#include "Cart3EPlusWidget.hxx"
|
#include "CartEnhancedWidget.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Cartridge3EPlusWidget::Cartridge3EPlusWidget(
|
Cartridge3EPlusWidget::Cartridge3EPlusWidget(
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h, Cartridge3EPlus& cart)
|
int x, int y, int w, int h, Cartridge3EPlus& cart)
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart),
|
||||||
myCart(cart)
|
myCart3EP(cart)
|
||||||
{
|
{
|
||||||
size_t size = cart.mySize;
|
initialize();
|
||||||
|
|
||||||
ostringstream info;
|
|
||||||
info << "3EPlus cartridge - (64K ROM + RAM)\n"
|
|
||||||
<< " 4-64K ROM (1K banks), 32K RAM (512b banks)\n"
|
|
||||||
<< "Each 1K ROM selected by writing to $3F\n"
|
|
||||||
"Each 512b RAM selected by writing to $3E\n"
|
|
||||||
" Lower 512b of bank x (R)\n"
|
|
||||||
" Upper 512b of bank x (+$200) (W)\n"
|
|
||||||
<< "Startup bank = 0/-1/-1/0 (ROM)\n";
|
|
||||||
|
|
||||||
// Eventually, we should query this from the debugger/disassembler
|
|
||||||
//uInt16 start = (cart.myImage[size-3] << 8) | cart.myImage[size-4];
|
|
||||||
// Currently the cart starts at bank 0. If we change that, we have to change this too.
|
|
||||||
uInt16 start = (cart.myImage[0x400-3] << 8) | cart.myImage[0x400 - 4];
|
|
||||||
start -= start % 0x1000;
|
|
||||||
info << "Bank RORG" << " = $" << Common::Base::HEX4 << start << "\n";
|
|
||||||
|
|
||||||
int xpos = 2,
|
|
||||||
ypos = addBaseInformation(size, "T. Jentzsch", info.str()) +
|
|
||||||
myLineHeight;
|
|
||||||
|
|
||||||
VariantList bankno;
|
|
||||||
for(uInt32 i = 0; i < myCart.ROM_BANK_COUNT; ++i)
|
|
||||||
VarList::push_back(bankno, i, i);
|
|
||||||
|
|
||||||
VariantList banktype;
|
|
||||||
VarList::push_back(banktype, "ROM", "ROM");
|
|
||||||
VarList::push_back(banktype, "RAM", "RAM");
|
|
||||||
|
|
||||||
for(uInt32 i = 0; i < 4; ++i)
|
|
||||||
{
|
|
||||||
int xpos_s, ypos_s = ypos;
|
|
||||||
|
|
||||||
ostringstream label;
|
|
||||||
label << "Set segment " << i << " as ";
|
|
||||||
|
|
||||||
new StaticTextWidget(boss, _font, xpos, ypos, _font.getStringWidth(label.str()),
|
|
||||||
myFontHeight, label.str(), TextAlign::Left);
|
|
||||||
ypos += myLineHeight + 8;
|
|
||||||
|
|
||||||
xpos += 20;
|
|
||||||
myBankNumber[i] =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("Slot "),
|
|
||||||
myLineHeight, bankno, "Slot ",
|
|
||||||
6*_font.getMaxCharWidth());
|
|
||||||
addFocusWidget(myBankNumber[i]);
|
|
||||||
|
|
||||||
xpos += myBankNumber[i]->getWidth();
|
|
||||||
myBankType[i] =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, 5*_font.getMaxCharWidth(),
|
|
||||||
myLineHeight, banktype, " of ", _font.getStringWidth(" of "));
|
|
||||||
addFocusWidget(myBankType[i]);
|
|
||||||
|
|
||||||
xpos += myBankType[i]->getWidth() + 10;
|
|
||||||
|
|
||||||
myBankCommit[i] = new ButtonWidget(boss, _font, xpos, ypos-4,
|
|
||||||
_font.getStringWidth(" Commit "), myButtonHeight,
|
|
||||||
"Commit", bankEnum[i]);
|
|
||||||
myBankCommit[i]->setTarget(this);
|
|
||||||
addFocusWidget(myBankCommit[i]);
|
|
||||||
|
|
||||||
xpos_s = xpos + myBankCommit[i]->getWidth() + 20;
|
|
||||||
|
|
||||||
StaticTextWidget* t;
|
|
||||||
int addr1 = start + (i*0x400), addr2 = addr1 + 0x1FF;
|
|
||||||
|
|
||||||
label.str("");
|
|
||||||
label << Common::Base::HEX4 << addr1 << "-" << Common::Base::HEX4 << addr2;
|
|
||||||
t = new StaticTextWidget(boss, _font, xpos_s, ypos_s+2,
|
|
||||||
_font.getStringWidth(label.str()), myFontHeight, label.str(), TextAlign::Left);
|
|
||||||
|
|
||||||
int xoffset = xpos_s+t->getWidth() + 10;
|
|
||||||
myBankState[2*i] = new EditTextWidget(boss, _font, xoffset, ypos_s,
|
|
||||||
w - xoffset - 10, myLineHeight, "");
|
|
||||||
myBankState[2*i]->setEditable(false, true);
|
|
||||||
ypos_s += myLineHeight + 4;
|
|
||||||
|
|
||||||
label.str("");
|
|
||||||
label << Common::Base::HEX4 << (addr2 + 1) << "-" << Common::Base::HEX4 << (addr2 + 1 + 0x1FF);
|
|
||||||
new StaticTextWidget(boss, _font, xpos_s, ypos_s+2,
|
|
||||||
_font.getStringWidth(label.str()), myFontHeight, label.str(), TextAlign::Left);
|
|
||||||
|
|
||||||
myBankState[2*i+1] = new EditTextWidget(boss, _font, xoffset, ypos_s,
|
|
||||||
w - xoffset - 10, myLineHeight, "");
|
|
||||||
myBankState[2*i+1]->setEditable(false, true);
|
|
||||||
|
|
||||||
xpos = 10;
|
|
||||||
ypos+= 2 * myLineHeight;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Cartridge3EPlusWidget::saveOldState()
|
string Cartridge3EPlusWidget::description()
|
||||||
{
|
{
|
||||||
myOldState.internalram.clear();
|
ostringstream info;
|
||||||
|
size_t size;
|
||||||
|
const uInt8* image = myCart.getImage(size);
|
||||||
|
uInt16 numRomBanks = myCart.romBankCount();
|
||||||
|
uInt16 numRamBanks = myCart.ramBankCount();
|
||||||
|
|
||||||
for(uInt32 i = 0; i < internalRamSize(); ++i)
|
info << "3E+ cartridge - (4..64K ROM + RAM)\n"
|
||||||
myOldState.internalram.push_back(myCart.myRAM[i]);
|
<< " " << numRomBanks << " 1K ROM banks + " << numRamBanks << " 512b RAM banks\n"
|
||||||
|
<< " mapped into four segments\n"
|
||||||
|
"ROM bank & segment selected by writing to $3F\n"
|
||||||
|
"RAM bank & segment selected by writing to $3E\n"
|
||||||
|
" Lower 512b of segment for read access\n"
|
||||||
|
" Upper 512b of segment for write access\n"
|
||||||
|
"Startup bank = 0/-1/-1/0 (ROM)\n";
|
||||||
|
|
||||||
|
// Eventually, we should query this from the debugger/disassembler
|
||||||
|
uInt16 start = (image[0x400 - 3] << 8) | image[0x400 - 4];
|
||||||
|
start -= start % 0x1000;
|
||||||
|
info << "Bank RORG" << " = $" << Common::Base::HEX4 << start << "\n";
|
||||||
|
|
||||||
|
return info.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void Cartridge3EPlusWidget::bankSelect(int& ypos)
|
||||||
|
{
|
||||||
|
size_t size;
|
||||||
|
const uInt8* image = myCart.getImage(size);
|
||||||
|
VariantList banktype;
|
||||||
|
|
||||||
|
VarList::push_back(banktype, "ROM", "ROM");
|
||||||
|
VarList::push_back(banktype, "RAM", "RAM");
|
||||||
|
|
||||||
|
myBankWidgets = make_unique<PopUpWidget* []>(bankSegs());
|
||||||
|
|
||||||
|
for(uInt32 seg = 0; seg < bankSegs(); ++seg)
|
||||||
|
{
|
||||||
|
int xpos = 2, xpos_s, ypos_s = ypos + 1, width;
|
||||||
|
ostringstream label;
|
||||||
|
VariantList items;
|
||||||
|
|
||||||
|
label << "Set segment " << seg << " as ";
|
||||||
|
|
||||||
|
new StaticTextWidget(_boss, _font, xpos, ypos, label.str());
|
||||||
|
ypos += myLineHeight + 8;
|
||||||
|
|
||||||
|
xpos += _font.getMaxCharWidth() * 2;
|
||||||
|
|
||||||
|
CartridgeEnhancedWidget::bankList(myCart.romBankCount(), seg, items, width);
|
||||||
|
myBankWidgets[seg] =
|
||||||
|
new PopUpWidget(_boss, _font, xpos, ypos - 2, width,
|
||||||
|
myLineHeight, items, "Bank ");
|
||||||
|
addFocusWidget(myBankWidgets[seg]);
|
||||||
|
|
||||||
|
xpos += myBankWidgets[seg]->getWidth();
|
||||||
|
myBankType[seg] =
|
||||||
|
new PopUpWidget(_boss, _font, xpos, ypos - 2, 3 * _font.getMaxCharWidth(),
|
||||||
|
myLineHeight, banktype, " of ");
|
||||||
|
addFocusWidget(myBankType[seg]);
|
||||||
|
|
||||||
|
xpos = myBankType[seg]->getRight() + _font.getMaxCharWidth();
|
||||||
|
|
||||||
|
// add "Commit" button (why required?)
|
||||||
|
myBankCommit[seg] = new ButtonWidget(_boss, _font, xpos, ypos - 4,
|
||||||
|
_font.getStringWidth(" Commit "), myButtonHeight,
|
||||||
|
"Commit", bankEnum[seg]);
|
||||||
|
myBankCommit[seg]->setTarget(this);
|
||||||
|
addFocusWidget(myBankCommit[seg]);
|
||||||
|
|
||||||
|
xpos_s = myBankCommit[seg]->getRight() + _font.getMaxCharWidth() * 2;
|
||||||
|
|
||||||
|
StaticTextWidget* t;
|
||||||
|
uInt16 start = (image[0x400 - 3] << 8) | image[0x400 - 4];
|
||||||
|
start -= start % 0x1000;
|
||||||
|
int addr1 = start + (seg * 0x400), addr2 = addr1 + 0x200;
|
||||||
|
|
||||||
|
label.str("");
|
||||||
|
label << "$" << Common::Base::HEX4 << addr1 << "-$" << Common::Base::HEX4 << (addr1 + 0x1FF);
|
||||||
|
t = new StaticTextWidget(_boss, _font, xpos_s, ypos_s + 2, label.str());
|
||||||
|
|
||||||
|
int xoffset = t->getRight() + _font.getMaxCharWidth();
|
||||||
|
myBankState[2 * seg] = new EditTextWidget(_boss, _font, xoffset, ypos_s,
|
||||||
|
_w - xoffset - 10, myLineHeight, "");
|
||||||
|
myBankState[2 * seg]->setEditable(false, true);
|
||||||
|
ypos_s += myLineHeight + 4;
|
||||||
|
|
||||||
|
label.str("");
|
||||||
|
label << "$" << Common::Base::HEX4 << addr2 << "-$" << Common::Base::HEX4 << (addr2 + 0x1FF);
|
||||||
|
new StaticTextWidget(_boss, _font, xpos_s, ypos_s + 2, label.str());
|
||||||
|
|
||||||
|
myBankState[2 * seg + 1] = new EditTextWidget(_boss, _font, xoffset, ypos_s,
|
||||||
|
_w - xoffset - 10, myLineHeight, "");
|
||||||
|
myBankState[2 * seg + 1]->setEditable(false, true);
|
||||||
|
|
||||||
|
ypos += 2 * myLineHeight;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Cartridge3EPlusWidget::loadConfig()
|
void Cartridge3EPlusWidget::loadConfig()
|
||||||
{
|
{
|
||||||
|
CartridgeEnhancedWidget::loadConfig();
|
||||||
updateUIState();
|
updateUIState();
|
||||||
CartDebugWidget::loadConfig();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -159,178 +162,79 @@ void Cartridge3EPlusWidget::handleCommand(CommandSender* sender,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore bank if either number or type hasn't been selected
|
// Ignore bank if either number or type hasn't been selected
|
||||||
if(myBankNumber[segment]->getSelected() < 0 ||
|
if(myBankWidgets[segment]->getSelected() < 0 ||
|
||||||
myBankType[segment]->getSelected() < 0)
|
myBankType[segment]->getSelected() < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uInt8 bank = (segment << myCart.BANK_BITS) |
|
uInt8 bank = myBankWidgets[segment]->getSelected();
|
||||||
(myBankNumber[segment]->getSelected() & myCart.BIT_BANK_MASK);
|
|
||||||
|
|
||||||
myCart.unlockBank();
|
myCart.unlockBank();
|
||||||
|
|
||||||
if(myBankType[segment]->getSelectedTag() == "ROM")
|
if(myBankType[segment]->getSelectedTag() == "ROM")
|
||||||
myCart.bankROM(bank);
|
myCart.bank(bank, segment);
|
||||||
else
|
else
|
||||||
myCart.bankRAM(bank);
|
myCart.bank(bank + myCart.romBankCount(), segment);
|
||||||
|
|
||||||
myCart.lockBank();
|
myCart.lockBank();
|
||||||
invalidate();
|
invalidate();
|
||||||
updateUIState();
|
updateUIState();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string Cartridge3EPlusWidget::bankState()
|
|
||||||
{
|
|
||||||
ostringstream& buf = buffer();
|
|
||||||
|
|
||||||
// In this scheme, consecutive 512b segments are either both ROM or both RAM;
|
|
||||||
// we only need to look at the lower segment to determine what the 1K bank is
|
|
||||||
for(int i = 0; i < 4; ++i)
|
|
||||||
{
|
|
||||||
uInt16 bank = myCart.bankInUse[i*2];
|
|
||||||
|
|
||||||
if(bank == myCart.BANK_UNDEFINED) // never accessed
|
|
||||||
{
|
|
||||||
buf << " U!";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int bankno = bank & myCart.BIT_BANK_MASK;
|
|
||||||
|
|
||||||
if(bank & myCart.BITMASK_ROMRAM) // was RAM mapped here?
|
|
||||||
buf << " RAM " << bankno;
|
|
||||||
else
|
|
||||||
buf << " ROM " << bankno;
|
|
||||||
}
|
|
||||||
if(i < 3)
|
|
||||||
buf << " /";
|
|
||||||
}
|
|
||||||
|
|
||||||
return buf.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Cartridge3EPlusWidget::updateUIState()
|
void Cartridge3EPlusWidget::updateUIState()
|
||||||
{
|
{
|
||||||
// Set description for each 512b bank state (@ each index)
|
// Set description for each 1K segment state (@ each index)
|
||||||
// Set contents for actual banks number and type (@ each even index)
|
// Set contents for actual banks number and type (@ each even index)
|
||||||
for(int i = 0; i < 8; ++i)
|
for(int seg = 0; seg < myCart3EP.myBankSegs; ++seg)
|
||||||
{
|
{
|
||||||
uInt16 bank = myCart.bankInUse[i];
|
uInt16 bank = myCart.getSegmentBank(seg);
|
||||||
|
ostringstream buf;
|
||||||
|
|
||||||
if(bank == myCart.BANK_UNDEFINED) // never accessed
|
if(bank >= myCart.romBankCount()) // was RAM mapped here?
|
||||||
{
|
{
|
||||||
myBankState[i]->setText("Undefined");
|
uInt16 ramBank = bank - myCart.romBankCount();
|
||||||
if(i % 2 == 0)
|
|
||||||
{
|
buf << "RAM @ $" << Common::Base::HEX4
|
||||||
myBankNumber[i/2]->clearSelection();
|
<< (ramBank << myCart3EP.myBankShift) << " (R)";
|
||||||
myBankType[i/2]->clearSelection();
|
myBankState[seg * 2]->setText(buf.str());
|
||||||
}
|
|
||||||
|
buf.str("");
|
||||||
|
buf << "RAM @ $" << Common::Base::HEX4
|
||||||
|
<< ((ramBank << myCart3EP.myBankShift) + myCart3EP.myBankSize) << " (W)";
|
||||||
|
myBankState[seg * 2 + 1]->setText(buf.str());
|
||||||
|
|
||||||
|
myBankWidgets[seg]->setSelectedIndex(ramBank);
|
||||||
|
myBankType[seg]->setSelected("RAM");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ostringstream buf;
|
buf << "ROM @ $" << Common::Base::HEX4
|
||||||
int bankno = bank & myCart.BIT_BANK_MASK;
|
<< ((bank << myCart3EP.myBankShift));
|
||||||
|
myBankState[seg * 2]->setText(buf.str());
|
||||||
|
|
||||||
if(bank & myCart.BITMASK_ROMRAM) // was RAM mapped here?
|
buf.str("");
|
||||||
{
|
buf << "ROM @ $" << Common::Base::HEX4
|
||||||
if(bank & myCart.BITMASK_LOWERUPPER) // upper is write port
|
<< ((bank << myCart3EP.myBankShift) + myCart3EP.myBankSize);
|
||||||
{
|
myBankState[seg * 2 + 1]->setText(buf.str());
|
||||||
buf << "RAM " << bankno << " @ $" << Common::Base::HEX4
|
|
||||||
<< (bankno << myCart.RAM_BANK_TO_POWER) << " (W)";
|
|
||||||
myBankState[i]->setText(buf.str());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
buf << "RAM " << bankno << " @ $" << Common::Base::HEX4
|
|
||||||
<< (bankno << myCart.RAM_BANK_TO_POWER) << " (R)";
|
|
||||||
myBankState[i]->setText(buf.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
if(i % 2 == 0)
|
myBankWidgets[seg]->setSelectedIndex(bank);
|
||||||
{
|
myBankType[seg]->setSelected("ROM");
|
||||||
myBankNumber[i/2]->setSelected(bankno);
|
|
||||||
myBankType[i/2]->setSelected("RAM");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(bank & myCart.BITMASK_LOWERUPPER) // upper is high 512b
|
|
||||||
{
|
|
||||||
buf << "ROM " << bankno << " @ $" << Common::Base::HEX4
|
|
||||||
<< ((bankno << myCart.RAM_BANK_TO_POWER) + myCart.RAM_BANK_SIZE);
|
|
||||||
myBankState[i]->setText(buf.str());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
buf << "ROM " << bankno << " @ $" << Common::Base::HEX4
|
|
||||||
<< (bankno << myCart.RAM_BANK_TO_POWER);
|
|
||||||
myBankState[i]->setText(buf.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
if(i % 2 == 0)
|
|
||||||
{
|
|
||||||
myBankNumber[i/2]->setSelected(bankno);
|
|
||||||
myBankType[i/2]->setSelected("ROM");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 Cartridge3EPlusWidget::internalRamSize()
|
|
||||||
{
|
|
||||||
return 32*1024;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 Cartridge3EPlusWidget::internalRamRPort(int start)
|
|
||||||
{
|
|
||||||
return 0x0000 + start;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
string Cartridge3EPlusWidget::internalRamDescription()
|
string Cartridge3EPlusWidget::internalRamDescription()
|
||||||
{
|
{
|
||||||
ostringstream desc;
|
ostringstream desc;
|
||||||
|
|
||||||
desc << "Accessible 512b at a time via:\n"
|
desc << "Accessible 512b at a time via:\n"
|
||||||
<< " $f000/$f400/$f800/$fc00 for Read Access\n"
|
<< " $f000/$f400/$f800/$fc00 for read access\n"
|
||||||
<< " $f200/$f600/$fa00/$fe00 for Write Access (+$200)";
|
<< " $f200/$f600/$fa00/$fe00 for write access";
|
||||||
|
|
||||||
return desc.str();
|
return desc.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const ByteArray& Cartridge3EPlusWidget::internalRamOld(int start, int count)
|
|
||||||
{
|
|
||||||
myRamOld.clear();
|
|
||||||
for(int i = 0; i < count; i++)
|
|
||||||
myRamOld.push_back(myOldState.internalram[start + i]);
|
|
||||||
return myRamOld;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const ByteArray& Cartridge3EPlusWidget::internalRamCurrent(int start, int count)
|
|
||||||
{
|
|
||||||
myRamCurrent.clear();
|
|
||||||
for(int i = 0; i < count; i++)
|
|
||||||
myRamCurrent.push_back(myCart.myRAM[start + i]);
|
|
||||||
return myRamCurrent;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void Cartridge3EPlusWidget::internalRamSetValue(int addr, uInt8 value)
|
|
||||||
{
|
|
||||||
myCart.myRAM[addr] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt8 Cartridge3EPlusWidget::internalRamGetValue(int addr)
|
|
||||||
{
|
|
||||||
return myCart.myRAM[addr];
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
const std::array<Cartridge3EPlusWidget::BankID, 4> Cartridge3EPlusWidget::bankEnum = {
|
const std::array<Cartridge3EPlusWidget::BankID, 4> Cartridge3EPlusWidget::bankEnum = {
|
||||||
kBank0Changed, kBank1Changed, kBank2Changed, kBank3Changed
|
kBank0Changed, kBank1Changed, kBank2Changed, kBank3Changed
|
||||||
|
|
|
@ -23,9 +23,9 @@ class ButtonWidget;
|
||||||
class EditTextWidget;
|
class EditTextWidget;
|
||||||
class PopUpWidget;
|
class PopUpWidget;
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
#include "CartEnhancedWidget.hxx"
|
||||||
|
|
||||||
class Cartridge3EPlusWidget : public CartDebugWidget
|
class Cartridge3EPlusWidget : public CartridgeEnhancedWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Cartridge3EPlusWidget(GuiObject* boss, const GUI::Font& lfont,
|
Cartridge3EPlusWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
|
@ -35,21 +35,27 @@ class Cartridge3EPlusWidget : public CartDebugWidget
|
||||||
virtual ~Cartridge3EPlusWidget() = default;
|
virtual ~Cartridge3EPlusWidget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
string manufacturer() override { return "Thomas Jentzsch"; }
|
||||||
|
|
||||||
|
string description() override;
|
||||||
|
|
||||||
|
void bankSelect(int& ypos) override;
|
||||||
|
|
||||||
|
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
||||||
|
|
||||||
void updateUIState();
|
void updateUIState();
|
||||||
|
|
||||||
private:
|
void loadConfig() override;
|
||||||
Cartridge3EPlus& myCart;
|
|
||||||
|
string internalRamDescription() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Cartridge3EPlus& myCart3EP;
|
||||||
|
|
||||||
std::array<PopUpWidget*, 4> myBankNumber{nullptr};
|
|
||||||
std::array<PopUpWidget*, 4> myBankType{nullptr};
|
std::array<PopUpWidget*, 4> myBankType{nullptr};
|
||||||
std::array<ButtonWidget*, 4> myBankCommit{nullptr};
|
std::array<ButtonWidget*, 4> myBankCommit{nullptr};
|
||||||
std::array<EditTextWidget*, 8> myBankState{nullptr};
|
std::array<EditTextWidget*, 8> myBankState{nullptr};
|
||||||
|
|
||||||
struct CartState {
|
|
||||||
ByteArray internalram;
|
|
||||||
};
|
|
||||||
CartState myOldState;
|
|
||||||
|
|
||||||
enum BankID {
|
enum BankID {
|
||||||
kBank0Changed = 'b0CH',
|
kBank0Changed = 'b0CH',
|
||||||
kBank1Changed = 'b1CH',
|
kBank1Changed = 'b1CH',
|
||||||
|
@ -59,22 +65,6 @@ class Cartridge3EPlusWidget : public CartDebugWidget
|
||||||
static const std::array<BankID, 4> bankEnum;
|
static const std::array<BankID, 4> bankEnum;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void saveOldState() override;
|
|
||||||
void loadConfig() override;
|
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
|
||||||
|
|
||||||
string bankState() override;
|
|
||||||
|
|
||||||
// start of functions for Cartridge RAM tab
|
|
||||||
uInt32 internalRamSize() override;
|
|
||||||
uInt32 internalRamRPort(int start) override;
|
|
||||||
string internalRamDescription() override;
|
|
||||||
const ByteArray& internalRamOld(int start, int count) override;
|
|
||||||
const ByteArray& internalRamCurrent(int start, int count) override;
|
|
||||||
void internalRamSetValue(int addr, uInt8 value) override;
|
|
||||||
uInt8 internalRamGetValue(int addr) override;
|
|
||||||
// end of functions for Cartridge RAM tab
|
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
Cartridge3EPlusWidget() = delete;
|
Cartridge3EPlusWidget() = delete;
|
||||||
Cartridge3EPlusWidget(const Cartridge3EPlusWidget&) = delete;
|
Cartridge3EPlusWidget(const Cartridge3EPlusWidget&) = delete;
|
||||||
|
|
|
@ -23,129 +23,134 @@
|
||||||
Cartridge3EWidget::Cartridge3EWidget(
|
Cartridge3EWidget::Cartridge3EWidget(
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h, Cartridge3E& cart)
|
int x, int y, int w, int h, Cartridge3E& cart)
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||||
myCart(cart),
|
|
||||||
myNumRomBanks(uInt32(cart.mySize >> 11)),
|
|
||||||
myNumRamBanks(32)
|
|
||||||
{
|
{
|
||||||
size_t size = cart.mySize;
|
initialize();
|
||||||
|
|
||||||
ostringstream info;
|
|
||||||
info << "3E cartridge - (3F + RAM)\n"
|
|
||||||
<< " 2-256 2K ROM (currently " << myNumRomBanks << "), 32 1K RAM\n"
|
|
||||||
<< "First 2K (ROM) selected by writing to $3F\n"
|
|
||||||
"First 2K (RAM) selected by writing to $3E\n"
|
|
||||||
" $F000 - $F3FF (R), $F400 - $F7FF (W)\n"
|
|
||||||
"Last 2K always points to last 2K of ROM\n";
|
|
||||||
if(cart.startBank() < myNumRomBanks)
|
|
||||||
info << "Startup bank = " << cart.startBank() << " (ROM)\n";
|
|
||||||
else
|
|
||||||
info << "Startup bank = " << (cart.startBank()-myNumRomBanks) << " (RAM)\n";
|
|
||||||
|
|
||||||
// Eventually, we should query this from the debugger/disassembler
|
|
||||||
uInt16 start = (cart.myImage[size-3] << 8) | cart.myImage[size-4];
|
|
||||||
start -= start % 0x1000;
|
|
||||||
info << "Bank RORG" << " = $" << Common::Base::HEX4 << start << "\n";
|
|
||||||
|
|
||||||
int xpos = 2,
|
|
||||||
ypos = addBaseInformation(size, "TigerVision", info.str()) + myLineHeight;
|
|
||||||
|
|
||||||
VariantList romitems;
|
|
||||||
for(uInt32 i = 0; i < myNumRomBanks; ++i)
|
|
||||||
VarList::push_back(romitems, i);
|
|
||||||
VarList::push_back(romitems, "Inactive", "");
|
|
||||||
|
|
||||||
VariantList ramitems;
|
|
||||||
for(uInt32 i = 0; i < myNumRamBanks; ++i)
|
|
||||||
VarList::push_back(ramitems, i);
|
|
||||||
VarList::push_back(ramitems, "Inactive", "");
|
|
||||||
|
|
||||||
ostringstream label;
|
|
||||||
label << "Set bank ($" << Common::Base::HEX4 << start << " - $"
|
|
||||||
<< (start+0x7FF) << "): ";
|
|
||||||
|
|
||||||
new StaticTextWidget(_boss, _font, xpos, ypos, _font.getStringWidth(label.str()),
|
|
||||||
myFontHeight, label.str(), TextAlign::Left);
|
|
||||||
ypos += myLineHeight + 8;
|
|
||||||
|
|
||||||
xpos += 40;
|
|
||||||
myROMBank =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("0 ($3E) "),
|
|
||||||
myLineHeight, romitems, "ROM ($3F) ",
|
|
||||||
_font.getStringWidth("ROM ($3F) "), kROMBankChanged);
|
|
||||||
myROMBank->setTarget(this);
|
|
||||||
addFocusWidget(myROMBank);
|
|
||||||
|
|
||||||
xpos += myROMBank->getWidth() + 20;
|
|
||||||
myRAMBank =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("0 ($3E) "),
|
|
||||||
myLineHeight, ramitems, "RAM ($3E) ",
|
|
||||||
_font.getStringWidth("RAM ($3E) "), kRAMBankChanged);
|
|
||||||
myRAMBank->setTarget(this);
|
|
||||||
addFocusWidget(myRAMBank);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Cartridge3EWidget::saveOldState()
|
string Cartridge3EWidget::description()
|
||||||
{
|
{
|
||||||
myOldState.internalram.clear();
|
ostringstream info;
|
||||||
|
size_t size;
|
||||||
|
const uInt8* image = myCart.getImage(size);
|
||||||
|
uInt16 numRomBanks = myCart.romBankCount();
|
||||||
|
uInt16 numRamBanks = myCart.ramBankCount();
|
||||||
|
|
||||||
for(uInt32 i = 0; i < internalRamSize(); ++i)
|
|
||||||
myOldState.internalram.push_back(myCart.myRAM[i]);
|
|
||||||
|
|
||||||
myOldState.bank = myCart.myCurrentBank;
|
info << "3E cartridge (3F + RAM),\n"
|
||||||
|
<< " " << numRomBanks << " 2K ROM banks, " << numRamBanks << " 1K RAM banks\n"
|
||||||
|
<< "First 2K (ROM) selected by writing to $3F\n"
|
||||||
|
"First 2K (RAM) selected by writing to $3E\n";
|
||||||
|
info << CartridgeEnhancedWidget::ramDescription();
|
||||||
|
info << "Last 2K always points to last 2K of ROM\n";
|
||||||
|
|
||||||
|
if(myCart.startBank() < numRomBanks)
|
||||||
|
info << "Startup bank = " << myCart.startBank() << " (ROM)\n";
|
||||||
|
else
|
||||||
|
info << "Startup bank = " << (myCart.startBank() - numRomBanks) << " (RAM)\n";
|
||||||
|
|
||||||
|
// Eventually, we should query this from the debugger/disassembler
|
||||||
|
uInt16 start = (image[size-3] << 8) | image[size-4];
|
||||||
|
start -= start % 0x1000;
|
||||||
|
info << "Bank RORG" << " = $" << Common::Base::HEX4 << start << "\n";
|
||||||
|
|
||||||
|
return info.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void Cartridge3EWidget::bankList(uInt16 bankCount, int seg, VariantList& items, int& width)
|
||||||
|
{
|
||||||
|
CartridgeEnhancedWidget::bankList(bankCount, seg, items, width);
|
||||||
|
|
||||||
|
VarList::push_back(items, "Inactive", "");
|
||||||
|
width = _font.getStringWidth("Inactive");
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void Cartridge3EWidget::bankSelect(int& ypos)
|
||||||
|
{
|
||||||
|
int xpos = 2;
|
||||||
|
VariantList items;
|
||||||
|
int pw;
|
||||||
|
|
||||||
|
myBankWidgets = make_unique<PopUpWidget* []>(2);
|
||||||
|
|
||||||
|
bankList(myCart.romBankCount(), 0, items, pw);
|
||||||
|
myBankWidgets[0] =
|
||||||
|
new PopUpWidget(_boss, _font, xpos, ypos - 2, pw,
|
||||||
|
myLineHeight, items, "Set bank ",
|
||||||
|
_font.getStringWidth("Set bank "), kBankChanged);
|
||||||
|
myBankWidgets[0]->setTarget(this);
|
||||||
|
myBankWidgets[0]->setID(0);
|
||||||
|
addFocusWidget(myBankWidgets[0]);
|
||||||
|
|
||||||
|
StaticTextWidget* t = new StaticTextWidget(_boss, _font, myBankWidgets[0]->getRight(), ypos - 1, " (ROM)");
|
||||||
|
|
||||||
|
xpos = t->getRight() + 20;
|
||||||
|
items.clear();
|
||||||
|
bankList(myCart.ramBankCount(), 0, items, pw);
|
||||||
|
myBankWidgets[1] =
|
||||||
|
new PopUpWidget(_boss, _font, xpos, ypos - 2, pw,
|
||||||
|
myLineHeight, items, "", 0, kRAMBankChanged);
|
||||||
|
myBankWidgets[1]->setTarget(this);
|
||||||
|
myBankWidgets[1]->setID(1);
|
||||||
|
addFocusWidget(myBankWidgets[1]);
|
||||||
|
|
||||||
|
new StaticTextWidget(_boss, _font, myBankWidgets[1]->getRight(), ypos - 1, " (RAM)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Cartridge3EWidget::loadConfig()
|
void Cartridge3EWidget::loadConfig()
|
||||||
{
|
{
|
||||||
if(myCart.myCurrentBank < 256)
|
uInt16 oldBank = myOldState.banks[0];
|
||||||
|
uInt16 bank = myCart.getBank();
|
||||||
|
|
||||||
|
if(myCart.getBank() < myCart.romBankCount())
|
||||||
{
|
{
|
||||||
myROMBank->setSelectedIndex(myCart.myCurrentBank % myNumRomBanks, myOldState.bank != myCart.myCurrentBank);
|
myBankWidgets[0]->setSelectedIndex(bank, oldBank != bank);
|
||||||
myRAMBank->setSelectedMax(myOldState.bank >= 256);
|
myBankWidgets[1]->setSelectedMax(oldBank >= myCart.romBankCount());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
myROMBank->setSelectedMax(myOldState.bank < 256);
|
myBankWidgets[0]->setSelectedMax(oldBank < myCart.romBankCount());
|
||||||
myRAMBank->setSelectedIndex(myCart.myCurrentBank - 256, myOldState.bank != myCart.myCurrentBank);
|
myBankWidgets[1]->setSelectedIndex(bank - myCart.romBankCount(), oldBank != bank);
|
||||||
}
|
}
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
CartDebugWidget::loadConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Cartridge3EWidget::handleCommand(CommandSender* sender,
|
void Cartridge3EWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
|
||||||
int cmd, int data, int id)
|
|
||||||
{
|
{
|
||||||
uInt16 bank = 0;
|
uInt16 bank = 0;
|
||||||
|
|
||||||
if(cmd == kROMBankChanged)
|
if(cmd == kBankChanged)
|
||||||
{
|
{
|
||||||
if(myROMBank->getSelected() < int(myNumRomBanks))
|
if(myBankWidgets[0]->getSelected() < myCart.romBankCount())
|
||||||
{
|
{
|
||||||
bank = myROMBank->getSelected();
|
bank = myBankWidgets[0]->getSelected();
|
||||||
myRAMBank->setSelectedMax();
|
myBankWidgets[1]->setSelectedMax();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bank = 256; // default to first RAM bank
|
bank = myCart.romBankCount(); // default to first RAM bank
|
||||||
myRAMBank->setSelectedIndex(0);
|
myBankWidgets[1]->setSelectedIndex(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(cmd == kRAMBankChanged)
|
else if(cmd == kRAMBankChanged)
|
||||||
{
|
{
|
||||||
if(myRAMBank->getSelected() < int(myNumRamBanks))
|
if(myBankWidgets[1]->getSelected() < myCart.ramBankCount())
|
||||||
{
|
{
|
||||||
myROMBank->setSelectedMax();
|
myBankWidgets[0]->setSelectedMax();
|
||||||
bank = myRAMBank->getSelected() + 256;
|
bank = myBankWidgets[1]->getSelected() + myCart.romBankCount();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bank = 0; // default to first ROM bank
|
bank = 0; // default to first ROM bank
|
||||||
myROMBank->setSelectedIndex(0);
|
myBankWidgets[0]->setSelectedIndex(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
myCart.unlockBank();
|
myCart.unlockBank();
|
||||||
myCart.bank(bank);
|
myCart.bank(bank);
|
||||||
myCart.lockBank();
|
myCart.lockBank();
|
||||||
|
@ -156,65 +161,13 @@ void Cartridge3EWidget::handleCommand(CommandSender* sender,
|
||||||
string Cartridge3EWidget::bankState()
|
string Cartridge3EWidget::bankState()
|
||||||
{
|
{
|
||||||
ostringstream& buf = buffer();
|
ostringstream& buf = buffer();
|
||||||
|
uInt16 bank = myCart.getBank();
|
||||||
|
|
||||||
uInt16& bank = myCart.myCurrentBank;
|
if(bank < myCart.romBankCount())
|
||||||
if(bank < 256)
|
buf << "ROM bank #" << std::dec << bank % myCart.romBankCount() << ", RAM inactive";
|
||||||
buf << "ROM bank #" << std::dec << bank % myNumRomBanks << ", RAM inactive";
|
|
||||||
else
|
else
|
||||||
buf << "ROM inactive, RAM bank #" << std::dec << bank % myNumRamBanks;
|
buf << "ROM inactive, RAM bank #"
|
||||||
|
<< std::dec << (bank - myCart.romBankCount()) % myCart.ramBankCount();
|
||||||
|
|
||||||
return buf.str();
|
return buf.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 Cartridge3EWidget::internalRamSize()
|
|
||||||
{
|
|
||||||
return 32*1024;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 Cartridge3EWidget::internalRamRPort(int start)
|
|
||||||
{
|
|
||||||
return 0x0000 + start;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string Cartridge3EWidget::internalRamDescription()
|
|
||||||
{
|
|
||||||
ostringstream desc;
|
|
||||||
desc << "Accessible 1K at a time via:\n"
|
|
||||||
<< " $F000 - $F3FF used for Read Access\n"
|
|
||||||
<< " $F400 - $F7FF used for Write Access";
|
|
||||||
|
|
||||||
return desc.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const ByteArray& Cartridge3EWidget::internalRamOld(int start, int count)
|
|
||||||
{
|
|
||||||
myRamOld.clear();
|
|
||||||
for(int i = 0; i < count; i++)
|
|
||||||
myRamOld.push_back(myOldState.internalram[start + i]);
|
|
||||||
return myRamOld;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const ByteArray& Cartridge3EWidget::internalRamCurrent(int start, int count)
|
|
||||||
{
|
|
||||||
myRamCurrent.clear();
|
|
||||||
for(int i = 0; i < count; i++)
|
|
||||||
myRamCurrent.push_back(myCart.myRAM[start + i]);
|
|
||||||
return myRamCurrent;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void Cartridge3EWidget::internalRamSetValue(int addr, uInt8 value)
|
|
||||||
{
|
|
||||||
myCart.myRAM[addr] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt8 Cartridge3EWidget::internalRamGetValue(int addr)
|
|
||||||
{
|
|
||||||
return myCart.myRAM[addr];
|
|
||||||
}
|
|
||||||
|
|
|
@ -19,11 +19,12 @@
|
||||||
#define CARTRIDGE3E_WIDGET_HXX
|
#define CARTRIDGE3E_WIDGET_HXX
|
||||||
|
|
||||||
class Cartridge3E;
|
class Cartridge3E;
|
||||||
class PopUpWidget;
|
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
#include "CartEnhancedWidget.hxx"
|
||||||
|
|
||||||
class Cartridge3EWidget : public CartDebugWidget
|
// Note: This class supports 3EX too
|
||||||
|
|
||||||
|
class Cartridge3EWidget : public CartridgeEnhancedWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Cartridge3EWidget(GuiObject* boss, const GUI::Font& lfont,
|
Cartridge3EWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
|
@ -33,39 +34,28 @@ class Cartridge3EWidget : public CartDebugWidget
|
||||||
virtual ~Cartridge3EWidget() = default;
|
virtual ~Cartridge3EWidget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Cartridge3E& myCart;
|
|
||||||
const uInt32 myNumRomBanks{0};
|
|
||||||
const uInt32 myNumRamBanks{0};
|
|
||||||
PopUpWidget *myROMBank{nullptr}, *myRAMBank{nullptr};
|
|
||||||
|
|
||||||
struct CartState {
|
|
||||||
ByteArray internalram;
|
|
||||||
uInt16 bank;
|
|
||||||
};
|
|
||||||
CartState myOldState;
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
kROMBankChanged = 'rmCH',
|
|
||||||
kRAMBankChanged = 'raCH'
|
kRAMBankChanged = 'raCH'
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void saveOldState() override;
|
string manufacturer() override { return "Andrew Davie & Thomas Jentzsch"; }
|
||||||
|
|
||||||
|
string description() override;
|
||||||
|
|
||||||
|
void bankList(uInt16 bankCount, int seg, VariantList& items, int& width) override;
|
||||||
|
|
||||||
|
void bankSelect(int& ypos) override;
|
||||||
|
|
||||||
|
uInt16 bankSegs() override { return 1; }
|
||||||
|
|
||||||
void loadConfig() override;
|
void loadConfig() override;
|
||||||
|
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
||||||
|
|
||||||
string bankState() override;
|
string bankState() override;
|
||||||
|
|
||||||
// start of functions for Cartridge RAM tab
|
private:
|
||||||
uInt32 internalRamSize() override;
|
|
||||||
uInt32 internalRamRPort(int start) override;
|
|
||||||
string internalRamDescription() override;
|
|
||||||
const ByteArray& internalRamOld(int start, int count) override;
|
|
||||||
const ByteArray& internalRamCurrent(int start, int count) override;
|
|
||||||
void internalRamSetValue(int addr, uInt8 value) override;
|
|
||||||
uInt8 internalRamGetValue(int addr) override;
|
|
||||||
// end of functions for Cartridge RAM tab
|
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
Cartridge3EWidget() = delete;
|
Cartridge3EWidget() = delete;
|
||||||
Cartridge3EWidget(const Cartridge3EWidget&) = delete;
|
Cartridge3EWidget(const Cartridge3EWidget&) = delete;
|
||||||
|
|
|
@ -16,79 +16,33 @@
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "Cart3F.hxx"
|
#include "Cart3F.hxx"
|
||||||
#include "PopUpWidget.hxx"
|
|
||||||
#include "Cart3FWidget.hxx"
|
#include "Cart3FWidget.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Cartridge3FWidget::Cartridge3FWidget(
|
Cartridge3FWidget::Cartridge3FWidget(
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h, Cartridge3F& cart)
|
int x, int y, int w, int h, Cartridge3F& cart)
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||||
myCart(cart)
|
|
||||||
{
|
{
|
||||||
size_t size = cart.mySize;
|
myHotspotDelta = 0;
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string Cartridge3FWidget::description()
|
||||||
|
{
|
||||||
ostringstream info;
|
ostringstream info;
|
||||||
info << "Tigervision 3F cartridge, 2-256 2K banks\n"
|
size_t size;
|
||||||
<< "Startup bank = " << cart.startBank() << " or undetermined\n"
|
const uInt8* image = myCart.getImage(size);
|
||||||
<< "First 2K bank selected by writing to $3F\n"
|
|
||||||
<< "Last 2K always points to last 2K of ROM\n";
|
|
||||||
|
|
||||||
|
info << "Tigervision 3F cartridge, 2 - 256 2K banks\n"
|
||||||
|
<< "First 2K bank selected by writing to " << hotspotStr() << "\n"
|
||||||
|
<< "Last 2K always points to last 2K of ROM\n"
|
||||||
|
<< "Startup bank = " << myCart.startBank() << " or undetermined\n";
|
||||||
// Eventually, we should query this from the debugger/disassembler
|
// Eventually, we should query this from the debugger/disassembler
|
||||||
uInt16 start = (cart.myImage[size-3] << 8) | cart.myImage[size-4];
|
uInt16 start = (image[size-3] << 8) | image[size-4];
|
||||||
start -= start % 0x1000;
|
start -= start % 0x1000;
|
||||||
info << "Bank RORG" << " = $" << Common::Base::HEX4 << start << "\n";
|
info << "Bank RORG $" << Common::Base::HEX4 << start << "\n";
|
||||||
|
|
||||||
int xpos = 2,
|
return info.str();
|
||||||
ypos = addBaseInformation(size, "TigerVision", info.str()) + myLineHeight;
|
|
||||||
|
|
||||||
VariantList items;
|
|
||||||
for(uInt16 i = 0; i < cart.bankCount(); ++i)
|
|
||||||
VarList::push_back(items, Variant(i).toString() + " ($3F)");
|
|
||||||
|
|
||||||
ostringstream label;
|
|
||||||
label << "Set bank ($" << Common::Base::HEX4 << start << " - $" <<
|
|
||||||
(start+0x7FF) << ") ";
|
|
||||||
myBank =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("0 ($3F) "),
|
|
||||||
myLineHeight, items, label.str(),
|
|
||||||
_font.getStringWidth(label.str()), kBankChanged);
|
|
||||||
myBank->setTarget(this);
|
|
||||||
addFocusWidget(myBank);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void Cartridge3FWidget::loadConfig()
|
|
||||||
{
|
|
||||||
Debugger& dbg = instance().debugger();
|
|
||||||
CartDebug& cart = dbg.cartDebug();
|
|
||||||
const CartState& state = static_cast<const CartState&>(cart.getState());
|
|
||||||
const CartState& oldstate = static_cast<const CartState&>(cart.getOldState());
|
|
||||||
|
|
||||||
myBank->setSelectedIndex(myCart.getBank(0), state.bank != oldstate.bank);
|
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void Cartridge3FWidget::handleCommand(CommandSender* sender,
|
|
||||||
int cmd, int data, int id)
|
|
||||||
{
|
|
||||||
if(cmd == kBankChanged)
|
|
||||||
{
|
|
||||||
myCart.unlockBank();
|
|
||||||
myCart.bank(myBank->getSelected());
|
|
||||||
myCart.lockBank();
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string Cartridge3FWidget::bankState()
|
|
||||||
{
|
|
||||||
ostringstream& buf = buffer();
|
|
||||||
|
|
||||||
buf << "Bank = #" << std::dec << myCart.myCurrentBank << ", hotspot = $3F";
|
|
||||||
|
|
||||||
return buf.str();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,10 @@
|
||||||
#define CARTRIDGE3F_WIDGET_HXX
|
#define CARTRIDGE3F_WIDGET_HXX
|
||||||
|
|
||||||
class Cartridge3F;
|
class Cartridge3F;
|
||||||
class PopUpWidget;
|
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
#include "CartEnhancedWidget.hxx"
|
||||||
|
|
||||||
class Cartridge3FWidget : public CartDebugWidget
|
class Cartridge3FWidget : public CartridgeEnhancedWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Cartridge3FWidget(GuiObject* boss, const GUI::Font& lfont,
|
Cartridge3FWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
|
@ -33,17 +32,13 @@ class Cartridge3FWidget : public CartDebugWidget
|
||||||
virtual ~Cartridge3FWidget() = default;
|
virtual ~Cartridge3FWidget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Cartridge3F& myCart;
|
string manufacturer() override { return "TigerVision"; }
|
||||||
PopUpWidget* myBank{nullptr};
|
|
||||||
|
|
||||||
enum { kBankChanged = 'bkCH' };
|
string description() override;
|
||||||
|
|
||||||
|
uInt16 bankSegs() override { return 1; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void loadConfig() override;
|
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
|
||||||
|
|
||||||
string bankState() override;
|
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
Cartridge3FWidget() = delete;
|
Cartridge3FWidget() = delete;
|
||||||
Cartridge3FWidget(const Cartridge3FWidget&) = delete;
|
Cartridge3FWidget(const Cartridge3FWidget&) = delete;
|
||||||
|
|
|
@ -15,8 +15,6 @@
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "Debugger.hxx"
|
|
||||||
#include "CartDebug.hxx"
|
|
||||||
#include "Cart4KSC.hxx"
|
#include "Cart4KSC.hxx"
|
||||||
#include "Cart4KSCWidget.hxx"
|
#include "Cart4KSCWidget.hxx"
|
||||||
|
|
||||||
|
@ -24,87 +22,18 @@
|
||||||
Cartridge4KSCWidget::Cartridge4KSCWidget(
|
Cartridge4KSCWidget::Cartridge4KSCWidget(
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h, Cartridge4KSC& cart)
|
int x, int y, int w, int h, Cartridge4KSC& cart)
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||||
myCart(cart)
|
|
||||||
{
|
{
|
||||||
// Eventually, we should query this from the debugger/disassembler
|
initialize();
|
||||||
uInt16 start = (cart.myImage[0xFFD] << 8) | cart.myImage[0xFFC];
|
}
|
||||||
start -= start % 0x1000;
|
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string Cartridge4KSCWidget::description()
|
||||||
|
{
|
||||||
ostringstream info;
|
ostringstream info;
|
||||||
info << "4KSC cartridge, non-bankswitched\n"
|
|
||||||
<< "128 bytes RAM @ $F000 - $F0FF\n"
|
|
||||||
<< " $F080 - $F0FF (R), $F000 - $F07F (W)\n"
|
|
||||||
<< "Accessible @ $" << Common::Base::HEX4 << start << " - "
|
|
||||||
<< "$" << (start + 0xFFF);
|
|
||||||
|
|
||||||
addBaseInformation(4096, "homebrew intermediate format", info.str());
|
info << "4KSC cartridge, non-bankswitched\n";
|
||||||
}
|
info << CartridgeEnhancedWidget::description();
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
return info.str();
|
||||||
void Cartridge4KSCWidget::saveOldState()
|
|
||||||
{
|
|
||||||
myOldState.internalram.clear();
|
|
||||||
|
|
||||||
for(uInt32 i = 0; i < internalRamSize(); ++i)
|
|
||||||
myOldState.internalram.push_back(myCart.myRAM[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 Cartridge4KSCWidget::internalRamSize()
|
|
||||||
{
|
|
||||||
return 128;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 Cartridge4KSCWidget::internalRamRPort(int start)
|
|
||||||
{
|
|
||||||
return 0xF080 + start;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string Cartridge4KSCWidget::internalRamDescription()
|
|
||||||
{
|
|
||||||
ostringstream desc;
|
|
||||||
desc << "$F000 - $F07F used for Write Access\n"
|
|
||||||
<< "$F080 - $F0FF used for Read Access";
|
|
||||||
|
|
||||||
return desc.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const ByteArray& Cartridge4KSCWidget::internalRamOld(int start, int count)
|
|
||||||
{
|
|
||||||
myRamOld.clear();
|
|
||||||
for(int i = 0; i < count; i++)
|
|
||||||
myRamOld.push_back(myOldState.internalram[start + i]);
|
|
||||||
return myRamOld;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const ByteArray& Cartridge4KSCWidget::internalRamCurrent(int start, int count)
|
|
||||||
{
|
|
||||||
myRamCurrent.clear();
|
|
||||||
for(int i = 0; i < count; i++)
|
|
||||||
myRamCurrent.push_back(myCart.myRAM[start + i]);
|
|
||||||
return myRamCurrent;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void Cartridge4KSCWidget::internalRamSetValue(int addr, uInt8 value)
|
|
||||||
{
|
|
||||||
myCart.myRAM[addr] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt8 Cartridge4KSCWidget::internalRamGetValue(int addr)
|
|
||||||
{
|
|
||||||
return myCart.myRAM[addr];
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string Cartridge4KSCWidget::internalRamLabel(int addr)
|
|
||||||
{
|
|
||||||
CartDebug& dbg = instance().debugger().cartDebug();
|
|
||||||
return dbg.getLabel(addr + 0xF080, false);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,9 +20,9 @@
|
||||||
|
|
||||||
class Cartridge4KSC;
|
class Cartridge4KSC;
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
#include "CartEnhancedWidget.hxx"
|
||||||
|
|
||||||
class Cartridge4KSCWidget : public CartDebugWidget
|
class Cartridge4KSCWidget : public CartridgeEnhancedWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Cartridge4KSCWidget(GuiObject* boss, const GUI::Font& lfont,
|
Cartridge4KSCWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
|
@ -32,30 +32,11 @@ class Cartridge4KSCWidget : public CartDebugWidget
|
||||||
virtual ~Cartridge4KSCWidget() = default;
|
virtual ~Cartridge4KSCWidget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Cartridge4KSC& myCart;
|
string manufacturer() override { return "homebrew intermediate format"; }
|
||||||
struct CartState {
|
|
||||||
ByteArray internalram;
|
string description() override;
|
||||||
};
|
|
||||||
CartState myOldState;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// No implementation for non-bankswitched ROMs
|
|
||||||
void loadConfig() override { }
|
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override { }
|
|
||||||
|
|
||||||
void saveOldState() override;
|
|
||||||
|
|
||||||
// start of functions for Cartridge RAM tab
|
|
||||||
uInt32 internalRamSize() override;
|
|
||||||
uInt32 internalRamRPort(int start) override;
|
|
||||||
string internalRamDescription() override;
|
|
||||||
const ByteArray& internalRamOld(int start, int count) override;
|
|
||||||
const ByteArray& internalRamCurrent(int start, int count) override;
|
|
||||||
void internalRamSetValue(int addr, uInt8 value) override;
|
|
||||||
uInt8 internalRamGetValue(int addr) override;
|
|
||||||
string internalRamLabel(int addr) override;
|
|
||||||
// end of functions for Cartridge RAM tab
|
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
Cartridge4KSCWidget() = delete;
|
Cartridge4KSCWidget() = delete;
|
||||||
Cartridge4KSCWidget(const Cartridge4KSCWidget&) = delete;
|
Cartridge4KSCWidget(const Cartridge4KSCWidget&) = delete;
|
||||||
|
|
|
@ -22,15 +22,29 @@
|
||||||
Cartridge4KWidget::Cartridge4KWidget(
|
Cartridge4KWidget::Cartridge4KWidget(
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h, Cartridge4K& cart)
|
int x, int y, int w, int h, Cartridge4K& cart)
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h)
|
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||||
{
|
{
|
||||||
// Eventually, we should query this from the debugger/disassembler
|
initialize();
|
||||||
uInt16 start = (cart.myImage[0xFFD] << 8) | cart.myImage[0xFFC];
|
|
||||||
start -= start % 0x1000;
|
|
||||||
|
|
||||||
ostringstream info;
|
//// Eventually, we should query this from the debugger/disassembler
|
||||||
info << "Standard 4K cartridge, non-bankswitched\n"
|
//uInt16 start = (cart.myImage[0xFFD] << 8) | cart.myImage[0xFFC];
|
||||||
<< "Accessible @ $" << Common::Base::HEX4 << start << " - "
|
//start -= start % 0x1000;
|
||||||
<< "$" << (start + 0xFFF);
|
|
||||||
addBaseInformation(4096, "Atari", info.str());
|
//ostringstream info;
|
||||||
|
//info << "Standard 4K cartridge, non-bankswitched\n"
|
||||||
|
// << "Accessible @ $" << Common::Base::HEX4 << start << " - "
|
||||||
|
// << "$" << (start + 0xFFF);
|
||||||
|
//addBaseInformation(4096, "Atari", info.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string Cartridge4KWidget::description()
|
||||||
|
{
|
||||||
|
ostringstream info;
|
||||||
|
|
||||||
|
info << "Standard 4K cartridge, non-bankswitched\n";
|
||||||
|
info << CartridgeEnhancedWidget::description();
|
||||||
|
|
||||||
|
return info.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,9 @@
|
||||||
|
|
||||||
class Cartridge4K;
|
class Cartridge4K;
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
#include "CartEnhanced.hxx"
|
||||||
|
|
||||||
class Cartridge4KWidget : public CartDebugWidget
|
class Cartridge4KWidget : public CartridgeEnhancedWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Cartridge4KWidget(GuiObject* boss, const GUI::Font& lfont,
|
Cartridge4KWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
|
@ -32,10 +32,11 @@ class Cartridge4KWidget : public CartDebugWidget
|
||||||
virtual ~Cartridge4KWidget() = default;
|
virtual ~Cartridge4KWidget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// No implementation for non-bankswitched ROMs
|
string manufacturer() override { return "Atari"; }
|
||||||
void loadConfig() override { }
|
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override { }
|
|
||||||
|
|
||||||
|
string description() override;
|
||||||
|
|
||||||
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
Cartridge4KWidget() = delete;
|
Cartridge4KWidget() = delete;
|
||||||
Cartridge4KWidget(const Cartridge4KWidget&) = delete;
|
Cartridge4KWidget(const Cartridge4KWidget&) = delete;
|
||||||
|
|
|
@ -15,221 +15,25 @@
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "Debugger.hxx"
|
|
||||||
#include "CartDebug.hxx"
|
|
||||||
#include "CartBFSC.hxx"
|
#include "CartBFSC.hxx"
|
||||||
#include "PopUpWidget.hxx"
|
|
||||||
#include "CartBFSCWidget.hxx"
|
#include "CartBFSCWidget.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CartridgeBFSCWidget::CartridgeBFSCWidget(
|
CartridgeBFSCWidget::CartridgeBFSCWidget(
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h, CartridgeBFSC& cart)
|
int x, int y, int w, int h, CartridgeBFSC& cart)
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||||
myCart(cart)
|
|
||||||
{
|
{
|
||||||
uInt32 size = 64 * 4096;
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string CartridgeBFSCWidget::description()
|
||||||
|
{
|
||||||
ostringstream info;
|
ostringstream info;
|
||||||
info << "256K BFSC + RAM, 64 4K banks\n"
|
|
||||||
<< "128 bytes RAM @ $F000 - $F0FF\n"
|
|
||||||
<< " $F080 - $F0FF (R), $F000 - $F07F (W)\n"
|
|
||||||
<< "Startup bank = " << cart.startBank() << "\n";
|
|
||||||
|
|
||||||
// Eventually, we should query this from the debugger/disassembler
|
info << "256K BFSC + RAM, 64 4K banks\n";
|
||||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0xF80; i < 64; ++i, offset += 0x1000)
|
info << CartridgeEnhancedWidget::description();
|
||||||
{
|
|
||||||
uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset];
|
|
||||||
start -= start % 0x1000;
|
|
||||||
info << "Bank " << std::dec << i << " @ $" << Common::Base::HEX4 << (start + 0x100)
|
|
||||||
<< " - " << "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
int xpos = 2,
|
return info.str();
|
||||||
ypos = addBaseInformation(size, "CPUWIZ", info.str()) + myLineHeight;
|
|
||||||
|
|
||||||
VariantList items;
|
|
||||||
VarList::push_back(items, " 0 ($FF80)");
|
|
||||||
VarList::push_back(items, " 1 ($FF81)");
|
|
||||||
VarList::push_back(items, " 2 ($FF82)");
|
|
||||||
VarList::push_back(items, " 3 ($FF83)");
|
|
||||||
VarList::push_back(items, " 4 ($FF84)");
|
|
||||||
VarList::push_back(items, " 5 ($FF85)");
|
|
||||||
VarList::push_back(items, " 6 ($FF86)");
|
|
||||||
VarList::push_back(items, " 7 ($FF87)");
|
|
||||||
VarList::push_back(items, " 8 ($FF88)");
|
|
||||||
VarList::push_back(items, " 9 ($FF89)");
|
|
||||||
VarList::push_back(items, "10 ($FF8A)");
|
|
||||||
VarList::push_back(items, "11 ($FF8B)");
|
|
||||||
VarList::push_back(items, "12 ($FF8C)");
|
|
||||||
VarList::push_back(items, "13 ($FF8D)");
|
|
||||||
VarList::push_back(items, "14 ($FF8E)");
|
|
||||||
VarList::push_back(items, "15 ($FF8F)");
|
|
||||||
VarList::push_back(items, "16 ($FF90)");
|
|
||||||
VarList::push_back(items, "17 ($FF91)");
|
|
||||||
VarList::push_back(items, "18 ($FF92)");
|
|
||||||
VarList::push_back(items, "19 ($FF93)");
|
|
||||||
VarList::push_back(items, "20 ($FF94)");
|
|
||||||
VarList::push_back(items, "21 ($FF95)");
|
|
||||||
VarList::push_back(items, "22 ($FF96)");
|
|
||||||
VarList::push_back(items, "23 ($FF97)");
|
|
||||||
VarList::push_back(items, "24 ($FF98)");
|
|
||||||
VarList::push_back(items, "25 ($FF99)");
|
|
||||||
VarList::push_back(items, "26 ($FF9A)");
|
|
||||||
VarList::push_back(items, "27 ($FF9B)");
|
|
||||||
VarList::push_back(items, "28 ($FF9C)");
|
|
||||||
VarList::push_back(items, "29 ($FF9D)");
|
|
||||||
VarList::push_back(items, "30 ($FF9E)");
|
|
||||||
VarList::push_back(items, "31 ($FF9F)");
|
|
||||||
VarList::push_back(items, "32 ($FFA0)");
|
|
||||||
VarList::push_back(items, "33 ($FFA1)");
|
|
||||||
VarList::push_back(items, "34 ($FFA2)");
|
|
||||||
VarList::push_back(items, "35 ($FFA3)");
|
|
||||||
VarList::push_back(items, "36 ($FFA4)");
|
|
||||||
VarList::push_back(items, "37 ($FFA5)");
|
|
||||||
VarList::push_back(items, "38 ($FFA6)");
|
|
||||||
VarList::push_back(items, "39 ($FFA7)");
|
|
||||||
VarList::push_back(items, "40 ($FFA8)");
|
|
||||||
VarList::push_back(items, "41 ($FFA9)");
|
|
||||||
VarList::push_back(items, "42 ($FFAA)");
|
|
||||||
VarList::push_back(items, "43 ($FFAB)");
|
|
||||||
VarList::push_back(items, "44 ($FFAC)");
|
|
||||||
VarList::push_back(items, "45 ($FFAD)");
|
|
||||||
VarList::push_back(items, "46 ($FFAE)");
|
|
||||||
VarList::push_back(items, "47 ($FFAF)");
|
|
||||||
VarList::push_back(items, "48 ($FFB0)");
|
|
||||||
VarList::push_back(items, "49 ($FFB1)");
|
|
||||||
VarList::push_back(items, "50 ($FFB2)");
|
|
||||||
VarList::push_back(items, "51 ($FFB3)");
|
|
||||||
VarList::push_back(items, "52 ($FFB4)");
|
|
||||||
VarList::push_back(items, "53 ($FFB5)");
|
|
||||||
VarList::push_back(items, "54 ($FFB6)");
|
|
||||||
VarList::push_back(items, "55 ($FFB7)");
|
|
||||||
VarList::push_back(items, "56 ($FFB8)");
|
|
||||||
VarList::push_back(items, "57 ($FFB9)");
|
|
||||||
VarList::push_back(items, "58 ($FFBA)");
|
|
||||||
VarList::push_back(items, "59 ($FFBB)");
|
|
||||||
VarList::push_back(items, "60 ($FFBC)");
|
|
||||||
VarList::push_back(items, "61 ($FFBD)");
|
|
||||||
VarList::push_back(items, "62 ($FFBE)");
|
|
||||||
VarList::push_back(items, "63 ($FFBF)");
|
|
||||||
|
|
||||||
myBank =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("63 ($FFBF)"),
|
|
||||||
myLineHeight, items, "Set bank ",
|
|
||||||
0, kBankChanged);
|
|
||||||
myBank->setTarget(this);
|
|
||||||
addFocusWidget(myBank);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeBFSCWidget::saveOldState()
|
|
||||||
{
|
|
||||||
myOldState.internalram.clear();
|
|
||||||
|
|
||||||
for(uInt32 i = 0; i < internalRamSize(); ++i)
|
|
||||||
myOldState.internalram.push_back(myCart.myRAM[i]);
|
|
||||||
|
|
||||||
myOldState.bank = myCart.getBank();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeBFSCWidget::loadConfig()
|
|
||||||
{
|
|
||||||
myBank->setSelectedIndex(myCart.getBank(), myCart.getBank() != myOldState.bank);
|
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeBFSCWidget::handleCommand(CommandSender* sender,
|
|
||||||
int cmd, int data, int id)
|
|
||||||
{
|
|
||||||
if(cmd == kBankChanged)
|
|
||||||
{
|
|
||||||
myCart.unlockBank();
|
|
||||||
myCart.bank(myBank->getSelected());
|
|
||||||
myCart.lockBank();
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeBFSCWidget::bankState()
|
|
||||||
{
|
|
||||||
ostringstream& buf = buffer();
|
|
||||||
|
|
||||||
static constexpr std::array<const char*, 64> spot = {
|
|
||||||
"$FF80", "$FF81", "$FF82", "$FF83", "$FF84", "$FF85", "$FF86", "$FF87",
|
|
||||||
"$FF88", "$FF89", "$FF8A", "$FF8B", "$FF8C", "$FF8D", "$FF8E", "$FF8F",
|
|
||||||
"$FF90", "$FF91", "$FF92", "$FF93", "$FF94", "$FF95", "$FF96", "$FF97",
|
|
||||||
"$FF98", "$FF99", "$FF9A", "$FF9B", "$FF9C", "$FF9D", "$FF9E", "$FF9F",
|
|
||||||
"$FFA0", "$FFA1", "$FFA2", "$FFA3", "$FFA4", "$FFA5", "$FFA6", "$FFA7",
|
|
||||||
"$FFA8", "$FFA9", "$FFAA", "$FFAB", "$FFAC", "$FFAD", "$FFAE", "$FFAF",
|
|
||||||
"$FFB0", "$FFB1", "$FFB2", "$FFB3", "$FFB4", "$FFB5", "$FFB6", "$FFB7",
|
|
||||||
"$FFB8", "$FFB9", "$FFBA", "$FFBB", "$FFBC", "$FFBD", "$FFBE", "$FFBF"
|
|
||||||
};
|
|
||||||
buf << "Bank = " << std::dec << myCart.getBank()
|
|
||||||
<< ", hotspot = " << spot[myCart.getBank()];
|
|
||||||
|
|
||||||
return buf.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 CartridgeBFSCWidget::internalRamSize()
|
|
||||||
{
|
|
||||||
return 128;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 CartridgeBFSCWidget::internalRamRPort(int start)
|
|
||||||
{
|
|
||||||
return 0xF080 + start;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeBFSCWidget::internalRamDescription()
|
|
||||||
{
|
|
||||||
ostringstream desc;
|
|
||||||
desc << "$F000 - $F07F used for Write Access\n"
|
|
||||||
<< "$F080 - $F0FF used for Read Access";
|
|
||||||
|
|
||||||
return desc.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const ByteArray& CartridgeBFSCWidget::internalRamOld(int start, int count)
|
|
||||||
{
|
|
||||||
myRamOld.clear();
|
|
||||||
for(int i = 0; i < count; i++)
|
|
||||||
myRamOld.push_back(myOldState.internalram[start + i]);
|
|
||||||
return myRamOld;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const ByteArray& CartridgeBFSCWidget::internalRamCurrent(int start, int count)
|
|
||||||
{
|
|
||||||
myRamCurrent.clear();
|
|
||||||
for(int i = 0; i < count; i++)
|
|
||||||
myRamCurrent.push_back(myCart.myRAM[start + i]);
|
|
||||||
return myRamCurrent;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeBFSCWidget::internalRamSetValue(int addr, uInt8 value)
|
|
||||||
{
|
|
||||||
myCart.myRAM[addr] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt8 CartridgeBFSCWidget::internalRamGetValue(int addr)
|
|
||||||
{
|
|
||||||
return myCart.myRAM[addr];
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeBFSCWidget::internalRamLabel(int addr)
|
|
||||||
{
|
|
||||||
CartDebug& dbg = instance().debugger().cartDebug();
|
|
||||||
return dbg.getLabel(addr + 0xF080, false);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,10 @@
|
||||||
#define CARTRIDGEBFSC_WIDGET_HXX
|
#define CARTRIDGEBFSC_WIDGET_HXX
|
||||||
|
|
||||||
class CartridgeBFSC;
|
class CartridgeBFSC;
|
||||||
class PopUpWidget;
|
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
#include "CartEnhancedWidget.hxx"
|
||||||
|
|
||||||
class CartridgeBFSCWidget : public CartDebugWidget
|
class CartridgeBFSCWidget : public CartridgeEnhancedWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CartridgeBFSCWidget(GuiObject* boss, const GUI::Font& lfont,
|
CartridgeBFSCWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
|
@ -33,35 +32,11 @@ class CartridgeBFSCWidget : public CartDebugWidget
|
||||||
virtual ~CartridgeBFSCWidget() = default;
|
virtual ~CartridgeBFSCWidget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CartridgeBFSC& myCart;
|
string manufacturer() override { return "CPUWIZ"; }
|
||||||
PopUpWidget* myBank{nullptr};
|
|
||||||
|
|
||||||
struct CartState {
|
string description() override;
|
||||||
ByteArray internalram;
|
|
||||||
uInt16 bank{0};
|
|
||||||
};
|
|
||||||
CartState myOldState;
|
|
||||||
|
|
||||||
enum { kBankChanged = 'bkCH' };
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void saveOldState() override;
|
|
||||||
void loadConfig() override;
|
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
|
||||||
|
|
||||||
string bankState() override;
|
|
||||||
|
|
||||||
// start of functions for Cartridge RAM tab
|
|
||||||
uInt32 internalRamSize() override;
|
|
||||||
uInt32 internalRamRPort(int start) override;
|
|
||||||
string internalRamDescription() override;
|
|
||||||
const ByteArray& internalRamOld(int start, int count) override;
|
|
||||||
const ByteArray& internalRamCurrent(int start, int count) override;
|
|
||||||
void internalRamSetValue(int addr, uInt8 value) override;
|
|
||||||
uInt8 internalRamGetValue(int addr) override;
|
|
||||||
string internalRamLabel(int addr) override;
|
|
||||||
// end of functions for Cartridge RAM tab
|
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeBFSCWidget() = delete;
|
CartridgeBFSCWidget() = delete;
|
||||||
CartridgeBFSCWidget(const CartridgeBFSCWidget&) = delete;
|
CartridgeBFSCWidget(const CartridgeBFSCWidget&) = delete;
|
||||||
|
|
|
@ -16,151 +16,24 @@
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "CartBF.hxx"
|
#include "CartBF.hxx"
|
||||||
#include "PopUpWidget.hxx"
|
|
||||||
#include "CartBFWidget.hxx"
|
#include "CartBFWidget.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CartridgeBFWidget::CartridgeBFWidget(
|
CartridgeBFWidget::CartridgeBFWidget(
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h, CartridgeBF& cart)
|
int x, int y, int w, int h, CartridgeBF& cart)
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||||
myCart(cart)
|
|
||||||
{
|
{
|
||||||
uInt32 size = 64 * 4096;
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string CartridgeBFWidget::description()
|
||||||
|
{
|
||||||
ostringstream info;
|
ostringstream info;
|
||||||
info << "BF cartridge, 64 4K banks\n"
|
|
||||||
<< "Startup bank = " << cart.startBank() << "\n";
|
|
||||||
|
|
||||||
// Eventually, we should query this from the debugger/disassembler
|
info << "256K BF cartridge, 64 4K banks\n";
|
||||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0xF80; i < 64; ++i, offset += 0x1000)
|
info << CartridgeEnhancedWidget::description();
|
||||||
{
|
|
||||||
uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset];
|
|
||||||
start -= start % 0x1000;
|
|
||||||
info << "Bank " << std::dec << i << " @ $" << Common::Base::HEX4 << start << " - "
|
|
||||||
<< "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
int xpos = 2,
|
return info.str();
|
||||||
ypos = addBaseInformation(size, "CPUWIZ", info.str()) + myLineHeight;
|
|
||||||
|
|
||||||
VariantList items;
|
|
||||||
VarList::push_back(items, " 0 ($FF80)");
|
|
||||||
VarList::push_back(items, " 1 ($FF81)");
|
|
||||||
VarList::push_back(items, " 2 ($FF82)");
|
|
||||||
VarList::push_back(items, " 3 ($FF83)");
|
|
||||||
VarList::push_back(items, " 4 ($FF84)");
|
|
||||||
VarList::push_back(items, " 5 ($FF85)");
|
|
||||||
VarList::push_back(items, " 6 ($FF86)");
|
|
||||||
VarList::push_back(items, " 7 ($FF87)");
|
|
||||||
VarList::push_back(items, " 8 ($FF88)");
|
|
||||||
VarList::push_back(items, " 9 ($FF89)");
|
|
||||||
VarList::push_back(items, "10 ($FF8A)");
|
|
||||||
VarList::push_back(items, "11 ($FF8B)");
|
|
||||||
VarList::push_back(items, "12 ($FF8C)");
|
|
||||||
VarList::push_back(items, "13 ($FF8D)");
|
|
||||||
VarList::push_back(items, "14 ($FF8E)");
|
|
||||||
VarList::push_back(items, "15 ($FF8F)");
|
|
||||||
VarList::push_back(items, "16 ($FF90)");
|
|
||||||
VarList::push_back(items, "17 ($FF91)");
|
|
||||||
VarList::push_back(items, "18 ($FF92)");
|
|
||||||
VarList::push_back(items, "19 ($FF93)");
|
|
||||||
VarList::push_back(items, "20 ($FF94)");
|
|
||||||
VarList::push_back(items, "21 ($FF95)");
|
|
||||||
VarList::push_back(items, "22 ($FF96)");
|
|
||||||
VarList::push_back(items, "23 ($FF97)");
|
|
||||||
VarList::push_back(items, "24 ($FF98)");
|
|
||||||
VarList::push_back(items, "25 ($FF99)");
|
|
||||||
VarList::push_back(items, "26 ($FF9A)");
|
|
||||||
VarList::push_back(items, "27 ($FF9B)");
|
|
||||||
VarList::push_back(items, "28 ($FF9C)");
|
|
||||||
VarList::push_back(items, "29 ($FF9D)");
|
|
||||||
VarList::push_back(items, "30 ($FF9E)");
|
|
||||||
VarList::push_back(items, "31 ($FF9F)");
|
|
||||||
VarList::push_back(items, "32 ($FFA0)");
|
|
||||||
VarList::push_back(items, "33 ($FFA1)");
|
|
||||||
VarList::push_back(items, "34 ($FFA2)");
|
|
||||||
VarList::push_back(items, "35 ($FFA3)");
|
|
||||||
VarList::push_back(items, "36 ($FFA4)");
|
|
||||||
VarList::push_back(items, "37 ($FFA5)");
|
|
||||||
VarList::push_back(items, "38 ($FFA6)");
|
|
||||||
VarList::push_back(items, "39 ($FFA7)");
|
|
||||||
VarList::push_back(items, "40 ($FFA8)");
|
|
||||||
VarList::push_back(items, "41 ($FFA9)");
|
|
||||||
VarList::push_back(items, "42 ($FFAA)");
|
|
||||||
VarList::push_back(items, "43 ($FFAB)");
|
|
||||||
VarList::push_back(items, "44 ($FFAC)");
|
|
||||||
VarList::push_back(items, "45 ($FFAD)");
|
|
||||||
VarList::push_back(items, "46 ($FFAE)");
|
|
||||||
VarList::push_back(items, "47 ($FFAF)");
|
|
||||||
VarList::push_back(items, "48 ($FFB0)");
|
|
||||||
VarList::push_back(items, "49 ($FFB1)");
|
|
||||||
VarList::push_back(items, "50 ($FFB2)");
|
|
||||||
VarList::push_back(items, "51 ($FFB3)");
|
|
||||||
VarList::push_back(items, "52 ($FFB4)");
|
|
||||||
VarList::push_back(items, "53 ($FFB5)");
|
|
||||||
VarList::push_back(items, "54 ($FFB6)");
|
|
||||||
VarList::push_back(items, "55 ($FFB7)");
|
|
||||||
VarList::push_back(items, "56 ($FFB8)");
|
|
||||||
VarList::push_back(items, "57 ($FFB9)");
|
|
||||||
VarList::push_back(items, "58 ($FFBA)");
|
|
||||||
VarList::push_back(items, "59 ($FFBB)");
|
|
||||||
VarList::push_back(items, "60 ($FFBC)");
|
|
||||||
VarList::push_back(items, "61 ($FFBD)");
|
|
||||||
VarList::push_back(items, "62 ($FFBE)");
|
|
||||||
VarList::push_back(items, "63 ($FFBF)");
|
|
||||||
|
|
||||||
myBank =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("64 ($FFBF)"),
|
|
||||||
myLineHeight, items, "Set bank ",
|
|
||||||
0, kBankChanged);
|
|
||||||
myBank->setTarget(this);
|
|
||||||
addFocusWidget(myBank);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeBFWidget::loadConfig()
|
|
||||||
{
|
|
||||||
Debugger& dbg = instance().debugger();
|
|
||||||
CartDebug& cart = dbg.cartDebug();
|
|
||||||
const CartState& state = static_cast<const CartState&>(cart.getState());
|
|
||||||
const CartState& oldstate = static_cast<const CartState&>(cart.getOldState());
|
|
||||||
|
|
||||||
myBank->setSelectedIndex(myCart.getBank(), state.bank != oldstate.bank);
|
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeBFWidget::handleCommand(CommandSender* sender,
|
|
||||||
int cmd, int data, int id)
|
|
||||||
{
|
|
||||||
if(cmd == kBankChanged)
|
|
||||||
{
|
|
||||||
myCart.unlockBank();
|
|
||||||
myCart.bank(myBank->getSelected());
|
|
||||||
myCart.lockBank();
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeBFWidget::bankState()
|
|
||||||
{
|
|
||||||
ostringstream& buf = buffer();
|
|
||||||
|
|
||||||
static constexpr std::array<const char*, 64> spot = {
|
|
||||||
"$FF80", "$FF81", "$FF82", "$FF83", "$FF84", "$FF85", "$FF86", "$FF87",
|
|
||||||
"$FF88", "$FF89", "$FF8A", "$FF8B", "$FF8C", "$FF8D", "$FF8E", "$FF8F",
|
|
||||||
"$FF90", "$FF91", "$FF92", "$FF93", "$FF94", "$FF95", "$FF96", "$FF97",
|
|
||||||
"$FF98", "$FF99", "$FF9A", "$FF9B", "$FF9C", "$FF9D", "$FF9E", "$FF9F",
|
|
||||||
"$FFA0", "$FFA1", "$FFA2", "$FFA3", "$FFA4", "$FFA5", "$FFA6", "$FFA7",
|
|
||||||
"$FFA8", "$FFA9", "$FFAA", "$FFAB", "$FFAC", "$FFAD", "$FFAE", "$FFAF",
|
|
||||||
"$FFB0", "$FFB1", "$FFB2", "$FFB3", "$FFB4", "$FFB5", "$FFB6", "$FFB7",
|
|
||||||
"$FFB8", "$FFB9", "$FFBA", "$FFBB", "$FFBC", "$FFBD", "$FFBE", "$FFBF"
|
|
||||||
};
|
|
||||||
buf << "Bank = " << std::dec << myCart.getBank()
|
|
||||||
<< ", hotspot = " << spot[myCart.getBank()];
|
|
||||||
|
|
||||||
return buf.str();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,10 @@
|
||||||
#define CARTRIDGEBF_WIDGET_HXX
|
#define CARTRIDGEBF_WIDGET_HXX
|
||||||
|
|
||||||
class CartridgeBF;
|
class CartridgeBF;
|
||||||
class PopUpWidget;
|
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
#include "CartEnhancedWidget.hxx"
|
||||||
|
|
||||||
class CartridgeBFWidget : public CartDebugWidget
|
class CartridgeBFWidget : public CartridgeEnhancedWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CartridgeBFWidget(GuiObject* boss, const GUI::Font& lfont,
|
CartridgeBFWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
|
@ -33,17 +32,11 @@ class CartridgeBFWidget : public CartDebugWidget
|
||||||
virtual ~CartridgeBFWidget() = default;
|
virtual ~CartridgeBFWidget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CartridgeBF& myCart;
|
string manufacturer() override { return "CPUWIZ"; }
|
||||||
PopUpWidget* myBank{nullptr};
|
|
||||||
|
|
||||||
enum { kBankChanged = 'bkCH' };
|
string description() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void loadConfig() override;
|
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
|
||||||
|
|
||||||
string bankState() override;
|
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeBFWidget() = delete;
|
CartridgeBFWidget() = delete;
|
||||||
CartridgeBFWidget(const CartridgeBFWidget&) = delete;
|
CartridgeBFWidget(const CartridgeBFWidget&) = delete;
|
||||||
|
|
|
@ -238,7 +238,7 @@ void CartridgeBUSWidget::saveOldState()
|
||||||
}
|
}
|
||||||
|
|
||||||
for(uInt32 i = 0; i < internalRamSize(); ++i)
|
for(uInt32 i = 0; i < internalRamSize(); ++i)
|
||||||
myOldState.internalram.push_back(myCart.myBUSRAM[i]);
|
myOldState.internalram.push_back(myCart.myRAM[i]);
|
||||||
|
|
||||||
myOldState.samplepointer.push_back(myCart.getSample());
|
myOldState.samplepointer.push_back(myCart.getSample());
|
||||||
}
|
}
|
||||||
|
@ -438,18 +438,18 @@ const ByteArray& CartridgeBUSWidget::internalRamCurrent(int start, int count)
|
||||||
{
|
{
|
||||||
myRamCurrent.clear();
|
myRamCurrent.clear();
|
||||||
for(int i = 0; i < count; i++)
|
for(int i = 0; i < count; i++)
|
||||||
myRamCurrent.push_back(myCart.myBUSRAM[start + i]);
|
myRamCurrent.push_back(myCart.myRAM[start + i]);
|
||||||
return myRamCurrent;
|
return myRamCurrent;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeBUSWidget::internalRamSetValue(int addr, uInt8 value)
|
void CartridgeBUSWidget::internalRamSetValue(int addr, uInt8 value)
|
||||||
{
|
{
|
||||||
myCart.myBUSRAM[addr] = value;
|
myCart.myRAM[addr] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt8 CartridgeBUSWidget::internalRamGetValue(int addr)
|
uInt8 CartridgeBUSWidget::internalRamGetValue(int addr)
|
||||||
{
|
{
|
||||||
return myCart.myBUSRAM[addr];
|
return myCart.myRAM[addr];
|
||||||
}
|
}
|
||||||
|
|
|
@ -232,7 +232,7 @@ void CartridgeCDFWidget::saveOldState()
|
||||||
}
|
}
|
||||||
|
|
||||||
for(uInt32 i = 0; i < internalRamSize(); ++i)
|
for(uInt32 i = 0; i < internalRamSize(); ++i)
|
||||||
myOldState.internalram.push_back(myCart.myCDFRAM[i]);
|
myOldState.internalram.push_back(myCart.myRAM[i]);
|
||||||
|
|
||||||
myOldState.samplepointer.push_back(myCart.getSample());
|
myOldState.samplepointer.push_back(myCart.getSample());
|
||||||
}
|
}
|
||||||
|
@ -437,20 +437,20 @@ const ByteArray& CartridgeCDFWidget::internalRamCurrent(int start, int count)
|
||||||
{
|
{
|
||||||
myRamCurrent.clear();
|
myRamCurrent.clear();
|
||||||
for(int i = 0; i < count; i++)
|
for(int i = 0; i < count; i++)
|
||||||
myRamCurrent.push_back(myCart.myCDFRAM[start + i]);
|
myRamCurrent.push_back(myCart.myRAM[start + i]);
|
||||||
return myRamCurrent;
|
return myRamCurrent;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeCDFWidget::internalRamSetValue(int addr, uInt8 value)
|
void CartridgeCDFWidget::internalRamSetValue(int addr, uInt8 value)
|
||||||
{
|
{
|
||||||
myCart.myCDFRAM[addr] = value;
|
myCart.myRAM[addr] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt8 CartridgeCDFWidget::internalRamGetValue(int addr)
|
uInt8 CartridgeCDFWidget::internalRamGetValue(int addr)
|
||||||
{
|
{
|
||||||
return myCart.myCDFRAM[addr];
|
return myCart.myRAM[addr];
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -1,157 +0,0 @@
|
||||||
//============================================================================
|
|
||||||
//
|
|
||||||
// SSSS tt lll lll
|
|
||||||
// SS SS tt ll ll
|
|
||||||
// SS tttttt eeee ll ll aaaa
|
|
||||||
// SSSS tt ee ee ll ll aa
|
|
||||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
|
||||||
// SS SS tt ee ll ll aa aa
|
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
|
||||||
//
|
|
||||||
// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
|
|
||||||
// and the Stella Team
|
|
||||||
//
|
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
#include "Debugger.hxx"
|
|
||||||
#include "CartDebug.hxx"
|
|
||||||
#include "CartCVPlus.hxx"
|
|
||||||
#include "PopUpWidget.hxx"
|
|
||||||
#include "CartCVPlusWidget.hxx"
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
CartridgeCVPlusWidget::CartridgeCVPlusWidget(
|
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
|
||||||
int x, int y, int w, int h, CartridgeCVPlus& cart)
|
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
|
||||||
myCart(cart)
|
|
||||||
{
|
|
||||||
size_t size = cart.mySize;
|
|
||||||
|
|
||||||
ostringstream info;
|
|
||||||
info << "LS_Dracon CV+ cartridge, 1K RAM, 2-256 2K ROM\n"
|
|
||||||
<< "1024 bytes RAM @ $F000 - $F7FF\n"
|
|
||||||
<< " $F000 - $F3FF (R), $F400 - $F7FF (W)\n"
|
|
||||||
<< "2048 bytes ROM @ $F800 - $FFFF, by writing to $3D\n"
|
|
||||||
<< "Startup bank = " << cart.startBank() << "\n";
|
|
||||||
|
|
||||||
int xpos = 2,
|
|
||||||
ypos = addBaseInformation(size, "LS_Dracon / Stephen Anthony",
|
|
||||||
info.str()) + myLineHeight;
|
|
||||||
|
|
||||||
VariantList items;
|
|
||||||
for(uInt16 i = 0; i < cart.bankCount(); ++i)
|
|
||||||
VarList::push_back(items, Variant(i).toString() + " ($3D)");
|
|
||||||
|
|
||||||
ostringstream label;
|
|
||||||
label << "Set bank ($F800 - $FFFF) ";
|
|
||||||
myBank =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("xxx ($3D)"),
|
|
||||||
myLineHeight, items, label.str(),
|
|
||||||
_font.getStringWidth(label.str()), kBankChanged);
|
|
||||||
myBank->setTarget(this);
|
|
||||||
addFocusWidget(myBank);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeCVPlusWidget::loadConfig()
|
|
||||||
{
|
|
||||||
myBank->setSelectedIndex(myCart.getBank(), myCart.getBank() != myOldState.bank);
|
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeCVPlusWidget::handleCommand(CommandSender* sender,
|
|
||||||
int cmd, int data, int id)
|
|
||||||
{
|
|
||||||
if(cmd == kBankChanged)
|
|
||||||
{
|
|
||||||
myCart.unlockBank();
|
|
||||||
myCart.bank(myBank->getSelected());
|
|
||||||
myCart.lockBank();
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeCVPlusWidget::bankState()
|
|
||||||
{
|
|
||||||
ostringstream& buf = buffer();
|
|
||||||
|
|
||||||
buf << "Bank = " << std::dec << myCart.myCurrentBank << ", hotspot = $3D";
|
|
||||||
|
|
||||||
return buf.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeCVPlusWidget::saveOldState()
|
|
||||||
{
|
|
||||||
myOldState.internalram.clear();
|
|
||||||
|
|
||||||
for(uInt32 i = 0; i < internalRamSize(); ++i)
|
|
||||||
myOldState.internalram.push_back(myCart.myRAM[i]);
|
|
||||||
|
|
||||||
myOldState.bank = myCart.getBank();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 CartridgeCVPlusWidget::internalRamSize()
|
|
||||||
{
|
|
||||||
return 1024;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 CartridgeCVPlusWidget::internalRamRPort(int start)
|
|
||||||
{
|
|
||||||
return 0xF000 + start;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeCVPlusWidget::internalRamDescription()
|
|
||||||
{
|
|
||||||
ostringstream desc;
|
|
||||||
desc << "$F000 - $F3FF used for Read Access\n"
|
|
||||||
<< "$F400 - $F7FF used for Write Access";
|
|
||||||
|
|
||||||
return desc.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const ByteArray& CartridgeCVPlusWidget::internalRamOld(int start, int count)
|
|
||||||
{
|
|
||||||
myRamOld.clear();
|
|
||||||
for(int i = 0; i < count; i++)
|
|
||||||
myRamOld.push_back(myOldState.internalram[start + i]);
|
|
||||||
return myRamOld;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const ByteArray& CartridgeCVPlusWidget::internalRamCurrent(int start, int count)
|
|
||||||
{
|
|
||||||
myRamCurrent.clear();
|
|
||||||
for(int i = 0; i < count; i++)
|
|
||||||
myRamCurrent.push_back(myCart.myRAM[start + i]);
|
|
||||||
return myRamCurrent;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeCVPlusWidget::internalRamSetValue(int addr, uInt8 value)
|
|
||||||
{
|
|
||||||
myCart.myRAM[addr] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt8 CartridgeCVPlusWidget::internalRamGetValue(int addr)
|
|
||||||
{
|
|
||||||
return myCart.myRAM[addr];
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeCVPlusWidget::internalRamLabel(int addr)
|
|
||||||
{
|
|
||||||
CartDebug& dbg = instance().debugger().cartDebug();
|
|
||||||
return dbg.getLabel(addr + 0xF000, false);
|
|
||||||
}
|
|
|
@ -24,88 +24,18 @@
|
||||||
CartridgeCVWidget::CartridgeCVWidget(
|
CartridgeCVWidget::CartridgeCVWidget(
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h, CartridgeCV& cart)
|
int x, int y, int w, int h, CartridgeCV& cart)
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||||
myCart(cart)
|
|
||||||
{
|
{
|
||||||
// Eventually, we should query this from the debugger/disassembler
|
initialize();
|
||||||
uInt16 size = 2048;
|
}
|
||||||
uInt16 start = (cart.myImage[size-3] << 8) | cart.myImage[size-4];
|
|
||||||
start -= start % size;
|
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string CartridgeCVWidget::description()
|
||||||
|
{
|
||||||
ostringstream info;
|
ostringstream info;
|
||||||
info << "CV 2K ROM + 1K RAM , non-bankswitched\n"
|
|
||||||
<< "1024 bytes RAM @ $F000 - $F7FF\n"
|
|
||||||
<< " $F000 - $F3FF (R), $F400 - $F7FF (W)\n"
|
|
||||||
<< "ROM accessible @ $" << Common::Base::HEX4 << start << " - "
|
|
||||||
<< "$" << (start + size - 1);
|
|
||||||
|
|
||||||
addBaseInformation(cart.mySize, "CommaVid", info.str());
|
info << "CV 2K ROM + 1K RAM, non-bankswitched\n";
|
||||||
}
|
info << CartridgeEnhancedWidget::description();
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
return info.str();
|
||||||
void CartridgeCVWidget::saveOldState()
|
|
||||||
{
|
|
||||||
myOldState.internalram.clear();
|
|
||||||
|
|
||||||
for(uInt32 i = 0; i < internalRamSize(); ++i)
|
|
||||||
myOldState.internalram.push_back(myCart.myRAM[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 CartridgeCVWidget::internalRamSize()
|
|
||||||
{
|
|
||||||
return 1024;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 CartridgeCVWidget::internalRamRPort(int start)
|
|
||||||
{
|
|
||||||
return 0xF000 + start;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeCVWidget::internalRamDescription()
|
|
||||||
{
|
|
||||||
ostringstream desc;
|
|
||||||
desc << "$F000 - $F3FF used for Read Access\n"
|
|
||||||
<< "$F400 - $F7FF used for Write Access";
|
|
||||||
|
|
||||||
return desc.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const ByteArray& CartridgeCVWidget::internalRamOld(int start, int count)
|
|
||||||
{
|
|
||||||
myRamOld.clear();
|
|
||||||
for(int i = 0; i < count; i++)
|
|
||||||
myRamOld.push_back(myOldState.internalram[start + i]);
|
|
||||||
return myRamOld;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const ByteArray& CartridgeCVWidget::internalRamCurrent(int start, int count)
|
|
||||||
{
|
|
||||||
myRamCurrent.clear();
|
|
||||||
for(int i = 0; i < count; i++)
|
|
||||||
myRamCurrent.push_back(myCart.myRAM[start + i]);
|
|
||||||
return myRamCurrent;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeCVWidget::internalRamSetValue(int addr, uInt8 value)
|
|
||||||
{
|
|
||||||
myCart.myRAM[addr] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt8 CartridgeCVWidget::internalRamGetValue(int addr)
|
|
||||||
{
|
|
||||||
return myCart.myRAM[addr];
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeCVWidget::internalRamLabel(int addr)
|
|
||||||
{
|
|
||||||
CartDebug& dbg = instance().debugger().cartDebug();
|
|
||||||
return dbg.getLabel(addr + 0xF000, false);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,9 +20,9 @@
|
||||||
|
|
||||||
class CartridgeCV;
|
class CartridgeCV;
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
#include "CartEnhancedWidget.hxx"
|
||||||
|
|
||||||
class CartridgeCVWidget : public CartDebugWidget
|
class CartridgeCVWidget : public CartridgeEnhancedWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CartridgeCVWidget(GuiObject* boss, const GUI::Font& lfont,
|
CartridgeCVWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
|
@ -32,30 +32,11 @@ class CartridgeCVWidget : public CartDebugWidget
|
||||||
virtual ~CartridgeCVWidget() = default;
|
virtual ~CartridgeCVWidget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CartridgeCV& myCart;
|
string manufacturer() override { return "CommaVid"; }
|
||||||
struct CartState {
|
|
||||||
ByteArray internalram;
|
string description() override;
|
||||||
};
|
|
||||||
CartState myOldState;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// No implementation for non-bankswitched ROMs
|
|
||||||
void loadConfig() override { }
|
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override { }
|
|
||||||
|
|
||||||
void saveOldState() override;
|
|
||||||
|
|
||||||
// start of functions for Cartridge RAM tab
|
|
||||||
uInt32 internalRamSize() override;
|
|
||||||
uInt32 internalRamRPort(int start) override;
|
|
||||||
string internalRamDescription() override;
|
|
||||||
const ByteArray& internalRamOld(int start, int count) override;
|
|
||||||
const ByteArray& internalRamCurrent(int start, int count) override;
|
|
||||||
void internalRamSetValue(int addr, uInt8 value) override;
|
|
||||||
uInt8 internalRamGetValue(int addr) override;
|
|
||||||
string internalRamLabel(int addr) override;
|
|
||||||
// end of functions for Cartridge RAM tab
|
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeCVWidget() = delete;
|
CartridgeCVWidget() = delete;
|
||||||
CartridgeCVWidget(const CartridgeCVWidget&) = delete;
|
CartridgeCVWidget(const CartridgeCVWidget&) = delete;
|
||||||
|
|
|
@ -1,371 +0,0 @@
|
||||||
//============================================================================
|
|
||||||
//
|
|
||||||
// SSSS tt lll lll
|
|
||||||
// SS SS tt ll ll
|
|
||||||
// SS tttttt eeee ll ll aaaa
|
|
||||||
// SSSS tt ee ee ll ll aa
|
|
||||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
|
||||||
// SS SS tt ee ll ll aa aa
|
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
|
||||||
//
|
|
||||||
// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
|
|
||||||
// and the Stella Team
|
|
||||||
//
|
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
#include "CartDASH.hxx"
|
|
||||||
#include "EditTextWidget.hxx"
|
|
||||||
#include "PopUpWidget.hxx"
|
|
||||||
#include "CartDASHWidget.hxx"
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
CartridgeDASHWidget::CartridgeDASHWidget(
|
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
|
||||||
int x, int y, int w, int h, CartridgeDASH& cart)
|
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
|
||||||
myCart(cart)
|
|
||||||
{
|
|
||||||
size_t size = cart.mySize;
|
|
||||||
|
|
||||||
ostringstream info;
|
|
||||||
info << "DASH cartridge - (64K ROM + RAM)\n"
|
|
||||||
<< " 4-64K ROM (1K banks), 32K RAM (512b banks)\n"
|
|
||||||
<< "Each 1K ROM selected by writing to $3F\n"
|
|
||||||
"Each 512b RAM selected by writing to $3E\n"
|
|
||||||
" First 512B of bank x (R)\n"
|
|
||||||
" First 512B of bank x+4 (+$800) (W)\n"
|
|
||||||
<< "Startup bank = 0/-1/-1/0 (ROM)\n";
|
|
||||||
|
|
||||||
// Eventually, we should query this from the debugger/disassembler
|
|
||||||
uInt16 start = (cart.myImage[size-3] << 8) | cart.myImage[size-4];
|
|
||||||
start -= start % 0x1000;
|
|
||||||
info << "Bank RORG" << " = $" << Common::Base::HEX4 << start << "\n";
|
|
||||||
|
|
||||||
int xpos = 2,
|
|
||||||
ypos = addBaseInformation(size, "A. Davie & T. Jentzsch", info.str()) +
|
|
||||||
myLineHeight;
|
|
||||||
|
|
||||||
VariantList bankno;
|
|
||||||
for(uInt32 i = 0; i < myCart.ROM_BANK_COUNT; ++i)
|
|
||||||
VarList::push_back(bankno, i, i);
|
|
||||||
|
|
||||||
VariantList banktype;
|
|
||||||
VarList::push_back(banktype, "ROM", "ROM");
|
|
||||||
VarList::push_back(banktype, "RAM", "RAM");
|
|
||||||
|
|
||||||
for(uInt32 i = 0; i < 4; ++i)
|
|
||||||
{
|
|
||||||
int xpos_s, ypos_s = ypos;
|
|
||||||
|
|
||||||
ostringstream label;
|
|
||||||
label << "Set segment " << i << " as: ";
|
|
||||||
|
|
||||||
new StaticTextWidget(boss, _font, xpos, ypos, _font.getStringWidth(label.str()),
|
|
||||||
myFontHeight, label.str(), TextAlign::Left);
|
|
||||||
ypos += myLineHeight + 8;
|
|
||||||
|
|
||||||
xpos += 20;
|
|
||||||
myBankNumber[i] =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("Slot "),
|
|
||||||
myLineHeight, bankno, "Slot ",
|
|
||||||
6*_font.getMaxCharWidth());
|
|
||||||
addFocusWidget(myBankNumber[i]);
|
|
||||||
|
|
||||||
xpos += myBankNumber[i]->getWidth();
|
|
||||||
myBankType[i] =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, 5*_font.getMaxCharWidth(),
|
|
||||||
myLineHeight, banktype, " of ", _font.getStringWidth(" of "));
|
|
||||||
addFocusWidget(myBankType[i]);
|
|
||||||
|
|
||||||
xpos += myBankType[i]->getWidth() + 10;
|
|
||||||
|
|
||||||
myBankCommit[i] = new ButtonWidget(boss, _font, xpos, ypos-4,
|
|
||||||
_font.getStringWidth(" Commit "), myButtonHeight,
|
|
||||||
"Commit", bankEnum[i]);
|
|
||||||
myBankCommit[i]->setTarget(this);
|
|
||||||
addFocusWidget(myBankCommit[i]);
|
|
||||||
|
|
||||||
xpos_s = xpos + myBankCommit[i]->getWidth() + 20;
|
|
||||||
|
|
||||||
StaticTextWidget* t;
|
|
||||||
int addr1 = start + (i*0x400), addr2 = addr1 + 0x1FF;
|
|
||||||
|
|
||||||
label.str("");
|
|
||||||
label << Common::Base::HEX4 << addr1 << "-" << Common::Base::HEX4 << addr2;
|
|
||||||
t = new StaticTextWidget(boss, _font, xpos_s, ypos_s+2,
|
|
||||||
_font.getStringWidth(label.str()), myFontHeight, label.str(), TextAlign::Left);
|
|
||||||
|
|
||||||
int xoffset = xpos_s+t->getWidth() + 10;
|
|
||||||
myBankState[2*i] = new EditTextWidget(boss, _font, xoffset, ypos_s,
|
|
||||||
w - xoffset - 10, myLineHeight, "");
|
|
||||||
myBankState[2*i]->setEditable(false, true);
|
|
||||||
ypos_s += myLineHeight + 4;
|
|
||||||
|
|
||||||
label.str("");
|
|
||||||
label << Common::Base::HEX4 << (addr2 + 1) << "-" << Common::Base::HEX4 << (addr2 + 1 + 0x1FF);
|
|
||||||
new StaticTextWidget(boss, _font, xpos_s, ypos_s+2,
|
|
||||||
_font.getStringWidth(label.str()), myFontHeight, label.str(), TextAlign::Left);
|
|
||||||
|
|
||||||
myBankState[2*i+1] = new EditTextWidget(boss, _font, xoffset, ypos_s,
|
|
||||||
w - xoffset - 10, myLineHeight, "");
|
|
||||||
myBankState[2*i+1]->setEditable(false, true);
|
|
||||||
|
|
||||||
xpos = 10;
|
|
||||||
ypos+= 2 * myLineHeight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeDASHWidget::saveOldState()
|
|
||||||
{
|
|
||||||
myOldState.internalram.clear();
|
|
||||||
|
|
||||||
for(uInt32 i = 0; i < internalRamSize(); ++i)
|
|
||||||
myOldState.internalram.push_back(myCart.myRAM[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeDASHWidget::loadConfig()
|
|
||||||
{
|
|
||||||
updateUIState();
|
|
||||||
CartDebugWidget::loadConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeDASHWidget::handleCommand(CommandSender* sender,
|
|
||||||
int cmd, int data, int id)
|
|
||||||
{
|
|
||||||
uInt16 segment = 0;
|
|
||||||
switch(cmd)
|
|
||||||
{
|
|
||||||
case kBank0Changed:
|
|
||||||
segment = 0;
|
|
||||||
break;
|
|
||||||
case kBank1Changed:
|
|
||||||
segment = 1;
|
|
||||||
break;
|
|
||||||
case kBank2Changed:
|
|
||||||
segment = 2;
|
|
||||||
break;
|
|
||||||
case kBank3Changed:
|
|
||||||
segment = 3;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ignore bank if either number or type hasn't been selected
|
|
||||||
if(myBankNumber[segment]->getSelected() < 0 ||
|
|
||||||
myBankType[segment]->getSelected() < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
uInt8 bank = (segment << myCart.BANK_BITS) |
|
|
||||||
(myBankNumber[segment]->getSelected() & myCart.BIT_BANK_MASK);
|
|
||||||
|
|
||||||
myCart.unlockBank();
|
|
||||||
|
|
||||||
if(myBankType[segment]->getSelectedTag() == "ROM")
|
|
||||||
myCart.bankROM(bank);
|
|
||||||
else
|
|
||||||
myCart.bankRAM(bank);
|
|
||||||
|
|
||||||
myCart.lockBank();
|
|
||||||
invalidate();
|
|
||||||
updateUIState();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeDASHWidget::bankState()
|
|
||||||
{
|
|
||||||
ostringstream& buf = buffer();
|
|
||||||
int lastROMBank = -1;
|
|
||||||
bool lastSlotRAM = false;
|
|
||||||
|
|
||||||
for(int i = 0; i < 8; ++i)
|
|
||||||
{
|
|
||||||
uInt16 bank = myCart.bankInUse[i];
|
|
||||||
|
|
||||||
if(bank == myCart.BANK_UNDEFINED) // never accessed
|
|
||||||
{
|
|
||||||
buf << " U!";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int bankno = bank & myCart.BIT_BANK_MASK;
|
|
||||||
|
|
||||||
if(bank & myCart.BITMASK_ROMRAM) // was RAM mapped here?
|
|
||||||
{
|
|
||||||
// RAM will always need a '+' placed somewhere, since it always
|
|
||||||
// consists of 512B segments
|
|
||||||
bool inFirstSlot = (i % 2 == 0);
|
|
||||||
if(!(inFirstSlot || lastSlotRAM))
|
|
||||||
{
|
|
||||||
lastSlotRAM = false;
|
|
||||||
buf << " +";
|
|
||||||
}
|
|
||||||
|
|
||||||
if(bank & myCart.BITMASK_LOWERUPPER) // upper is write port
|
|
||||||
buf << " RAM " << bankno << "W";
|
|
||||||
else
|
|
||||||
buf << " RAM " << bankno << "R";
|
|
||||||
|
|
||||||
if(inFirstSlot)
|
|
||||||
{
|
|
||||||
buf << " +";
|
|
||||||
lastSlotRAM = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// ROM can be contiguous, since 2 512B segments can form a single
|
|
||||||
// 1K bank; in this case we only show the info once
|
|
||||||
bool highBankSame = (i % 2 == 1) && (bankno == lastROMBank);
|
|
||||||
if(!highBankSame)
|
|
||||||
{
|
|
||||||
buf << " ROM " << bankno;
|
|
||||||
lastROMBank = bankno;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
lastROMBank = -1;
|
|
||||||
|
|
||||||
lastSlotRAM = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if((i+1) % 2 == 0 && i < 7)
|
|
||||||
buf << " /";
|
|
||||||
}
|
|
||||||
|
|
||||||
return buf.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeDASHWidget::updateUIState()
|
|
||||||
{
|
|
||||||
// Set contents for actual banks number and type
|
|
||||||
for(int i = 0; i < 4; ++i)
|
|
||||||
{
|
|
||||||
uInt16 segment = myCart.segmentInUse[i];
|
|
||||||
|
|
||||||
if(segment == myCart.BANK_UNDEFINED)
|
|
||||||
{
|
|
||||||
myBankNumber[i]->clearSelection();
|
|
||||||
myBankType[i]->clearSelection();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int bankno = segment & myCart.BIT_BANK_MASK;
|
|
||||||
const string& banktype = (segment & myCart.BITMASK_ROMRAM) ? "RAM" : "ROM";
|
|
||||||
|
|
||||||
myBankNumber[i]->setSelected(bankno);
|
|
||||||
myBankType[i]->setSelected(banktype);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set description for each 512b bank state
|
|
||||||
for(int i = 0; i < 8; ++i)
|
|
||||||
{
|
|
||||||
uInt16 bank = myCart.bankInUse[i];
|
|
||||||
|
|
||||||
if(bank == myCart.BANK_UNDEFINED) // never accessed
|
|
||||||
{
|
|
||||||
myBankState[i]->setText("Undefined");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ostringstream buf;
|
|
||||||
int bankno = bank & myCart.BIT_BANK_MASK;
|
|
||||||
|
|
||||||
if(bank & myCart.BITMASK_ROMRAM) // was RAM mapped here?
|
|
||||||
{
|
|
||||||
if(bank & myCart.BITMASK_LOWERUPPER) // upper is write port
|
|
||||||
{
|
|
||||||
buf << "RAM " << bankno << " @ $" << Common::Base::HEX4
|
|
||||||
<< (bankno << myCart.RAM_BANK_TO_POWER) << " (W)";
|
|
||||||
myBankState[i]->setText(buf.str());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
buf << "RAM " << bankno << " @ $" << Common::Base::HEX4
|
|
||||||
<< (bankno << myCart.RAM_BANK_TO_POWER) << " (R)";
|
|
||||||
myBankState[i]->setText(buf.str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(bank & myCart.BITMASK_LOWERUPPER) // upper is high 512b
|
|
||||||
{
|
|
||||||
buf << "ROM " << bankno << " @ $" << Common::Base::HEX4
|
|
||||||
<< ((bankno << myCart.RAM_BANK_TO_POWER) + myCart.RAM_BANK_SIZE);
|
|
||||||
myBankState[i]->setText(buf.str());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
buf << "ROM " << bankno << " @ $" << Common::Base::HEX4
|
|
||||||
<< (bankno << myCart.RAM_BANK_TO_POWER);
|
|
||||||
myBankState[i]->setText(buf.str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 CartridgeDASHWidget::internalRamSize()
|
|
||||||
{
|
|
||||||
return 32*1024;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 CartridgeDASHWidget::internalRamRPort(int start)
|
|
||||||
{
|
|
||||||
return 0x0000 + start;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeDASHWidget::internalRamDescription()
|
|
||||||
{
|
|
||||||
ostringstream desc;
|
|
||||||
desc << "Accessible 512b at a time via:\n"
|
|
||||||
<< " $F000/$F200/$F400/etc used for Read Access\n"
|
|
||||||
<< " $F800/$FA00/$FC00/etc used for Write Access (+$800)";
|
|
||||||
|
|
||||||
return desc.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const ByteArray& CartridgeDASHWidget::internalRamOld(int start, int count)
|
|
||||||
{
|
|
||||||
myRamOld.clear();
|
|
||||||
for(int i = 0; i < count; i++)
|
|
||||||
myRamOld.push_back(myOldState.internalram[start + i]);
|
|
||||||
return myRamOld;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const ByteArray& CartridgeDASHWidget::internalRamCurrent(int start, int count)
|
|
||||||
{
|
|
||||||
myRamCurrent.clear();
|
|
||||||
for(int i = 0; i < count; i++)
|
|
||||||
myRamCurrent.push_back(myCart.myRAM[start + i]);
|
|
||||||
return myRamCurrent;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeDASHWidget::internalRamSetValue(int addr, uInt8 value)
|
|
||||||
{
|
|
||||||
myCart.myRAM[addr] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt8 CartridgeDASHWidget::internalRamGetValue(int addr)
|
|
||||||
{
|
|
||||||
return myCart.myRAM[addr];
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const std::array<CartridgeDASHWidget::BankID, 4> CartridgeDASHWidget::bankEnum = {
|
|
||||||
kBank0Changed, kBank1Changed, kBank2Changed, kBank3Changed
|
|
||||||
};
|
|
|
@ -1,86 +0,0 @@
|
||||||
//============================================================================
|
|
||||||
//
|
|
||||||
// SSSS tt lll lll
|
|
||||||
// SS SS tt ll ll
|
|
||||||
// SS tttttt eeee ll ll aaaa
|
|
||||||
// SSSS tt ee ee ll ll aa
|
|
||||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
|
||||||
// SS SS tt ee ll ll aa aa
|
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
|
||||||
//
|
|
||||||
// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
|
|
||||||
// and the Stella Team
|
|
||||||
//
|
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
#ifndef CARTRIDGEDASH_WIDGET_HXX
|
|
||||||
#define CARTRIDGEDASH_WIDGET_HXX
|
|
||||||
|
|
||||||
class CartridgeDASH;
|
|
||||||
class ButtonWidget;
|
|
||||||
class EditTextWidget;
|
|
||||||
class PopUpWidget;
|
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
|
||||||
|
|
||||||
class CartridgeDASHWidget : public CartDebugWidget
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CartridgeDASHWidget(GuiObject* boss, const GUI::Font& lfont,
|
|
||||||
const GUI::Font& nfont,
|
|
||||||
int x, int y, int w, int h,
|
|
||||||
CartridgeDASH& cart);
|
|
||||||
virtual ~CartridgeDASHWidget() = default;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void updateUIState();
|
|
||||||
|
|
||||||
private:
|
|
||||||
CartridgeDASH& myCart;
|
|
||||||
|
|
||||||
std::array<PopUpWidget*, 4> myBankNumber{nullptr};
|
|
||||||
std::array<PopUpWidget*, 4> myBankType{nullptr};
|
|
||||||
std::array<ButtonWidget*, 4> myBankCommit{nullptr};
|
|
||||||
std::array<EditTextWidget*, 8> myBankState{nullptr};
|
|
||||||
|
|
||||||
struct CartState {
|
|
||||||
ByteArray internalram;
|
|
||||||
};
|
|
||||||
CartState myOldState;
|
|
||||||
|
|
||||||
enum BankID {
|
|
||||||
kBank0Changed = 'b0CH',
|
|
||||||
kBank1Changed = 'b1CH',
|
|
||||||
kBank2Changed = 'b2CH',
|
|
||||||
kBank3Changed = 'b3CH'
|
|
||||||
};
|
|
||||||
static const std::array<BankID, 4> bankEnum;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void saveOldState() override;
|
|
||||||
void loadConfig() override;
|
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
|
||||||
|
|
||||||
string bankState() override;
|
|
||||||
|
|
||||||
// start of functions for Cartridge RAM tab
|
|
||||||
uInt32 internalRamSize() override;
|
|
||||||
uInt32 internalRamRPort(int start) override;
|
|
||||||
string internalRamDescription() override;
|
|
||||||
const ByteArray& internalRamOld(int start, int count) override;
|
|
||||||
const ByteArray& internalRamCurrent(int start, int count) override;
|
|
||||||
void internalRamSetValue(int addr, uInt8 value) override;
|
|
||||||
uInt8 internalRamGetValue(int addr) override;
|
|
||||||
// end of functions for Cartridge RAM tab
|
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
|
||||||
CartridgeDASHWidget() = delete;
|
|
||||||
CartridgeDASHWidget(const CartridgeDASHWidget&) = delete;
|
|
||||||
CartridgeDASHWidget(CartridgeDASHWidget&&) = delete;
|
|
||||||
CartridgeDASHWidget& operator=(const CartridgeDASHWidget&) = delete;
|
|
||||||
CartridgeDASHWidget& operator=(CartridgeDASHWidget&&) = delete;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -15,185 +15,25 @@
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "Debugger.hxx"
|
|
||||||
#include "CartDebug.hxx"
|
|
||||||
#include "CartDFSC.hxx"
|
#include "CartDFSC.hxx"
|
||||||
#include "PopUpWidget.hxx"
|
|
||||||
#include "CartDFSCWidget.hxx"
|
#include "CartDFSCWidget.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CartridgeDFSCWidget::CartridgeDFSCWidget(
|
CartridgeDFSCWidget::CartridgeDFSCWidget(
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h, CartridgeDFSC& cart)
|
int x, int y, int w, int h, CartridgeDFSC& cart)
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||||
myCart(cart)
|
|
||||||
{
|
{
|
||||||
uInt32 size = 32 * 4096;
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string CartridgeDFSCWidget::description()
|
||||||
|
{
|
||||||
ostringstream info;
|
ostringstream info;
|
||||||
info << "128K DFSC + RAM, 32 4K banks\n"
|
|
||||||
<< "128 bytes RAM @ $F000 - $F0FF\n"
|
|
||||||
<< " $F080 - $F0FF (R), $F000 - $F07F (W)\n"
|
|
||||||
<< "Startup bank = " << cart.startBank() << "\n";
|
|
||||||
|
|
||||||
// Eventually, we should query this from the debugger/disassembler
|
info << "128K DFSC + RAM, 32 4K banks\n";
|
||||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0xFC0; i < 32; ++i, offset += 0x1000)
|
info << CartridgeEnhancedWidget::description();
|
||||||
{
|
|
||||||
uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset];
|
|
||||||
start -= start % 0x1000;
|
|
||||||
info << "Bank " << std::dec << i << " @ $" << Common::Base::HEX4 << (start + 0x100)
|
|
||||||
<< " - " << "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
int xpos = 2,
|
return info.str();
|
||||||
ypos = addBaseInformation(size, "CPUWIZ", info.str()) + myLineHeight;
|
|
||||||
|
|
||||||
VariantList items;
|
|
||||||
VarList::push_back(items, " 0 ($FFC0)");
|
|
||||||
VarList::push_back(items, " 1 ($FFC1)");
|
|
||||||
VarList::push_back(items, " 2 ($FFC2)");
|
|
||||||
VarList::push_back(items, " 3 ($FFC3)");
|
|
||||||
VarList::push_back(items, " 4 ($FFC4)");
|
|
||||||
VarList::push_back(items, " 5 ($FFC5)");
|
|
||||||
VarList::push_back(items, " 6 ($FFC6)");
|
|
||||||
VarList::push_back(items, " 7 ($FFC7)");
|
|
||||||
VarList::push_back(items, " 8 ($FFC8)");
|
|
||||||
VarList::push_back(items, " 9 ($FFC9)");
|
|
||||||
VarList::push_back(items, "10 ($FFCA)");
|
|
||||||
VarList::push_back(items, "11 ($FFCB)");
|
|
||||||
VarList::push_back(items, "12 ($FFCC)");
|
|
||||||
VarList::push_back(items, "13 ($FFCD)");
|
|
||||||
VarList::push_back(items, "14 ($FFCE)");
|
|
||||||
VarList::push_back(items, "15 ($FFCF)");
|
|
||||||
VarList::push_back(items, "16 ($FFD0)");
|
|
||||||
VarList::push_back(items, "17 ($FFD1)");
|
|
||||||
VarList::push_back(items, "18 ($FFD2)");
|
|
||||||
VarList::push_back(items, "19 ($FFD3)");
|
|
||||||
VarList::push_back(items, "20 ($FFD4)");
|
|
||||||
VarList::push_back(items, "21 ($FFD5)");
|
|
||||||
VarList::push_back(items, "22 ($FFD6)");
|
|
||||||
VarList::push_back(items, "23 ($FFD7)");
|
|
||||||
VarList::push_back(items, "24 ($FFD8)");
|
|
||||||
VarList::push_back(items, "25 ($FFD9)");
|
|
||||||
VarList::push_back(items, "26 ($FFDA)");
|
|
||||||
VarList::push_back(items, "27 ($FFDB)");
|
|
||||||
VarList::push_back(items, "28 ($FFDC)");
|
|
||||||
VarList::push_back(items, "29 ($FFDD)");
|
|
||||||
VarList::push_back(items, "30 ($FFDE)");
|
|
||||||
VarList::push_back(items, "31 ($FFDF)");
|
|
||||||
|
|
||||||
myBank =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("31 ($FFE0)"),
|
|
||||||
myLineHeight, items, "Set bank ",
|
|
||||||
0, kBankChanged);
|
|
||||||
myBank->setTarget(this);
|
|
||||||
addFocusWidget(myBank);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeDFSCWidget::saveOldState()
|
|
||||||
{
|
|
||||||
myOldState.internalram.clear();
|
|
||||||
|
|
||||||
for(uInt32 i = 0; i < internalRamSize(); ++i)
|
|
||||||
myOldState.internalram.push_back(myCart.myRAM[i]);
|
|
||||||
|
|
||||||
myOldState.bank = myCart.getBank();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeDFSCWidget::loadConfig()
|
|
||||||
{
|
|
||||||
myBank->setSelectedIndex(myCart.getBank(), myCart.getBank() != myOldState.bank);
|
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeDFSCWidget::handleCommand(CommandSender* sender,
|
|
||||||
int cmd, int data, int id)
|
|
||||||
{
|
|
||||||
if(cmd == kBankChanged)
|
|
||||||
{
|
|
||||||
myCart.unlockBank();
|
|
||||||
myCart.bank(myBank->getSelected());
|
|
||||||
myCart.lockBank();
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeDFSCWidget::bankState()
|
|
||||||
{
|
|
||||||
ostringstream& buf = buffer();
|
|
||||||
|
|
||||||
static constexpr std::array<const char*, 32> spot = {
|
|
||||||
"$FFC0", "$FFC1", "$FFC2", "$FFC3", "$FFC4", "$FFC5", "$FFC6", "$FFC7",
|
|
||||||
"$FFC8", "$FFC9", "$FFCA", "$FFCB", "$FFCC", "$FFCD", "$FFCE", "$FFCF",
|
|
||||||
"$FFD0", "$FFD1", "$FFD2", "$FFD3", "$FFD4", "$FFD5", "$FFD6", "$FFE7",
|
|
||||||
"$FFD8", "$FFD9", "$FFDA", "$FFDB", "$FFDC", "$FFDD", "$FFDE", "$FFDF"
|
|
||||||
};
|
|
||||||
buf << "Bank = " << std::dec << myCart.getBank()
|
|
||||||
<< ", hotspot = " << spot[myCart.getBank()];
|
|
||||||
|
|
||||||
return buf.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 CartridgeDFSCWidget::internalRamSize()
|
|
||||||
{
|
|
||||||
return 128;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 CartridgeDFSCWidget::internalRamRPort(int start)
|
|
||||||
{
|
|
||||||
return 0xF080 + start;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeDFSCWidget::internalRamDescription()
|
|
||||||
{
|
|
||||||
ostringstream desc;
|
|
||||||
desc << "$F000 - $F07F used for Write Access\n"
|
|
||||||
<< "$F080 - $F0FF used for Read Access";
|
|
||||||
|
|
||||||
return desc.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const ByteArray& CartridgeDFSCWidget::internalRamOld(int start, int count)
|
|
||||||
{
|
|
||||||
myRamOld.clear();
|
|
||||||
for(int i = 0; i < count; i++)
|
|
||||||
myRamOld.push_back(myOldState.internalram[start + i]);
|
|
||||||
return myRamOld;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const ByteArray& CartridgeDFSCWidget::internalRamCurrent(int start, int count)
|
|
||||||
{
|
|
||||||
myRamCurrent.clear();
|
|
||||||
for(int i = 0; i < count; i++)
|
|
||||||
myRamCurrent.push_back(myCart.myRAM[start + i]);
|
|
||||||
return myRamCurrent;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeDFSCWidget::internalRamSetValue(int addr, uInt8 value)
|
|
||||||
{
|
|
||||||
myCart.myRAM[addr] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt8 CartridgeDFSCWidget::internalRamGetValue(int addr)
|
|
||||||
{
|
|
||||||
return myCart.myRAM[addr];
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeDFSCWidget::internalRamLabel(int addr)
|
|
||||||
{
|
|
||||||
CartDebug& dbg = instance().debugger().cartDebug();
|
|
||||||
return dbg.getLabel(addr + 0xF080, false);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,10 @@
|
||||||
#define CARTRIDGEDFSC_WIDGET_HXX
|
#define CARTRIDGEDFSC_WIDGET_HXX
|
||||||
|
|
||||||
class CartridgeDFSC;
|
class CartridgeDFSC;
|
||||||
class PopUpWidget;
|
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
#include "CartEnhancedWidget.hxx"
|
||||||
|
|
||||||
class CartridgeDFSCWidget : public CartDebugWidget
|
class CartridgeDFSCWidget : public CartridgeEnhancedWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CartridgeDFSCWidget(GuiObject* boss, const GUI::Font& lfont,
|
CartridgeDFSCWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
|
@ -33,35 +32,11 @@ class CartridgeDFSCWidget : public CartDebugWidget
|
||||||
virtual ~CartridgeDFSCWidget() = default;
|
virtual ~CartridgeDFSCWidget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CartridgeDFSC& myCart;
|
string manufacturer() override { return "CPUWIZ"; }
|
||||||
PopUpWidget* myBank{nullptr};
|
|
||||||
|
|
||||||
struct CartState {
|
string description() override;
|
||||||
ByteArray internalram;
|
|
||||||
uInt16 bank{0};
|
|
||||||
};
|
|
||||||
CartState myOldState;
|
|
||||||
|
|
||||||
enum { kBankChanged = 'bkCH' };
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void saveOldState() override;
|
|
||||||
void loadConfig() override;
|
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
|
||||||
|
|
||||||
string bankState() override;
|
|
||||||
|
|
||||||
// start of functions for Cartridge RAM tab
|
|
||||||
uInt32 internalRamSize() override;
|
|
||||||
uInt32 internalRamRPort(int start) override;
|
|
||||||
string internalRamDescription() override;
|
|
||||||
const ByteArray& internalRamOld(int start, int count) override;
|
|
||||||
const ByteArray& internalRamCurrent(int start, int count) override;
|
|
||||||
void internalRamSetValue(int addr, uInt8 value) override;
|
|
||||||
uInt8 internalRamGetValue(int addr) override;
|
|
||||||
string internalRamLabel(int addr) override;
|
|
||||||
// end of functions for Cartridge RAM tab
|
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeDFSCWidget() = delete;
|
CartridgeDFSCWidget() = delete;
|
||||||
CartridgeDFSCWidget(const CartridgeDFSCWidget&) = delete;
|
CartridgeDFSCWidget(const CartridgeDFSCWidget&) = delete;
|
||||||
|
|
|
@ -16,115 +16,24 @@
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "CartDF.hxx"
|
#include "CartDF.hxx"
|
||||||
#include "PopUpWidget.hxx"
|
|
||||||
#include "CartDFWidget.hxx"
|
#include "CartDFWidget.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CartridgeDFWidget::CartridgeDFWidget(
|
CartridgeDFWidget::CartridgeDFWidget(
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h, CartridgeDF& cart)
|
int x, int y, int w, int h, CartridgeDF& cart)
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||||
myCart(cart)
|
|
||||||
{
|
{
|
||||||
uInt32 size = 32 * 4096;
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string CartridgeDFWidget::description()
|
||||||
|
{
|
||||||
ostringstream info;
|
ostringstream info;
|
||||||
info << "EF 2 cartridge, 32 4K banks\n"
|
|
||||||
<< "Startup bank = " << cart.startBank() << "\n";
|
|
||||||
|
|
||||||
// Eventually, we should query this from the debugger/disassembler
|
info << "128K DF, 32 4K banks\n";
|
||||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0xFD0; i < 32; ++i, offset += 0x1000)
|
info << CartridgeEnhancedWidget::description();
|
||||||
{
|
|
||||||
uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset];
|
|
||||||
start -= start % 0x1000;
|
|
||||||
info << "Bank " << std::dec << i << " @ $" << Common::Base::HEX4 << start << " - "
|
|
||||||
<< "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
int xpos = 2,
|
return info.str();
|
||||||
ypos = addBaseInformation(size, "CPUWIZ", info.str()) + myLineHeight;
|
|
||||||
|
|
||||||
VariantList items;
|
|
||||||
VarList::push_back(items, " 0 ($FFC0)");
|
|
||||||
VarList::push_back(items, " 1 ($FFC1)");
|
|
||||||
VarList::push_back(items, " 2 ($FFC2)");
|
|
||||||
VarList::push_back(items, " 3 ($FFC3)");
|
|
||||||
VarList::push_back(items, " 4 ($FFC4)");
|
|
||||||
VarList::push_back(items, " 5 ($FFC5)");
|
|
||||||
VarList::push_back(items, " 6 ($FFC6)");
|
|
||||||
VarList::push_back(items, " 7 ($FFC7)");
|
|
||||||
VarList::push_back(items, " 8 ($FFC8)");
|
|
||||||
VarList::push_back(items, " 9 ($FFC9)");
|
|
||||||
VarList::push_back(items, "10 ($FFCA)");
|
|
||||||
VarList::push_back(items, "11 ($FFCB)");
|
|
||||||
VarList::push_back(items, "12 ($FFCC)");
|
|
||||||
VarList::push_back(items, "13 ($FFCD)");
|
|
||||||
VarList::push_back(items, "14 ($FFCE)");
|
|
||||||
VarList::push_back(items, "15 ($FFCF)");
|
|
||||||
VarList::push_back(items, "16 ($FFD0)");
|
|
||||||
VarList::push_back(items, "17 ($FFD1)");
|
|
||||||
VarList::push_back(items, "18 ($FFD2)");
|
|
||||||
VarList::push_back(items, "19 ($FFD3)");
|
|
||||||
VarList::push_back(items, "20 ($FFD4)");
|
|
||||||
VarList::push_back(items, "21 ($FFD5)");
|
|
||||||
VarList::push_back(items, "22 ($FFD6)");
|
|
||||||
VarList::push_back(items, "23 ($FFD7)");
|
|
||||||
VarList::push_back(items, "24 ($FFD8)");
|
|
||||||
VarList::push_back(items, "25 ($FFD9)");
|
|
||||||
VarList::push_back(items, "26 ($FFDA)");
|
|
||||||
VarList::push_back(items, "27 ($FFDB)");
|
|
||||||
VarList::push_back(items, "28 ($FFDC)");
|
|
||||||
VarList::push_back(items, "29 ($FFDD)");
|
|
||||||
VarList::push_back(items, "30 ($FFDE)");
|
|
||||||
VarList::push_back(items, "31 ($FFDF)");
|
|
||||||
|
|
||||||
myBank =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("31 ($FFDF)"),
|
|
||||||
myLineHeight, items, "Set bank ",
|
|
||||||
0, kBankChanged);
|
|
||||||
myBank->setTarget(this);
|
|
||||||
addFocusWidget(myBank);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeDFWidget::loadConfig()
|
|
||||||
{
|
|
||||||
Debugger& dbg = instance().debugger();
|
|
||||||
CartDebug& cart = dbg.cartDebug();
|
|
||||||
const CartState& state = static_cast<const CartState&>(cart.getState());
|
|
||||||
const CartState& oldstate = static_cast<const CartState&>(cart.getOldState());
|
|
||||||
|
|
||||||
myBank->setSelectedIndex(myCart.getBank(), state.bank != oldstate.bank);
|
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeDFWidget::handleCommand(CommandSender* sender,
|
|
||||||
int cmd, int data, int id)
|
|
||||||
{
|
|
||||||
if(cmd == kBankChanged)
|
|
||||||
{
|
|
||||||
myCart.unlockBank();
|
|
||||||
myCart.bank(myBank->getSelected());
|
|
||||||
myCart.lockBank();
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeDFWidget::bankState()
|
|
||||||
{
|
|
||||||
ostringstream& buf = buffer();
|
|
||||||
|
|
||||||
static constexpr std::array<const char*, 32> spot = {
|
|
||||||
"$FFC0", "$FFC1", "$FFC2", "$FFC3", "$FFC4", "$FFC5", "$FFC6", "$FFC7",
|
|
||||||
"$FFC8", "$FFC9", "$FFCA", "$FFCB", "$FFCC", "$FFCD", "$FFCE", "$FFCF",
|
|
||||||
"$FFD0", "$FFD1", "$FFD2", "$FFD3", "$FFD4", "$FFD5", "$FFD6", "$FFD7",
|
|
||||||
"$FFD8", "$FFD9", "$FFDA", "$FFDB", "$FFDC", "$FFDD", "$FFDE", "$FFDF"
|
|
||||||
};
|
|
||||||
buf << "Bank = " << std::dec << myCart.getBank()
|
|
||||||
<< ", hotspot = " << spot[myCart.getBank()];
|
|
||||||
|
|
||||||
return buf.str();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,10 @@
|
||||||
#define CARTRIDGEDF_WIDGET_HXX
|
#define CARTRIDGEDF_WIDGET_HXX
|
||||||
|
|
||||||
class CartridgeDF;
|
class CartridgeDF;
|
||||||
class PopUpWidget;
|
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
#include "CartEnhancedWidget.hxx"
|
||||||
|
|
||||||
class CartridgeDFWidget : public CartDebugWidget
|
class CartridgeDFWidget : public CartridgeEnhancedWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CartridgeDFWidget(GuiObject* boss, const GUI::Font& lfont,
|
CartridgeDFWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
|
@ -33,17 +32,11 @@ class CartridgeDFWidget : public CartDebugWidget
|
||||||
virtual ~CartridgeDFWidget() = default;
|
virtual ~CartridgeDFWidget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CartridgeDF& myCart;
|
string manufacturer() override { return "CPUWIZ"; }
|
||||||
PopUpWidget* myBank{nullptr};
|
|
||||||
|
|
||||||
enum { kBankChanged = 'bkCH' };
|
string description() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void loadConfig() override;
|
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
|
||||||
|
|
||||||
string bankState() override;
|
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeDFWidget() = delete;
|
CartridgeDFWidget() = delete;
|
||||||
CartridgeDFWidget(const CartridgeDFWidget&) = delete;
|
CartridgeDFWidget(const CartridgeDFWidget&) = delete;
|
||||||
|
|
|
@ -27,12 +27,13 @@ CartridgeDPCWidget::CartridgeDPCWidget(
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||||
myCart(cart)
|
myCart(cart)
|
||||||
{
|
{
|
||||||
|
const int V_GAP = 4;
|
||||||
size_t size = cart.mySize;
|
size_t size = cart.mySize;
|
||||||
|
|
||||||
ostringstream info;
|
ostringstream info;
|
||||||
|
|
||||||
info << "DPC cartridge, two 4K banks + 2K display bank\n"
|
info << "DPC cartridge, two 4K banks + 2K display bank\n"
|
||||||
<< "DPC registers accessible @ $F000 - $F07F\n"
|
<< "DPC registers accessible @ $" << Common::Base::HEX4 << 0xF000 << " - $" << 0xF07F << "\n"
|
||||||
<< " $F000 - $F03F (R), $F040 - $F07F (W)\n"
|
<< " $" << 0xF000 << " - " << 0xF03F << " (R), $" << 0xF040 << " - $" << 0xF07F << " (W)\n"
|
||||||
|
|
||||||
<< "Startup bank = " << cart.startBank() << " or undetermined\n";
|
<< "Startup bank = " << cart.startBank() << " or undetermined\n";
|
||||||
|
|
||||||
|
@ -42,7 +43,7 @@ CartridgeDPCWidget::CartridgeDPCWidget(
|
||||||
uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset];
|
uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset];
|
||||||
start -= start % 0x1000;
|
start -= start % 0x1000;
|
||||||
info << "Bank " << i << " @ $" << Common::Base::HEX4 << (start + 0x80) << " - "
|
info << "Bank " << i << " @ $" << Common::Base::HEX4 << (start + 0x80) << " - "
|
||||||
<< "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n";
|
<< "$" << (start + 0xFFF) << " (hotspot = $" << (0xF000 + spot + i) << ")\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
int xpos = 2,
|
int xpos = 2,
|
||||||
|
@ -50,26 +51,30 @@ CartridgeDPCWidget::CartridgeDPCWidget(
|
||||||
myLineHeight;
|
myLineHeight;
|
||||||
|
|
||||||
VariantList items;
|
VariantList items;
|
||||||
VarList::push_back(items, "0 ($FFF8)");
|
for(int bank = 0; bank < 2; ++bank)
|
||||||
VarList::push_back(items, "1 ($FFF9)");
|
{
|
||||||
|
ostringstream buf;
|
||||||
|
|
||||||
|
buf << "#" << std::dec << bank << " ($" << Common::Base::HEX4 << (0xFFF8 + bank) << ")";
|
||||||
|
VarList::push_back(items, buf.str());
|
||||||
|
}
|
||||||
|
|
||||||
myBank =
|
myBank =
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("0 ($FFFx)"),
|
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("#0 ($FFFx)"),
|
||||||
myLineHeight, items, "Set bank ",
|
myLineHeight, items, "Set bank ",
|
||||||
0, kBankChanged);
|
0, kBankChanged);
|
||||||
myBank->setTarget(this);
|
myBank->setTarget(this);
|
||||||
addFocusWidget(myBank);
|
addFocusWidget(myBank);
|
||||||
ypos += myLineHeight + 8;
|
ypos += myLineHeight + V_GAP * 3;
|
||||||
|
|
||||||
// Data fetchers
|
// Data fetchers
|
||||||
int lwidth = _font.getStringWidth("Data Fetchers ");
|
int lwidth = _font.getStringWidth("Data fetchers ");
|
||||||
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
new StaticTextWidget(boss, _font, xpos, ypos, "Data fetchers ");
|
||||||
myFontHeight, "Data Fetchers ", TextAlign::Left);
|
|
||||||
|
|
||||||
// Top registers
|
// Top registers
|
||||||
lwidth = _font.getStringWidth("Counter Registers ");
|
lwidth = _font.getStringWidth("Counter registers ");
|
||||||
xpos = 18; ypos += myLineHeight + 4;
|
xpos = 2 + _font.getMaxCharWidth() * 2; ypos += myLineHeight + 4;
|
||||||
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
new StaticTextWidget(boss, _font, xpos, ypos, "Top registers ");
|
||||||
myFontHeight, "Top Registers ", TextAlign::Left);
|
|
||||||
xpos += lwidth;
|
xpos += lwidth;
|
||||||
|
|
||||||
myTops = new DataGridWidget(boss, _nfont, xpos, ypos-2, 8, 1, 2, 8, Common::Base::Fmt::_16);
|
myTops = new DataGridWidget(boss, _nfont, xpos, ypos-2, 8, 1, 2, 8, Common::Base::Fmt::_16);
|
||||||
|
@ -77,9 +82,8 @@ CartridgeDPCWidget::CartridgeDPCWidget(
|
||||||
myTops->setEditable(false);
|
myTops->setEditable(false);
|
||||||
|
|
||||||
// Bottom registers
|
// Bottom registers
|
||||||
xpos = 10; ypos += myLineHeight + 4;
|
xpos = 2 + _font.getMaxCharWidth() * 2; ypos += myLineHeight + 4;
|
||||||
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
new StaticTextWidget(boss, _font, xpos, ypos, "Bottom registers ");
|
||||||
myFontHeight, "Bottom Registers ", TextAlign::Left);
|
|
||||||
xpos += lwidth;
|
xpos += lwidth;
|
||||||
|
|
||||||
myBottoms = new DataGridWidget(boss, _nfont, xpos, ypos-2, 8, 1, 2, 8, Common::Base::Fmt::_16);
|
myBottoms = new DataGridWidget(boss, _nfont, xpos, ypos-2, 8, 1, 2, 8, Common::Base::Fmt::_16);
|
||||||
|
@ -87,9 +91,8 @@ CartridgeDPCWidget::CartridgeDPCWidget(
|
||||||
myBottoms->setEditable(false);
|
myBottoms->setEditable(false);
|
||||||
|
|
||||||
// Counter registers
|
// Counter registers
|
||||||
xpos = 10; ypos += myLineHeight + 4;
|
xpos = 2 + _font.getMaxCharWidth() * 2; ypos += myLineHeight + 4;
|
||||||
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
new StaticTextWidget(boss, _font, xpos, ypos, "Counter registers ");
|
||||||
myFontHeight, "Counter Registers ", TextAlign::Left);
|
|
||||||
xpos += lwidth;
|
xpos += lwidth;
|
||||||
|
|
||||||
myCounters = new DataGridWidget(boss, _nfont, xpos, ypos-2, 8, 1, 4, 16, Common::Base::Fmt::_16_4);
|
myCounters = new DataGridWidget(boss, _nfont, xpos, ypos-2, 8, 1, 4, 16, Common::Base::Fmt::_16_4);
|
||||||
|
@ -97,9 +100,8 @@ CartridgeDPCWidget::CartridgeDPCWidget(
|
||||||
myCounters->setEditable(false);
|
myCounters->setEditable(false);
|
||||||
|
|
||||||
// Flag registers
|
// Flag registers
|
||||||
xpos = 10; ypos += myLineHeight + 4;
|
xpos = 2 + _font.getMaxCharWidth() * 2; ypos += myLineHeight + 4;
|
||||||
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
new StaticTextWidget(boss, _font, xpos, ypos, "Flag registers ");
|
||||||
myFontHeight, "Flag Registers ", TextAlign::Left);
|
|
||||||
xpos += lwidth;
|
xpos += lwidth;
|
||||||
|
|
||||||
myFlags = new DataGridWidget(boss, _nfont, xpos, ypos-2, 8, 1, 2, 8, Common::Base::Fmt::_16);
|
myFlags = new DataGridWidget(boss, _nfont, xpos, ypos-2, 8, 1, 2, 8, Common::Base::Fmt::_16);
|
||||||
|
@ -107,10 +109,9 @@ CartridgeDPCWidget::CartridgeDPCWidget(
|
||||||
myFlags->setEditable(false);
|
myFlags->setEditable(false);
|
||||||
|
|
||||||
// Music mode
|
// Music mode
|
||||||
xpos = 2; ypos += myLineHeight + 12;
|
xpos = 2; ypos += myLineHeight + V_GAP * 3;
|
||||||
lwidth = _font.getStringWidth("Music mode (DF5/DF6/DF7) ");
|
lwidth = _font.getStringWidth("Music mode (DF5/DF6/DF7) ");
|
||||||
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
new StaticTextWidget(boss, _font, xpos, ypos, "Music mode (DF5/DF6/DF7) ");
|
||||||
myFontHeight, "Music mode (DF5/DF6/DF7) ", TextAlign::Left);
|
|
||||||
xpos += lwidth;
|
xpos += lwidth;
|
||||||
|
|
||||||
myMusicMode = new DataGridWidget(boss, _nfont, xpos, ypos-2, 3, 1, 2, 8, Common::Base::Fmt::_16);
|
myMusicMode = new DataGridWidget(boss, _nfont, xpos, ypos-2, 3, 1, 2, 8, Common::Base::Fmt::_16);
|
||||||
|
@ -118,9 +119,8 @@ CartridgeDPCWidget::CartridgeDPCWidget(
|
||||||
myMusicMode->setEditable(false);
|
myMusicMode->setEditable(false);
|
||||||
|
|
||||||
// Current random number
|
// Current random number
|
||||||
xpos = 10; ypos += myLineHeight + 4;
|
xpos = 2; ypos += myLineHeight + V_GAP * 3;
|
||||||
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
new StaticTextWidget(boss, _font, xpos, ypos, "Current random number ");
|
||||||
myFontHeight, "Current random number ", TextAlign::Left);
|
|
||||||
xpos += lwidth;
|
xpos += lwidth;
|
||||||
|
|
||||||
myRandom = new DataGridWidget(boss, _nfont, xpos, ypos-2, 1, 1, 2, 8, Common::Base::Fmt::_16);
|
myRandom = new DataGridWidget(boss, _nfont, xpos, ypos-2, 1, 1, 2, 8, Common::Base::Fmt::_16);
|
||||||
|
@ -229,9 +229,8 @@ string CartridgeDPCWidget::bankState()
|
||||||
{
|
{
|
||||||
ostringstream& buf = buffer();
|
ostringstream& buf = buffer();
|
||||||
|
|
||||||
static constexpr std::array<const char*, 2> spot = { "$FFF8", "$FFF9" };
|
buf << "Bank #" << std::dec << myCart.getBank()
|
||||||
buf << "Bank = " << std::dec << myCart.getBank()
|
<< " (hotspot $" << Common::Base::HEX4 << (0xFFF8 + myCart.getBank()) << ")";
|
||||||
<< ", hotspot = " << spot[myCart.getBank()];
|
|
||||||
|
|
||||||
return buf.str();
|
return buf.str();
|
||||||
}
|
}
|
||||||
|
@ -252,10 +251,9 @@ uInt32 CartridgeDPCWidget::internalRamRPort(int start)
|
||||||
string CartridgeDPCWidget::internalRamDescription()
|
string CartridgeDPCWidget::internalRamDescription()
|
||||||
{
|
{
|
||||||
ostringstream desc;
|
ostringstream desc;
|
||||||
desc << "$0000 - $07FF - 2K display data\n"
|
desc << "2K display data @ $0000 - $" << Common::Base::HEX4 << 0x07FF << "\n"
|
||||||
<< " indirectly accessible to 6507\n"
|
<< " indirectly accessible to 6507 via DPC's\n"
|
||||||
<< " via DPC+'s Data Fetcher\n"
|
<< " data fetcher registers\n";
|
||||||
<< " registers\n";
|
|
||||||
|
|
||||||
return desc.str();
|
return desc.str();
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,6 +75,7 @@ class CartridgeDPCWidget : public CartDebugWidget
|
||||||
const ByteArray& internalRamCurrent(int start, int count) override;
|
const ByteArray& internalRamCurrent(int start, int count) override;
|
||||||
void internalRamSetValue(int addr, uInt8 value) override;
|
void internalRamSetValue(int addr, uInt8 value) override;
|
||||||
uInt8 internalRamGetValue(int addr) override;
|
uInt8 internalRamGetValue(int addr) override;
|
||||||
|
string tabLabel() override { return " DPC Display Data "; }
|
||||||
// end of functions for Cartridge RAM tab
|
// end of functions for Cartridge RAM tab
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
|
|
|
@ -42,14 +42,14 @@ int CartDebugWidget::addBaseInformation(size_t bytes, const string& manufacturer
|
||||||
const string& desc, const uInt16 maxlines)
|
const string& desc, const uInt16 maxlines)
|
||||||
{
|
{
|
||||||
const int lwidth = _font.getStringWidth("Manufacturer "),
|
const int lwidth = _font.getStringWidth("Manufacturer "),
|
||||||
fwidth = _w - lwidth - 20;
|
fwidth = _w - lwidth - 12;
|
||||||
EditTextWidget* w = nullptr;
|
EditTextWidget* w = nullptr;
|
||||||
ostringstream buf;
|
ostringstream buf;
|
||||||
|
|
||||||
int x = 2, y = 8;
|
int x = 2, y = 8;
|
||||||
|
|
||||||
// Add ROM size, manufacturer and bankswitch info
|
// Add ROM size, manufacturer and bankswitch info
|
||||||
new StaticTextWidget(_boss, _font, x, y + 1, "ROM Size ");
|
new StaticTextWidget(_boss, _font, x, y + 1, "ROM size ");
|
||||||
buf << bytes << " bytes";
|
buf << bytes << " bytes";
|
||||||
if(bytes >= 1024)
|
if(bytes >= 1024)
|
||||||
buf << " / " << (bytes/1024) << "KB";
|
buf << " / " << (bytes/1024) << "KB";
|
||||||
|
|
|
@ -58,7 +58,7 @@ class CartDebugWidget : public Widget, public CommandSender
|
||||||
virtual string bankState() { return "0 (non-bankswitched)"; }
|
virtual string bankState() { return "0 (non-bankswitched)"; }
|
||||||
|
|
||||||
// To make the Cartridge RAM show up in the debugger, implement
|
// To make the Cartridge RAM show up in the debugger, implement
|
||||||
// the following 8 functions for cartridges with internal RAM
|
// the following 9 functions for cartridges with internal RAM
|
||||||
virtual uInt32 internalRamSize() { return 0; }
|
virtual uInt32 internalRamSize() { return 0; }
|
||||||
virtual uInt32 internalRamRPort(int start) { return 0; }
|
virtual uInt32 internalRamRPort(int start) { return 0; }
|
||||||
virtual string internalRamDescription() { return EmptyString; }
|
virtual string internalRamDescription() { return EmptyString; }
|
||||||
|
@ -67,6 +67,7 @@ class CartDebugWidget : public Widget, public CommandSender
|
||||||
virtual void internalRamSetValue(int addr, uInt8 value) { }
|
virtual void internalRamSetValue(int addr, uInt8 value) { }
|
||||||
virtual uInt8 internalRamGetValue(int addr) { return 0; }
|
virtual uInt8 internalRamGetValue(int addr) { return 0; }
|
||||||
virtual string internalRamLabel(int addr) { return "Not available/applicable"; }
|
virtual string internalRamLabel(int addr) { return "Not available/applicable"; }
|
||||||
|
virtual string tabLabel() { return " Cartridge RAM "; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Arrays used to hold current and previous internal RAM values
|
// Arrays used to hold current and previous internal RAM values
|
||||||
|
|
|
@ -16,129 +16,59 @@
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "CartE0.hxx"
|
#include "CartE0.hxx"
|
||||||
#include "PopUpWidget.hxx"
|
|
||||||
#include "CartE0Widget.hxx"
|
#include "CartE0Widget.hxx"
|
||||||
|
|
||||||
static constexpr std::array<const char*, 8> seg0 = {
|
|
||||||
"0 ($FFE0)", "1 ($FFE1)", "2 ($FFE2)", "3 ($FFE3)",
|
|
||||||
"4 ($FFE4)", "5 ($FFE5)", "6 ($FFE6)", "7 ($FFE7)"
|
|
||||||
};
|
|
||||||
static constexpr std::array<const char*, 8> seg1 = {
|
|
||||||
"0 ($FFE8)", "1 ($FFE9)", "2 ($FFEA)", "3 ($FFEB)",
|
|
||||||
"4 ($FFEC)", "5 ($FFED)", "6 ($FFEE)", "7 ($FFEF)"
|
|
||||||
};
|
|
||||||
static constexpr std::array<const char*, 8> seg2 = {
|
|
||||||
"0 ($FFF0)", "1 ($FFF1)", "2 ($FFF2)", "3 ($FFF3)",
|
|
||||||
"4 ($FFF4)", "5 ($FFF5)", "6 ($FFF6)", "7 ($FFF7)"
|
|
||||||
};
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CartridgeE0Widget::CartridgeE0Widget(
|
CartridgeE0Widget::CartridgeE0Widget(
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h, CartridgeE0& cart)
|
int x, int y, int w, int h, CartridgeE0& cart)
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||||
myCart(cart)
|
|
||||||
{
|
{
|
||||||
uInt32 size = 8 * 1024;
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
string info =
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
"E0 cartridge, eight 1K slices\n"
|
string CartridgeE0Widget::description()
|
||||||
"Segment 0 accessible @ $F000 - $F3FF\n"
|
{
|
||||||
" Hotspots $FE0 to $FE7\n"
|
ostringstream info;
|
||||||
"Segment 1 accessible @ $F400 - $F7FF\n"
|
|
||||||
" Hotspots $FE8 to $FEF\n"
|
|
||||||
"Segment 2 accessible @ $F800 - $FBFF\n"
|
|
||||||
" Hotspots $FF0 to $FF7\n"
|
|
||||||
"Segment 3 accessible @ $FC00 - $FFFF\n"
|
|
||||||
" Always points to last 1K of ROM\n"
|
|
||||||
"Startup slices = 4 / 5 / 6 or undetermined\n";
|
|
||||||
|
|
||||||
#if 0
|
info << "E0 cartridge,\n eight 1K banks mapped into four segments\n";
|
||||||
// Eventually, we should query this from the debugger/disassembler
|
info << CartridgeEnhancedWidget::description();
|
||||||
uInt16 start = (cart.myImage[size-3] << 8) | cart.myImage[size-4];
|
|
||||||
start -= start % 0x1000;
|
|
||||||
info << "Bank RORG" << " = $" << HEX4 << start << "\n";
|
|
||||||
#endif
|
|
||||||
int xpos = 2,
|
|
||||||
ypos = addBaseInformation(size, "Parker Brothers", info) + myLineHeight;
|
|
||||||
|
|
||||||
VariantList items0, items1, items2;
|
return info.str();
|
||||||
for(int i = 0; i < 8; ++i)
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string CartridgeE0Widget::romDescription()
|
||||||
|
{
|
||||||
|
ostringstream info;
|
||||||
|
|
||||||
|
for(int seg = 0; seg < 4; ++seg)
|
||||||
{
|
{
|
||||||
VarList::push_back(items0, seg0[i]);
|
uInt16 segmentOffset = seg << 10; // myCart.myBankShift;
|
||||||
VarList::push_back(items1, seg1[i]);
|
|
||||||
VarList::push_back(items2, seg2[i]);
|
info << "Segment #" << seg << " accessible @ $"
|
||||||
|
<< Common::Base::HEX4 << (ADDR_BASE | segmentOffset)
|
||||||
|
<< " - $" << (ADDR_BASE | segmentOffset + /*myCart.myBankSize - 1*/ 0x3FF) << ",\n";
|
||||||
|
if (seg < 3)
|
||||||
|
info << " Hotspots " << hotspotStr(0, seg, true) << " - " << hotspotStr(7, seg, true) << "\n";
|
||||||
|
else
|
||||||
|
info << " Always points to last 1K bank of ROM\n";
|
||||||
}
|
}
|
||||||
|
info << "Startup banks = 4 / 5 / 6 or undetermined";
|
||||||
|
|
||||||
const int lwidth = _font.getStringWidth("Set slice for segment X ");
|
return info.str();
|
||||||
mySlice0 =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("7 ($FFF7)"),
|
|
||||||
myLineHeight, items0, "Set slice for segment 0 ",
|
|
||||||
lwidth, kSlice0Changed);
|
|
||||||
mySlice0->setTarget(this);
|
|
||||||
addFocusWidget(mySlice0);
|
|
||||||
ypos += mySlice0->getHeight() + 4;
|
|
||||||
|
|
||||||
mySlice1 =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("7 ($FFF7)"),
|
|
||||||
myLineHeight, items1, "Set slice for segment 1 ",
|
|
||||||
lwidth, kSlice1Changed);
|
|
||||||
mySlice1->setTarget(this);
|
|
||||||
addFocusWidget(mySlice1);
|
|
||||||
ypos += mySlice1->getHeight() + 4;
|
|
||||||
|
|
||||||
mySlice2 =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("7 ($FFF7)"),
|
|
||||||
myLineHeight, items2, "Set slice for segment 2 ",
|
|
||||||
lwidth, kSlice2Changed);
|
|
||||||
mySlice2->setTarget(this);
|
|
||||||
addFocusWidget(mySlice2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeE0Widget::loadConfig()
|
string CartridgeE0Widget::hotspotStr(int bank, int segment, bool noBrackets)
|
||||||
{
|
{
|
||||||
mySlice0->setSelectedIndex(myCart.myCurrentSlice[0]);
|
ostringstream info;
|
||||||
mySlice1->setSelectedIndex(myCart.myCurrentSlice[1]);
|
uInt16 hotspot = myCart.hotspot();
|
||||||
mySlice2->setSelectedIndex(myCart.myCurrentSlice[2]);
|
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
info << (noBrackets ? "" : "(");
|
||||||
}
|
info << "$" << Common::Base::HEX1 << (hotspot + bank + segment * 8);
|
||||||
|
info << (noBrackets ? "" : ")");
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeE0Widget::handleCommand(CommandSender* sender,
|
return info.str();
|
||||||
int cmd, int data, int id)
|
|
||||||
{
|
|
||||||
myCart.unlockBank();
|
|
||||||
|
|
||||||
switch(cmd)
|
|
||||||
{
|
|
||||||
case kSlice0Changed:
|
|
||||||
myCart.segmentZero(mySlice0->getSelected());
|
|
||||||
break;
|
|
||||||
case kSlice1Changed:
|
|
||||||
myCart.segmentOne(mySlice1->getSelected());
|
|
||||||
break;
|
|
||||||
case kSlice2Changed:
|
|
||||||
myCart.segmentTwo(mySlice2->getSelected());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
myCart.lockBank();
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeE0Widget::bankState()
|
|
||||||
{
|
|
||||||
ostringstream& buf = buffer();
|
|
||||||
|
|
||||||
buf << "Slices: " << std::dec
|
|
||||||
<< seg0[myCart.myCurrentSlice[0]] << " / "
|
|
||||||
<< seg1[myCart.myCurrentSlice[1]] << " / "
|
|
||||||
<< seg2[myCart.myCurrentSlice[2]];
|
|
||||||
|
|
||||||
return buf.str();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,10 @@
|
||||||
#define CARTRIDGEE0_WIDGET_HXX
|
#define CARTRIDGEE0_WIDGET_HXX
|
||||||
|
|
||||||
class CartridgeE0;
|
class CartridgeE0;
|
||||||
class PopUpWidget;
|
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
#include "CartEnhancedWidget.hxx"
|
||||||
|
|
||||||
class CartridgeE0Widget : public CartDebugWidget
|
class CartridgeE0Widget : public CartridgeEnhancedWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CartridgeE0Widget(GuiObject* boss, const GUI::Font& lfont,
|
CartridgeE0Widget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
|
@ -33,21 +32,17 @@ class CartridgeE0Widget : public CartDebugWidget
|
||||||
virtual ~CartridgeE0Widget() = default;
|
virtual ~CartridgeE0Widget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CartridgeE0& myCart;
|
string manufacturer() override { return "Parker Brothers"; }
|
||||||
PopUpWidget *mySlice0{nullptr}, *mySlice1{nullptr}, *mySlice2{nullptr};
|
|
||||||
|
|
||||||
enum {
|
string description() override;
|
||||||
kSlice0Changed = 's0CH',
|
|
||||||
kSlice1Changed = 's1CH',
|
string romDescription() override;
|
||||||
kSlice2Changed = 's2CH'
|
|
||||||
};
|
string hotspotStr(int bank, int segment, bool noBrackets = false) override;
|
||||||
|
|
||||||
|
uInt16 bankSegs() override { return 3; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void loadConfig() override;
|
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
|
||||||
|
|
||||||
string bankState() override;
|
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeE0Widget() = delete;
|
CartridgeE0Widget() = delete;
|
||||||
CartridgeE0Widget(const CartridgeE0Widget&) = delete;
|
CartridgeE0Widget(const CartridgeE0Widget&) = delete;
|
||||||
|
|
|
@ -27,17 +27,18 @@ CartridgeE78KWidget::CartridgeE78KWidget(
|
||||||
: CartridgeMNetworkWidget(boss, lfont, nfont, x, y, w, h, cart)
|
: CartridgeMNetworkWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||||
{
|
{
|
||||||
ostringstream info;
|
ostringstream info;
|
||||||
info << "E78K cartridge, 4 2K slices ROM + 2 1K RAM\n"
|
info << "E78K cartridge, four 2K banks ROM + 2K RAM,\n"
|
||||||
<< "Lower 2K accessible @ $F000 - $F7FF\n"
|
<< " mapped into three segments\n"
|
||||||
<< " Slice 0 - 2 of ROM (hotspots $FE4 to $FE6)\n"
|
<< "Lower 2K accessible @ $F000 - $F7FF\n"
|
||||||
<< " Slice 7 (1K) of RAM (hotspot $FE7)\n"
|
<< " ROM banks 0 - 2 (hotspots $FFE4 to $FFE6)\n"
|
||||||
<< " $F400 - $F7FF (R), $F000 - $F3FF (W)\n"
|
<< " 1K RAM bank 3 (hotspot $FFE7)\n"
|
||||||
<< "256B RAM accessible @ $F800 - $F9FF\n"
|
<< " $F400 - $F7FF (R), $F000 - $F3FF (W)\n"
|
||||||
<< " Hotspots $FE8 - $FEB (256B of RAM slice 1)\n"
|
<< "256B RAM accessible @ $F800 - $F9FF\n"
|
||||||
<< " $F900 - $F9FF (R), $F800 - $F8FF (W)\n"
|
<< " RAM banks 0 - 3 (hotspots $FFE8 - $FFEB)\n"
|
||||||
<< "Upper 1.5K ROM accessible @ $FA00 - $FFFF\n"
|
<< " $F900 - $F9FF (R), $F800 - $F8FF (W)\n"
|
||||||
<< " Always points to last 1.5K of ROM\n"
|
<< "Upper 1.5K ROM accessible @ $FA00 - $FFFF\n"
|
||||||
<< "Startup slices = 0 / 0 or undetermined\n";
|
<< " Always points to last 1.5K of ROM\n"
|
||||||
|
<< "Startup segments = 0 / 0 or undetermined\n";
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// Eventually, we should query this from the debugger/disassembler
|
// Eventually, we should query this from the debugger/disassembler
|
||||||
|
@ -53,7 +54,7 @@ CartridgeE78KWidget::CartridgeE78KWidget(
|
||||||
const char* CartridgeE78KWidget::getSpotLower(int idx)
|
const char* CartridgeE78KWidget::getSpotLower(int idx)
|
||||||
{
|
{
|
||||||
static constexpr std::array<const char*, 4> spot_lower = {
|
static constexpr std::array<const char*, 4> spot_lower = {
|
||||||
"0 - ROM ($FFE4)", "1 - ROM ($FFE5)", "2 - ROM ($FFE6)", "3 - RAM ($FFE7)"
|
"#0 - ROM ($FFE4)", "#1 - ROM ($FFE5)", "#2 - ROM ($FFE6)", "#3 - RAM ($FFE7)"
|
||||||
};
|
};
|
||||||
|
|
||||||
return spot_lower[idx];
|
return spot_lower[idx];
|
||||||
|
@ -63,7 +64,7 @@ const char* CartridgeE78KWidget::getSpotLower(int idx)
|
||||||
const char* CartridgeE78KWidget::getSpotUpper(int idx)
|
const char* CartridgeE78KWidget::getSpotUpper(int idx)
|
||||||
{
|
{
|
||||||
static constexpr std::array<const char*, 4> spot_upper = {
|
static constexpr std::array<const char*, 4> spot_upper = {
|
||||||
"0 - RAM ($FFE8)", "1 - RAM ($FFE9)", "2 - RAM ($FFEA)", "3 - RAM ($FFEB)"
|
"#0 - RAM ($FFE8)", "#1 - RAM ($FFE9)", "#2 - RAM ($FFEA)", "#3 - RAM ($FFEB)"
|
||||||
};
|
};
|
||||||
|
|
||||||
return spot_upper[idx];
|
return spot_upper[idx];
|
||||||
|
|
|
@ -26,17 +26,18 @@ CartridgeE7Widget::CartridgeE7Widget(
|
||||||
: CartridgeMNetworkWidget(boss, lfont, nfont, x, y, w, h, cart)
|
: CartridgeMNetworkWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||||
{
|
{
|
||||||
ostringstream info;
|
ostringstream info;
|
||||||
info << "E7 cartridge, 8 2K slices ROM + 2 1K RAM\n"
|
info << "E7 cartridge, eight 2K banks ROM + 2K RAM,\n"
|
||||||
|
<< " mapped into three segments\n"
|
||||||
<< "Lower 2K accessible @ $F000 - $F7FF\n"
|
<< "Lower 2K accessible @ $F000 - $F7FF\n"
|
||||||
<< " Slice 0 - 6 of ROM (hotspots $FE0 to $FE6)\n"
|
<< " ROM Banks 0 - 6 (hotspots $FFE0 to $FFE6)\n"
|
||||||
<< " Slice 7 (1K) of RAM (hotspot $FE7)\n"
|
<< " 1K RAM Bank 7 (hotspot $FFE7)\n"
|
||||||
<< " $F400 - $F7FF (R), $F000 - $F3FF (W)\n"
|
<< " $F400 - $F7FF (R), $F000 - $F3FF (W)\n"
|
||||||
<< "256B RAM accessible @ $F800 - $F9FF\n"
|
<< "256B RAM accessible @ $F800 - $F9FF\n"
|
||||||
<< " Hotspots $FE8 - $FEB (256B of RAM slice 1)\n"
|
<< " RAM banks 0 - 3 (hotspots $FFE8 - $FFEB)\n"
|
||||||
<< " $F900 - $F9FF (R), $F800 - $F8FF (W)\n"
|
<< " $F900 - $F9FF (R), $F800 - $F8FF (W)\n"
|
||||||
<< "Upper 1.5K ROM accessible @ $FA00 - $FFFF\n"
|
<< "Upper 1.5K ROM accessible @ $FA00 - $FFFF\n"
|
||||||
<< " Always points to last 1.5K of ROM\n"
|
<< " Always points to last 1.5K of ROM\n"
|
||||||
<< "Startup slices = 0 / 0 or undetermined\n";
|
<< "Startup segments = 0 / 0 or undetermined\n";
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// Eventually, we should query this from the debugger/disassembler
|
// Eventually, we should query this from the debugger/disassembler
|
||||||
|
@ -52,8 +53,8 @@ CartridgeE7Widget::CartridgeE7Widget(
|
||||||
const char* CartridgeE7Widget::getSpotLower(int idx)
|
const char* CartridgeE7Widget::getSpotLower(int idx)
|
||||||
{
|
{
|
||||||
static constexpr std::array<const char*, 8> spot_lower = {
|
static constexpr std::array<const char*, 8> spot_lower = {
|
||||||
"0 - ROM ($FFE0)", "1 - ROM ($FFE1)", "2 - ROM ($FFE2)", "3 - ROM ($FFE3)",
|
"#0 - ROM ($FFE0)", "#1 - ROM ($FFE1)", "#2 - ROM ($FFE2)", "#3 - ROM ($FFE3)",
|
||||||
"4 - ROM ($FFE4)", "5 - ROM ($FFE5)", "6 - ROM ($FFE6)", "7 - RAM ($FFE7)"
|
"#4 - ROM ($FFE4)", "#5 - ROM ($FFE5)", "#6 - ROM ($FFE6)", "#7 - RAM ($FFE7)"
|
||||||
};
|
};
|
||||||
|
|
||||||
return spot_lower[idx];
|
return spot_lower[idx];
|
||||||
|
@ -63,7 +64,7 @@ const char* CartridgeE7Widget::getSpotLower(int idx)
|
||||||
const char* CartridgeE7Widget::getSpotUpper(int idx)
|
const char* CartridgeE7Widget::getSpotUpper(int idx)
|
||||||
{
|
{
|
||||||
static constexpr std::array<const char*, 4> spot_upper = {
|
static constexpr std::array<const char*, 4> spot_upper = {
|
||||||
"0 - RAM ($FFE8)", "1 - RAM ($FFE9)", "2 - RAM ($FFEA)", "3 - RAM ($FFEB)"
|
"#0 - RAM ($FFE8)", "#1 - RAM ($FFE9)", "#2 - RAM ($FFEA)", "#3 - RAM ($FFEB)"
|
||||||
};
|
};
|
||||||
|
|
||||||
return spot_upper[idx];
|
return spot_upper[idx];
|
||||||
|
|
|
@ -15,167 +15,25 @@
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "Debugger.hxx"
|
|
||||||
#include "CartDebug.hxx"
|
|
||||||
#include "CartEFSC.hxx"
|
#include "CartEFSC.hxx"
|
||||||
#include "PopUpWidget.hxx"
|
|
||||||
#include "CartEFSCWidget.hxx"
|
#include "CartEFSCWidget.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CartridgeEFSCWidget::CartridgeEFSCWidget(
|
CartridgeEFSCWidget::CartridgeEFSCWidget(
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h, CartridgeEFSC& cart)
|
int x, int y, int w, int h, CartridgeEFSC& cart)
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||||
myCart(cart)
|
|
||||||
{
|
{
|
||||||
uInt32 size = 16 * 4096;
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string CartridgeEFSCWidget::description()
|
||||||
|
{
|
||||||
ostringstream info;
|
ostringstream info;
|
||||||
info << "64K H. Runner EFSC + RAM, 16 4K banks\n"
|
|
||||||
<< "128 bytes RAM @ $F000 - $F0FF\n"
|
|
||||||
<< " $F080 - $F0FF (R), $F000 - $F07F (W)\n"
|
|
||||||
<< "Startup bank = " << cart.startBank() << "\n";
|
|
||||||
|
|
||||||
// Eventually, we should query this from the debugger/disassembler
|
info << "64K H. Runner EFSC + RAM, 16 4K banks\n";
|
||||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0xFE0; i < 16; ++i, offset += 0x1000)
|
info << CartridgeEnhancedWidget::description();
|
||||||
{
|
|
||||||
uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset];
|
|
||||||
start -= start % 0x1000;
|
|
||||||
info << "Bank " << std::dec << i << " @ $" << Common::Base::HEX4 << (start + 0x100)
|
|
||||||
<< " - " << "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
int xpos = 2,
|
return info.str();
|
||||||
ypos = addBaseInformation(size, "Paul Slocum / Homestar Runner",
|
|
||||||
info.str()) + myLineHeight;
|
|
||||||
|
|
||||||
VariantList items;
|
|
||||||
VarList::push_back(items, " 0 ($FFE0)");
|
|
||||||
VarList::push_back(items, " 1 ($FFE1)");
|
|
||||||
VarList::push_back(items, " 2 ($FFE2)");
|
|
||||||
VarList::push_back(items, " 3 ($FFE3)");
|
|
||||||
VarList::push_back(items, " 4 ($FFE4)");
|
|
||||||
VarList::push_back(items, " 5 ($FFE5)");
|
|
||||||
VarList::push_back(items, " 6 ($FFE6)");
|
|
||||||
VarList::push_back(items, " 7 ($FFE7)");
|
|
||||||
VarList::push_back(items, " 8 ($FFE8)");
|
|
||||||
VarList::push_back(items, " 9 ($FFE9)");
|
|
||||||
VarList::push_back(items, "10 ($FFEA)");
|
|
||||||
VarList::push_back(items, "11 ($FFEB)");
|
|
||||||
VarList::push_back(items, "12 ($FFEC)");
|
|
||||||
VarList::push_back(items, "13 ($FFED)");
|
|
||||||
VarList::push_back(items, "14 ($FFEE)");
|
|
||||||
VarList::push_back(items, "15 ($FFEF)");
|
|
||||||
myBank =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("15 ($FFE0)"),
|
|
||||||
myLineHeight, items, "Set bank ",
|
|
||||||
0, kBankChanged);
|
|
||||||
myBank->setTarget(this);
|
|
||||||
addFocusWidget(myBank);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeEFSCWidget::saveOldState()
|
|
||||||
{
|
|
||||||
myOldState.internalram.clear();
|
|
||||||
|
|
||||||
for(uInt32 i = 0; i < internalRamSize(); ++i)
|
|
||||||
myOldState.internalram.push_back(myCart.myRAM[i]);
|
|
||||||
|
|
||||||
myOldState.bank = myCart.getBank();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeEFSCWidget::loadConfig()
|
|
||||||
{
|
|
||||||
myBank->setSelectedIndex(myCart.getBank(), myCart.getBank() != myOldState.bank);
|
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeEFSCWidget::handleCommand(CommandSender* sender,
|
|
||||||
int cmd, int data, int id)
|
|
||||||
{
|
|
||||||
if(cmd == kBankChanged)
|
|
||||||
{
|
|
||||||
myCart.unlockBank();
|
|
||||||
myCart.bank(myBank->getSelected());
|
|
||||||
myCart.lockBank();
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeEFSCWidget::bankState()
|
|
||||||
{
|
|
||||||
ostringstream& buf = buffer();
|
|
||||||
|
|
||||||
static constexpr std::array<const char*, 16> spot = {
|
|
||||||
"$FFE0", "$FFE1", "$FFE2", "$FFE3", "$FFE4", "$FFE5", "$FFE6", "$FFE7",
|
|
||||||
"$FFE8", "$FFE9", "$FFEA", "$FFEB", "$FFEC", "$FFED", "$FFEE", "$FFEF"
|
|
||||||
};
|
|
||||||
buf << "Bank = " << std::dec << myCart.getBank()
|
|
||||||
<< ", hotspot = " << spot[myCart.getBank()];
|
|
||||||
|
|
||||||
return buf.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 CartridgeEFSCWidget::internalRamSize()
|
|
||||||
{
|
|
||||||
return 128;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 CartridgeEFSCWidget::internalRamRPort(int start)
|
|
||||||
{
|
|
||||||
return 0xF080 + start;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeEFSCWidget::internalRamDescription()
|
|
||||||
{
|
|
||||||
ostringstream desc;
|
|
||||||
desc << "$F000 - $F07F used for Write Access\n"
|
|
||||||
<< "$F080 - $F0FF used for Read Access";
|
|
||||||
|
|
||||||
return desc.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const ByteArray& CartridgeEFSCWidget::internalRamOld(int start, int count)
|
|
||||||
{
|
|
||||||
myRamOld.clear();
|
|
||||||
for(int i = 0; i < count; i++)
|
|
||||||
myRamOld.push_back(myOldState.internalram[start + i]);
|
|
||||||
return myRamOld;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const ByteArray& CartridgeEFSCWidget::internalRamCurrent(int start, int count)
|
|
||||||
{
|
|
||||||
myRamCurrent.clear();
|
|
||||||
for(int i = 0; i < count; i++)
|
|
||||||
myRamCurrent.push_back(myCart.myRAM[start + i]);
|
|
||||||
return myRamCurrent;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeEFSCWidget::internalRamSetValue(int addr, uInt8 value)
|
|
||||||
{
|
|
||||||
myCart.myRAM[addr] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt8 CartridgeEFSCWidget::internalRamGetValue(int addr)
|
|
||||||
{
|
|
||||||
return myCart.myRAM[addr];
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeEFSCWidget::internalRamLabel(int addr)
|
|
||||||
{
|
|
||||||
CartDebug& dbg = instance().debugger().cartDebug();
|
|
||||||
return dbg.getLabel(addr + 0xF080, false);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,10 @@
|
||||||
#define CARTRIDGEEFSC_WIDGET_HXX
|
#define CARTRIDGEEFSC_WIDGET_HXX
|
||||||
|
|
||||||
class CartridgeEFSC;
|
class CartridgeEFSC;
|
||||||
class PopUpWidget;
|
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
#include "CartEnhancedWidget.hxx"
|
||||||
|
|
||||||
class CartridgeEFSCWidget : public CartDebugWidget
|
class CartridgeEFSCWidget : public CartridgeEnhancedWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CartridgeEFSCWidget(GuiObject* boss, const GUI::Font& lfont,
|
CartridgeEFSCWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
|
@ -33,35 +32,11 @@ class CartridgeEFSCWidget : public CartDebugWidget
|
||||||
virtual ~CartridgeEFSCWidget() = default;
|
virtual ~CartridgeEFSCWidget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CartridgeEFSC& myCart;
|
string manufacturer() override { return "Paul Slocum / Homestar Runner"; }
|
||||||
PopUpWidget* myBank{nullptr};
|
|
||||||
|
|
||||||
struct CartState {
|
string description() override;
|
||||||
ByteArray internalram;
|
|
||||||
uInt16 bank{0};
|
|
||||||
};
|
|
||||||
CartState myOldState;
|
|
||||||
|
|
||||||
enum { kBankChanged = 'bkCH' };
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void saveOldState() override;
|
|
||||||
void loadConfig() override;
|
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
|
||||||
|
|
||||||
string bankState() override;
|
|
||||||
|
|
||||||
// start of functions for Cartridge RAM tab
|
|
||||||
uInt32 internalRamSize() override;
|
|
||||||
uInt32 internalRamRPort(int start) override;
|
|
||||||
string internalRamDescription() override;
|
|
||||||
const ByteArray& internalRamOld(int start, int count) override;
|
|
||||||
const ByteArray& internalRamCurrent(int start, int count) override;
|
|
||||||
void internalRamSetValue(int addr, uInt8 value) override;
|
|
||||||
uInt8 internalRamGetValue(int addr) override;
|
|
||||||
string internalRamLabel(int addr) override;
|
|
||||||
// end of functions for Cartridge RAM tab
|
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeEFSCWidget() = delete;
|
CartridgeEFSCWidget() = delete;
|
||||||
CartridgeEFSCWidget(const CartridgeEFSCWidget&) = delete;
|
CartridgeEFSCWidget(const CartridgeEFSCWidget&) = delete;
|
||||||
|
|
|
@ -16,97 +16,24 @@
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "CartEF.hxx"
|
#include "CartEF.hxx"
|
||||||
#include "PopUpWidget.hxx"
|
|
||||||
#include "CartEFWidget.hxx"
|
#include "CartEFWidget.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CartridgeEFWidget::CartridgeEFWidget(
|
CartridgeEFWidget::CartridgeEFWidget(
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h, CartridgeEF& cart)
|
int x, int y, int w, int h, CartridgeEF& cart)
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||||
myCart(cart)
|
|
||||||
{
|
{
|
||||||
uInt32 size = 16 * 4096;
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string CartridgeEFWidget::description()
|
||||||
|
{
|
||||||
ostringstream info;
|
ostringstream info;
|
||||||
info << "64K H. Runner EF cartridge, 16 4K banks\n"
|
|
||||||
<< "Startup bank = " << cart.startBank() << "\n";
|
|
||||||
|
|
||||||
// Eventually, we should query this from the debugger/disassembler
|
info << "64K H. Runner EF cartridge, 16 4K banks\n";
|
||||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0xFE0; i < 16; ++i, offset += 0x1000)
|
info << CartridgeEnhancedWidget::description();
|
||||||
{
|
|
||||||
uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset];
|
|
||||||
start -= start % 0x1000;
|
|
||||||
info << "Bank " << std::dec << i << " @ $" << Common::Base::HEX4 << start << " - "
|
|
||||||
<< "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
int xpos = 2,
|
return info.str();
|
||||||
ypos = addBaseInformation(size, "Paul Slocum / Homestar Runner",
|
|
||||||
info.str()) + myLineHeight;
|
|
||||||
|
|
||||||
VariantList items;
|
|
||||||
VarList::push_back(items, " 0 ($FFE0)");
|
|
||||||
VarList::push_back(items, " 1 ($FFE1)");
|
|
||||||
VarList::push_back(items, " 2 ($FFE2)");
|
|
||||||
VarList::push_back(items, " 3 ($FFE3)");
|
|
||||||
VarList::push_back(items, " 4 ($FFE4)");
|
|
||||||
VarList::push_back(items, " 5 ($FFE5)");
|
|
||||||
VarList::push_back(items, " 6 ($FFE6)");
|
|
||||||
VarList::push_back(items, " 7 ($FFE7)");
|
|
||||||
VarList::push_back(items, " 8 ($FFE8)");
|
|
||||||
VarList::push_back(items, " 9 ($FFE9)");
|
|
||||||
VarList::push_back(items, "10 ($FFEA)");
|
|
||||||
VarList::push_back(items, "11 ($FFEB)");
|
|
||||||
VarList::push_back(items, "12 ($FFEC)");
|
|
||||||
VarList::push_back(items, "13 ($FFED)");
|
|
||||||
VarList::push_back(items, "14 ($FFEE)");
|
|
||||||
VarList::push_back(items, "15 ($FFEF)");
|
|
||||||
myBank =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("15 ($FFE0)"),
|
|
||||||
myLineHeight, items, "Set bank ",
|
|
||||||
0, kBankChanged);
|
|
||||||
myBank->setTarget(this);
|
|
||||||
addFocusWidget(myBank);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeEFWidget::loadConfig()
|
|
||||||
{
|
|
||||||
Debugger& dbg = instance().debugger();
|
|
||||||
CartDebug& cart = dbg.cartDebug();
|
|
||||||
const CartState& state = static_cast<const CartState&>(cart.getState());
|
|
||||||
const CartState& oldstate = static_cast<const CartState&>(cart.getOldState());
|
|
||||||
|
|
||||||
myBank->setSelectedIndex(myCart.getBank(), state.bank != oldstate.bank);
|
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeEFWidget::handleCommand(CommandSender* sender,
|
|
||||||
int cmd, int data, int id)
|
|
||||||
{
|
|
||||||
if(cmd == kBankChanged)
|
|
||||||
{
|
|
||||||
myCart.unlockBank();
|
|
||||||
myCart.bank(myBank->getSelected());
|
|
||||||
myCart.lockBank();
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeEFWidget::bankState()
|
|
||||||
{
|
|
||||||
ostringstream& buf = buffer();
|
|
||||||
|
|
||||||
static constexpr std::array<const char*, 16> spot = {
|
|
||||||
"$FFE0", "$FFE1", "$FFE2", "$FFE3", "$FFE4", "$FFE5", "$FFE6", "$FFE7",
|
|
||||||
"$FFE8", "$FFE9", "$FFEA", "$FFEB", "$FFEC", "$FFED", "$FFEE", "$FFEF"
|
|
||||||
};
|
|
||||||
buf << "Bank = " << std::dec << myCart.getBank()
|
|
||||||
<< ", hotspot = " << spot[myCart.getBank()];
|
|
||||||
|
|
||||||
return buf.str();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,10 @@
|
||||||
#define CARTRIDGEEF_WIDGET_HXX
|
#define CARTRIDGEEF_WIDGET_HXX
|
||||||
|
|
||||||
class CartridgeEF;
|
class CartridgeEF;
|
||||||
class PopUpWidget;
|
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
#include "CartEnhancedWidget.hxx"
|
||||||
|
|
||||||
class CartridgeEFWidget : public CartDebugWidget
|
class CartridgeEFWidget : public CartridgeEnhancedWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CartridgeEFWidget(GuiObject* boss, const GUI::Font& lfont,
|
CartridgeEFWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
|
@ -33,17 +32,11 @@ class CartridgeEFWidget : public CartDebugWidget
|
||||||
virtual ~CartridgeEFWidget() = default;
|
virtual ~CartridgeEFWidget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CartridgeEF& myCart;
|
string manufacturer() override { return "Paul Slocum / Homestar Runner"; }
|
||||||
PopUpWidget* myBank{nullptr};
|
|
||||||
|
|
||||||
enum { kBankChanged = 'bkCH' };
|
string description() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void loadConfig() override;
|
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
|
||||||
|
|
||||||
string bankState() override;
|
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeEFWidget() = delete;
|
CartridgeEFWidget() = delete;
|
||||||
CartridgeEFWidget(const CartridgeEFWidget&) = delete;
|
CartridgeEFWidget(const CartridgeEFWidget&) = delete;
|
||||||
|
|
|
@ -0,0 +1,394 @@
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// SSSS tt lll lll
|
||||||
|
// SS SS tt ll ll
|
||||||
|
// SS tttttt eeee ll ll aaaa
|
||||||
|
// SSSS tt ee ee ll ll aa
|
||||||
|
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||||
|
// SS SS tt ee ll ll aa aa
|
||||||
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
|
//
|
||||||
|
// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
|
||||||
|
// and the Stella Team
|
||||||
|
//
|
||||||
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
|
||||||
|
#include "PopUpWidget.hxx"
|
||||||
|
#include "CartEnhanced.hxx"
|
||||||
|
#include "CartEnhancedWidget.hxx"
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
CartridgeEnhancedWidget::CartridgeEnhancedWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
|
const GUI::Font& nfont,
|
||||||
|
int x, int y, int w, int h,
|
||||||
|
CartridgeEnhanced& cart)
|
||||||
|
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||||
|
myCart(cart)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
int CartridgeEnhancedWidget::initialize()
|
||||||
|
{
|
||||||
|
int ypos = addBaseInformation(size(), manufacturer(), description(), descriptionLines())
|
||||||
|
+ myLineHeight;
|
||||||
|
|
||||||
|
bankSelect(ypos);
|
||||||
|
|
||||||
|
return ypos;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
size_t CartridgeEnhancedWidget::size()
|
||||||
|
{
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
myCart.getImage(size);
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string CartridgeEnhancedWidget::description()
|
||||||
|
{
|
||||||
|
ostringstream info;
|
||||||
|
|
||||||
|
if (myCart.myRamSize > 0)
|
||||||
|
info << ramDescription();
|
||||||
|
info << romDescription();
|
||||||
|
|
||||||
|
return info.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
int CartridgeEnhancedWidget::descriptionLines()
|
||||||
|
{
|
||||||
|
return 18; // should be enough for almost all types
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string CartridgeEnhancedWidget::ramDescription()
|
||||||
|
{
|
||||||
|
ostringstream info;
|
||||||
|
|
||||||
|
if(myCart.ramBankCount() == 0)
|
||||||
|
info << myCart.myRamSize << " bytes RAM @ "
|
||||||
|
<< "$" << Common::Base::HEX4 << ADDR_BASE << " - "
|
||||||
|
<< "$" << (ADDR_BASE | (myCart.myRamSize * 2 - 1)) << "\n";
|
||||||
|
|
||||||
|
info << " $" << Common::Base::HEX4 << (ADDR_BASE | myCart.myReadOffset)
|
||||||
|
<< " - $" << (ADDR_BASE | (myCart.myReadOffset + myCart.myRamMask)) << " (R)"
|
||||||
|
<< ", $" << (ADDR_BASE | myCart.myWriteOffset)
|
||||||
|
<< " - $" << (ADDR_BASE | (myCart.myWriteOffset + myCart.myRamMask)) << " (W)\n";
|
||||||
|
|
||||||
|
return info.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string CartridgeEnhancedWidget::romDescription()
|
||||||
|
{
|
||||||
|
ostringstream info;
|
||||||
|
size_t size;
|
||||||
|
const uInt8* image = myCart.getImage(size);
|
||||||
|
|
||||||
|
if(myCart.romBankCount() > 1)
|
||||||
|
{
|
||||||
|
for(int bank = 0, offset = 0xFFC; bank < myCart.romBankCount(); ++bank, offset += 0x1000)
|
||||||
|
{
|
||||||
|
uInt16 start = (image[offset + 1] << 8) | image[offset];
|
||||||
|
start -= start % 0x1000;
|
||||||
|
string hash = myCart.romBankCount() > 10 && bank < 10 ? " #" : "#";
|
||||||
|
|
||||||
|
info << "Bank " << hash << std::dec << bank << " @ $"
|
||||||
|
<< Common::Base::HEX4 << (start + myCart.myRomOffset) << " - $" << (start + 0xFFF);
|
||||||
|
if(myCart.hotspot() != 0)
|
||||||
|
{
|
||||||
|
string hs = hotspotStr(bank, 0, true);
|
||||||
|
if(hs.length() > 22)
|
||||||
|
info << "\n ";
|
||||||
|
info << " " << hs;
|
||||||
|
}
|
||||||
|
info << "\n";
|
||||||
|
}
|
||||||
|
info << "Startup bank = #" << std::dec << myCart.startBank() << " or undetermined\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uInt16 start = (image[myCart.mySize - 3] << 8) | image[myCart.mySize - 4];
|
||||||
|
uInt16 end;
|
||||||
|
|
||||||
|
start -= start % std::min(int(size), 0x1000);
|
||||||
|
end = start + uInt16(myCart.mySize) - 1;
|
||||||
|
// special check for ROMs where the extra RAM is not included in the image (e.g. CV).
|
||||||
|
if((start & 0xFFF) < size)
|
||||||
|
{
|
||||||
|
start += myCart.myRomOffset;
|
||||||
|
}
|
||||||
|
info << "ROM accessible @ $"
|
||||||
|
<< Common::Base::HEX4 << start << " - $"
|
||||||
|
<< Common::Base::HEX4 << end;
|
||||||
|
}
|
||||||
|
|
||||||
|
return info.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void CartridgeEnhancedWidget::bankList(uInt16 bankCount, int seg, VariantList& items, int& width)
|
||||||
|
{
|
||||||
|
width = 0;
|
||||||
|
|
||||||
|
for(int bank = 0; bank < bankCount; ++bank)
|
||||||
|
{
|
||||||
|
ostringstream buf;
|
||||||
|
|
||||||
|
buf << std::setw(bank < 10 ? 2 : 1) << "#" << std::dec << bank;
|
||||||
|
if(myCart.hotspot() != 0 && myHotspotDelta > 0)
|
||||||
|
buf << " " << hotspotStr(bank, seg);
|
||||||
|
VarList::push_back(items, buf.str());
|
||||||
|
width = std::max(width, _font.getStringWidth(buf.str()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void CartridgeEnhancedWidget::bankSelect(int& ypos)
|
||||||
|
{
|
||||||
|
if(myCart.romBankCount() > 1)
|
||||||
|
{
|
||||||
|
int xpos = 2;
|
||||||
|
|
||||||
|
myBankWidgets = make_unique<PopUpWidget* []>(bankSegs());
|
||||||
|
|
||||||
|
for(int seg = 0; seg < bankSegs(); ++seg)
|
||||||
|
{
|
||||||
|
// fill bank and hotspot list
|
||||||
|
VariantList items;
|
||||||
|
int pw = 0;
|
||||||
|
|
||||||
|
bankList(myCart.romBankCount(), seg, items, pw);
|
||||||
|
|
||||||
|
// create widgets
|
||||||
|
ostringstream buf;
|
||||||
|
|
||||||
|
buf << "Set bank";
|
||||||
|
if(bankSegs() > 1)
|
||||||
|
buf << " for segment #" << seg << " ";
|
||||||
|
else
|
||||||
|
buf << " "; // align with info
|
||||||
|
|
||||||
|
myBankWidgets[seg] = new PopUpWidget(_boss, _font, xpos, ypos - 2,
|
||||||
|
pw, myLineHeight, items, buf.str(),
|
||||||
|
0, kBankChanged);
|
||||||
|
myBankWidgets[seg]->setTarget(this);
|
||||||
|
myBankWidgets[seg]->setID(seg);
|
||||||
|
addFocusWidget(myBankWidgets[seg]);
|
||||||
|
|
||||||
|
ypos += myBankWidgets[seg]->getHeight() + 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string CartridgeEnhancedWidget::bankState()
|
||||||
|
{
|
||||||
|
if(myCart.romBankCount() > 1)
|
||||||
|
{
|
||||||
|
ostringstream& buf = buffer();
|
||||||
|
uInt16 hotspot = myCart.hotspot();
|
||||||
|
bool hasRamBanks = myCart.myRamBankCount > 0;
|
||||||
|
|
||||||
|
if(bankSegs() > 1)
|
||||||
|
{
|
||||||
|
buf << "Segments: ";
|
||||||
|
|
||||||
|
for(int seg = 0; seg < bankSegs(); ++seg)
|
||||||
|
{
|
||||||
|
int bank = myCart.getSegmentBank(seg);
|
||||||
|
bool isRamBank = (bank >= myCart.romBankCount());
|
||||||
|
|
||||||
|
|
||||||
|
if(seg > 0)
|
||||||
|
buf << " / ";
|
||||||
|
|
||||||
|
buf << "#" << std::dec << (bank - (isRamBank ? myCart.romBankCount() : 0));
|
||||||
|
|
||||||
|
if(isRamBank) // was RAM mapped here?
|
||||||
|
buf << " RAM";
|
||||||
|
else if (hasRamBanks)
|
||||||
|
buf << " ROM";
|
||||||
|
|
||||||
|
//if(hotspot >= 0x100)
|
||||||
|
if(hotspot != 0 && myHotspotDelta > 0)
|
||||||
|
buf << " " << hotspotStr(bank, 0, bankSegs() < 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buf << "Bank #" << std::dec << myCart.getBank();
|
||||||
|
|
||||||
|
if(hotspot != 0 && myHotspotDelta > 0)
|
||||||
|
buf << " " << hotspotStr(myCart.getBank(), 0, true);
|
||||||
|
}
|
||||||
|
return buf.str();
|
||||||
|
}
|
||||||
|
return "non-bankswitched";
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string CartridgeEnhancedWidget::hotspotStr(int bank, int segment, bool prefix)
|
||||||
|
{
|
||||||
|
ostringstream info;
|
||||||
|
uInt16 hotspot = myCart.hotspot();
|
||||||
|
|
||||||
|
if(hotspot & 0x1000)
|
||||||
|
hotspot |= ADDR_BASE;
|
||||||
|
|
||||||
|
info << "(" << (prefix ? "hotspot " : "");
|
||||||
|
info << "$" << Common::Base::HEX1 << (hotspot + bank * myHotspotDelta);
|
||||||
|
info << ")";
|
||||||
|
|
||||||
|
return info.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
uInt16 CartridgeEnhancedWidget::bankSegs()
|
||||||
|
{
|
||||||
|
return myCart.myBankSegs;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void CartridgeEnhancedWidget::saveOldState()
|
||||||
|
{
|
||||||
|
myOldState.internalRam.clear();
|
||||||
|
for(uInt32 i = 0; i < myCart.myRamSize; ++i)
|
||||||
|
myOldState.internalRam.push_back(myCart.myRAM[i]);
|
||||||
|
|
||||||
|
myOldState.banks.clear();
|
||||||
|
if (bankSegs() > 1)
|
||||||
|
for(int seg = 0; seg < bankSegs(); ++seg)
|
||||||
|
myOldState.banks.push_back(myCart.getSegmentBank(seg));
|
||||||
|
else
|
||||||
|
myOldState.banks.push_back(myCart.getBank());
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void CartridgeEnhancedWidget::loadConfig()
|
||||||
|
{
|
||||||
|
if(myBankWidgets != nullptr)
|
||||||
|
{
|
||||||
|
if (bankSegs() > 1)
|
||||||
|
for(int seg = 0; seg < bankSegs(); ++seg)
|
||||||
|
myBankWidgets[seg]->setSelectedIndex(myCart.getSegmentBank(seg),
|
||||||
|
myCart.getSegmentBank(seg) != myOldState.banks[seg]);
|
||||||
|
else
|
||||||
|
myBankWidgets[0]->setSelectedIndex(myCart.getBank(),
|
||||||
|
myCart.getBank() != myOldState.banks[0]);
|
||||||
|
}
|
||||||
|
CartDebugWidget::loadConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void CartridgeEnhancedWidget::handleCommand(CommandSender* sender,
|
||||||
|
int cmd, int data, int id)
|
||||||
|
{
|
||||||
|
if(cmd == kBankChanged)
|
||||||
|
{
|
||||||
|
myCart.unlockBank();
|
||||||
|
myCart.bank(myBankWidgets[id]->getSelected(), id);
|
||||||
|
myCart.lockBank();
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
uInt32 CartridgeEnhancedWidget::internalRamSize()
|
||||||
|
{
|
||||||
|
return uInt32(myCart.myRamSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
uInt32 CartridgeEnhancedWidget::internalRamRPort(int start)
|
||||||
|
{
|
||||||
|
if(myCart.ramBankCount() == 0)
|
||||||
|
return ADDR_BASE + myCart.myReadOffset + start;
|
||||||
|
else
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string CartridgeEnhancedWidget::internalRamDescription()
|
||||||
|
{
|
||||||
|
ostringstream desc;
|
||||||
|
string indent = "";
|
||||||
|
|
||||||
|
if(myCart.ramBankCount())
|
||||||
|
{
|
||||||
|
desc << "Accessible ";
|
||||||
|
if (myCart.bankSize() >> 1 >= 1024)
|
||||||
|
desc << ((myCart.bankSize() >> 1) / 1024) << "K";
|
||||||
|
else
|
||||||
|
desc << (myCart.bankSize() >> 1) << " bytes";
|
||||||
|
desc << " at a time via:\n";
|
||||||
|
indent = " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
// order RW by addresses
|
||||||
|
if(myCart.myReadOffset <= myCart.myWriteOffset)
|
||||||
|
{
|
||||||
|
desc << indent << "$" << Common::Base::HEX4 << (ADDR_BASE | myCart.myReadOffset)
|
||||||
|
<< " - $" << (ADDR_BASE | (myCart.myReadOffset + myCart.myRamMask))
|
||||||
|
<< " used for read access\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
desc << indent << "$" << Common::Base::HEX4 << (ADDR_BASE | myCart.myWriteOffset)
|
||||||
|
<< " - $" << (ADDR_BASE | (myCart.myWriteOffset + myCart.myRamMask))
|
||||||
|
<< " used for write access";
|
||||||
|
|
||||||
|
if(myCart.myReadOffset > myCart.myWriteOffset)
|
||||||
|
{
|
||||||
|
desc << indent << "\n$" << Common::Base::HEX4 << (ADDR_BASE | myCart.myReadOffset)
|
||||||
|
<< " - $" << (ADDR_BASE | (myCart.myReadOffset + myCart.myRamMask))
|
||||||
|
<< " used for read access";
|
||||||
|
}
|
||||||
|
|
||||||
|
return desc.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
const ByteArray& CartridgeEnhancedWidget::internalRamOld(int start, int count)
|
||||||
|
{
|
||||||
|
myRamOld.clear();
|
||||||
|
for(int i = 0; i < count; i++)
|
||||||
|
myRamOld.push_back(myOldState.internalRam[start + i]);
|
||||||
|
return myRamOld;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
const ByteArray& CartridgeEnhancedWidget::internalRamCurrent(int start, int count)
|
||||||
|
{
|
||||||
|
myRamCurrent.clear();
|
||||||
|
for(int i = 0; i < count; i++)
|
||||||
|
myRamCurrent.push_back(myCart.myRAM[start + i]);
|
||||||
|
return myRamCurrent;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void CartridgeEnhancedWidget::internalRamSetValue(int addr, uInt8 value)
|
||||||
|
{
|
||||||
|
myCart.myRAM[addr] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
uInt8 CartridgeEnhancedWidget::internalRamGetValue(int addr)
|
||||||
|
{
|
||||||
|
return myCart.myRAM[addr];
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string CartridgeEnhancedWidget::internalRamLabel(int addr)
|
||||||
|
{
|
||||||
|
CartDebug& dbg = instance().debugger().cartDebug();
|
||||||
|
return dbg.getLabel(addr + ADDR_BASE + myCart.myReadOffset, false);
|
||||||
|
}
|
|
@ -15,42 +15,57 @@
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#ifndef CARTRIDGECVPlus_WIDGET_HXX
|
#ifndef CART_ENHANCED_WIDGET_HXX
|
||||||
#define CARTRIDGECVPlus_WIDGET_HXX
|
#define CART_ENHANCED_WIDGET_HXX
|
||||||
|
|
||||||
class CartridgeCVPlus;
|
class CartridgeEnhanced;
|
||||||
class PopUpWidget;
|
class PopUpWidget;
|
||||||
|
|
||||||
|
namespace GUI {
|
||||||
|
class Font;
|
||||||
|
}
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
#include "CartDebugWidget.hxx"
|
||||||
|
|
||||||
class CartridgeCVPlusWidget : public CartDebugWidget
|
class CartridgeEnhancedWidget : public CartDebugWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CartridgeCVPlusWidget(GuiObject* boss, const GUI::Font& lfont,
|
CartridgeEnhancedWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
const GUI::Font& nfont,
|
const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h,
|
int x, int y, int w, int h,
|
||||||
CartridgeCVPlus& cart);
|
CartridgeEnhanced& cart);
|
||||||
virtual ~CartridgeCVPlusWidget() = default;
|
virtual ~CartridgeEnhancedWidget() = default;
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
CartridgeCVPlus& myCart;
|
int initialize();
|
||||||
PopUpWidget* myBank{nullptr};
|
|
||||||
struct CartState {
|
|
||||||
ByteArray internalram;
|
|
||||||
uInt16 bank{0};
|
|
||||||
};
|
|
||||||
CartState myOldState;
|
|
||||||
|
|
||||||
enum { kBankChanged = 'bkCH' };
|
virtual size_t size();
|
||||||
|
|
||||||
private:
|
virtual string manufacturer() = 0;
|
||||||
|
|
||||||
|
virtual string description();
|
||||||
|
|
||||||
|
virtual int descriptionLines();
|
||||||
|
|
||||||
|
virtual string ramDescription();
|
||||||
|
|
||||||
|
virtual string romDescription();
|
||||||
|
|
||||||
|
virtual void bankList(uInt16 bankCount, int seg, VariantList& items, int& width);
|
||||||
|
|
||||||
|
virtual void bankSelect(int& ypos);
|
||||||
|
|
||||||
|
virtual string hotspotStr(int bank = 0, int segment = 0, bool prefix = false);
|
||||||
|
|
||||||
|
virtual uInt16 bankSegs(); // { return myCart.myBankSegs; }
|
||||||
|
|
||||||
|
void saveOldState() override;
|
||||||
void loadConfig() override;
|
void loadConfig() override;
|
||||||
|
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
||||||
|
|
||||||
string bankState() override;
|
string bankState() override;
|
||||||
|
|
||||||
void saveOldState() override;
|
|
||||||
|
|
||||||
// start of functions for Cartridge RAM tab
|
// start of functions for Cartridge RAM tab
|
||||||
uInt32 internalRamSize() override;
|
uInt32 internalRamSize() override;
|
||||||
uInt32 internalRamRPort(int start) override;
|
uInt32 internalRamRPort(int start) override;
|
||||||
|
@ -62,12 +77,34 @@ class CartridgeCVPlusWidget : public CartDebugWidget
|
||||||
string internalRamLabel(int addr) override;
|
string internalRamLabel(int addr) override;
|
||||||
// end of functions for Cartridge RAM tab
|
// end of functions for Cartridge RAM tab
|
||||||
|
|
||||||
|
protected:
|
||||||
|
enum { kBankChanged = 'bkCH' };
|
||||||
|
|
||||||
|
struct CartState {
|
||||||
|
ByteArray internalRam;
|
||||||
|
ByteArray banks;
|
||||||
|
};
|
||||||
|
CartState myOldState;
|
||||||
|
|
||||||
|
CartridgeEnhanced& myCart;
|
||||||
|
|
||||||
|
// Distance between two hotspots
|
||||||
|
int myHotspotDelta{1};
|
||||||
|
|
||||||
|
std::unique_ptr<PopUpWidget* []> myBankWidgets{nullptr};
|
||||||
|
|
||||||
|
|
||||||
|
// Display all addresses based on this
|
||||||
|
static constexpr uInt16 ADDR_BASE = 0xF000;
|
||||||
|
|
||||||
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeCVPlusWidget() = delete;
|
CartridgeEnhancedWidget() = delete;
|
||||||
CartridgeCVPlusWidget(const CartridgeCVPlusWidget&) = delete;
|
CartridgeEnhancedWidget(const CartridgeEnhancedWidget&) = delete;
|
||||||
CartridgeCVPlusWidget(CartridgeCVPlusWidget&&) = delete;
|
CartridgeEnhancedWidget(CartridgeEnhancedWidget&&) = delete;
|
||||||
CartridgeCVPlusWidget& operator=(const CartridgeCVPlusWidget&) = delete;
|
CartridgeEnhancedWidget& operator=(const CartridgeEnhancedWidget&) = delete;
|
||||||
CartridgeCVPlusWidget& operator=(CartridgeCVPlusWidget&&) = delete;
|
CartridgeEnhancedWidget& operator=(CartridgeEnhancedWidget&&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -16,85 +16,28 @@
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "CartF0.hxx"
|
#include "CartF0.hxx"
|
||||||
#include "PopUpWidget.hxx"
|
|
||||||
#include "CartF0Widget.hxx"
|
#include "CartF0Widget.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CartridgeF0Widget::CartridgeF0Widget(
|
CartridgeF0Widget::CartridgeF0Widget(
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h, CartridgeF0& cart)
|
int x, int y, int w, int h, CartridgeF0& cart)
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||||
myCart(cart)
|
|
||||||
{
|
{
|
||||||
uInt32 size = 16 * 4096;
|
myHotspotDelta = 0;
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string CartridgeF0Widget::description()
|
||||||
|
{
|
||||||
ostringstream info;
|
ostringstream info;
|
||||||
info << "64K Megaboy F0 cartridge, 16 4K banks\n"
|
|
||||||
<< "Startup bank = #" << cart.startBank() << " or undetermined\n"
|
|
||||||
<< "Bankswitch triggered by accessing $1FF0\n";
|
|
||||||
|
|
||||||
// Eventually, we should query this from the debugger/disassembler
|
info << "Megaboy F0 cartridge, 16 4K banks\n"
|
||||||
for(uInt32 i = 0, offset = 0xFFC; i < 16; ++i, offset += 0x1000)
|
<< "Startup bank = #" << myCart.startBank() << " or undetermined\n"
|
||||||
{
|
<< "Bankswitch triggered by accessing $" << Common::Base::HEX4 << 0xFFF0 << "\n";
|
||||||
uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset];
|
|
||||||
start -= start % 0x1000;
|
|
||||||
info << "Bank " << std::dec << i << " @ $" << Common::Base::HEX4 << start
|
|
||||||
<< " - " << "$" << (start + 0xFFF) << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
int xpos = 2,
|
return info.str();
|
||||||
ypos = addBaseInformation(size, "Dynacom Megaboy",
|
|
||||||
info.str()) + myLineHeight;
|
|
||||||
|
|
||||||
VariantList items;
|
|
||||||
VarList::push_back(items, " 0");
|
|
||||||
VarList::push_back(items, " 1");
|
|
||||||
VarList::push_back(items, " 2");
|
|
||||||
VarList::push_back(items, " 3");
|
|
||||||
VarList::push_back(items, " 4");
|
|
||||||
VarList::push_back(items, " 5");
|
|
||||||
VarList::push_back(items, " 6");
|
|
||||||
VarList::push_back(items, " 7");
|
|
||||||
VarList::push_back(items, " 8");
|
|
||||||
VarList::push_back(items, " 9");
|
|
||||||
VarList::push_back(items, " 10");
|
|
||||||
VarList::push_back(items, " 11");
|
|
||||||
VarList::push_back(items, " 12");
|
|
||||||
VarList::push_back(items, " 13");
|
|
||||||
VarList::push_back(items, " 14");
|
|
||||||
VarList::push_back(items, " 15");
|
|
||||||
myBank =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth(" 15"),
|
|
||||||
myLineHeight, items, "Set bank #",
|
|
||||||
0, kBankChanged);
|
|
||||||
myBank->setTarget(this);
|
|
||||||
addFocusWidget(myBank);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeF0Widget::loadConfig()
|
|
||||||
{
|
|
||||||
Debugger& dbg = instance().debugger();
|
|
||||||
CartDebug& cart = dbg.cartDebug();
|
|
||||||
const CartState& state = static_cast<const CartState&>(cart.getState());
|
|
||||||
const CartState& oldstate = static_cast<const CartState&>(cart.getOldState());
|
|
||||||
|
|
||||||
myBank->setSelectedIndex(myCart.getBank(), state.bank != oldstate.bank);
|
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeF0Widget::handleCommand(CommandSender* sender,
|
|
||||||
int cmd, int data, int id)
|
|
||||||
{
|
|
||||||
if(cmd == kBankChanged)
|
|
||||||
{
|
|
||||||
myCart.unlockBank();
|
|
||||||
myCart.bank(myBank->getSelected());
|
|
||||||
myCart.lockBank();
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -102,7 +45,8 @@ string CartridgeF0Widget::bankState()
|
||||||
{
|
{
|
||||||
ostringstream& buf = buffer();
|
ostringstream& buf = buffer();
|
||||||
|
|
||||||
buf << "Bank = #" << std::dec << myCart.getBank() << ", hotspot = $FFF0";
|
buf << "Bank #" << std::dec << myCart.getBank()
|
||||||
|
<< " (hotspot $" << Common::Base::HEX4 << 0xFFF0 << ")";
|
||||||
|
|
||||||
return buf.str();
|
return buf.str();
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,10 @@
|
||||||
#define CARTRIDGEF0_WIDGET_HXX
|
#define CARTRIDGEF0_WIDGET_HXX
|
||||||
|
|
||||||
class CartridgeF0;
|
class CartridgeF0;
|
||||||
class PopUpWidget;
|
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
#include "CartEnhancedWidget.hxx"
|
||||||
|
|
||||||
class CartridgeF0Widget : public CartDebugWidget
|
class CartridgeF0Widget : public CartridgeEnhancedWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CartridgeF0Widget(GuiObject* boss, const GUI::Font& lfont,
|
CartridgeF0Widget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
|
@ -33,17 +32,13 @@ class CartridgeF0Widget : public CartDebugWidget
|
||||||
virtual ~CartridgeF0Widget() = default;
|
virtual ~CartridgeF0Widget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CartridgeF0& myCart;
|
string manufacturer() override { return "Dynacom Megaboy"; }
|
||||||
PopUpWidget* myBank{nullptr};
|
|
||||||
|
|
||||||
enum { kBankChanged = 'bkCH' };
|
string description() override;
|
||||||
|
|
||||||
private:
|
|
||||||
void loadConfig() override;
|
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
|
||||||
|
|
||||||
string bankState() override;
|
string bankState() override;
|
||||||
|
|
||||||
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeF0Widget() = delete;
|
CartridgeF0Widget() = delete;
|
||||||
CartridgeF0Widget(const CartridgeF0Widget&) = delete;
|
CartridgeF0Widget(const CartridgeF0Widget&) = delete;
|
||||||
|
|
|
@ -15,157 +15,25 @@
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "Debugger.hxx"
|
|
||||||
#include "CartDebug.hxx"
|
|
||||||
#include "CartF4SC.hxx"
|
#include "CartF4SC.hxx"
|
||||||
#include "PopUpWidget.hxx"
|
|
||||||
#include "CartF4SCWidget.hxx"
|
#include "CartF4SCWidget.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CartridgeF4SCWidget::CartridgeF4SCWidget(
|
CartridgeF4SCWidget::CartridgeF4SCWidget(
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h, CartridgeF4SC& cart)
|
int x, int y, int w, int h, CartridgeF4SC& cart)
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||||
myCart(cart)
|
|
||||||
{
|
{
|
||||||
uInt16 size = 8 * 4096;
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string CartridgeF4SCWidget::description()
|
||||||
|
{
|
||||||
ostringstream info;
|
ostringstream info;
|
||||||
info << "Standard F4SC cartridge, eight 4K banks\n"
|
|
||||||
<< "128 bytes RAM @ $F000 - $F0FF\n"
|
|
||||||
<< " $F080 - $F0FF (R), $F000 - $F07F (W)\n"
|
|
||||||
<< "Startup bank = " << cart.startBank() << " or undetermined\n";
|
|
||||||
|
|
||||||
// Eventually, we should query this from the debugger/disassembler
|
info << "Standard F4SC cartridge, eight 4K banks\n";
|
||||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0xFF4; i < 8; ++i, offset += 0x1000)
|
info << CartridgeEnhancedWidget::description();
|
||||||
{
|
|
||||||
uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset];
|
|
||||||
start -= start % 0x1000;
|
|
||||||
info << "Bank " << i << " @ $" << Common::Base::HEX4 << (start + 0x100) << " - "
|
|
||||||
<< "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
int xpos = 2,
|
return info.str();
|
||||||
ypos = addBaseInformation(size, "Atari", info.str(), 15) + myLineHeight;
|
|
||||||
|
|
||||||
VariantList items;
|
|
||||||
VarList::push_back(items, "0 ($FFF4)");
|
|
||||||
VarList::push_back(items, "1 ($FFF5)");
|
|
||||||
VarList::push_back(items, "2 ($FFF6)");
|
|
||||||
VarList::push_back(items, "3 ($FFF7)");
|
|
||||||
VarList::push_back(items, "4 ($FFF8)");
|
|
||||||
VarList::push_back(items, "5 ($FFF9)");
|
|
||||||
VarList::push_back(items, "6 ($FFFA)");
|
|
||||||
VarList::push_back(items, "7 ($FFFB)");
|
|
||||||
myBank =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("0 ($FFFx)"),
|
|
||||||
myLineHeight, items, "Set bank ",
|
|
||||||
0, kBankChanged);
|
|
||||||
myBank->setTarget(this);
|
|
||||||
addFocusWidget(myBank);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeF4SCWidget::saveOldState()
|
|
||||||
{
|
|
||||||
myOldState.internalram.clear();
|
|
||||||
|
|
||||||
for(uInt32 i = 0; i < internalRamSize(); ++i)
|
|
||||||
myOldState.internalram.push_back(myCart.myRAM[i]);
|
|
||||||
|
|
||||||
myOldState.bank = myCart.getBank();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeF4SCWidget::loadConfig()
|
|
||||||
{
|
|
||||||
myBank->setSelectedIndex(myCart.getBank(), myCart.getBank() != myOldState.bank);
|
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeF4SCWidget::handleCommand(CommandSender* sender,
|
|
||||||
int cmd, int data, int id)
|
|
||||||
{
|
|
||||||
if(cmd == kBankChanged)
|
|
||||||
{
|
|
||||||
myCart.unlockBank();
|
|
||||||
myCart.bank(myBank->getSelected());
|
|
||||||
myCart.lockBank();
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeF4SCWidget::bankState()
|
|
||||||
{
|
|
||||||
ostringstream& buf = buffer();
|
|
||||||
|
|
||||||
static constexpr std::array<const char*, 8> spot = {
|
|
||||||
"$FFF4", "$FFF5", "$FFF6", "$FFF7", "$FFF8", "$FFF9", "$FFFA", "$FFFB"
|
|
||||||
};
|
|
||||||
buf << "Bank = " << std::dec << myCart.getBank()
|
|
||||||
<< ", hotspot = " << spot[myCart.getBank()];
|
|
||||||
|
|
||||||
return buf.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 CartridgeF4SCWidget::internalRamSize()
|
|
||||||
{
|
|
||||||
return 128;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 CartridgeF4SCWidget::internalRamRPort(int start)
|
|
||||||
{
|
|
||||||
return 0xF080 + start;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeF4SCWidget::internalRamDescription()
|
|
||||||
{
|
|
||||||
ostringstream desc;
|
|
||||||
desc << "$F000 - $F07F used for Write Access\n"
|
|
||||||
<< "$F080 - $F0FF used for Read Access";
|
|
||||||
|
|
||||||
return desc.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const ByteArray& CartridgeF4SCWidget::internalRamOld(int start, int count)
|
|
||||||
{
|
|
||||||
myRamOld.clear();
|
|
||||||
for(int i = 0; i < count; i++)
|
|
||||||
myRamOld.push_back(myOldState.internalram[start + i]);
|
|
||||||
return myRamOld;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const ByteArray& CartridgeF4SCWidget::internalRamCurrent(int start, int count)
|
|
||||||
{
|
|
||||||
myRamCurrent.clear();
|
|
||||||
for(int i = 0; i < count; i++)
|
|
||||||
myRamCurrent.push_back(myCart.myRAM[start + i]);
|
|
||||||
return myRamCurrent;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeF4SCWidget::internalRamSetValue(int addr, uInt8 value)
|
|
||||||
{
|
|
||||||
myCart.myRAM[addr] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt8 CartridgeF4SCWidget::internalRamGetValue(int addr)
|
|
||||||
{
|
|
||||||
return myCart.myRAM[addr];
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeF4SCWidget::internalRamLabel(int addr)
|
|
||||||
{
|
|
||||||
CartDebug& dbg = instance().debugger().cartDebug();
|
|
||||||
return dbg.getLabel(addr + 0xF080, false);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,10 @@
|
||||||
#define CARTRIDGEF4SC_WIDGET_HXX
|
#define CARTRIDGEF4SC_WIDGET_HXX
|
||||||
|
|
||||||
class CartridgeF4SC;
|
class CartridgeF4SC;
|
||||||
class PopUpWidget;
|
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
#include "CartEnhancedWidget.hxx"
|
||||||
|
|
||||||
class CartridgeF4SCWidget : public CartDebugWidget
|
class CartridgeF4SCWidget : public CartridgeEnhancedWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CartridgeF4SCWidget(GuiObject* boss, const GUI::Font& lfont,
|
CartridgeF4SCWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
|
@ -33,36 +32,11 @@ class CartridgeF4SCWidget : public CartDebugWidget
|
||||||
virtual ~CartridgeF4SCWidget() = default;
|
virtual ~CartridgeF4SCWidget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CartridgeF4SC& myCart;
|
string manufacturer() override { return "Atari"; }
|
||||||
PopUpWidget* myBank{nullptr};
|
|
||||||
|
|
||||||
struct CartState {
|
string description() override;
|
||||||
ByteArray internalram;
|
|
||||||
uInt16 bank{0};
|
|
||||||
};
|
|
||||||
CartState myOldState;
|
|
||||||
|
|
||||||
|
|
||||||
enum { kBankChanged = 'bkCH' };
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void saveOldState() override;
|
|
||||||
void loadConfig() override;
|
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
|
||||||
|
|
||||||
string bankState() override;
|
|
||||||
|
|
||||||
// start of functions for Cartridge RAM tab
|
|
||||||
uInt32 internalRamSize() override;
|
|
||||||
uInt32 internalRamRPort(int start) override;
|
|
||||||
string internalRamDescription() override;
|
|
||||||
const ByteArray& internalRamOld(int start, int count) override;
|
|
||||||
const ByteArray& internalRamCurrent(int start, int count) override;
|
|
||||||
void internalRamSetValue(int addr, uInt8 value) override;
|
|
||||||
uInt8 internalRamGetValue(int addr) override;
|
|
||||||
string internalRamLabel(int addr) override;
|
|
||||||
// end of functions for Cartridge RAM tab
|
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeF4SCWidget() = delete;
|
CartridgeF4SCWidget() = delete;
|
||||||
CartridgeF4SCWidget(const CartridgeF4SCWidget&) = delete;
|
CartridgeF4SCWidget(const CartridgeF4SCWidget&) = delete;
|
||||||
|
|
|
@ -16,87 +16,24 @@
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "CartF4.hxx"
|
#include "CartF4.hxx"
|
||||||
#include "PopUpWidget.hxx"
|
|
||||||
#include "CartF4Widget.hxx"
|
#include "CartF4Widget.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CartridgeF4Widget::CartridgeF4Widget(
|
CartridgeF4Widget::CartridgeF4Widget(
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h, CartridgeF4& cart)
|
int x, int y, int w, int h, CartridgeF4& cart)
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||||
myCart(cart)
|
|
||||||
{
|
{
|
||||||
uInt16 size = 8 * 4096;
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string CartridgeF4Widget::description()
|
||||||
|
{
|
||||||
ostringstream info;
|
ostringstream info;
|
||||||
info << "Standard F4 cartridge, eight 4K banks\n"
|
|
||||||
<< "Startup bank = " << cart.startBank() << " or undetermined\n";
|
|
||||||
|
|
||||||
// Eventually, we should query this from the debugger/disassembler
|
info << "Standard F4 cartridge, eight 4K banks\n";
|
||||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0xFF4; i < 8; ++i, offset += 0x1000)
|
info << CartridgeEnhancedWidget::description();
|
||||||
{
|
|
||||||
uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset];
|
|
||||||
start -= start % 0x1000;
|
|
||||||
info << "Bank " << i << " @ $" << Common::Base::HEX4 << start << " - "
|
|
||||||
<< "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
int xpos = 2,
|
return info.str();
|
||||||
ypos = addBaseInformation(size, "Atari", info.str(), 15) + myLineHeight;
|
|
||||||
|
|
||||||
VariantList items;
|
|
||||||
VarList::push_back(items, "0 ($FFF4)");
|
|
||||||
VarList::push_back(items, "1 ($FFF5)");
|
|
||||||
VarList::push_back(items, "2 ($FFF6)");
|
|
||||||
VarList::push_back(items, "3 ($FFF7)");
|
|
||||||
VarList::push_back(items, "4 ($FFF8)");
|
|
||||||
VarList::push_back(items, "5 ($FFF9)");
|
|
||||||
VarList::push_back(items, "6 ($FFFA)");
|
|
||||||
VarList::push_back(items, "7 ($FFFB)");
|
|
||||||
myBank =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("0 ($FFFx)"),
|
|
||||||
myLineHeight, items, "Set bank ",
|
|
||||||
0, kBankChanged);
|
|
||||||
myBank->setTarget(this);
|
|
||||||
addFocusWidget(myBank);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeF4Widget::loadConfig()
|
|
||||||
{
|
|
||||||
Debugger& dbg = instance().debugger();
|
|
||||||
CartDebug& cart = dbg.cartDebug();
|
|
||||||
const CartState& state = static_cast<const CartState&>(cart.getState());
|
|
||||||
const CartState& oldstate = static_cast<const CartState&>(cart.getOldState());
|
|
||||||
|
|
||||||
myBank->setSelectedIndex(myCart.getBank(), state.bank != oldstate.bank);
|
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeF4Widget::handleCommand(CommandSender* sender,
|
|
||||||
int cmd, int data, int id)
|
|
||||||
{
|
|
||||||
if(cmd == kBankChanged)
|
|
||||||
{
|
|
||||||
myCart.unlockBank();
|
|
||||||
myCart.bank(myBank->getSelected());
|
|
||||||
myCart.lockBank();
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeF4Widget::bankState()
|
|
||||||
{
|
|
||||||
ostringstream& buf = buffer();
|
|
||||||
|
|
||||||
static constexpr std::array<const char*, 8> spot = {
|
|
||||||
"$FFF4", "$FFF5", "$FFF6", "$FFF7", "$FFF8", "$FFF9", "$FFFA", "$FFFB"
|
|
||||||
};
|
|
||||||
buf << "Bank = " << std::dec << myCart.getBank()
|
|
||||||
<< ", hotspot = " << spot[myCart.getBank()];
|
|
||||||
|
|
||||||
return buf.str();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,10 @@
|
||||||
#define CARTRIDGEF4_WIDGET_HXX
|
#define CARTRIDGEF4_WIDGET_HXX
|
||||||
|
|
||||||
class CartridgeF4;
|
class CartridgeF4;
|
||||||
class PopUpWidget;
|
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
#include "CartEnhancedWidget.hxx"
|
||||||
|
|
||||||
class CartridgeF4Widget : public CartDebugWidget
|
class CartridgeF4Widget : public CartridgeEnhancedWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CartridgeF4Widget(GuiObject* boss, const GUI::Font& lfont,
|
CartridgeF4Widget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
|
@ -33,17 +32,11 @@ class CartridgeF4Widget : public CartDebugWidget
|
||||||
virtual ~CartridgeF4Widget() = default;
|
virtual ~CartridgeF4Widget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CartridgeF4& myCart;
|
string manufacturer() override { return "Atari"; }
|
||||||
PopUpWidget* myBank{nullptr};
|
|
||||||
|
|
||||||
enum { kBankChanged = 'bkCH' };
|
string description() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void loadConfig() override;
|
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
|
||||||
|
|
||||||
string bankState() override;
|
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeF4Widget() = delete;
|
CartridgeF4Widget() = delete;
|
||||||
CartridgeF4Widget(const CartridgeF4Widget&) = delete;
|
CartridgeF4Widget(const CartridgeF4Widget&) = delete;
|
||||||
|
|
|
@ -15,151 +15,25 @@
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "Debugger.hxx"
|
|
||||||
#include "CartDebug.hxx"
|
|
||||||
#include "CartF6SC.hxx"
|
#include "CartF6SC.hxx"
|
||||||
#include "PopUpWidget.hxx"
|
|
||||||
#include "CartF6SCWidget.hxx"
|
#include "CartF6SCWidget.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CartridgeF6SCWidget::CartridgeF6SCWidget(
|
CartridgeF6SCWidget::CartridgeF6SCWidget(
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h, CartridgeF6SC& cart)
|
int x, int y, int w, int h, CartridgeF6SC& cart)
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||||
myCart(cart)
|
|
||||||
{
|
{
|
||||||
uInt16 size = 4 * 4096;
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string CartridgeF6SCWidget::description()
|
||||||
|
{
|
||||||
ostringstream info;
|
ostringstream info;
|
||||||
info << "Standard F6SC cartridge, four 4K banks\n"
|
|
||||||
<< "128 bytes RAM @ $F000 - $F0FF\n"
|
|
||||||
<< " $F080 - $F0FF (R), $F000 - $F07F (W)\n"
|
|
||||||
<< "Startup bank = " << cart.startBank() << " or undetermined\n";
|
|
||||||
|
|
||||||
// Eventually, we should query this from the debugger/disassembler
|
info << "Standard F6SC cartridge, four 4K banks\n";
|
||||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0xFF6; i < 4; ++i, offset += 0x1000)
|
info << CartridgeEnhancedWidget::description();
|
||||||
{
|
|
||||||
uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset];
|
|
||||||
start -= start % 0x1000;
|
|
||||||
info << "Bank " << i << " @ $" << Common::Base::HEX4 << (start + 0x100) << " - "
|
|
||||||
<< "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
int xpos = 2,
|
return info.str();
|
||||||
ypos = addBaseInformation(size, "Atari", info.str()) + myLineHeight;
|
|
||||||
|
|
||||||
VariantList items;
|
|
||||||
VarList::push_back(items, "0 ($FFF6)");
|
|
||||||
VarList::push_back(items, "1 ($FFF7)");
|
|
||||||
VarList::push_back(items, "2 ($FFF8)");
|
|
||||||
VarList::push_back(items, "3 ($FFF9)");
|
|
||||||
myBank =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("0 ($FFFx)"),
|
|
||||||
myLineHeight, items, "Set bank ",
|
|
||||||
0, kBankChanged);
|
|
||||||
myBank->setTarget(this);
|
|
||||||
addFocusWidget(myBank);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeF6SCWidget::saveOldState()
|
|
||||||
{
|
|
||||||
myOldState.internalram.clear();
|
|
||||||
|
|
||||||
for(uInt32 i = 0; i < internalRamSize(); ++i)
|
|
||||||
myOldState.internalram.push_back(myCart.myRAM[i]);
|
|
||||||
|
|
||||||
myOldState.bank = myCart.getBank();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeF6SCWidget::loadConfig()
|
|
||||||
{
|
|
||||||
myBank->setSelectedIndex(myCart.getBank(), myCart.getBank() != myOldState.bank);
|
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeF6SCWidget::handleCommand(CommandSender* sender,
|
|
||||||
int cmd, int data, int id)
|
|
||||||
{
|
|
||||||
if(cmd == kBankChanged)
|
|
||||||
{
|
|
||||||
myCart.unlockBank();
|
|
||||||
myCart.bank(myBank->getSelected());
|
|
||||||
myCart.lockBank();
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeF6SCWidget::bankState()
|
|
||||||
{
|
|
||||||
ostringstream& buf = buffer();
|
|
||||||
|
|
||||||
static constexpr std::array<const char*, 4> spot = { "$FFF6", "$FFF7", "$FFF8", "$FFF9" };
|
|
||||||
buf << "Bank = " << std::dec << myCart.getBank()
|
|
||||||
<< ", hotspot = " << spot[myCart.getBank()];
|
|
||||||
|
|
||||||
return buf.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 CartridgeF6SCWidget::internalRamSize()
|
|
||||||
{
|
|
||||||
return 128;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 CartridgeF6SCWidget::internalRamRPort(int start)
|
|
||||||
{
|
|
||||||
return 0xF080 + start;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeF6SCWidget::internalRamDescription()
|
|
||||||
{
|
|
||||||
ostringstream desc;
|
|
||||||
desc << "$F000 - $F07F used for Write Access\n"
|
|
||||||
<< "$F080 - $F0FF used for Read Access";
|
|
||||||
|
|
||||||
return desc.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const ByteArray& CartridgeF6SCWidget::internalRamOld(int start, int count)
|
|
||||||
{
|
|
||||||
myRamOld.clear();
|
|
||||||
for(int i = 0; i < count; i++)
|
|
||||||
myRamOld.push_back(myOldState.internalram[start + i]);
|
|
||||||
return myRamOld;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const ByteArray& CartridgeF6SCWidget::internalRamCurrent(int start, int count)
|
|
||||||
{
|
|
||||||
myRamCurrent.clear();
|
|
||||||
for(int i = 0; i < count; i++)
|
|
||||||
myRamCurrent.push_back(myCart.myRAM[start + i]);
|
|
||||||
return myRamCurrent;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeF6SCWidget::internalRamSetValue(int addr, uInt8 value)
|
|
||||||
{
|
|
||||||
myCart.myRAM[addr] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt8 CartridgeF6SCWidget::internalRamGetValue(int addr)
|
|
||||||
{
|
|
||||||
return myCart.myRAM[addr];
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeF6SCWidget::internalRamLabel(int addr)
|
|
||||||
{
|
|
||||||
CartDebug& dbg = instance().debugger().cartDebug();
|
|
||||||
return dbg.getLabel(addr + 0xF080, false);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,10 @@
|
||||||
#define CARTRIDGEF6SC_WIDGET_HXX
|
#define CARTRIDGEF6SC_WIDGET_HXX
|
||||||
|
|
||||||
class CartridgeF6SC;
|
class CartridgeF6SC;
|
||||||
class PopUpWidget;
|
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
#include "CartEnhancedWidget.hxx"
|
||||||
|
|
||||||
class CartridgeF6SCWidget : public CartDebugWidget
|
class CartridgeF6SCWidget : public CartridgeEnhancedWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CartridgeF6SCWidget(GuiObject* boss, const GUI::Font& lfont,
|
CartridgeF6SCWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
|
@ -33,34 +32,11 @@ class CartridgeF6SCWidget : public CartDebugWidget
|
||||||
virtual ~CartridgeF6SCWidget() = default;
|
virtual ~CartridgeF6SCWidget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct CartState {
|
string manufacturer() override { return "Atari"; }
|
||||||
ByteArray internalram;
|
|
||||||
uInt16 bank{0};
|
|
||||||
};
|
|
||||||
CartridgeF6SC& myCart;
|
|
||||||
PopUpWidget* myBank{nullptr};
|
|
||||||
CartState myOldState;
|
|
||||||
|
|
||||||
enum { kBankChanged = 'bkCH' };
|
string description() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void saveOldState() override;
|
|
||||||
void loadConfig() override;
|
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
|
||||||
|
|
||||||
string bankState() override;
|
|
||||||
|
|
||||||
// start of functions for Cartridge RAM tab
|
|
||||||
uInt32 internalRamSize() override;
|
|
||||||
uInt32 internalRamRPort(int start) override;
|
|
||||||
string internalRamDescription() override;
|
|
||||||
const ByteArray& internalRamOld(int start, int count) override;
|
|
||||||
const ByteArray& internalRamCurrent(int start, int count) override;
|
|
||||||
void internalRamSetValue(int addr, uInt8 value) override;
|
|
||||||
uInt8 internalRamGetValue(int addr) override;
|
|
||||||
string internalRamLabel(int addr) override;
|
|
||||||
// end of functions for Cartridge RAM tab
|
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeF6SCWidget() = delete;
|
CartridgeF6SCWidget() = delete;
|
||||||
CartridgeF6SCWidget(const CartridgeF6SCWidget&) = delete;
|
CartridgeF6SCWidget(const CartridgeF6SCWidget&) = delete;
|
||||||
|
|
|
@ -16,81 +16,24 @@
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "CartF6.hxx"
|
#include "CartF6.hxx"
|
||||||
#include "PopUpWidget.hxx"
|
|
||||||
#include "CartF6Widget.hxx"
|
#include "CartF6Widget.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CartridgeF6Widget::CartridgeF6Widget(
|
CartridgeF6Widget::CartridgeF6Widget(
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h, CartridgeF6& cart)
|
int x, int y, int w, int h, CartridgeF6& cart)
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||||
myCart(cart)
|
|
||||||
{
|
{
|
||||||
uInt16 size = 4 * 4096;
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string CartridgeF6Widget::description()
|
||||||
|
{
|
||||||
ostringstream info;
|
ostringstream info;
|
||||||
info << "Standard F6 cartridge, four 4K banks\n"
|
|
||||||
<< "Startup bank = " << cart.startBank() << " or undetermined\n";
|
|
||||||
|
|
||||||
// Eventually, we should query this from the debugger/disassembler
|
info << "Standard F6 cartridge, four 4K banks\n";
|
||||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0xFF6; i < 4; ++i, offset += 0x1000)
|
info << CartridgeEnhancedWidget::description();
|
||||||
{
|
|
||||||
uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset];
|
|
||||||
start -= start % 0x1000;
|
|
||||||
info << "Bank " << i << " @ $" << Common::Base::HEX4 << start << " - "
|
|
||||||
<< "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
int xpos = 2,
|
return info.str();
|
||||||
ypos = addBaseInformation(size, "Atari", info.str()) + myLineHeight;
|
|
||||||
|
|
||||||
VariantList items;
|
|
||||||
VarList::push_back(items, "0 ($FFF6)");
|
|
||||||
VarList::push_back(items, "1 ($FFF7)");
|
|
||||||
VarList::push_back(items, "2 ($FFF8)");
|
|
||||||
VarList::push_back(items, "3 ($FFF9)");
|
|
||||||
myBank =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("0 ($FFFx) "),
|
|
||||||
myLineHeight, items, "Set bank ",
|
|
||||||
0, kBankChanged);
|
|
||||||
myBank->setTarget(this);
|
|
||||||
addFocusWidget(myBank);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeF6Widget::loadConfig()
|
|
||||||
{
|
|
||||||
Debugger& dbg = instance().debugger();
|
|
||||||
CartDebug& cart = dbg.cartDebug();
|
|
||||||
const CartState& state = static_cast<const CartState&>(cart.getState());
|
|
||||||
const CartState& oldstate = static_cast<const CartState&>(cart.getOldState());
|
|
||||||
|
|
||||||
myBank->setSelectedIndex(myCart.getBank(), state.bank != oldstate.bank);
|
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeF6Widget::handleCommand(CommandSender* sender,
|
|
||||||
int cmd, int data, int id)
|
|
||||||
{
|
|
||||||
if(cmd == kBankChanged)
|
|
||||||
{
|
|
||||||
myCart.unlockBank();
|
|
||||||
myCart.bank(myBank->getSelected());
|
|
||||||
myCart.lockBank();
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeF6Widget::bankState()
|
|
||||||
{
|
|
||||||
ostringstream& buf = buffer();
|
|
||||||
|
|
||||||
static constexpr std::array<const char*, 4> spot = { "$FFF6", "$FFF7", "$FFF8", "$FFF9" };
|
|
||||||
buf << "Bank = " << std::dec << myCart.getBank()
|
|
||||||
<< ", hotspot = " << spot[myCart.getBank()];
|
|
||||||
|
|
||||||
return buf.str();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,10 @@
|
||||||
#define CARTRIDGEF6_WIDGET_HXX
|
#define CARTRIDGEF6_WIDGET_HXX
|
||||||
|
|
||||||
class CartridgeF6;
|
class CartridgeF6;
|
||||||
class PopUpWidget;
|
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
#include "CartEnhancedWidget.hxx"
|
||||||
|
|
||||||
class CartridgeF6Widget : public CartDebugWidget
|
class CartridgeF6Widget : public CartridgeEnhancedWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CartridgeF6Widget(GuiObject* boss, const GUI::Font& lfont,
|
CartridgeF6Widget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
|
@ -33,17 +32,11 @@ class CartridgeF6Widget : public CartDebugWidget
|
||||||
virtual ~CartridgeF6Widget() = default;
|
virtual ~CartridgeF6Widget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CartridgeF6& myCart;
|
string manufacturer() override { return "Atari"; }
|
||||||
PopUpWidget* myBank{nullptr};
|
|
||||||
|
|
||||||
enum { kBankChanged = 'bkCH' };
|
string description() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void loadConfig() override;
|
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
|
||||||
|
|
||||||
string bankState() override;
|
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeF6Widget() = delete;
|
CartridgeF6Widget() = delete;
|
||||||
CartridgeF6Widget(const CartridgeF6Widget&) = delete;
|
CartridgeF6Widget(const CartridgeF6Widget&) = delete;
|
||||||
|
|
|
@ -15,149 +15,25 @@
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "Debugger.hxx"
|
|
||||||
#include "CartDebug.hxx"
|
|
||||||
#include "CartF8SC.hxx"
|
#include "CartF8SC.hxx"
|
||||||
#include "PopUpWidget.hxx"
|
|
||||||
#include "CartF8SCWidget.hxx"
|
#include "CartF8SCWidget.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CartridgeF8SCWidget::CartridgeF8SCWidget(
|
CartridgeF8SCWidget::CartridgeF8SCWidget(
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h, CartridgeF8SC& cart)
|
int x, int y, int w, int h, CartridgeF8SC& cart)
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||||
myCart(cart)
|
|
||||||
{
|
{
|
||||||
uInt16 size = 8192;
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string CartridgeF8SCWidget::description()
|
||||||
|
{
|
||||||
ostringstream info;
|
ostringstream info;
|
||||||
info << "Standard F8SC cartridge, two 4K banks\n"
|
|
||||||
<< "128 bytes RAM @ $F000 - $F0FF\n"
|
|
||||||
<< " $F080 - $F0FF (R), $F000 - $F07F (W)\n"
|
|
||||||
<< "Startup bank = " << cart.startBank() << " or undetermined\n";
|
|
||||||
|
|
||||||
// Eventually, we should query this from the debugger/disassembler
|
info << "Standard F8SC cartridge, two 4K banks\n";
|
||||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0xFF8; i < 2; ++i, offset += 0x1000)
|
info << CartridgeEnhancedWidget::description();
|
||||||
{
|
|
||||||
uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset];
|
|
||||||
start -= start % 0x1000;
|
|
||||||
info << "Bank " << i << " @ $" << Common::Base::HEX4 << (start + 0x100) << " - "
|
|
||||||
<< "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
int xpos = 2,
|
return info.str();
|
||||||
ypos = addBaseInformation(size, "Atari", info.str()) + myLineHeight;
|
|
||||||
|
|
||||||
VariantList items;
|
|
||||||
VarList::push_back(items, "0 ($FFF8)");
|
|
||||||
VarList::push_back(items, "1 ($FFF9)");
|
|
||||||
myBank =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("0 ($FFFx)"),
|
|
||||||
myLineHeight, items, "Set bank ",
|
|
||||||
0, kBankChanged);
|
|
||||||
myBank->setTarget(this);
|
|
||||||
addFocusWidget(myBank);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeF8SCWidget::saveOldState()
|
|
||||||
{
|
|
||||||
myOldState.internalram.clear();
|
|
||||||
|
|
||||||
for(uInt32 i = 0; i < internalRamSize(); ++i)
|
|
||||||
myOldState.internalram.push_back(myCart.myRAM[i]);
|
|
||||||
|
|
||||||
myOldState.bank = myCart.getBank();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeF8SCWidget::loadConfig()
|
|
||||||
{
|
|
||||||
myBank->setSelectedIndex(myCart.getBank(), myCart.getBank() != myOldState.bank);
|
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeF8SCWidget::handleCommand(CommandSender* sender,
|
|
||||||
int cmd, int data, int id)
|
|
||||||
{
|
|
||||||
if(cmd == kBankChanged)
|
|
||||||
{
|
|
||||||
myCart.unlockBank();
|
|
||||||
myCart.bank(myBank->getSelected());
|
|
||||||
myCart.lockBank();
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeF8SCWidget::bankState()
|
|
||||||
{
|
|
||||||
ostringstream& buf = buffer();
|
|
||||||
|
|
||||||
static constexpr std::array<const char*, 2> spot = { "$FFF8", "$FFF9" };
|
|
||||||
buf << "Bank = " << std::dec << myCart.getBank()
|
|
||||||
<< ", hotspot = " << spot[myCart.getBank()];
|
|
||||||
|
|
||||||
return buf.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 CartridgeF8SCWidget::internalRamSize()
|
|
||||||
{
|
|
||||||
return 128;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 CartridgeF8SCWidget::internalRamRPort(int start)
|
|
||||||
{
|
|
||||||
return 0xF080 + start;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeF8SCWidget::internalRamDescription()
|
|
||||||
{
|
|
||||||
ostringstream desc;
|
|
||||||
desc << "$F000 - $F07F used for Write Access\n"
|
|
||||||
<< "$F080 - $F0FF used for Read Access";
|
|
||||||
|
|
||||||
return desc.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const ByteArray& CartridgeF8SCWidget::internalRamOld(int start, int count)
|
|
||||||
{
|
|
||||||
myRamOld.clear();
|
|
||||||
for(int i = 0; i < count; i++)
|
|
||||||
myRamOld.push_back(myOldState.internalram[start + i]);
|
|
||||||
return myRamOld;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const ByteArray& CartridgeF8SCWidget::internalRamCurrent(int start, int count)
|
|
||||||
{
|
|
||||||
myRamCurrent.clear();
|
|
||||||
for(int i = 0; i < count; i++)
|
|
||||||
myRamCurrent.push_back(myCart.myRAM[start + i]);
|
|
||||||
return myRamCurrent;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeF8SCWidget::internalRamSetValue(int addr, uInt8 value)
|
|
||||||
{
|
|
||||||
myCart.myRAM[addr] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt8 CartridgeF8SCWidget::internalRamGetValue(int addr)
|
|
||||||
{
|
|
||||||
return myCart.myRAM[addr];
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeF8SCWidget::internalRamLabel(int addr)
|
|
||||||
{
|
|
||||||
CartDebug& dbg = instance().debugger().cartDebug();
|
|
||||||
return dbg.getLabel(addr + 0xF080, false);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,10 @@
|
||||||
#define CARTRIDGEF8SC_WIDGET_HXX
|
#define CARTRIDGEF8SC_WIDGET_HXX
|
||||||
|
|
||||||
class CartridgeF8SC;
|
class CartridgeF8SC;
|
||||||
class PopUpWidget;
|
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
#include "CartEnhancedWidget.hxx"
|
||||||
|
|
||||||
class CartridgeF8SCWidget : public CartDebugWidget
|
class CartridgeF8SCWidget : public CartridgeEnhancedWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CartridgeF8SCWidget(GuiObject* boss, const GUI::Font& lfont,
|
CartridgeF8SCWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
|
@ -33,35 +32,11 @@ class CartridgeF8SCWidget : public CartDebugWidget
|
||||||
virtual ~CartridgeF8SCWidget() = default;
|
virtual ~CartridgeF8SCWidget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CartridgeF8SC& myCart;
|
string manufacturer() override { return "Atari"; }
|
||||||
PopUpWidget* myBank{nullptr};
|
|
||||||
|
|
||||||
struct CartState {
|
string description() override;
|
||||||
ByteArray internalram;
|
|
||||||
uInt16 bank{0};
|
|
||||||
};
|
|
||||||
CartState myOldState;
|
|
||||||
|
|
||||||
enum { kBankChanged = 'bkCH' };
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void saveOldState() override;
|
|
||||||
void loadConfig() override;
|
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
|
||||||
|
|
||||||
string bankState() override;
|
|
||||||
|
|
||||||
// start of functions for Cartridge RAM tab
|
|
||||||
uInt32 internalRamSize() override;
|
|
||||||
uInt32 internalRamRPort(int start) override;
|
|
||||||
string internalRamDescription() override;
|
|
||||||
const ByteArray& internalRamOld(int start, int count) override;
|
|
||||||
const ByteArray& internalRamCurrent(int start, int count) override;
|
|
||||||
void internalRamSetValue(int addr, uInt8 value) override;
|
|
||||||
uInt8 internalRamGetValue(int addr) override;
|
|
||||||
string internalRamLabel(int addr) override;
|
|
||||||
// end of functions for Cartridge RAM tab
|
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeF8SCWidget() = delete;
|
CartridgeF8SCWidget() = delete;
|
||||||
CartridgeF8SCWidget(const CartridgeF8SCWidget&) = delete;
|
CartridgeF8SCWidget(const CartridgeF8SCWidget&) = delete;
|
||||||
|
|
|
@ -16,79 +16,24 @@
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "CartF8.hxx"
|
#include "CartF8.hxx"
|
||||||
#include "PopUpWidget.hxx"
|
|
||||||
#include "CartF8Widget.hxx"
|
#include "CartF8Widget.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CartridgeF8Widget::CartridgeF8Widget(
|
CartridgeF8Widget::CartridgeF8Widget(
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h, CartridgeF8& cart)
|
int x, int y, int w, int h, CartridgeF8& cart)
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||||
myCart(cart)
|
|
||||||
{
|
{
|
||||||
uInt16 size = 2 * 4096;
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string CartridgeF8Widget::description()
|
||||||
|
{
|
||||||
ostringstream info;
|
ostringstream info;
|
||||||
info << "Standard F8 cartridge, two 4K banks\n"
|
|
||||||
<< "Startup bank = " << cart.startBank() << " or undetermined\n";
|
|
||||||
|
|
||||||
// Eventually, we should query this from the debugger/disassembler
|
info << "Standard F8 cartridge, two 4K banks\n";
|
||||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0xFF8; i < 2; ++i, offset += 0x1000)
|
info << CartridgeEnhancedWidget::description();
|
||||||
{
|
|
||||||
uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset];
|
|
||||||
start -= start % 0x1000;
|
|
||||||
info << "Bank " << i << " @ $" << Common::Base::HEX4 << start << " - "
|
|
||||||
<< "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
int xpos = 2,
|
return info.str();
|
||||||
ypos = addBaseInformation(size, "Atari", info.str()) + myLineHeight;
|
|
||||||
|
|
||||||
VariantList items;
|
|
||||||
VarList::push_back(items, "0 ($FFF8)");
|
|
||||||
VarList::push_back(items, "1 ($FFF9)");
|
|
||||||
myBank =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("0 ($FFFx)"),
|
|
||||||
myLineHeight, items, "Set bank ",
|
|
||||||
0, kBankChanged);
|
|
||||||
myBank->setTarget(this);
|
|
||||||
addFocusWidget(myBank);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeF8Widget::loadConfig()
|
|
||||||
{
|
|
||||||
Debugger& dbg = instance().debugger();
|
|
||||||
CartDebug& cart = dbg.cartDebug();
|
|
||||||
const CartState& state = static_cast<const CartState&>(cart.getState());
|
|
||||||
const CartState& oldstate = static_cast<const CartState&>(cart.getOldState());
|
|
||||||
|
|
||||||
myBank->setSelectedIndex(myCart.getBank(), state.bank != oldstate.bank);
|
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeF8Widget::handleCommand(CommandSender* sender,
|
|
||||||
int cmd, int data, int id)
|
|
||||||
{
|
|
||||||
if(cmd == kBankChanged)
|
|
||||||
{
|
|
||||||
myCart.unlockBank();
|
|
||||||
myCart.bank(myBank->getSelected());
|
|
||||||
myCart.lockBank();
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeF8Widget::bankState()
|
|
||||||
{
|
|
||||||
ostringstream& buf = buffer();
|
|
||||||
|
|
||||||
static constexpr std::array<const char*, 2> spot = { "$FFF8", "$FFF9" };
|
|
||||||
buf << "Bank = " << std::dec << myCart.getBank()
|
|
||||||
<< ", hotspot = " << spot[myCart.getBank()];
|
|
||||||
|
|
||||||
return buf.str();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,9 +21,9 @@
|
||||||
class CartridgeF8;
|
class CartridgeF8;
|
||||||
class PopUpWidget;
|
class PopUpWidget;
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
#include "CartEnhancedWidget.hxx"
|
||||||
|
|
||||||
class CartridgeF8Widget : public CartDebugWidget
|
class CartridgeF8Widget : public CartridgeEnhancedWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CartridgeF8Widget(GuiObject* boss, const GUI::Font& lfont,
|
CartridgeF8Widget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
|
@ -33,17 +33,11 @@ class CartridgeF8Widget : public CartDebugWidget
|
||||||
virtual ~CartridgeF8Widget() = default;
|
virtual ~CartridgeF8Widget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CartridgeF8& myCart;
|
string manufacturer() override { return "Atari"; }
|
||||||
PopUpWidget* myBank{nullptr};
|
|
||||||
|
|
||||||
enum { kBankChanged = 'bkCH' };
|
string description() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void loadConfig() override;
|
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
|
||||||
|
|
||||||
string bankState() override;
|
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeF8Widget() = delete;
|
CartridgeF8Widget() = delete;
|
||||||
CartridgeF8Widget(const CartridgeF8Widget&) = delete;
|
CartridgeF8Widget(const CartridgeF8Widget&) = delete;
|
||||||
|
|
|
@ -15,65 +15,26 @@
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "Debugger.hxx"
|
|
||||||
#include "CartDebug.hxx"
|
|
||||||
#include "CartFA2.hxx"
|
#include "CartFA2.hxx"
|
||||||
#include "PopUpWidget.hxx"
|
|
||||||
#include "CartFA2Widget.hxx"
|
#include "CartFA2Widget.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CartridgeFA2Widget::CartridgeFA2Widget(
|
CartridgeFA2Widget::CartridgeFA2Widget(
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h, CartridgeFA2& cart)
|
int x, int y, int w, int h, CartridgeFA2& cart)
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart),
|
||||||
myCart(cart)
|
myCartFA2(cart)
|
||||||
{
|
{
|
||||||
size_t size = cart.mySize;
|
|
||||||
|
|
||||||
ostringstream info;
|
|
||||||
info << "Modified FA RAM+, six or seven 4K banks\n"
|
|
||||||
<< "256 bytes RAM @ $F000 - $F1FF\n"
|
|
||||||
<< " $F100 - $F1FF (R), $F000 - $F0FF (W)\n"
|
|
||||||
<< "RAM can be loaded/saved to Harmony flash by accessing $FFF4\n"
|
|
||||||
<< "Startup bank = " << cart.startBank() << " or undetermined\n";
|
|
||||||
|
|
||||||
// Eventually, we should query this from the debugger/disassembler
|
|
||||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0xFF5; i < cart.bankCount();
|
|
||||||
++i, offset += 0x1000)
|
|
||||||
{
|
|
||||||
uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset];
|
|
||||||
start -= start % 0x1000;
|
|
||||||
info << "Bank " << i << " @ $" << Common::Base::HEX4 << (start + 0x200) << " - "
|
|
||||||
<< "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
int xpos = 2,
|
int xpos = 2,
|
||||||
ypos = addBaseInformation(size, "Chris D. Walton (Star Castle 2600)",
|
ypos = initialize();
|
||||||
info.str(), 15) + myLineHeight;
|
|
||||||
|
|
||||||
VariantList items;
|
ypos += 12;
|
||||||
VarList::push_back(items, "0 ($FFF5)");
|
|
||||||
VarList::push_back(items, "1 ($FFF6)");
|
|
||||||
VarList::push_back(items, "2 ($FFF7)");
|
|
||||||
VarList::push_back(items, "3 ($FFF8)");
|
|
||||||
VarList::push_back(items, "4 ($FFF9)");
|
|
||||||
VarList::push_back(items, "5 ($FFFA)");
|
|
||||||
if(cart.bankCount() == 7)
|
|
||||||
VarList::push_back(items, "6 ($FFFB)");
|
|
||||||
|
|
||||||
myBank =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("0 ($FFFx)"),
|
|
||||||
myLineHeight, items, "Set bank ",
|
|
||||||
0, kBankChanged);
|
|
||||||
myBank->setTarget(this);
|
|
||||||
addFocusWidget(myBank);
|
|
||||||
ypos += myLineHeight + 20;
|
|
||||||
|
|
||||||
const int bwidth = _font.getStringWidth("Erase") + 20;
|
const int bwidth = _font.getStringWidth("Erase") + 20;
|
||||||
|
|
||||||
StaticTextWidget* t = new StaticTextWidget(boss, _font, xpos, ypos,
|
StaticTextWidget* t = new StaticTextWidget(boss, _font, xpos, ypos,
|
||||||
_font.getStringWidth("Harmony Flash "),
|
_font.getStringWidth("Harmony flash memory "),
|
||||||
myFontHeight, "Harmony Flash ", TextAlign::Left);
|
myFontHeight, "Harmony flash memory ", TextAlign::Left);
|
||||||
|
|
||||||
xpos += t->getWidth() + 4;
|
xpos += t->getWidth() + 4;
|
||||||
myFlashErase =
|
myFlashErase =
|
||||||
|
@ -98,22 +59,16 @@ CartridgeFA2Widget::CartridgeFA2Widget(
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeFA2Widget::saveOldState()
|
string CartridgeFA2Widget::description()
|
||||||
{
|
{
|
||||||
myOldState.internalram.clear();
|
ostringstream info;
|
||||||
|
|
||||||
for(uInt32 i = 0; i < internalRamSize(); ++i)
|
info << "Modified FA RAM+, six or seven 4K banks\n";
|
||||||
myOldState.internalram.push_back(myCart.myRAM[i]);
|
info << "RAM+ can be loaded/saved to Harmony flash memory by accessing $"
|
||||||
|
<< Common::Base::HEX4 << 0xFFF4 << "\n";
|
||||||
|
info << CartridgeEnhancedWidget::description();
|
||||||
|
|
||||||
myOldState.bank = myCart.getBank();
|
return info.str();
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeFA2Widget::loadConfig()
|
|
||||||
{
|
|
||||||
myBank->setSelectedIndex(myCart.getBank(), myCart.getBank() != myOldState.bank);
|
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -122,99 +77,19 @@ void CartridgeFA2Widget::handleCommand(CommandSender* sender,
|
||||||
{
|
{
|
||||||
switch(cmd)
|
switch(cmd)
|
||||||
{
|
{
|
||||||
case kBankChanged:
|
|
||||||
myCart.unlockBank();
|
|
||||||
myCart.bank(myBank->getSelected());
|
|
||||||
myCart.lockBank();
|
|
||||||
invalidate();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kFlashErase:
|
case kFlashErase:
|
||||||
myCart.flash(0);
|
myCartFA2.flash(0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kFlashLoad:
|
case kFlashLoad:
|
||||||
myCart.flash(1);
|
myCartFA2.flash(1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kFlashSave:
|
case kFlashSave:
|
||||||
myCart.flash(2);
|
myCartFA2.flash(2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
CartridgeEnhancedWidget::handleCommand(sender, cmd, data, id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeFA2Widget::bankState()
|
|
||||||
{
|
|
||||||
ostringstream& buf = buffer();
|
|
||||||
|
|
||||||
static constexpr std::array<const char*, 7> spot = {
|
|
||||||
"$FFF5", "$FFF6", "$FFF7", "$FFF8", "$FFF9", "$FFFA", "$FFFB"
|
|
||||||
};
|
|
||||||
buf << "Bank = " << std::dec << myCart.getBank()
|
|
||||||
<< ", hotspot = " << spot[myCart.getBank()];
|
|
||||||
|
|
||||||
return buf.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 CartridgeFA2Widget::internalRamSize()
|
|
||||||
{
|
|
||||||
return 256;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 CartridgeFA2Widget::internalRamRPort(int start)
|
|
||||||
{
|
|
||||||
return 0xF100 + start;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeFA2Widget::internalRamDescription()
|
|
||||||
{
|
|
||||||
ostringstream desc;
|
|
||||||
desc << "$F000 - $F0FF used for Write Access\n"
|
|
||||||
<< "$F100 - $F1FF used for Read Access";
|
|
||||||
|
|
||||||
return desc.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const ByteArray& CartridgeFA2Widget::internalRamOld(int start, int count)
|
|
||||||
{
|
|
||||||
myRamOld.clear();
|
|
||||||
for(int i = 0; i < count; i++)
|
|
||||||
myRamOld.push_back(myOldState.internalram[start + i]);
|
|
||||||
return myRamOld;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const ByteArray& CartridgeFA2Widget::internalRamCurrent(int start, int count)
|
|
||||||
{
|
|
||||||
myRamCurrent.clear();
|
|
||||||
for(int i = 0; i < count; i++)
|
|
||||||
myRamCurrent.push_back(myCart.myRAM[start + i]);
|
|
||||||
return myRamCurrent;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeFA2Widget::internalRamSetValue(int addr, uInt8 value)
|
|
||||||
{
|
|
||||||
myCart.myRAM[addr] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt8 CartridgeFA2Widget::internalRamGetValue(int addr)
|
|
||||||
{
|
|
||||||
return myCart.myRAM[addr];
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeFA2Widget::internalRamLabel(int addr)
|
|
||||||
{
|
|
||||||
CartDebug& dbg = instance().debugger().cartDebug();
|
|
||||||
return dbg.getLabel(addr + 0xF100, false);
|
|
||||||
}
|
|
||||||
|
|
|
@ -20,11 +20,10 @@
|
||||||
|
|
||||||
class CartridgeFA2;
|
class CartridgeFA2;
|
||||||
class ButtonWidget;
|
class ButtonWidget;
|
||||||
class PopUpWidget;
|
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
#include "CartEnhancedWidget.hxx"
|
||||||
|
|
||||||
class CartridgeFA2Widget : public CartDebugWidget
|
class CartridgeFA2Widget : public CartridgeEnhancedWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CartridgeFA2Widget(GuiObject* boss, const GUI::Font& lfont,
|
CartridgeFA2Widget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
|
@ -34,41 +33,25 @@ class CartridgeFA2Widget : public CartDebugWidget
|
||||||
virtual ~CartridgeFA2Widget() = default;
|
virtual ~CartridgeFA2Widget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CartridgeFA2& myCart;
|
CartridgeFA2& myCartFA2;
|
||||||
PopUpWidget* myBank{nullptr};
|
|
||||||
ButtonWidget *myFlashErase{nullptr}, *myFlashLoad{nullptr}, *myFlashSave{nullptr};
|
ButtonWidget *myFlashErase{nullptr}, *myFlashLoad{nullptr}, *myFlashSave{nullptr};
|
||||||
|
|
||||||
struct CartState {
|
|
||||||
ByteArray internalram;
|
|
||||||
uInt16 bank{0};
|
|
||||||
};
|
|
||||||
CartState myOldState;
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
kBankChanged = 'bkCH',
|
|
||||||
kFlashErase = 'flER',
|
kFlashErase = 'flER',
|
||||||
kFlashLoad = 'flLD',
|
kFlashLoad = 'flLD',
|
||||||
kFlashSave = 'flSV'
|
kFlashSave = 'flSV'
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void saveOldState() override;
|
string manufacturer() override { return "Chris D. Walton (Star Castle 2600 Arcade)"; }
|
||||||
void loadConfig() override;
|
|
||||||
|
string description() override;
|
||||||
|
|
||||||
|
private:
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
||||||
|
|
||||||
string bankState() override;
|
private:
|
||||||
|
|
||||||
// start of functions for Cartridge RAM tab
|
|
||||||
uInt32 internalRamSize() override;
|
|
||||||
uInt32 internalRamRPort(int start) override;
|
|
||||||
string internalRamDescription() override;
|
|
||||||
const ByteArray& internalRamOld(int start, int count) override;
|
|
||||||
const ByteArray& internalRamCurrent(int start, int count) override;
|
|
||||||
void internalRamSetValue(int addr, uInt8 value) override;
|
|
||||||
uInt8 internalRamGetValue(int addr) override;
|
|
||||||
string internalRamLabel(int addr) override;
|
|
||||||
// end of functions for Cartridge RAM tab
|
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeFA2Widget() = delete;
|
CartridgeFA2Widget() = delete;
|
||||||
CartridgeFA2Widget(const CartridgeFA2Widget&) = delete;
|
CartridgeFA2Widget(const CartridgeFA2Widget&) = delete;
|
||||||
|
|
|
@ -15,150 +15,25 @@
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "Debugger.hxx"
|
|
||||||
#include "CartDebug.hxx"
|
|
||||||
#include "CartFA.hxx"
|
#include "CartFA.hxx"
|
||||||
#include "PopUpWidget.hxx"
|
|
||||||
#include "CartFAWidget.hxx"
|
#include "CartFAWidget.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CartridgeFAWidget::CartridgeFAWidget(
|
CartridgeFAWidget::CartridgeFAWidget(
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h, CartridgeFA& cart)
|
int x, int y, int w, int h, CartridgeFA& cart)
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||||
myCart(cart)
|
|
||||||
{
|
{
|
||||||
uInt16 size = 3 * 4096;
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string CartridgeFAWidget::description()
|
||||||
|
{
|
||||||
ostringstream info;
|
ostringstream info;
|
||||||
info << "CBS RAM+ FA cartridge, three 4K banks\n"
|
|
||||||
<< "256 bytes RAM @ $F000 - $F1FF\n"
|
|
||||||
<< " $F100 - $F1FF (R), $F000 - $F0FF (W)\n"
|
|
||||||
<< "Startup bank = " << cart.startBank() << " or undetermined\n";
|
|
||||||
|
|
||||||
// Eventually, we should query this from the debugger/disassembler
|
info << "CBS RAM+ FA cartridge, three 4K banks\n";
|
||||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0xFF8; i < 3; ++i, offset += 0x1000)
|
info << CartridgeEnhancedWidget::description();
|
||||||
{
|
|
||||||
uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset];
|
|
||||||
start -= start % 0x1000;
|
|
||||||
info << "Bank " << i << " @ $" << Common::Base::HEX4 << (start + 0x200) << " - "
|
|
||||||
<< "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
int xpos = 2,
|
return info.str();
|
||||||
ypos = addBaseInformation(size, "CBS", info.str()) + myLineHeight;
|
|
||||||
|
|
||||||
VariantList items;
|
|
||||||
VarList::push_back(items, "0 ($FFF8)");
|
|
||||||
VarList::push_back(items, "1 ($FFF9)");
|
|
||||||
VarList::push_back(items, "2 ($FFFA)");
|
|
||||||
myBank =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("0 ($FFFx)"),
|
|
||||||
myLineHeight, items, "Set bank ",
|
|
||||||
0, kBankChanged);
|
|
||||||
myBank->setTarget(this);
|
|
||||||
addFocusWidget(myBank);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeFAWidget::saveOldState()
|
|
||||||
{
|
|
||||||
myOldState.internalram.clear();
|
|
||||||
|
|
||||||
for(uInt32 i = 0; i < internalRamSize(); ++i)
|
|
||||||
myOldState.internalram.push_back(myCart.myRAM[i]);
|
|
||||||
|
|
||||||
myOldState.bank = myCart.getBank();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeFAWidget::loadConfig()
|
|
||||||
{
|
|
||||||
myBank->setSelectedIndex(myCart.getBank(), myCart.getBank() != myOldState.bank);
|
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeFAWidget::handleCommand(CommandSender* sender,
|
|
||||||
int cmd, int data, int id)
|
|
||||||
{
|
|
||||||
if(cmd == kBankChanged)
|
|
||||||
{
|
|
||||||
myCart.unlockBank();
|
|
||||||
myCart.bank(myBank->getSelected());
|
|
||||||
myCart.lockBank();
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeFAWidget::bankState()
|
|
||||||
{
|
|
||||||
ostringstream& buf = buffer();
|
|
||||||
|
|
||||||
static constexpr std::array<const char*, 3> spot = { "$FFF8", "$FFF9", "$FFFA" };
|
|
||||||
buf << "Bank = " << std::dec << myCart.getBank()
|
|
||||||
<< ", hotspot = " << spot[myCart.getBank()];
|
|
||||||
|
|
||||||
return buf.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 CartridgeFAWidget::internalRamSize()
|
|
||||||
{
|
|
||||||
return 256;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 CartridgeFAWidget::internalRamRPort(int start)
|
|
||||||
{
|
|
||||||
return 0xF100 + start;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeFAWidget::internalRamDescription()
|
|
||||||
{
|
|
||||||
ostringstream desc;
|
|
||||||
desc << "$F000 - $F0FF used for Write Access\n"
|
|
||||||
<< "$F100 - $F1FF used for Read Access";
|
|
||||||
|
|
||||||
return desc.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const ByteArray& CartridgeFAWidget::internalRamOld(int start, int count)
|
|
||||||
{
|
|
||||||
myRamOld.clear();
|
|
||||||
for(int i = 0; i < count; i++)
|
|
||||||
myRamOld.push_back(myOldState.internalram[start + i]);
|
|
||||||
return myRamOld;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const ByteArray& CartridgeFAWidget::internalRamCurrent(int start, int count)
|
|
||||||
{
|
|
||||||
myRamCurrent.clear();
|
|
||||||
for(int i = 0; i < count; i++)
|
|
||||||
myRamCurrent.push_back(myCart.myRAM[start + i]);
|
|
||||||
return myRamCurrent;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeFAWidget::internalRamSetValue(int addr, uInt8 value)
|
|
||||||
{
|
|
||||||
myCart.myRAM[addr] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt8 CartridgeFAWidget::internalRamGetValue(int addr)
|
|
||||||
{
|
|
||||||
return myCart.myRAM[addr];
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeFAWidget::internalRamLabel(int addr)
|
|
||||||
{
|
|
||||||
CartDebug& dbg = instance().debugger().cartDebug();
|
|
||||||
return dbg.getLabel(addr + 0xF100, false);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,10 @@
|
||||||
#define CARTRIDGEFA_WIDGET_HXX
|
#define CARTRIDGEFA_WIDGET_HXX
|
||||||
|
|
||||||
class CartridgeFA;
|
class CartridgeFA;
|
||||||
class PopUpWidget;
|
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
#include "CartEnhancedWidget.hxx"
|
||||||
|
|
||||||
class CartridgeFAWidget : public CartDebugWidget
|
class CartridgeFAWidget : public CartridgeEnhancedWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CartridgeFAWidget(GuiObject* boss, const GUI::Font& lfont,
|
CartridgeFAWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
|
@ -33,35 +32,11 @@ class CartridgeFAWidget : public CartDebugWidget
|
||||||
virtual ~CartridgeFAWidget() = default;
|
virtual ~CartridgeFAWidget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CartridgeFA& myCart;
|
string manufacturer() override { return "CBS"; }
|
||||||
PopUpWidget* myBank{nullptr};
|
|
||||||
|
|
||||||
struct CartState {
|
string description() override;
|
||||||
ByteArray internalram;
|
|
||||||
uInt16 bank{0};
|
|
||||||
};
|
|
||||||
CartState myOldState;
|
|
||||||
|
|
||||||
enum { kBankChanged = 'bkCH' };
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void saveOldState() override;
|
|
||||||
void loadConfig() override;
|
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
|
||||||
|
|
||||||
string bankState() override;
|
|
||||||
|
|
||||||
// start of functions for Cartridge RAM tab
|
|
||||||
uInt32 internalRamSize() override;
|
|
||||||
uInt32 internalRamRPort(int start) override;
|
|
||||||
string internalRamDescription() override;
|
|
||||||
const ByteArray& internalRamOld(int start, int count) override;
|
|
||||||
const ByteArray& internalRamCurrent(int start, int count) override;
|
|
||||||
void internalRamSetValue(int addr, uInt8 value) override;
|
|
||||||
uInt8 internalRamGetValue(int addr) override;
|
|
||||||
string internalRamLabel(int addr) override;
|
|
||||||
// end of functions for Cartridge RAM tab
|
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeFAWidget() = delete;
|
CartridgeFAWidget() = delete;
|
||||||
CartridgeFAWidget(const CartridgeFAWidget&) = delete;
|
CartridgeFAWidget(const CartridgeFAWidget&) = delete;
|
||||||
|
|
|
@ -16,80 +16,44 @@
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "CartFC.hxx"
|
#include "CartFC.hxx"
|
||||||
#include "PopUpWidget.hxx"
|
|
||||||
#include "CartFCWidget.hxx"
|
#include "CartFCWidget.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CartridgeFCWidget::CartridgeFCWidget(
|
CartridgeFCWidget::CartridgeFCWidget(
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h, CartridgeFC& cart)
|
int x, int y, int w, int h, CartridgeFC& cart)
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||||
myCart(cart)
|
|
||||||
{
|
{
|
||||||
uInt16 size = cart.bankCount() * 4096;
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string CartridgeFCWidget::description()
|
||||||
|
{
|
||||||
ostringstream info;
|
ostringstream info;
|
||||||
info << "FC cartridge, up to eight 4K banks\n"
|
uInt16 hotspot = myCart.hotspot() | ADDR_BASE;
|
||||||
<< "Startup bank = " << cart.startBank() << " or undetermined\n";
|
|
||||||
|
|
||||||
// Eventually, we should query this from the debugger/disassembler
|
info << "FC cartridge, up to eight 4K banks\n";
|
||||||
info << "Bank selected by hotspots\n"
|
info << "Bank selected by hotspots\n"
|
||||||
<< " $FFF8 (defines low 2 bits)\n"
|
<< " $" << Common::Base::HEX4 << hotspot << " (defines low 2 bits)\n"
|
||||||
<< " $FFF9 (defines high bits)\n"
|
<< " $" << Common::Base::HEX4 << (hotspot + 1) << " (defines high bits)\n"
|
||||||
<< " $FFFC (triggers bank switch)";
|
<< " $" << Common::Base::HEX4 << (hotspot + 4) << " (triggers bank switch)\n";
|
||||||
|
|
||||||
int xpos = 2,
|
info << CartridgeEnhancedWidget::description();
|
||||||
ypos = addBaseInformation(size, "Amiga Corp.", info.str()) + myLineHeight;
|
|
||||||
|
|
||||||
VariantList items;
|
return info.str();
|
||||||
for (uInt16 i = 0; i < cart.bankCount(); ++i)
|
|
||||||
VarList::push_back(items, Variant(i).toString() +
|
|
||||||
" ($FFF8 = " + Variant(i & 0b11).toString() +
|
|
||||||
"/$FFF9 = " + Variant(i >> 2).toString() +")");
|
|
||||||
|
|
||||||
myBank = new PopUpWidget(boss, _font, xpos, ypos - 2,
|
|
||||||
_font.getStringWidth("7 ($FFF8 = 3/$FFF9 = 1)"),
|
|
||||||
myLineHeight, items, "Set bank ",
|
|
||||||
0, kBankChanged);
|
|
||||||
myBank->setTarget(this);
|
|
||||||
addFocusWidget(myBank);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeFCWidget::loadConfig()
|
string CartridgeFCWidget::hotspotStr(int bank, int, bool prefix)
|
||||||
{
|
{
|
||||||
Debugger& dbg = instance().debugger();
|
ostringstream info;
|
||||||
CartDebug& cart = dbg.cartDebug();
|
uInt16 hotspot = myCart.hotspot() | ADDR_BASE;
|
||||||
const CartState& state = static_cast<const CartState&>(cart.getState());
|
|
||||||
const CartState& oldstate = static_cast<const CartState&>(cart.getOldState());
|
|
||||||
|
|
||||||
myBank->setSelectedIndex(myCart.getBank(), state.bank != oldstate.bank);
|
info << "(" << (prefix ? "hotspots " : "");
|
||||||
|
info << "$" << Common::Base::HEX4 << hotspot << " = " << (bank & 0b11);
|
||||||
|
info << ", $" << Common::Base::HEX4 << (hotspot + 1) << " = " << (bank >> 2);
|
||||||
|
info << ")";
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
return info.str();
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeFCWidget::handleCommand(CommandSender* sender,
|
|
||||||
int cmd, int data, int id)
|
|
||||||
{
|
|
||||||
if (cmd == kBankChanged)
|
|
||||||
{
|
|
||||||
myCart.unlockBank();
|
|
||||||
myCart.bank(myBank->getSelected());
|
|
||||||
myCart.lockBank();
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeFCWidget::bankState()
|
|
||||||
{
|
|
||||||
ostringstream& buf = buffer();
|
|
||||||
uInt16 bank = myCart.getBank();
|
|
||||||
|
|
||||||
buf << "Bank = #" << std::dec << bank
|
|
||||||
<< ", hotspots $FFF8 = " << (bank & 0b11)
|
|
||||||
<< "/$FF99 = " << (bank >> 2);
|
|
||||||
|
|
||||||
return buf.str();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,10 @@
|
||||||
#define CARTRIDGEFC_WIDGET_HXX
|
#define CARTRIDGEFC_WIDGET_HXX
|
||||||
|
|
||||||
class CartridgeFC;
|
class CartridgeFC;
|
||||||
class PopUpWidget;
|
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
#include "CartEnhancedWidget.hxx"
|
||||||
|
|
||||||
class CartridgeFCWidget : public CartDebugWidget
|
class CartridgeFCWidget : public CartridgeEnhancedWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CartridgeFCWidget(GuiObject* boss, const GUI::Font& lfont,
|
CartridgeFCWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
|
@ -33,17 +32,13 @@ class CartridgeFCWidget : public CartDebugWidget
|
||||||
virtual ~CartridgeFCWidget() = default;
|
virtual ~CartridgeFCWidget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CartridgeFC& myCart;
|
string manufacturer() override { return "Amiga Corp."; }
|
||||||
PopUpWidget* myBank{nullptr};
|
|
||||||
|
|
||||||
enum { kBankChanged = 'bkCH' };
|
string description() override;
|
||||||
|
|
||||||
|
string hotspotStr(int bank, int seg = 0, bool prefix = false) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void loadConfig() override;
|
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
|
||||||
|
|
||||||
string bankState() override;
|
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeFCWidget() = delete;
|
CartridgeFCWidget() = delete;
|
||||||
CartridgeFCWidget(const CartridgeFCWidget&) = delete;
|
CartridgeFCWidget(const CartridgeFCWidget&) = delete;
|
||||||
|
|
|
@ -16,72 +16,36 @@
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "CartFE.hxx"
|
#include "CartFE.hxx"
|
||||||
#include "PopUpWidget.hxx"
|
|
||||||
#include "CartFEWidget.hxx"
|
#include "CartFEWidget.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CartridgeFEWidget::CartridgeFEWidget(
|
CartridgeFEWidget::CartridgeFEWidget(
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h, CartridgeFE& cart)
|
int x, int y, int w, int h, CartridgeFE& cart)
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||||
myCart(cart)
|
|
||||||
{
|
{
|
||||||
string info =
|
initialize();
|
||||||
"FE cartridge, two 4K banks\n"
|
|
||||||
"Monitors access to hotspot $01FE, and uses "
|
|
||||||
"upper 3 bits of databus for bank number:\n"
|
|
||||||
"Bank 0 @ $F000 - $FFFF (DATA = 111, D5 = 1)\n"
|
|
||||||
"Bank 1 @ $D000 - $DFFF (DATA = 110, D5 = 0)\n";
|
|
||||||
|
|
||||||
int xpos = 2,
|
|
||||||
ypos = addBaseInformation(2 * 4096, "Activision", info) + myLineHeight;
|
|
||||||
|
|
||||||
VariantList items;
|
|
||||||
VarList::push_back(items, "0 ($01FE, D5=1)");
|
|
||||||
VarList::push_back(items, "1 ($01FE, D5=0)");
|
|
||||||
myBank =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2,
|
|
||||||
_font.getStringWidth("0 ($01FE, D5=1)"),
|
|
||||||
myLineHeight, items, "Set bank ",
|
|
||||||
0, kBankChanged);
|
|
||||||
myBank->setTarget(this);
|
|
||||||
addFocusWidget(myBank);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeFEWidget::loadConfig()
|
string CartridgeFEWidget::description()
|
||||||
{
|
{
|
||||||
Debugger& dbg = instance().debugger();
|
ostringstream info;
|
||||||
CartDebug& cart = dbg.cartDebug();
|
|
||||||
const CartState& state = static_cast<const CartState&>(cart.getState());
|
|
||||||
const CartState& oldstate = static_cast<const CartState&>(cart.getOldState());
|
|
||||||
|
|
||||||
myBank->setSelectedIndex(myCart.getBank(), state.bank != oldstate.bank);
|
info << "FE cartridge, two 4K banks\n"
|
||||||
|
<< "Monitors access to hotspot $01FE, and uses "
|
||||||
|
<< "upper 3 bits of databus for bank number:\n";
|
||||||
|
info << CartridgeEnhancedWidget::description();
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
return info.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeFEWidget::handleCommand(CommandSender* sender,
|
string CartridgeFEWidget::hotspotStr(int bank, int, bool)
|
||||||
int cmd, int data, int id)
|
|
||||||
{
|
{
|
||||||
if(cmd == kBankChanged)
|
ostringstream info;
|
||||||
{
|
|
||||||
myCart.unlockBank();
|
info << "(DATA = 11" << !bank << ", D5 = " << !bank << ")";
|
||||||
myCart.bank(myBank->getSelected());
|
|
||||||
myCart.lockBank();
|
return info.str();
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeFEWidget::bankState()
|
|
||||||
{
|
|
||||||
ostringstream& buf = buffer();
|
|
||||||
|
|
||||||
static constexpr std::array<const char*, 2> range = { "$F000", "$D000" };
|
|
||||||
buf << "Bank = " << std::dec << myCart.getBank()
|
|
||||||
<< ", address range = " << range[myCart.getBank()];
|
|
||||||
|
|
||||||
return buf.str();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,10 @@
|
||||||
#define CARTRIDGEFE_WIDGET_HXX
|
#define CARTRIDGEFE_WIDGET_HXX
|
||||||
|
|
||||||
class CartridgeFE;
|
class CartridgeFE;
|
||||||
class PopUpWidget;
|
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
#include "CartEnhancedWidget.hxx"
|
||||||
|
|
||||||
class CartridgeFEWidget : public CartDebugWidget
|
class CartridgeFEWidget : public CartridgeEnhancedWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CartridgeFEWidget(GuiObject* boss, const GUI::Font& lfont,
|
CartridgeFEWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
|
@ -33,18 +32,13 @@ class CartridgeFEWidget : public CartDebugWidget
|
||||||
virtual ~CartridgeFEWidget() = default;
|
virtual ~CartridgeFEWidget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CartridgeFE& myCart;
|
string manufacturer() override { return "Activision"; }
|
||||||
PopUpWidget* myBank{nullptr};
|
|
||||||
|
|
||||||
enum { kBankChanged = 'bkCH' };
|
string description() override;
|
||||||
|
|
||||||
|
string hotspotStr(int bank, int, bool) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// No implementation for non-bankswitched ROMs
|
|
||||||
void loadConfig() override;
|
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
|
||||||
|
|
||||||
string bankState() override;
|
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeFEWidget() = delete;
|
CartridgeFEWidget() = delete;
|
||||||
CartridgeFEWidget(const CartridgeFEWidget&) = delete;
|
CartridgeFEWidget(const CartridgeFEWidget&) = delete;
|
||||||
|
|
|
@ -17,44 +17,39 @@
|
||||||
|
|
||||||
#include "CartMDM.hxx"
|
#include "CartMDM.hxx"
|
||||||
#include "PopUpWidget.hxx"
|
#include "PopUpWidget.hxx"
|
||||||
#include "Widget.hxx"
|
|
||||||
#include "CartMDMWidget.hxx"
|
#include "CartMDMWidget.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CartridgeMDMWidget::CartridgeMDMWidget(
|
CartridgeMDMWidget::CartridgeMDMWidget(
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h, CartridgeMDM& cart)
|
int x, int y, int w, int h, CartridgeMDM& cart)
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart),
|
||||||
myCart(cart)
|
myCartMDM(cart)
|
||||||
{
|
{
|
||||||
size_t size = myCart.mySize;
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string CartridgeMDMWidget::description()
|
||||||
|
{
|
||||||
ostringstream info;
|
ostringstream info;
|
||||||
info << "Menu Driven Megacart, containing up to 128 4K banks\n"
|
|
||||||
<< "Startup bank = " << cart.startBank() << "\n"
|
|
||||||
<< "\nBanks are selected by reading from $800 - $BFF, where the lower "
|
|
||||||
"byte determines the 4K bank to use.";
|
|
||||||
|
|
||||||
int xpos = 2,
|
info << "Menu Driven Megacart, " << myCart.romBankCount() << " 4K banks\n"
|
||||||
ypos = addBaseInformation(size, "Edwin Blink", info.str(), 15) + myLineHeight;
|
<< "Banks are selected by reading from $800 - $" << Common::Base::HEX1 << 0xBFF
|
||||||
|
<< ", where the lower byte determines the 4K bank to use.\n";
|
||||||
|
info << CartridgeEnhancedWidget::description();
|
||||||
|
|
||||||
VariantList items;
|
return info.str();
|
||||||
for(uInt32 i = 0x800; i < (0x800U + myCart.bankCount()); ++i)
|
}
|
||||||
{
|
|
||||||
info.str("");
|
|
||||||
info << std::dec << (i & 0xFF) << " ($" << Common::Base::HEX4 << i << ")";
|
|
||||||
VarList::push_back(items, info.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
myBank =
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
new PopUpWidget(boss, _font, xpos, ypos, _font.getStringWidth("xxx ($0FFF)"),
|
void CartridgeMDMWidget::bankSelect(int& ypos)
|
||||||
myLineHeight, items, "Set bank ",
|
{
|
||||||
0, kBankChanged);
|
CartridgeEnhancedWidget::bankSelect(ypos);
|
||||||
myBank->setTarget(this);
|
int xpos = myBankWidgets[0]->getRight() + 20;
|
||||||
addFocusWidget(myBank);
|
ypos = myBankWidgets[0]->getTop();
|
||||||
|
|
||||||
xpos += myBank->getWidth() + 30;
|
myBankDisabled = new CheckboxWidget(_boss, _font, xpos, ypos + 1,
|
||||||
myBankDisabled = new CheckboxWidget(boss, _font, xpos, ypos + 1,
|
|
||||||
"Bankswitching is locked/disabled",
|
"Bankswitching is locked/disabled",
|
||||||
kBankDisabled);
|
kBankDisabled);
|
||||||
myBankDisabled->setTarget(this);
|
myBankDisabled->setTarget(this);
|
||||||
|
@ -64,39 +59,21 @@ CartridgeMDMWidget::CartridgeMDMWidget(
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeMDMWidget::loadConfig()
|
void CartridgeMDMWidget::loadConfig()
|
||||||
{
|
{
|
||||||
myBank->setSelectedIndex(myCart.getBank());
|
myBankWidgets[0]->setEnabled(!myCartMDM.myBankingDisabled);
|
||||||
myBank->setEnabled(!myCart.myBankingDisabled);
|
myBankDisabled->setState(myCartMDM.myBankingDisabled);
|
||||||
myBankDisabled->setState(myCart.myBankingDisabled);
|
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
CartridgeEnhancedWidget::loadConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeMDMWidget::handleCommand(CommandSender* sender,
|
void CartridgeMDMWidget::handleCommand(CommandSender* sender,
|
||||||
int cmd, int data, int id)
|
int cmd, int data, int id)
|
||||||
{
|
{
|
||||||
if(cmd == kBankChanged)
|
if(cmd == kBankDisabled)
|
||||||
{
|
{
|
||||||
myCart.unlockBank();
|
myCartMDM.myBankingDisabled = myBankDisabled->getState();
|
||||||
myCart.bank(myBank->getSelected());
|
myBankWidgets[0]->setEnabled(!myCartMDM.myBankingDisabled);
|
||||||
myCart.lockBank();
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
else if(cmd == kBankDisabled)
|
|
||||||
{
|
|
||||||
myCart.myBankingDisabled = myBankDisabled->getState();
|
|
||||||
myBank->setEnabled(!myCart.myBankingDisabled);
|
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
|
CartridgeEnhancedWidget::handleCommand(sender, cmd, data, id);
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeMDMWidget::bankState()
|
|
||||||
{
|
|
||||||
ostringstream& buf = buffer();
|
|
||||||
|
|
||||||
buf << "Bank = " << std::dec << myCart.getBank()
|
|
||||||
<< ", hotspot = " << "$" << Common::Base::HEX4
|
|
||||||
<< (myCart.getBank()+0x800);
|
|
||||||
|
|
||||||
return buf.str();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,11 +20,10 @@
|
||||||
|
|
||||||
class CartridgeMDM;
|
class CartridgeMDM;
|
||||||
class CheckboxWidget;
|
class CheckboxWidget;
|
||||||
class PopUpWidget;
|
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
#include "CartEnhancedWidget.hxx"
|
||||||
|
|
||||||
class CartridgeMDMWidget : public CartDebugWidget
|
class CartridgeMDMWidget : public CartridgeEnhancedWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CartridgeMDMWidget(GuiObject* boss, const GUI::Font& lfont,
|
CartridgeMDMWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
|
@ -34,18 +33,24 @@ class CartridgeMDMWidget : public CartDebugWidget
|
||||||
virtual ~CartridgeMDMWidget() = default;
|
virtual ~CartridgeMDMWidget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CartridgeMDM& myCart;
|
string manufacturer() override { return "Edwin Blink"; }
|
||||||
PopUpWidget* myBank{nullptr};
|
|
||||||
|
string description() override;
|
||||||
|
|
||||||
|
void bankSelect(int& ypos) override;
|
||||||
|
|
||||||
|
CartridgeMDM& myCartMDM;
|
||||||
CheckboxWidget* myBankDisabled{nullptr};
|
CheckboxWidget* myBankDisabled{nullptr};
|
||||||
|
|
||||||
enum { kBankChanged = 'bkCH', kBankDisabled = 'bkDI' };
|
enum {
|
||||||
|
kBankDisabled = 'bkDI'
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void loadConfig() override;
|
void loadConfig() override;
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
||||||
|
|
||||||
string bankState() override;
|
private:
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeMDMWidget() = delete;
|
CartridgeMDMWidget() = delete;
|
||||||
CartridgeMDMWidget(const CartridgeMDMWidget&) = delete;
|
CartridgeMDMWidget(const CartridgeMDMWidget&) = delete;
|
||||||
|
|
|
@ -35,30 +35,30 @@ CartridgeMNetworkWidget::CartridgeMNetworkWidget(
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeMNetworkWidget::initialize(GuiObject* boss, CartridgeMNetwork& cart, ostringstream& info)
|
void CartridgeMNetworkWidget::initialize(GuiObject* boss, CartridgeMNetwork& cart, ostringstream& info)
|
||||||
{
|
{
|
||||||
uInt32 size = cart.bankCount() * cart.BANK_SIZE;
|
uInt32 size = cart.romBankCount() * cart.BANK_SIZE;
|
||||||
|
|
||||||
int xpos = 2,
|
int xpos = 2,
|
||||||
ypos = addBaseInformation(size, "M-Network", info.str(), 15) +
|
ypos = addBaseInformation(size, "M-Network", info.str(), 15) +
|
||||||
myLineHeight;
|
myLineHeight;
|
||||||
|
|
||||||
VariantList items0, items1;
|
VariantList items0, items1;
|
||||||
for(int i = 0; i < cart.bankCount(); ++i)
|
for(int i = 0; i < cart.romBankCount(); ++i)
|
||||||
VarList::push_back(items0, getSpotLower(i));
|
VarList::push_back(items0, getSpotLower(i));
|
||||||
for(int i = 0; i < 4; ++i)
|
for(int i = 0; i < 4; ++i)
|
||||||
VarList::push_back(items1, getSpotUpper(i));
|
VarList::push_back(items1, getSpotUpper(i));
|
||||||
|
|
||||||
const int lwidth = _font.getStringWidth("Set slice for upper 256B "),
|
const int lwidth = _font.getStringWidth("Set bank for upper 256B segment "),
|
||||||
fwidth = _font.getStringWidth("3 - RAM ($FFEB)");
|
fwidth = _font.getStringWidth("#3 - RAM ($FFEB)");
|
||||||
myLower2K =
|
myLower2K =
|
||||||
new PopUpWidget(boss, _font, xpos, ypos - 2, fwidth, myLineHeight, items0,
|
new PopUpWidget(boss, _font, xpos, ypos - 2, fwidth, myLineHeight, items0,
|
||||||
"Set slice for lower 2K ", lwidth, kLowerChanged);
|
"Set bank for lower 2K segment", lwidth, kLowerChanged);
|
||||||
myLower2K->setTarget(this);
|
myLower2K->setTarget(this);
|
||||||
addFocusWidget(myLower2K);
|
addFocusWidget(myLower2K);
|
||||||
ypos += myLower2K->getHeight() + 4;
|
ypos += myLower2K->getHeight() + 4;
|
||||||
|
|
||||||
myUpper256B =
|
myUpper256B =
|
||||||
new PopUpWidget(boss, _font, xpos, ypos - 2, fwidth, myLineHeight, items1,
|
new PopUpWidget(boss, _font, xpos, ypos - 2, fwidth, myLineHeight, items1,
|
||||||
"Set slice for upper 256B ", lwidth, kUpperChanged);
|
"Set bank for upper 256B segment ", lwidth, kUpperChanged);
|
||||||
myUpper256B->setTarget(this);
|
myUpper256B->setTarget(this);
|
||||||
addFocusWidget(myUpper256B);
|
addFocusWidget(myUpper256B);
|
||||||
}
|
}
|
||||||
|
@ -71,14 +71,14 @@ void CartridgeMNetworkWidget::saveOldState()
|
||||||
for(uInt32 i = 0; i < internalRamSize(); ++i)
|
for(uInt32 i = 0; i < internalRamSize(); ++i)
|
||||||
myOldState.internalram.push_back(myCart.myRAM[i]);
|
myOldState.internalram.push_back(myCart.myRAM[i]);
|
||||||
|
|
||||||
myOldState.lowerBank = myCart.myCurrentSlice[0];
|
myOldState.lowerBank = myCart.myCurrentBank[0];
|
||||||
myOldState.upperBank = myCart.myCurrentRAM;
|
myOldState.upperBank = myCart.myCurrentRAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeMNetworkWidget::loadConfig()
|
void CartridgeMNetworkWidget::loadConfig()
|
||||||
{
|
{
|
||||||
myLower2K->setSelectedIndex(myCart.myCurrentSlice[0], myCart.myCurrentSlice[0] != myOldState.lowerBank);
|
myLower2K->setSelectedIndex(myCart.myCurrentBank[0], myCart.myCurrentBank[0] != myOldState.lowerBank);
|
||||||
myUpper256B->setSelectedIndex(myCart.myCurrentRAM, myCart.myCurrentRAM != myOldState.upperBank);
|
myUpper256B->setSelectedIndex(myCart.myCurrentRAM, myCart.myCurrentRAM != myOldState.upperBank);
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
CartDebugWidget::loadConfig();
|
||||||
|
@ -111,8 +111,8 @@ string CartridgeMNetworkWidget::bankState()
|
||||||
{
|
{
|
||||||
ostringstream& buf = buffer();
|
ostringstream& buf = buffer();
|
||||||
|
|
||||||
buf << "Slices: " << std::dec
|
buf << "Segments: " << std::dec
|
||||||
<< getSpotLower(myCart.myCurrentSlice[0]) << " / "
|
<< getSpotLower(myCart.myCurrentBank[0]) << " / "
|
||||||
<< getSpotUpper(myCart.myCurrentRAM);
|
<< getSpotUpper(myCart.myCurrentRAM);
|
||||||
|
|
||||||
return buf.str();
|
return buf.str();
|
||||||
|
@ -135,11 +135,11 @@ string CartridgeMNetworkWidget::internalRamDescription()
|
||||||
{
|
{
|
||||||
ostringstream desc;
|
ostringstream desc;
|
||||||
desc << "First 1K accessible via:\n"
|
desc << "First 1K accessible via:\n"
|
||||||
<< " $F000 - $F3FF used for Write Access\n"
|
<< " $F000 - $F3FF used for write access\n"
|
||||||
<< " $F400 - $F7FF used for Read Access\n"
|
<< " $F400 - $F7FF used for read access\n"
|
||||||
<< "256K of second 1K accessible via:\n"
|
<< "256 bytes of second 1K accessible via:\n"
|
||||||
<< " $F800 - $F8FF used for Write Access\n"
|
<< " $F800 - $F8FF used for write access\n"
|
||||||
<< " $F900 - $F9FF used for Read Access";
|
<< " $F900 - $F9FF used for read access";
|
||||||
|
|
||||||
return desc.str();
|
return desc.str();
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ CartRamWidget::CartRamWidget(
|
||||||
int xpos = 2, ypos = 8;
|
int xpos = 2, ypos = 8;
|
||||||
|
|
||||||
// Add RAM size
|
// Add RAM size
|
||||||
new StaticTextWidget(_boss, _font, xpos, ypos + 1, "RAM Size ");
|
new StaticTextWidget(_boss, _font, xpos, ypos + 1, "RAM size ");
|
||||||
|
|
||||||
uInt32 ramsize = cartDebug.internalRamSize();
|
uInt32 ramsize = cartDebug.internalRamSize();
|
||||||
buf << ramsize << " bytes";
|
buf << ramsize << " bytes";
|
||||||
|
@ -65,13 +65,14 @@ CartRamWidget::CartRamWidget(
|
||||||
StringParser bs(desc, (fwidth - ScrollBarWidget::scrollBarWidth(_font)) / myFontWidth);
|
StringParser bs(desc, (fwidth - ScrollBarWidget::scrollBarWidth(_font)) / myFontWidth);
|
||||||
const StringList& sl = bs.stringList();
|
const StringList& sl = bs.stringList();
|
||||||
uInt32 lines = uInt32(sl.size());
|
uInt32 lines = uInt32(sl.size());
|
||||||
if(lines < 3) lines = 3;
|
if(lines < 2) lines = 2;
|
||||||
if(lines > maxlines) lines = maxlines;
|
if(lines > maxlines) lines = maxlines;
|
||||||
|
|
||||||
new StaticTextWidget(_boss, _font, xpos, ypos + 1, "Description ");
|
new StaticTextWidget(_boss, _font, xpos, ypos + 1, "Description ");
|
||||||
myDesc = new StringListWidget(boss, nfont, xpos+lwidth, ypos - 1,
|
myDesc = new StringListWidget(boss, nfont, xpos+lwidth, ypos - 1,
|
||||||
fwidth, lines * myLineHeight, false);
|
fwidth, lines * myLineHeight, false);
|
||||||
myDesc->setEditable(false);
|
myDesc->setEditable(false);
|
||||||
|
myDesc->setEnabled(false);
|
||||||
myDesc->setList(sl);
|
myDesc->setList(sl);
|
||||||
addFocusWidget(myDesc);
|
addFocusWidget(myDesc);
|
||||||
|
|
||||||
|
|
|
@ -16,85 +16,27 @@
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "CartSB.hxx"
|
#include "CartSB.hxx"
|
||||||
#include "PopUpWidget.hxx"
|
|
||||||
#include "CartSBWidget.hxx"
|
#include "CartSBWidget.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CartridgeSBWidget::CartridgeSBWidget(
|
CartridgeSBWidget::CartridgeSBWidget(
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h, CartridgeSB& cart)
|
int x, int y, int w, int h, CartridgeSB& cart)
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||||
myCart(cart)
|
|
||||||
{
|
{
|
||||||
size_t size = myCart.mySize;
|
initialize();
|
||||||
|
|
||||||
VariantList items;
|
|
||||||
ostringstream info, bank;
|
|
||||||
info << "SB SUPERbanking, 32 or 64 4K banks\n"
|
|
||||||
<< "Hotspots are from $800 to $"
|
|
||||||
<< Common::Base::HEX2 << (0x800 + myCart.bankCount() - 1) << ", including\n"
|
|
||||||
<< "mirrors ($900, $A00, $B00, ...)\n"
|
|
||||||
<< "Startup bank = " << std::dec << cart.startBank() << "\n";
|
|
||||||
|
|
||||||
// Eventually, we should query this from the debugger/disassembler
|
|
||||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0x800; i < myCart.bankCount();
|
|
||||||
++i, offset += 0x1000, ++spot)
|
|
||||||
{
|
|
||||||
uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset];
|
|
||||||
start -= start % 0x1000;
|
|
||||||
info << "Bank " << std::dec << i << " @ $" << Common::Base::HEX4 << start << " - "
|
|
||||||
<< "$" << (start + 0xFFF) << " (hotspot = $" << spot << ")\n";
|
|
||||||
|
|
||||||
bank << std::dec << std::setw(2) << std::setfill(' ') << i << " ($"
|
|
||||||
<< Common::Base::HEX2 << spot << ")";
|
|
||||||
VarList::push_back(items, bank.str());
|
|
||||||
bank.str("");
|
|
||||||
}
|
|
||||||
|
|
||||||
int xpos = 2,
|
|
||||||
ypos = addBaseInformation(size, "Fred X. Quimby", info.str()) + myLineHeight;
|
|
||||||
|
|
||||||
myBank =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("XX ($800)"),
|
|
||||||
myLineHeight, items, "Set bank ",
|
|
||||||
0, kBankChanged);
|
|
||||||
myBank->setTarget(this);
|
|
||||||
addFocusWidget(myBank);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeSBWidget::loadConfig()
|
string CartridgeSBWidget::description()
|
||||||
{
|
{
|
||||||
Debugger& dbg = instance().debugger();
|
ostringstream info;
|
||||||
CartDebug& cart = dbg.cartDebug();
|
|
||||||
const CartState& state = static_cast<const CartState&>(cart.getState());
|
|
||||||
const CartState& oldstate = static_cast<const CartState&>(cart.getOldState());
|
|
||||||
|
|
||||||
myBank->setSelectedIndex(myCart.getBank(), state.bank != oldstate.bank);
|
info << "SB SUPERbanking, " << myCart.romBankCount() << " 4K banks\n"
|
||||||
|
<< "Hotspots are from $800 to $"
|
||||||
|
<< Common::Base::HEX2 << (0x800 + myCart.romBankCount() - 1) << ", including\n"
|
||||||
|
<< "mirrors ($900, $" << 0xA00 << ", $" << 0xB00 << ", ...)\n";
|
||||||
|
info << CartridgeEnhancedWidget::description();
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
return info.str();
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeSBWidget::handleCommand(CommandSender* sender,
|
|
||||||
int cmd, int data, int id)
|
|
||||||
{
|
|
||||||
if(cmd == kBankChanged)
|
|
||||||
{
|
|
||||||
myCart.unlockBank();
|
|
||||||
myCart.bank(myBank->getSelected());
|
|
||||||
myCart.lockBank();
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeSBWidget::bankState()
|
|
||||||
{
|
|
||||||
ostringstream& buf = buffer();
|
|
||||||
|
|
||||||
buf << "Bank = " << std::dec << myCart.getBank()
|
|
||||||
<< ", hotspot = $" << Common::Base::HEX2 << (myCart.getBank() + 0x800);
|
|
||||||
|
|
||||||
return buf.str();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,10 @@
|
||||||
#define CARTRIDGESB_WIDGET_HXX
|
#define CARTRIDGESB_WIDGET_HXX
|
||||||
|
|
||||||
class CartridgeSB;
|
class CartridgeSB;
|
||||||
class PopUpWidget;
|
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
#include "CartEnhancedWidget.hxx"
|
||||||
|
|
||||||
class CartridgeSBWidget : public CartDebugWidget
|
class CartridgeSBWidget : public CartridgeEnhancedWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CartridgeSBWidget(GuiObject* boss, const GUI::Font& lfont,
|
CartridgeSBWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
|
@ -33,17 +32,11 @@ class CartridgeSBWidget : public CartDebugWidget
|
||||||
virtual ~CartridgeSBWidget() = default;
|
virtual ~CartridgeSBWidget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CartridgeSB& myCart;
|
string manufacturer() override { return "Fred X. Quimby"; }
|
||||||
PopUpWidget* myBank{nullptr};
|
|
||||||
|
|
||||||
enum { kBankChanged = 'bkCH' };
|
string description() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void loadConfig() override;
|
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
|
||||||
|
|
||||||
string bankState() override;
|
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeSBWidget() = delete;
|
CartridgeSBWidget() = delete;
|
||||||
CartridgeSBWidget(const CartridgeSBWidget&) = delete;
|
CartridgeSBWidget(const CartridgeSBWidget&) = delete;
|
||||||
|
|
|
@ -16,89 +16,39 @@
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "CartUA.hxx"
|
#include "CartUA.hxx"
|
||||||
#include "PopUpWidget.hxx"
|
|
||||||
#include "CartUAWidget.hxx"
|
#include "CartUAWidget.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CartridgeUAWidget::CartridgeUAWidget(
|
CartridgeUAWidget::CartridgeUAWidget(
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h, CartridgeUA& cart, bool swapHotspots)
|
int x, int y, int w, int h, CartridgeUA& cart, bool swapHotspots)
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart),
|
||||||
myCart(cart),
|
|
||||||
mySwappedHotspots(swapHotspots)
|
mySwappedHotspots(swapHotspots)
|
||||||
{
|
{
|
||||||
uInt16 size = 2 * 4096;
|
myHotspotDelta = 0x20;
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string CartridgeUAWidget::description()
|
||||||
|
{
|
||||||
ostringstream info;
|
ostringstream info;
|
||||||
info << "8K UA cartridge" << (mySwappedHotspots ? " (swapped banks)" : "") << ", two 4K banks\n"
|
|
||||||
<< "Startup bank = " << cart.startBank() << " or undetermined\n";
|
|
||||||
|
|
||||||
// Eventually, we should query this from the debugger/disassembler
|
info << "8K UA cartridge" << (mySwappedHotspots ? " (swapped banks)" : "") << ", two 4K banks\n";
|
||||||
for(uInt32 i = 0, offset = 0xFFC, spot = mySwappedHotspots ? 0x240 : 0x220; i < 2;
|
info << CartridgeEnhancedWidget::description();
|
||||||
++i, offset += 0x1000, spot += mySwappedHotspots ? -0x20 : 0x20)
|
|
||||||
{
|
|
||||||
uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset];
|
|
||||||
start -= start % 0x1000;
|
|
||||||
info << "Bank " << i << " @ $" << Common::Base::HEX4 << start << " - "
|
|
||||||
<< "$" << (start + 0xFFF) << " (hotspots = $" << spot << ", $" << (spot | 0x80) << ")\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
int xpos = 2,
|
return info.str();
|
||||||
ypos = addBaseInformation(size, "UA Limited", info.str()) + myLineHeight;
|
|
||||||
|
|
||||||
VariantList items;
|
|
||||||
if (swapHotspots)
|
|
||||||
{
|
|
||||||
VarList::push_back(items, "0 ($240, $2C0)");
|
|
||||||
VarList::push_back(items, "1 ($220, $2A0)");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
VarList::push_back(items, "0 ($220, $2A0)");
|
|
||||||
VarList::push_back(items, "1 ($240, $2C0)");
|
|
||||||
}
|
|
||||||
myBank =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("0 ($FFx, $FFx)"),
|
|
||||||
myLineHeight, items, "Set bank ",
|
|
||||||
0, kBankChanged);
|
|
||||||
myBank->setTarget(this);
|
|
||||||
addFocusWidget(myBank);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeUAWidget::loadConfig()
|
string CartridgeUAWidget::hotspotStr(int bank, int, bool prefix)
|
||||||
{
|
{
|
||||||
Debugger& dbg = instance().debugger();
|
ostringstream info;
|
||||||
CartDebug& cart = dbg.cartDebug();
|
uInt16 hotspot = myCart.hotspot() + (bank ^ (mySwappedHotspots ? 1 : 0)) * myHotspotDelta;
|
||||||
const CartState& state = static_cast<const CartState&>(cart.getState());
|
|
||||||
const CartState& oldstate = static_cast<const CartState&>(cart.getOldState());
|
|
||||||
|
|
||||||
myBank->setSelectedIndex(myCart.getBank(), state.bank != oldstate.bank);
|
info << "(" << (prefix ? "hotspot " : "");
|
||||||
|
info << "$" << Common::Base::HEX1 << hotspot << ", $" << (hotspot | 0x80);
|
||||||
|
info << ")";
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
return info.str();
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeUAWidget::handleCommand(CommandSender* sender,
|
|
||||||
int cmd, int data, int id)
|
|
||||||
{
|
|
||||||
if(cmd == kBankChanged)
|
|
||||||
{
|
|
||||||
myCart.unlockBank();
|
|
||||||
myCart.bank(myBank->getSelected());
|
|
||||||
myCart.lockBank();
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeUAWidget::bankState()
|
|
||||||
{
|
|
||||||
ostringstream& buf = buffer();
|
|
||||||
|
|
||||||
static constexpr std::array<const char*, 2> spot = { "$220, $2A0", "$240, $2C0" };
|
|
||||||
buf << "Bank = " << std::dec << myCart.getBank()
|
|
||||||
<< ", hotspots = " << spot[myCart.getBank() ^ (mySwappedHotspots ? 1U : 0U)];
|
|
||||||
|
|
||||||
return buf.str();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,10 @@
|
||||||
#define CARTRIDGEUA_WIDGET_HXX
|
#define CARTRIDGEUA_WIDGET_HXX
|
||||||
|
|
||||||
class CartridgeUA;
|
class CartridgeUA;
|
||||||
class PopUpWidget;
|
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
#include "CartEnhancedWidget.hxx"
|
||||||
|
|
||||||
class CartridgeUAWidget : public CartDebugWidget
|
class CartridgeUAWidget : public CartridgeEnhancedWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CartridgeUAWidget(GuiObject* boss, const GUI::Font& lfont,
|
CartridgeUAWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
|
@ -33,19 +32,16 @@ class CartridgeUAWidget : public CartDebugWidget
|
||||||
virtual ~CartridgeUAWidget() = default;
|
virtual ~CartridgeUAWidget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CartridgeUA& myCart;
|
string manufacturer() override { return "UA Limited"; }
|
||||||
PopUpWidget* myBank{nullptr};
|
|
||||||
|
|
||||||
bool mySwappedHotspots;
|
string description() override;
|
||||||
|
|
||||||
enum { kBankChanged = 'bkCH' };
|
string hotspotStr(int bank, int seg, bool prefix = false) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void loadConfig() override;
|
const bool mySwappedHotspots;
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
|
||||||
|
|
||||||
string bankState() override;
|
|
||||||
|
|
||||||
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeUAWidget() = delete;
|
CartridgeUAWidget() = delete;
|
||||||
CartridgeUAWidget(const CartridgeUAWidget&) = delete;
|
CartridgeUAWidget(const CartridgeUAWidget&) = delete;
|
||||||
|
|
|
@ -15,157 +15,45 @@
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "Debugger.hxx"
|
|
||||||
#include "CartDebug.hxx"
|
|
||||||
#include "CartWD.hxx"
|
#include "CartWD.hxx"
|
||||||
#include "PopUpWidget.hxx"
|
|
||||||
#include "CartWDWidget.hxx"
|
#include "CartWDWidget.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CartridgeWDWidget::CartridgeWDWidget(
|
CartridgeWDWidget::CartridgeWDWidget(
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h, CartridgeWD& cart)
|
int x, int y, int w, int h, CartridgeWD& cart)
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart),
|
||||||
myCart(cart)
|
myCartWD(cart)
|
||||||
{
|
{
|
||||||
string info =
|
initialize();
|
||||||
"This scheme has eight 1K slices, which can be mapped into four 1K "
|
|
||||||
"segments in various combinations. Each 'bank' selects a predefined "
|
|
||||||
"segment arrangement (indicated in square brackets)\n"
|
|
||||||
"In the third (uppermost) segment the byte at $3FC is overwritten with 0.\n\n"
|
|
||||||
"64 bytes RAM @ $F000 - $F080\n"
|
|
||||||
" $F000 - $F03F (R), $F040 - $F07F (W)\n";
|
|
||||||
|
|
||||||
int xpos = 2,
|
|
||||||
ypos = addBaseInformation(myCart.mySize, "Wickstead Design", info, 12) + myLineHeight;
|
|
||||||
|
|
||||||
VariantList items;
|
|
||||||
VarList::push_back(items, "0 ($30) [0,0,1,3]", 0);
|
|
||||||
VarList::push_back(items, "1 ($31) [0,1,2,3]", 1);
|
|
||||||
VarList::push_back(items, "2 ($32) [4,5,6,7]", 2);
|
|
||||||
VarList::push_back(items, "3 ($33) [7,4,2,3]", 3);
|
|
||||||
VarList::push_back(items, "4 ($34) [0,0,6,7]", 4);
|
|
||||||
VarList::push_back(items, "5 ($35) [0,1,7,6]", 5);
|
|
||||||
VarList::push_back(items, "6 ($36) [2,3,4,5]", 6);
|
|
||||||
VarList::push_back(items, "7 ($37) [6,0,5,1]", 7);
|
|
||||||
VarList::push_back(items, "8 ($38) [0,0,1,3]", 8);
|
|
||||||
VarList::push_back(items, "9 ($39) [0,1,2,3]", 9);
|
|
||||||
VarList::push_back(items, "10 ($3A) [4,5,6,7]", 10);
|
|
||||||
VarList::push_back(items, "11 ($3B) [7,4,2,3]", 11);
|
|
||||||
VarList::push_back(items, "12 ($3C) [0,0,6,7]", 12);
|
|
||||||
VarList::push_back(items, "13 ($3D) [0,1,7,6]", 13);
|
|
||||||
VarList::push_back(items, "14 ($3E) [2,3,4,5]", 14);
|
|
||||||
VarList::push_back(items, "15 ($3F) [6,0,5,1]", 15);
|
|
||||||
myBank = new PopUpWidget(boss, _font, xpos, ypos-2,
|
|
||||||
_font.getStringWidth("15 ($3F) [6,0,5,1]"),
|
|
||||||
myLineHeight, items, "Set bank ",
|
|
||||||
0, kBankChanged);
|
|
||||||
myBank->setTarget(this);
|
|
||||||
addFocusWidget(myBank);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeWDWidget::saveOldState()
|
string CartridgeWDWidget::description()
|
||||||
{
|
{
|
||||||
myOldState.internalram.clear();
|
ostringstream info;
|
||||||
|
|
||||||
for(uInt32 i = 0; i < internalRamSize(); ++i)
|
info << "8K + RAM Wickstead Design cartridge, \n"
|
||||||
myOldState.internalram.push_back(myCart.myRAM[i]);
|
<< " eight 1K banks, mapped into four segments\n"
|
||||||
|
<< "Hotspots $" << Common::Base::HEX1 << myCart.hotspot() << " - $" << (myCart.hotspot() + 7) << ", "
|
||||||
|
<< "each hotspot selects a [predefined bank mapping]\n";
|
||||||
|
info << ramDescription();
|
||||||
|
|
||||||
myOldState.bank = myCart.getBank();
|
return info.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeWDWidget::loadConfig()
|
string CartridgeWDWidget::hotspotStr(int bank, int segment, bool prefix)
|
||||||
{
|
{
|
||||||
myBank->setSelectedIndex(myCart.getBank(), myCart.getBank() != myOldState.bank);
|
ostringstream info;
|
||||||
|
CartridgeWD::BankOrg banks = myCartWD.ourBankOrg[bank];
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
info << "(" << (prefix ? "hotspot " : "")
|
||||||
}
|
<< "$" << Common::Base::HEX1 << (myCart.hotspot() + bank) << ") ["
|
||||||
|
<< uInt16(banks.zero) << ", "
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
<< uInt16(banks.one) << ", "
|
||||||
void CartridgeWDWidget::handleCommand(CommandSender* sender,
|
<< uInt16(banks.two) << ", "
|
||||||
int cmd, int data, int id)
|
<< uInt16(banks.three) << "]";
|
||||||
{
|
|
||||||
if(cmd == kBankChanged)
|
return info.str();
|
||||||
{
|
|
||||||
myCart.unlockBank();
|
|
||||||
myCart.bank(myBank->getSelected());
|
|
||||||
myCart.lockBank();
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeWDWidget::bankState()
|
|
||||||
{
|
|
||||||
ostringstream& buf = buffer();
|
|
||||||
|
|
||||||
static constexpr std::array<const char*, 8> segments = {
|
|
||||||
"[0,0,1,3]", "[0,1,2,3]", "[4,5,6,7]", "[7,4,2,3]",
|
|
||||||
"[0,0,6,7]", "[0,1,7,6]", "[2,3,4,5]", "[6,0,5,1]"
|
|
||||||
};
|
|
||||||
uInt16 bank = myCart.getBank();
|
|
||||||
buf << "Bank = " << std::dec << bank << ", segments = " << segments[bank & 0x7];
|
|
||||||
|
|
||||||
return buf.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 CartridgeWDWidget::internalRamSize()
|
|
||||||
{
|
|
||||||
return 64;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt32 CartridgeWDWidget::internalRamRPort(int start)
|
|
||||||
{
|
|
||||||
return 0xF000 + start;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeWDWidget::internalRamDescription()
|
|
||||||
{
|
|
||||||
ostringstream desc;
|
|
||||||
desc << "$F000 - $F03F used for Read Access\n"
|
|
||||||
<< "$F040 - $F07F used for Write Access";
|
|
||||||
|
|
||||||
return desc.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const ByteArray& CartridgeWDWidget::internalRamOld(int start, int count)
|
|
||||||
{
|
|
||||||
myRamOld.clear();
|
|
||||||
for(int i = 0; i < count; ++i)
|
|
||||||
myRamOld.push_back(myOldState.internalram[start + i]);
|
|
||||||
return myRamOld;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const ByteArray& CartridgeWDWidget::internalRamCurrent(int start, int count)
|
|
||||||
{
|
|
||||||
myRamCurrent.clear();
|
|
||||||
for(int i = 0; i < count; ++i)
|
|
||||||
myRamCurrent.push_back(myCart.myRAM[start + i]);
|
|
||||||
return myRamCurrent;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeWDWidget::internalRamSetValue(int addr, uInt8 value)
|
|
||||||
{
|
|
||||||
myCart.myRAM[addr] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt8 CartridgeWDWidget::internalRamGetValue(int addr)
|
|
||||||
{
|
|
||||||
return myCart.myRAM[addr];
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeWDWidget::internalRamLabel(int addr)
|
|
||||||
{
|
|
||||||
CartDebug& dbg = instance().debugger().cartDebug();
|
|
||||||
return dbg.getLabel(addr + 0xF000, false);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,10 @@
|
||||||
#define CARTRIDGEWD_WIDGET_HXX
|
#define CARTRIDGEWD_WIDGET_HXX
|
||||||
|
|
||||||
class CartridgeWD;
|
class CartridgeWD;
|
||||||
class PopUpWidget;
|
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
#include "CartEnhancedWidget.hxx"
|
||||||
|
|
||||||
class CartridgeWDWidget : public CartDebugWidget
|
class CartridgeWDWidget : public CartridgeEnhancedWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CartridgeWDWidget(GuiObject* boss, const GUI::Font& lfont,
|
CartridgeWDWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
|
@ -32,36 +31,19 @@ class CartridgeWDWidget : public CartDebugWidget
|
||||||
CartridgeWD& cart);
|
CartridgeWD& cart);
|
||||||
virtual ~CartridgeWDWidget() = default;
|
virtual ~CartridgeWDWidget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CartridgeWD& myCart;
|
CartridgeWD& myCartWD;
|
||||||
PopUpWidget* myBank{nullptr};
|
|
||||||
|
|
||||||
struct CartState {
|
|
||||||
ByteArray internalram;
|
|
||||||
uInt16 bank{0}; // Current banking layout
|
|
||||||
};
|
|
||||||
CartState myOldState;
|
|
||||||
|
|
||||||
enum { kBankChanged = 'bkCH' };
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void saveOldState() override;
|
string manufacturer() override { return "Wickstead Design"; }
|
||||||
void loadConfig() override;
|
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
|
||||||
|
|
||||||
string bankState() override;
|
string description() override;
|
||||||
|
|
||||||
// start of functions for Cartridge RAM tab
|
string hotspotStr(int bank, int seg = 0, bool prefix = false) override;
|
||||||
uInt32 internalRamSize() override;
|
|
||||||
uInt32 internalRamRPort(int start) override;
|
|
||||||
string internalRamDescription() override;
|
|
||||||
const ByteArray& internalRamOld(int start, int count) override;
|
|
||||||
const ByteArray& internalRamCurrent(int start, int count) override;
|
|
||||||
void internalRamSetValue(int addr, uInt8 value) override;
|
|
||||||
uInt8 internalRamGetValue(int addr) override;
|
|
||||||
string internalRamLabel(int addr) override;
|
|
||||||
// end of functions for Cartridge RAM tab
|
|
||||||
|
|
||||||
|
uInt16 bankSegs() override { return 1; }
|
||||||
|
|
||||||
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeWDWidget() = delete;
|
CartridgeWDWidget() = delete;
|
||||||
CartridgeWDWidget(const CartridgeWDWidget&) = delete;
|
CartridgeWDWidget(const CartridgeWDWidget&) = delete;
|
||||||
|
|
|
@ -16,94 +16,26 @@
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "CartX07.hxx"
|
#include "CartX07.hxx"
|
||||||
#include "PopUpWidget.hxx"
|
|
||||||
#include "CartX07Widget.hxx"
|
#include "CartX07Widget.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CartridgeX07Widget::CartridgeX07Widget(
|
CartridgeX07Widget::CartridgeX07Widget(
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h, CartridgeX07& cart)
|
int x, int y, int w, int h, CartridgeX07& cart)
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||||
myCart(cart)
|
|
||||||
{
|
{
|
||||||
uInt32 size = 16 * 4096;
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
string CartridgeX07Widget::description()
|
||||||
|
{
|
||||||
ostringstream info;
|
ostringstream info;
|
||||||
|
|
||||||
info << "64K X07 cartridge, 16 4K banks\n"
|
info << "64K X07 cartridge, 16 4K banks\n"
|
||||||
<< "Startup bank = " << cart.startBank() << "\n"
|
|
||||||
<< "Multiple hotspots, all below $1000\n"
|
<< "Multiple hotspots, all below $1000\n"
|
||||||
<< "See documentation for further details\n";
|
<< "See documentation for further details\n";
|
||||||
|
info << CartridgeEnhancedWidget::description();
|
||||||
|
|
||||||
// Eventually, we should query this from the debugger/disassembler
|
return info.str();
|
||||||
for(uInt32 i = 0, offset = 0xFFC; i < 16; ++i, offset += 0x1000)
|
|
||||||
{
|
|
||||||
uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset];
|
|
||||||
start -= start % 0x1000;
|
|
||||||
info << "Bank " << std::dec << i << " @ $" << Common::Base::HEX4 << start
|
|
||||||
<< " - " << "$" << (start + 0xFFF) << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
int xpos = 2,
|
|
||||||
ypos = addBaseInformation(size, "AtariAge / John Payson / Fred Quimby",
|
|
||||||
info.str()) + myLineHeight;
|
|
||||||
|
|
||||||
VariantList items;
|
|
||||||
VarList::push_back(items, " 0");
|
|
||||||
VarList::push_back(items, " 1");
|
|
||||||
VarList::push_back(items, " 2");
|
|
||||||
VarList::push_back(items, " 3");
|
|
||||||
VarList::push_back(items, " 4");
|
|
||||||
VarList::push_back(items, " 5");
|
|
||||||
VarList::push_back(items, " 6");
|
|
||||||
VarList::push_back(items, " 7");
|
|
||||||
VarList::push_back(items, " 8");
|
|
||||||
VarList::push_back(items, " 9");
|
|
||||||
VarList::push_back(items, " 10");
|
|
||||||
VarList::push_back(items, " 11");
|
|
||||||
VarList::push_back(items, " 12");
|
|
||||||
VarList::push_back(items, " 13");
|
|
||||||
VarList::push_back(items, " 14");
|
|
||||||
VarList::push_back(items, " 15");
|
|
||||||
myBank =
|
|
||||||
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth(" 15"),
|
|
||||||
myLineHeight, items, "Set bank ",
|
|
||||||
0, kBankChanged);
|
|
||||||
myBank->setTarget(this);
|
|
||||||
addFocusWidget(myBank);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeX07Widget::loadConfig()
|
|
||||||
{
|
|
||||||
Debugger& dbg = instance().debugger();
|
|
||||||
CartDebug& cart = dbg.cartDebug();
|
|
||||||
const CartState& state = static_cast<const CartState&>(cart.getState());
|
|
||||||
const CartState& oldstate = static_cast<const CartState&>(cart.getOldState());
|
|
||||||
|
|
||||||
myBank->setSelectedIndex(myCart.getBank(), state.bank != oldstate.bank);
|
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeX07Widget::handleCommand(CommandSender* sender,
|
|
||||||
int cmd, int data, int id)
|
|
||||||
{
|
|
||||||
if(cmd == kBankChanged)
|
|
||||||
{
|
|
||||||
myCart.unlockBank();
|
|
||||||
myCart.bank(myBank->getSelected());
|
|
||||||
myCart.lockBank();
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
string CartridgeX07Widget::bankState()
|
|
||||||
{
|
|
||||||
ostringstream& buf = buffer();
|
|
||||||
|
|
||||||
buf << "Bank = " << std::dec << myCart.myCurrentBank;
|
|
||||||
|
|
||||||
return buf.str();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,10 @@
|
||||||
#define CARTRIDGEX07_WIDGET_HXX
|
#define CARTRIDGEX07_WIDGET_HXX
|
||||||
|
|
||||||
class CartridgeX07;
|
class CartridgeX07;
|
||||||
class PopUpWidget;
|
|
||||||
|
|
||||||
#include "CartDebugWidget.hxx"
|
#include "CartEnhancedWidget.hxx"
|
||||||
|
|
||||||
class CartridgeX07Widget : public CartDebugWidget
|
class CartridgeX07Widget : public CartridgeEnhancedWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CartridgeX07Widget(GuiObject* boss, const GUI::Font& lfont,
|
CartridgeX07Widget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
|
@ -33,17 +32,11 @@ class CartridgeX07Widget : public CartDebugWidget
|
||||||
virtual ~CartridgeX07Widget() = default;
|
virtual ~CartridgeX07Widget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CartridgeX07& myCart;
|
string manufacturer() override { return "AtariAge / John Payson / Fred Quimby"; }
|
||||||
PopUpWidget* myBank{nullptr};
|
|
||||||
|
|
||||||
enum { kBankChanged = 'bkCH' };
|
string description() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void loadConfig() override;
|
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
|
||||||
|
|
||||||
string bankState() override;
|
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeX07Widget() = delete;
|
CartridgeX07Widget() = delete;
|
||||||
CartridgeX07Widget(const CartridgeX07Widget&) = delete;
|
CartridgeX07Widget(const CartridgeX07Widget&) = delete;
|
||||||
|
|
|
@ -621,7 +621,7 @@ void DebuggerDialog::addRomArea()
|
||||||
|
|
||||||
// The 'cart-specific' information tab (optional)
|
// The 'cart-specific' information tab (optional)
|
||||||
|
|
||||||
tabID = myRomTab->addTab(" " + instance().console().cartridge().name() + " ", TabWidget::AUTO_WIDTH);
|
tabID = myRomTab->addTab(" " + instance().console().cartridge().name() + " ", TabWidget::AUTO_WIDTH);
|
||||||
myCartInfo = instance().console().cartridge().infoWidget(
|
myCartInfo = instance().console().cartridge().infoWidget(
|
||||||
myRomTab, *myLFont, *myNFont, 2, 2, tabWidth - 1,
|
myRomTab, *myLFont, *myNFont, 2, 2, tabWidth - 1,
|
||||||
tabHeight - myRomTab->getTabHeight() - 2);
|
tabHeight - myRomTab->getTabHeight() - 2);
|
||||||
|
@ -644,7 +644,7 @@ void DebuggerDialog::addRomArea()
|
||||||
// The cartridge RAM tab
|
// The cartridge RAM tab
|
||||||
if (myCartDebug->internalRamSize() > 0)
|
if (myCartDebug->internalRamSize() > 0)
|
||||||
{
|
{
|
||||||
tabID = myRomTab->addTab(" Cartridge RAM ", TabWidget::AUTO_WIDTH);
|
tabID = myRomTab->addTab(myCartDebug->tabLabel(), TabWidget::AUTO_WIDTH);
|
||||||
myCartRam =
|
myCartRam =
|
||||||
new CartRamWidget(myRomTab, *myLFont, *myNFont, 2, 2, tabWidth - 1,
|
new CartRamWidget(myRomTab, *myLFont, *myNFont, 2, 2, tabWidth - 1,
|
||||||
tabHeight - myRomTab->getTabHeight() - 2, *myCartDebug);
|
tabHeight - myRomTab->getTabHeight() - 2, *myCartDebug);
|
||||||
|
|
|
@ -41,12 +41,9 @@ RomWidget::RomWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n
|
||||||
|
|
||||||
// Show current bank state
|
// Show current bank state
|
||||||
xpos = x; ypos = y + 7;
|
xpos = x; ypos = y + 7;
|
||||||
t = new StaticTextWidget(boss, lfont, xpos, ypos,
|
t = new StaticTextWidget(boss, lfont, xpos, ypos, "Info ");
|
||||||
lfont.getStringWidth("Bank"),
|
|
||||||
lfont.getFontHeight(),
|
|
||||||
"Bank", TextAlign::Left);
|
|
||||||
|
|
||||||
xpos += t->getWidth() + 5;
|
xpos += t->getRight();
|
||||||
myBank = new EditTextWidget(boss, nfont, xpos, ypos-2,
|
myBank = new EditTextWidget(boss, nfont, xpos, ypos-2,
|
||||||
_w - 2 - xpos, nfont.getLineHeight());
|
_w - 2 - xpos, nfont.getLineHeight());
|
||||||
myBank->setEditable(false);
|
myBank->setEditable(false);
|
||||||
|
@ -68,7 +65,7 @@ void RomWidget::loadConfig()
|
||||||
const CartState& oldstate = static_cast<const CartState&>(cart.getOldState());
|
const CartState& oldstate = static_cast<const CartState&>(cart.getOldState());
|
||||||
|
|
||||||
// Fill romlist the current bank of source or disassembly
|
// Fill romlist the current bank of source or disassembly
|
||||||
myListIsDirty |= cart.disassemble(myListIsDirty);
|
myListIsDirty |= cart.disassemblePC(myListIsDirty);
|
||||||
if(myListIsDirty)
|
if(myListIsDirty)
|
||||||
{
|
{
|
||||||
myRomList->setList(cart.disassembly());
|
myRomList->setList(cart.disassembly());
|
||||||
|
|
|
@ -22,14 +22,13 @@ MODULE_OBJS := \
|
||||||
src/debugger/gui/CartCDFInfoWidget.o \
|
src/debugger/gui/CartCDFInfoWidget.o \
|
||||||
src/debugger/gui/CartCMWidget.o \
|
src/debugger/gui/CartCMWidget.o \
|
||||||
src/debugger/gui/CartCTYWidget.o \
|
src/debugger/gui/CartCTYWidget.o \
|
||||||
src/debugger/gui/CartCVPlusWidget.o \
|
|
||||||
src/debugger/gui/CartCVWidget.o \
|
src/debugger/gui/CartCVWidget.o \
|
||||||
src/debugger/gui/CartDASHWidget.o \
|
|
||||||
src/debugger/gui/CartDFSCWidget.o \
|
src/debugger/gui/CartDFSCWidget.o \
|
||||||
src/debugger/gui/CartDFWidget.o \
|
src/debugger/gui/CartDFWidget.o \
|
||||||
src/debugger/gui/CartDPCPlusWidget.o \
|
src/debugger/gui/CartDPCPlusWidget.o \
|
||||||
src/debugger/gui/CartDPCWidget.o \
|
src/debugger/gui/CartDPCWidget.o \
|
||||||
src/debugger/gui/CartE0Widget.o \
|
src/debugger/gui/CartE0Widget.o \
|
||||||
|
src/debugger/gui/CartEnhancedWidget.o \
|
||||||
src/debugger/gui/CartMNetworkWidget.o \
|
src/debugger/gui/CartMNetworkWidget.o \
|
||||||
src/debugger/gui/CartE7Widget.o \
|
src/debugger/gui/CartE7Widget.o \
|
||||||
src/debugger/gui/CartE78KWidget.o \
|
src/debugger/gui/CartE78KWidget.o \
|
||||||
|
|
|
@ -104,8 +104,9 @@ Bankswitch::BSList = {{
|
||||||
{ "64IN1" , "64IN1 Multicart (128/256K)" },
|
{ "64IN1" , "64IN1 Multicart (128/256K)" },
|
||||||
{ "128IN1" , "128IN1 Multicart (256/512K)" },
|
{ "128IN1" , "128IN1 Multicart (256/512K)" },
|
||||||
{ "2K" , "2K (32-2048 bytes Atari)" },
|
{ "2K" , "2K (32-2048 bytes Atari)" },
|
||||||
{ "3E" , "3E (32K Tigervision)" },
|
{ "3E" , "3E (Tigervision, 32K RAM)" },
|
||||||
{ "3E+" , "3E+ (TJ modified DASH)" },
|
{ "3EX" , "3EX (Tigervision, 256K RAM)" },
|
||||||
|
{ "3E+" , "3E+ (TJ modified 3E)" },
|
||||||
{ "3F" , "3F (512K Tigervision)" },
|
{ "3F" , "3F (512K Tigervision)" },
|
||||||
{ "4A50" , "4A50 (64K 4A50 + RAM)" },
|
{ "4A50" , "4A50 (64K 4A50 + RAM)" },
|
||||||
{ "4K" , "4K (4K Atari)" },
|
{ "4K" , "4K (4K Atari)" },
|
||||||
|
@ -118,8 +119,6 @@ Bankswitch::BSList = {{
|
||||||
{ "CM" , "CM (SpectraVideo CompuMate)" },
|
{ "CM" , "CM (SpectraVideo CompuMate)" },
|
||||||
{ "CTY" , "CTY (CDW - Chetiry)" },
|
{ "CTY" , "CTY (CDW - Chetiry)" },
|
||||||
{ "CV" , "CV (Commavid extra RAM)" },
|
{ "CV" , "CV (Commavid extra RAM)" },
|
||||||
{ "CV+" , "CV+ (Extended Commavid)" },
|
|
||||||
{ "DASH" , "DASH (Experimental)" },
|
|
||||||
{ "DF" , "DF (CPUWIZ 128K)" },
|
{ "DF" , "DF (CPUWIZ 128K)" },
|
||||||
{ "DFSC" , "DFSC (CPUWIZ 128K + RAM)" },
|
{ "DFSC" , "DFSC (CPUWIZ 128K + RAM)" },
|
||||||
{ "DPC" , "DPC (Pitfall II)" },
|
{ "DPC" , "DPC (Pitfall II)" },
|
||||||
|
@ -180,6 +179,7 @@ Bankswitch::ExtensionMap Bankswitch::ourExtensions = {
|
||||||
{ "128N1" , Bankswitch::Type::_128IN1 },
|
{ "128N1" , Bankswitch::Type::_128IN1 },
|
||||||
{ "2K" , Bankswitch::Type::_2K },
|
{ "2K" , Bankswitch::Type::_2K },
|
||||||
{ "3E" , Bankswitch::Type::_3E },
|
{ "3E" , Bankswitch::Type::_3E },
|
||||||
|
{ "3EX" , Bankswitch::Type::_3EX },
|
||||||
{ "3EP" , Bankswitch::Type::_3EP },
|
{ "3EP" , Bankswitch::Type::_3EP },
|
||||||
{ "3E+" , Bankswitch::Type::_3EP },
|
{ "3E+" , Bankswitch::Type::_3EP },
|
||||||
{ "3F" , Bankswitch::Type::_3F },
|
{ "3F" , Bankswitch::Type::_3F },
|
||||||
|
@ -197,9 +197,6 @@ Bankswitch::ExtensionMap Bankswitch::ourExtensions = {
|
||||||
{ "CM" , Bankswitch::Type::_CM },
|
{ "CM" , Bankswitch::Type::_CM },
|
||||||
{ "CTY" , Bankswitch::Type::_CTY },
|
{ "CTY" , Bankswitch::Type::_CTY },
|
||||||
{ "CV" , Bankswitch::Type::_CV },
|
{ "CV" , Bankswitch::Type::_CV },
|
||||||
{ "CVP" , Bankswitch::Type::_CVP },
|
|
||||||
{ "DAS" , Bankswitch::Type::_DASH },
|
|
||||||
{ "DASH" , Bankswitch::Type::_DASH },
|
|
||||||
{ "DF" , Bankswitch::Type::_DF },
|
{ "DF" , Bankswitch::Type::_DF },
|
||||||
{ "DFS" , Bankswitch::Type::_DFSC },
|
{ "DFS" , Bankswitch::Type::_DFSC },
|
||||||
{ "DFSC" , Bankswitch::Type::_DFSC },
|
{ "DFSC" , Bankswitch::Type::_DFSC },
|
||||||
|
@ -250,6 +247,7 @@ Bankswitch::NameToTypeMap Bankswitch::ourNameToTypes = {
|
||||||
{ "2K" , Bankswitch::Type::_2K },
|
{ "2K" , Bankswitch::Type::_2K },
|
||||||
{ "3E" , Bankswitch::Type::_3E },
|
{ "3E" , Bankswitch::Type::_3E },
|
||||||
{ "3E+" , Bankswitch::Type::_3EP },
|
{ "3E+" , Bankswitch::Type::_3EP },
|
||||||
|
{ "3EX" , Bankswitch::Type::_3EX },
|
||||||
{ "3F" , Bankswitch::Type::_3F },
|
{ "3F" , Bankswitch::Type::_3F },
|
||||||
{ "4A50" , Bankswitch::Type::_4A50 },
|
{ "4A50" , Bankswitch::Type::_4A50 },
|
||||||
{ "4K" , Bankswitch::Type::_4K },
|
{ "4K" , Bankswitch::Type::_4K },
|
||||||
|
@ -262,8 +260,6 @@ Bankswitch::NameToTypeMap Bankswitch::ourNameToTypes = {
|
||||||
{ "CM" , Bankswitch::Type::_CM },
|
{ "CM" , Bankswitch::Type::_CM },
|
||||||
{ "CTY" , Bankswitch::Type::_CTY },
|
{ "CTY" , Bankswitch::Type::_CTY },
|
||||||
{ "CV" , Bankswitch::Type::_CV },
|
{ "CV" , Bankswitch::Type::_CV },
|
||||||
{ "CV+" , Bankswitch::Type::_CVP },
|
|
||||||
{ "DASH" , Bankswitch::Type::_DASH },
|
|
||||||
{ "DF" , Bankswitch::Type::_DF },
|
{ "DF" , Bankswitch::Type::_DF },
|
||||||
{ "DFSC" , Bankswitch::Type::_DFSC },
|
{ "DFSC" , Bankswitch::Type::_DFSC },
|
||||||
{ "DPC" , Bankswitch::Type::_DPC },
|
{ "DPC" , Bankswitch::Type::_DPC },
|
||||||
|
|
|
@ -38,14 +38,14 @@ class Bankswitch
|
||||||
public:
|
public:
|
||||||
// Currently supported bankswitch schemes
|
// Currently supported bankswitch schemes
|
||||||
enum class Type {
|
enum class Type {
|
||||||
_AUTO, _0840, _2IN1, _4IN1, _8IN1, _16IN1, _32IN1,
|
_AUTO, _0840, _2IN1, _4IN1, _8IN1, _16IN1, _32IN1,
|
||||||
_64IN1, _128IN1, _2K, _3E, _3EP, _3F, _4A50,
|
_64IN1, _128IN1, _2K, _3E, _3EX, _3EP, _3F,
|
||||||
_4K, _4KSC, _AR, _BF, _BFSC, _BUS, _CDF,
|
_4A50, _4K, _4KSC, _AR, _BF, _BFSC, _BUS,
|
||||||
_CM, _CTY, _CV, _CVP, _DASH, _DF, _DFSC,
|
_CDF, _CM, _CTY, _CV, _DF, _DFSC, _DPC,
|
||||||
_DPC, _DPCP, _E0, _E7, _E78K, _EF, _EFSC,
|
_DPCP, _E0, _E7, _E78K, _EF, _EFSC, _F0,
|
||||||
_F0, _F4, _F4SC, _F6, _F6SC, _F8, _F8SC,
|
_F4, _F4SC, _F6, _F6SC, _F8, _F8SC, _FA,
|
||||||
_FA, _FA2, _FC, _FE, _MDM, _SB, _UA,
|
_FA2, _FC, _FE, _MDM, _SB, _UA, _UASW,
|
||||||
_UASW, _WD, _WDSW, _X07,
|
_WD, _WDSW, _X07,
|
||||||
#ifdef CUSTOM_ARM
|
#ifdef CUSTOM_ARM
|
||||||
_CUSTOM,
|
_CUSTOM,
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -83,7 +83,7 @@ uInt16 Cartridge::bankSize(uInt16 bank) const
|
||||||
|
|
||||||
getImage(size);
|
getImage(size);
|
||||||
|
|
||||||
return std::min(uInt32(size) / bankCount(), 4_KB); // assuming that each bank has the same size
|
return std::min(uInt32(size) / romBankCount(), 4_KB); // assuming that each bank has the same size
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -145,13 +145,13 @@ string Cartridge::getAccessCounters() const
|
||||||
ostringstream out;
|
ostringstream out;
|
||||||
uInt32 offset = 0;
|
uInt32 offset = 0;
|
||||||
|
|
||||||
for(uInt16 bank = 0; bank < bankCount(); ++bank)
|
for(uInt16 bank = 0; bank < romBankCount(); ++bank)
|
||||||
{
|
{
|
||||||
uInt16 origin = bankOrigin(bank);
|
uInt16 origin = bankOrigin(bank);
|
||||||
uInt16 bankSize = this->bankSize(bank);
|
uInt16 bankSize = this->bankSize(bank);
|
||||||
|
|
||||||
out << "Bank " << Common::Base::toString(bank, Common::Base::Fmt::_10_8) << " / 0.."
|
out << "Bank " << Common::Base::toString(bank, Common::Base::Fmt::_10_8) << " / 0.."
|
||||||
<< Common::Base::toString(bankCount() - 1, Common::Base::Fmt::_10_8) << " reads:\n";
|
<< Common::Base::toString(romBankCount() - 1, Common::Base::Fmt::_10_8) << " reads:\n";
|
||||||
for(uInt16 addr = 0; addr < bankSize; ++addr)
|
for(uInt16 addr = 0; addr < bankSize; ++addr)
|
||||||
{
|
{
|
||||||
out << Common::Base::HEX4 << (addr | origin) << ","
|
out << Common::Base::HEX4 << (addr | origin) << ","
|
||||||
|
@ -159,7 +159,7 @@ string Cartridge::getAccessCounters() const
|
||||||
}
|
}
|
||||||
out << "\n";
|
out << "\n";
|
||||||
out << "Bank " << Common::Base::toString(bank, Common::Base::Fmt::_10_8) << " / 0.."
|
out << "Bank " << Common::Base::toString(bank, Common::Base::Fmt::_10_8) << " / 0.."
|
||||||
<< Common::Base::toString(bankCount() - 1, Common::Base::Fmt::_10_8) << " writes:\n";
|
<< Common::Base::toString(romBankCount() - 1, Common::Base::Fmt::_10_8) << " writes:\n";
|
||||||
for(uInt16 addr = 0; addr < bankSize; ++addr)
|
for(uInt16 addr = 0; addr < bankSize; ++addr)
|
||||||
{
|
{
|
||||||
out << Common::Base::HEX4 << (addr | origin) << ","
|
out << Common::Base::HEX4 << (addr | origin) << ","
|
||||||
|
@ -230,11 +230,11 @@ uInt16 Cartridge::initializeStartBank(uInt16 defaultBank)
|
||||||
int propsBank = myStartBankFromPropsFunc();
|
int propsBank = myStartBankFromPropsFunc();
|
||||||
|
|
||||||
if(randomStartBank())
|
if(randomStartBank())
|
||||||
return myStartBank = mySystem->randGenerator().next() % bankCount();
|
return myStartBank = mySystem->randGenerator().next() % romBankCount();
|
||||||
else if(propsBank >= 0)
|
else if(propsBank >= 0)
|
||||||
return myStartBank = BSPF::clamp(propsBank, 0, bankCount() - 1);
|
return myStartBank = BSPF::clamp(propsBank, 0, romBankCount() - 1);
|
||||||
else
|
else
|
||||||
return myStartBank = BSPF::clamp(int(defaultBank), 0, bankCount() - 1);
|
return myStartBank = BSPF::clamp(int(defaultBank), 0, romBankCount() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -180,7 +180,7 @@ class Cartridge : public Device
|
||||||
virtual uInt16 getBank(uInt16 address = 0) const { return 0; }
|
virtual uInt16 getBank(uInt16 address = 0) const { return 0; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Query the number of 'banks' supported by the cartridge. Note that
|
Query the number of ROM 'banks' supported by the cartridge. Note that
|
||||||
this information is cart-specific, where each cart basically defines
|
this information is cart-specific, where each cart basically defines
|
||||||
what a 'bank' is.
|
what a 'bank' is.
|
||||||
|
|
||||||
|
@ -189,10 +189,18 @@ class Cartridge : public Device
|
||||||
cases where ROMs have 2K blocks in some preset area, the bankCount
|
cases where ROMs have 2K blocks in some preset area, the bankCount
|
||||||
is the number of such blocks. Finally, in some esoteric schemes,
|
is the number of such blocks. Finally, in some esoteric schemes,
|
||||||
the number of ways that the addressing can change (multiple ROM and
|
the number of ways that the addressing can change (multiple ROM and
|
||||||
RAM slices at multiple access points) is so complicated that the
|
RAM segments at multiple access points) is so complicated that the
|
||||||
cart will report having only one 'virtual' bank.
|
cart will report having only one 'virtual' bank.
|
||||||
*/
|
*/
|
||||||
virtual uInt16 bankCount() const { return 1; }
|
virtual uInt16 romBankCount() const { return 1; }
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Query the number of RAM 'banks' supported by the cartridge. Note that
|
||||||
|
this information is cart-specific, where each cart basically defines
|
||||||
|
what a 'bank' is.
|
||||||
|
*/
|
||||||
|
virtual uInt16 ramBankCount() const { return 0; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get the size of a bank.
|
Get the size of a bank.
|
||||||
|
|
|
@ -21,25 +21,14 @@
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Cartridge0840::Cartridge0840(const ByteBuffer& image, size_t size,
|
Cartridge0840::Cartridge0840(const ByteBuffer& image, size_t size,
|
||||||
const string& md5, const Settings& settings)
|
const string& md5, const Settings& settings)
|
||||||
: Cartridge(settings, md5)
|
: CartridgeEnhanced(image, size, md5, settings)
|
||||||
{
|
{
|
||||||
// Copy the ROM image into my buffer
|
|
||||||
std::copy_n(image.get(), std::min(myImage.size(), size), myImage.begin());
|
|
||||||
createRomAccessArrays(myImage.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void Cartridge0840::reset()
|
|
||||||
{
|
|
||||||
// Upon reset we switch to the startup bank
|
|
||||||
initializeStartBank(0);
|
|
||||||
bank(startBank());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Cartridge0840::install(System& system)
|
void Cartridge0840::install(System& system)
|
||||||
{
|
{
|
||||||
mySystem = &system;
|
CartridgeEnhanced::install(system);
|
||||||
|
|
||||||
// Get the page accessing methods for the hot spots since they overlap
|
// Get the page accessing methods for the hot spots since they overlap
|
||||||
// areas within the TIA we'll need to forward requests to the TIA
|
// areas within the TIA we'll need to forward requests to the TIA
|
||||||
|
@ -56,32 +45,34 @@ void Cartridge0840::install(System& system)
|
||||||
System::PageAccess access(this, System::PageAccessType::READ);
|
System::PageAccess access(this, System::PageAccessType::READ);
|
||||||
for(uInt16 addr = 0x0800; addr < 0x0FFF; addr += System::PAGE_SIZE)
|
for(uInt16 addr = 0x0800; addr < 0x0FFF; addr += System::PAGE_SIZE)
|
||||||
mySystem->setPageAccess(addr, access);
|
mySystem->setPageAccess(addr, access);
|
||||||
|
}
|
||||||
|
|
||||||
// Install pages for bank 0
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bank(startBank());
|
bool Cartridge0840::checkSwitchBank(uInt16 address, uInt8)
|
||||||
|
{
|
||||||
|
// Switch banks if necessary
|
||||||
|
switch(address & 0x1840)
|
||||||
|
{
|
||||||
|
case 0x0800:
|
||||||
|
// Set the current bank to the lower 4k bank
|
||||||
|
bank(0);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case 0x0840:
|
||||||
|
// Set the current bank to the upper 4k bank
|
||||||
|
bank(1);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt8 Cartridge0840::peek(uInt16 address)
|
uInt8 Cartridge0840::peek(uInt16 address)
|
||||||
{
|
{
|
||||||
address &= 0x1840;
|
checkSwitchBank(address);
|
||||||
|
|
||||||
// Switch banks if necessary
|
|
||||||
switch(address)
|
|
||||||
{
|
|
||||||
case 0x0800:
|
|
||||||
// Set the current bank to the lower 4k bank
|
|
||||||
bank(0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x0840:
|
|
||||||
// Set the current bank to the upper 4k bank
|
|
||||||
bank(1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Because of the way we've set up accessing above, we can only
|
// Because of the way we've set up accessing above, we can only
|
||||||
// get here when the addresses are from 0x800 - 0xFFF
|
// get here when the addresses are from 0x800 - 0xFFF
|
||||||
|
@ -92,24 +83,7 @@ uInt8 Cartridge0840::peek(uInt16 address)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool Cartridge0840::poke(uInt16 address, uInt8 value)
|
bool Cartridge0840::poke(uInt16 address, uInt8 value)
|
||||||
{
|
{
|
||||||
address &= 0x1840;
|
checkSwitchBank(address);
|
||||||
|
|
||||||
// Switch banks if necessary
|
|
||||||
switch(address)
|
|
||||||
{
|
|
||||||
case 0x0800:
|
|
||||||
// Set the current bank to the lower 4k bank
|
|
||||||
bank(0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x0840:
|
|
||||||
// Set the current bank to the upper 4k bank
|
|
||||||
bank(1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Because of the way accessing is set up, we will may get here by
|
// Because of the way accessing is set up, we will may get here by
|
||||||
// doing a write to 0x800 - 0xFFF or cart; we ignore the cart write
|
// doing a write to 0x800 - 0xFFF or cart; we ignore the cart write
|
||||||
|
@ -121,85 +95,3 @@ bool Cartridge0840::poke(uInt16 address, uInt8 value)
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool Cartridge0840::bank(uInt16 bank)
|
|
||||||
{
|
|
||||||
if(bankLocked()) return false;
|
|
||||||
|
|
||||||
// Remember what bank we're in
|
|
||||||
myBankOffset = bank << 12;
|
|
||||||
|
|
||||||
// Setup the page access methods for the current bank
|
|
||||||
System::PageAccess access(this, System::PageAccessType::READ);
|
|
||||||
|
|
||||||
// Map ROM image into the system
|
|
||||||
for(uInt16 addr = 0x1000; addr < 0x2000; addr += System::PAGE_SIZE)
|
|
||||||
{
|
|
||||||
access.directPeekBase = &myImage[myBankOffset + (addr & 0x0FFF)];
|
|
||||||
access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)];
|
|
||||||
mySystem->setPageAccess(addr, access);
|
|
||||||
}
|
|
||||||
return myBankChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt16 Cartridge0840::getBank(uInt16) const
|
|
||||||
{
|
|
||||||
return myBankOffset >> 12;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt16 Cartridge0840::bankCount() const
|
|
||||||
{
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool Cartridge0840::patch(uInt16 address, uInt8 value)
|
|
||||||
{
|
|
||||||
myImage[myBankOffset + (address & 0x0fff)] = value;
|
|
||||||
return myBankChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const uInt8* Cartridge0840::getImage(size_t& size) const
|
|
||||||
{
|
|
||||||
size = myImage.size();
|
|
||||||
return myImage.data();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool Cartridge0840::save(Serializer& out) const
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
out.putShort(myBankOffset);
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
cerr << "ERROR: Cartridge0840::save" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool Cartridge0840::load(Serializer& in)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
myBankOffset = in.getShort();
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
cerr << "ERROR: Cartridge0840::load" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remember what bank we were in
|
|
||||||
bank(myBankOffset);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#define CARTRIDGE0840_HXX
|
#define CARTRIDGE0840_HXX
|
||||||
|
|
||||||
#include "bspf.hxx"
|
#include "bspf.hxx"
|
||||||
#include "Cart.hxx"
|
#include "CartEnhanced.hxx"
|
||||||
#include "System.hxx"
|
#include "System.hxx"
|
||||||
#ifdef DEBUGGER_SUPPORT
|
#ifdef DEBUGGER_SUPPORT
|
||||||
#include "Cart0840Widget.hxx"
|
#include "Cart0840Widget.hxx"
|
||||||
|
@ -30,9 +30,9 @@
|
||||||
are two 4K banks, which are switched by accessing $0800 (bank 0) and
|
are two 4K banks, which are switched by accessing $0800 (bank 0) and
|
||||||
$0840 (bank 1).
|
$0840 (bank 1).
|
||||||
|
|
||||||
@author Fred X. Quimby
|
@author Fred X. Quimby, Thomas Jentzsch
|
||||||
*/
|
*/
|
||||||
class Cartridge0840 : public Cartridge
|
class Cartridge0840 : public CartridgeEnhanced
|
||||||
{
|
{
|
||||||
friend class Cartridge0840Widget;
|
friend class Cartridge0840Widget;
|
||||||
|
|
||||||
|
@ -50,11 +50,6 @@ class Cartridge0840 : public Cartridge
|
||||||
virtual ~Cartridge0840() = default;
|
virtual ~Cartridge0840() = default;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
|
||||||
Reset device to its power-on state
|
|
||||||
*/
|
|
||||||
void reset() override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Install cartridge in the specified system. Invoked by the system
|
Install cartridge in the specified system. Invoked by the system
|
||||||
when the cartridge is attached to it.
|
when the cartridge is attached to it.
|
||||||
|
@ -63,58 +58,6 @@ class Cartridge0840 : public Cartridge
|
||||||
*/
|
*/
|
||||||
void install(System& system) override;
|
void install(System& system) override;
|
||||||
|
|
||||||
/**
|
|
||||||
Install pages for the specified bank in the system.
|
|
||||||
|
|
||||||
@param bank The bank that should be installed in the system
|
|
||||||
*/
|
|
||||||
bool bank(uInt16 bank) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get the current bank.
|
|
||||||
|
|
||||||
@param address The address to use when querying the bank
|
|
||||||
*/
|
|
||||||
uInt16 getBank(uInt16 address = 0) const override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Query the number of banks supported by the cartridge.
|
|
||||||
*/
|
|
||||||
uInt16 bankCount() const override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Patch the cartridge ROM.
|
|
||||||
|
|
||||||
@param address The ROM address to patch
|
|
||||||
@param value The value to place into the address
|
|
||||||
@return Success or failure of the patch operation
|
|
||||||
*/
|
|
||||||
bool patch(uInt16 address, uInt8 value) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Access the internal ROM image for this cartridge.
|
|
||||||
|
|
||||||
@param size Set to the size of the internal ROM image data
|
|
||||||
@return A pointer to the internal ROM image data
|
|
||||||
*/
|
|
||||||
const uInt8* getImage(size_t& size) const override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Save the current state of this cart to the given Serializer.
|
|
||||||
|
|
||||||
@param out The Serializer object to use
|
|
||||||
@return False on any errors, else true
|
|
||||||
*/
|
|
||||||
bool save(Serializer& out) const override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Load the current state of this cart from the given Serializer.
|
|
||||||
|
|
||||||
@param in The Serializer object to use
|
|
||||||
@return False on any errors, else true
|
|
||||||
*/
|
|
||||||
bool load(Serializer& in) override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get a descriptor for the device name (used in error checking).
|
Get a descriptor for the device name (used in error checking).
|
||||||
|
|
||||||
|
@ -152,12 +95,11 @@ class Cartridge0840 : public Cartridge
|
||||||
bool poke(uInt16 address, uInt8 value) override;
|
bool poke(uInt16 address, uInt8 value) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// The 8K ROM image of the cartridge
|
bool checkSwitchBank(uInt16 address, uInt8 value = 0) override;
|
||||||
std::array<uInt8, 8_KB> myImage;
|
|
||||||
|
|
||||||
// Indicates the offset into the ROM image (aligns to current bank)
|
uInt16 hotspot() const override { return 0x0840; }
|
||||||
uInt16 myBankOffset{0};
|
|
||||||
|
|
||||||
|
private:
|
||||||
// Previous Device's page access
|
// Previous Device's page access
|
||||||
std::array<System::PageAccess, 8> myHotSpotPageAccess;
|
std::array<System::PageAccess, 8> myHotSpotPageAccess;
|
||||||
|
|
||||||
|
|
|
@ -21,15 +21,19 @@
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Cartridge2K::Cartridge2K(const ByteBuffer& image, size_t size,
|
Cartridge2K::Cartridge2K(const ByteBuffer& image, size_t size,
|
||||||
const string& md5, const Settings& settings)
|
const string& md5, const Settings& settings)
|
||||||
: Cartridge(settings, md5)
|
: CartridgeEnhanced(image, size, md5, settings)
|
||||||
{
|
{
|
||||||
// Size can be a maximum of 2K
|
// Size can be a maximum of 2K
|
||||||
if(size > 2_KB) size = 2_KB;
|
if(size > 2_KB)
|
||||||
|
size = 2_KB;
|
||||||
|
|
||||||
// Set image size to closest power-of-two for the given size
|
// Set image size to closest power-of-two for the given size
|
||||||
mySize = 1;
|
mySize = 1; myBankShift = 0;
|
||||||
while(mySize < size)
|
while(mySize < size)
|
||||||
|
{
|
||||||
mySize <<= 1;
|
mySize <<= 1;
|
||||||
|
myBankShift++;
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize ROM with illegal 6502 opcode that causes a real 6502 to jam
|
// Initialize ROM with illegal 6502 opcode that causes a real 6502 to jam
|
||||||
size_t bufSize = std::max<size_t>(mySize, System::PAGE_SIZE);
|
size_t bufSize = std::max<size_t>(mySize, System::PAGE_SIZE);
|
||||||
|
@ -49,62 +53,6 @@ Cartridge2K::Cartridge2K(const ByteBuffer& image, size_t size,
|
||||||
for(size_t i = 0; i < System::PAGE_SIZE; i += mySize)
|
for(size_t i = 0; i < System::PAGE_SIZE; i += mySize)
|
||||||
std::copy_n(image.get(), mySize, myImage.get() + i);
|
std::copy_n(image.get(), mySize, myImage.get() + i);
|
||||||
mySize = System::PAGE_SIZE;
|
mySize = System::PAGE_SIZE;
|
||||||
}
|
myBankShift = 6;
|
||||||
|
|
||||||
createRomAccessArrays(mySize);
|
|
||||||
|
|
||||||
// Set mask for accessing the image buffer
|
|
||||||
// This is guaranteed to work, as mySize is a power of two
|
|
||||||
myMask = static_cast<uInt16>(mySize) - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void Cartridge2K::reset()
|
|
||||||
{
|
|
||||||
myBankChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void Cartridge2K::install(System& system)
|
|
||||||
{
|
|
||||||
mySystem = &system;
|
|
||||||
|
|
||||||
// Map ROM image into the system
|
|
||||||
// Note that we don't need our own peek/poke methods, since the mapping
|
|
||||||
// takes care of the entire address space
|
|
||||||
System::PageAccess access(this, System::PageAccessType::READ);
|
|
||||||
for(uInt16 addr = 0x1000; addr < 0x2000; addr += System::PAGE_SIZE)
|
|
||||||
{
|
|
||||||
access.directPeekBase = &myImage[addr & myMask];
|
|
||||||
access.romAccessBase = &myRomAccessBase[addr & myMask];
|
|
||||||
access.romPeekCounter = &myRomAccessCounter[addr & myMask];
|
|
||||||
access.romPokeCounter = &myRomAccessCounter[(addr & myMask) + myAccessSize];
|
|
||||||
mySystem->setPageAccess(addr, access);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool Cartridge2K::patch(uInt16 address, uInt8 value)
|
|
||||||
{
|
|
||||||
myImage[address & myMask] = value;
|
|
||||||
return myBankChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const uInt8* Cartridge2K::getImage(size_t& size) const
|
|
||||||
{
|
|
||||||
size = mySize;
|
|
||||||
return myImage.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool Cartridge2K::save(Serializer&) const
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool Cartridge2K::load(Serializer&)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
class System;
|
class System;
|
||||||
|
|
||||||
#include "bspf.hxx"
|
#include "bspf.hxx"
|
||||||
#include "Cart.hxx"
|
#include "CartEnhanced.hxx"
|
||||||
#ifdef DEBUGGER_SUPPORT
|
#ifdef DEBUGGER_SUPPORT
|
||||||
#include "Cart2KWidget.hxx"
|
#include "Cart2KWidget.hxx"
|
||||||
#endif
|
#endif
|
||||||
|
@ -33,9 +33,9 @@ class System;
|
||||||
data repeats in intervals based on the size of the ROM (which will
|
data repeats in intervals based on the size of the ROM (which will
|
||||||
always be a power of 2).
|
always be a power of 2).
|
||||||
|
|
||||||
@author Stephen Anthony
|
@author Stephen Anthony, Thomas Jentzsch
|
||||||
*/
|
*/
|
||||||
class Cartridge2K : public Cartridge
|
class Cartridge2K : public CartridgeEnhanced
|
||||||
{
|
{
|
||||||
friend class Cartridge2KWidget;
|
friend class Cartridge2KWidget;
|
||||||
|
|
||||||
|
@ -53,52 +53,6 @@ class Cartridge2K : public Cartridge
|
||||||
virtual ~Cartridge2K() = default;
|
virtual ~Cartridge2K() = default;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
|
||||||
Reset cartridge to its power-on state
|
|
||||||
*/
|
|
||||||
void reset() override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Install cartridge in the specified system. Invoked by the system
|
|
||||||
when the cartridge is attached to it.
|
|
||||||
|
|
||||||
@param system The system the device should install itself in
|
|
||||||
*/
|
|
||||||
void install(System& system) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Patch the cartridge ROM.
|
|
||||||
|
|
||||||
@param address The ROM address to patch
|
|
||||||
@param value The value to place into the address
|
|
||||||
@return Success or failure of the patch operation
|
|
||||||
*/
|
|
||||||
bool patch(uInt16 address, uInt8 value) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Access the internal ROM image for this cartridge.
|
|
||||||
|
|
||||||
@param size Set to the size of the internal ROM image data
|
|
||||||
@return A pointer to the internal ROM image data
|
|
||||||
*/
|
|
||||||
const uInt8* getImage(size_t& size) const override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Save the current state of this cart to the given Serializer.
|
|
||||||
|
|
||||||
@param out The Serializer object to use
|
|
||||||
@return False on any errors, else true
|
|
||||||
*/
|
|
||||||
bool save(Serializer& out) const override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Load the current state of this cart from the given Serializer.
|
|
||||||
|
|
||||||
@param in The Serializer object to use
|
|
||||||
@return False on any errors, else true
|
|
||||||
*/
|
|
||||||
bool load(Serializer& in) override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get a descriptor for the device name (used in error checking).
|
Get a descriptor for the device name (used in error checking).
|
||||||
|
|
||||||
|
@ -118,22 +72,8 @@ class Cartridge2K : public Cartridge
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
|
||||||
Get the byte at the specified address.
|
|
||||||
|
|
||||||
@return The byte at the specified address
|
|
||||||
*/
|
|
||||||
uInt8 peek(uInt16 address) override { return myImage[address & myMask]; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Pointer to a dynamically allocated ROM image of the cartridge
|
bool checkSwitchBank(uInt16 address, uInt8 value = 0) override { return false; }
|
||||||
ByteBuffer myImage;
|
|
||||||
|
|
||||||
// Size of the ROM image
|
|
||||||
size_t mySize{0};
|
|
||||||
|
|
||||||
// Mask to use for mirroring
|
|
||||||
uInt16 myMask{0};
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
|
|
|
@ -22,268 +22,52 @@
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Cartridge3E::Cartridge3E(const ByteBuffer& image, size_t size,
|
Cartridge3E::Cartridge3E(const ByteBuffer& image, size_t size,
|
||||||
const string& md5, const Settings& settings)
|
const string& md5, const Settings& settings)
|
||||||
: Cartridge(settings, md5),
|
: CartridgeEnhanced(image, size, md5, settings)
|
||||||
mySize(size)
|
|
||||||
{
|
{
|
||||||
// Allocate array for the ROM image
|
myBankShift = BANK_SHIFT;
|
||||||
myImage = make_unique<uInt8[]>(mySize);
|
myRamSize = RAM_SIZE;
|
||||||
|
myRamBankCount = RAM_BANKS;
|
||||||
// Copy the ROM image into my buffer
|
myRamWpHigh = RAM_HIGH_WP;
|
||||||
std::copy_n(image.get(), mySize, myImage.get());
|
|
||||||
createRomAccessArrays(mySize + myRAM.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void Cartridge3E::reset()
|
|
||||||
{
|
|
||||||
initializeRAM(myRAM.data(), myRAM.size());
|
|
||||||
initializeStartBank(0);
|
|
||||||
|
|
||||||
// We'll map the startup bank into the first segment upon reset
|
|
||||||
bank(startBank());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Cartridge3E::install(System& system)
|
void Cartridge3E::install(System& system)
|
||||||
{
|
{
|
||||||
mySystem = &system;
|
CartridgeEnhanced::install(system);
|
||||||
|
|
||||||
System::PageAccess access(this, System::PageAccessType::READWRITE);
|
System::PageAccess access(this, System::PageAccessType::WRITE);
|
||||||
|
|
||||||
// The hotspots ($3E and $3F) are in TIA address space, so we claim it here
|
// The hotspots ($3E and $3F) are in TIA address space, so we claim it here
|
||||||
for(uInt16 addr = 0x00; addr < 0x40; addr += System::PAGE_SIZE)
|
for(uInt16 addr = 0x00; addr < 0x40; addr += System::PAGE_SIZE)
|
||||||
mySystem->setPageAccess(addr, access);
|
mySystem->setPageAccess(addr, access);
|
||||||
|
}
|
||||||
|
|
||||||
// Setup the second segment to always point to the last ROM slice
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
access.type = System::PageAccessType::READ;
|
bool Cartridge3E::checkSwitchBank(uInt16 address, uInt8 value)
|
||||||
for(uInt16 addr = 0x1800; addr < 0x2000; addr += System::PAGE_SIZE)
|
{
|
||||||
{
|
// Switch banks if necessary
|
||||||
access.directPeekBase = &myImage[(mySize - 2048) + (addr & 0x07FF)];
|
if(address == 0x003F) {
|
||||||
access.romAccessBase = &myRomAccessBase[(mySize - 2048) + (addr & 0x07FF)];
|
// Switch ROM bank into segment 0
|
||||||
access.romPeekCounter = &myRomAccessCounter[(mySize - 2048) + (addr & 0x07FF)];
|
bank(value);
|
||||||
access.romPokeCounter = &myRomAccessCounter[(mySize - 2048) + (addr & 0x07FF) + myAccessSize];
|
return true;
|
||||||
mySystem->setPageAccess(addr, access);
|
|
||||||
}
|
}
|
||||||
|
else if(address == 0x003E)
|
||||||
// Install pages for the startup bank into the first segment
|
{
|
||||||
bank(startBank());
|
// Switch RAM bank into segment 0
|
||||||
|
bank(value + romBankCount());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt8 Cartridge3E::peek(uInt16 address)
|
uInt8 Cartridge3E::peek(uInt16 address)
|
||||||
{
|
{
|
||||||
uInt16 peekAddress = address;
|
uInt16 peekAddress = address;
|
||||||
address &= 0x0FFF;
|
address &= ROM_MASK;
|
||||||
|
|
||||||
// Due to the way paging is set up, the only way to get here is a TIA read or
|
|
||||||
// attempting to read from the RAM write port
|
|
||||||
|
|
||||||
if(address < 0x0040) // TIA access
|
if(address < 0x0040) // TIA access
|
||||||
return mySystem->tia().peek(address);
|
return mySystem->tia().peek(address);
|
||||||
else if(myCurrentBank >= 256)
|
|
||||||
{
|
|
||||||
// Reading from the write port triggers an unwanted write
|
|
||||||
return peekRAM(myRAM[(address & 0x03FF) + ((myCurrentBank - 256) << 10)], peekAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make compiler happy; should never get here
|
return CartridgeEnhanced::peek(peekAddress);
|
||||||
return myImage[(address & 0x07FF) + mySize - 2048];
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool Cartridge3E::poke(uInt16 address, uInt8 value)
|
|
||||||
{
|
|
||||||
uInt16 pokeAddress = address;
|
|
||||||
address &= 0x0FFF;
|
|
||||||
|
|
||||||
// Switch banks if necessary. Armin (Kroko) says there are no mirrored
|
|
||||||
// hotspots.
|
|
||||||
if(address < 0x0040)
|
|
||||||
{
|
|
||||||
if(address == 0x003F)
|
|
||||||
bank(value);
|
|
||||||
else if(address == 0x003E)
|
|
||||||
bank(value + 256);
|
|
||||||
|
|
||||||
return mySystem->tia().poke(address, value);
|
|
||||||
}
|
|
||||||
else if(myCurrentBank >= 256)
|
|
||||||
{
|
|
||||||
if(address & 0x0400)
|
|
||||||
{
|
|
||||||
pokeRAM(myRAM[(address & 0x03FF) + ((myCurrentBank - 256) << 10)],
|
|
||||||
pokeAddress, value);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Writing to the read port should be ignored, but trigger a break if option enabled
|
|
||||||
uInt8 dummy;
|
|
||||||
|
|
||||||
pokeRAM(dummy, pokeAddress, value);
|
|
||||||
myRamWriteAccess = pokeAddress;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool Cartridge3E::bank(uInt16 bank)
|
|
||||||
{
|
|
||||||
if(bankLocked()) return false;
|
|
||||||
|
|
||||||
if(bank < 256)
|
|
||||||
{
|
|
||||||
// Make sure the bank they're asking for is reasonable
|
|
||||||
if((uInt32(bank) << 11) < mySize)
|
|
||||||
{
|
|
||||||
myCurrentBank = bank;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Oops, the bank they're asking for isn't valid so let's wrap it
|
|
||||||
// around to a valid bank number
|
|
||||||
myCurrentBank = bank % (mySize >> 11);
|
|
||||||
}
|
|
||||||
|
|
||||||
uInt32 offset = myCurrentBank << 11;
|
|
||||||
|
|
||||||
// Setup the page access methods for the current bank
|
|
||||||
System::PageAccess access(this, System::PageAccessType::READ);
|
|
||||||
|
|
||||||
// Map ROM image into the system
|
|
||||||
for(uInt16 addr = 0x1000; addr < 0x1800; addr += System::PAGE_SIZE)
|
|
||||||
{
|
|
||||||
access.directPeekBase = &myImage[offset + (addr & 0x07FF)];
|
|
||||||
access.romAccessBase = &myRomAccessBase[offset + (addr & 0x07FF)];
|
|
||||||
access.romPeekCounter = &myRomAccessCounter[offset + (addr & 0x07FF)];
|
|
||||||
access.romPokeCounter = &myRomAccessCounter[offset + (addr & 0x07FF) + myAccessSize];
|
|
||||||
mySystem->setPageAccess(addr, access);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bank -= 256;
|
|
||||||
bank %= 32;
|
|
||||||
myCurrentBank = bank + 256;
|
|
||||||
|
|
||||||
uInt32 offset = bank << 10;
|
|
||||||
|
|
||||||
// Setup the page access methods for the current bank
|
|
||||||
System::PageAccess access(this, System::PageAccessType::READ);
|
|
||||||
|
|
||||||
// Map read-port RAM image into the system
|
|
||||||
// Writes are mapped to poke(), to check for write to the read port
|
|
||||||
for(uInt16 addr = 0x1000; addr < 0x1400; addr += System::PAGE_SIZE)
|
|
||||||
{
|
|
||||||
access.directPeekBase = &myRAM[offset + (addr & 0x03FF)];
|
|
||||||
access.romAccessBase = &myRomAccessBase[mySize + offset + (addr & 0x03FF)];
|
|
||||||
access.romPeekCounter = &myRomAccessCounter[mySize + offset + (addr & 0x03FF)];
|
|
||||||
access.romPokeCounter = &myRomAccessCounter[mySize + offset + (addr & 0x03FF) + myAccessSize];
|
|
||||||
mySystem->setPageAccess(addr, access);
|
|
||||||
}
|
|
||||||
|
|
||||||
access.directPeekBase = nullptr;
|
|
||||||
access.type = System::PageAccessType::WRITE;
|
|
||||||
|
|
||||||
// Map write-port RAM image into the system
|
|
||||||
// Reads are mapped to peek(), to check for read from write port
|
|
||||||
for(uInt16 addr = 0x1400; addr < 0x1800; addr += System::PAGE_SIZE)
|
|
||||||
{
|
|
||||||
access.romAccessBase = &myRomAccessBase[mySize + offset + (addr & 0x03FF)];
|
|
||||||
access.romPeekCounter = &myRomAccessCounter[mySize + offset + (addr & 0x03FF)];
|
|
||||||
access.romPokeCounter = &myRomAccessCounter[mySize + offset + (addr & 0x03FF) + myAccessSize];
|
|
||||||
mySystem->setPageAccess(addr, access);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return myBankChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt16 Cartridge3E::getBank(uInt16 address) const
|
|
||||||
{
|
|
||||||
if (address & 0x800)
|
|
||||||
return 255; // 256 - 1 // 2K slices, fixed bank
|
|
||||||
else
|
|
||||||
return myCurrentBank;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt16 Cartridge3E::bankCount() const
|
|
||||||
{
|
|
||||||
// Because the RAM banks always start at 256 and above, we require the
|
|
||||||
// number of ROM banks to be 256
|
|
||||||
// If the RAM banks were simply appended to the number of actual
|
|
||||||
// ROM banks, bank numbers would be ambiguous (ie, would bank 128 be
|
|
||||||
// the last bank of ROM, or one of the banks of RAM?)
|
|
||||||
return 256 + 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt16 Cartridge3E::bankSize(uInt16 bank) const
|
|
||||||
{
|
|
||||||
return 2_KB; // we cannot use bankCount() here, because it delivers wrong numbers
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool Cartridge3E::patch(uInt16 address, uInt8 value)
|
|
||||||
{
|
|
||||||
address &= 0x0FFF;
|
|
||||||
|
|
||||||
if(address < 0x0800)
|
|
||||||
{
|
|
||||||
if(myCurrentBank < 256)
|
|
||||||
myImage[(address & 0x07FF) + (myCurrentBank << 11)] = value;
|
|
||||||
else
|
|
||||||
myRAM[(address & 0x03FF) + ((myCurrentBank - 256) << 10)] = value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
myImage[(address & 0x07FF) + mySize - 2048] = value;
|
|
||||||
|
|
||||||
return myBankChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const uInt8* Cartridge3E::getImage(size_t& size) const
|
|
||||||
{
|
|
||||||
size = mySize;
|
|
||||||
return myImage.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool Cartridge3E::save(Serializer& out) const
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
out.putShort(myCurrentBank);
|
|
||||||
out.putByteArray(myRAM.data(), myRAM.size());
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
cerr << "ERROR: Cartridge3E::save" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool Cartridge3E::load(Serializer& in)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
myCurrentBank = in.getShort();
|
|
||||||
in.getByteArray(myRAM.data(), myRAM.size());
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
cerr << "ERROR: Cartridge3E::load" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now, go to the current bank
|
|
||||||
bank(myCurrentBank);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
class System;
|
class System;
|
||||||
|
|
||||||
#include "bspf.hxx"
|
#include "bspf.hxx"
|
||||||
#include "Cart.hxx"
|
#include "CartEnhanced.hxx"
|
||||||
#ifdef DEBUGGER_SUPPORT
|
#ifdef DEBUGGER_SUPPORT
|
||||||
#include "Cart3EWidget.hxx"
|
#include "Cart3EWidget.hxx"
|
||||||
#endif
|
#endif
|
||||||
|
@ -47,10 +47,8 @@ class System;
|
||||||
by storing its value into $3F. To map RAM in the first 2K segment
|
by storing its value into $3F. To map RAM in the first 2K segment
|
||||||
instead, store the RAM bank number into $3E.
|
instead, store the RAM bank number into $3E.
|
||||||
|
|
||||||
This implementation of 3E bankswitching numbers the ROM banks 0 to
|
This implementation of 3E bankswitching numbers the RAM banks (up to 32)
|
||||||
255, and the RAM banks 256 to 287. This is done because the public
|
after the ROM banks (up to 256).
|
||||||
bankswitching interface requires us to use one bank number, not one
|
|
||||||
bank number plus the knowledge of whether it's RAM or ROM.
|
|
||||||
|
|
||||||
All 32K of potential RAM is available to a game using this class, even
|
All 32K of potential RAM is available to a game using this class, even
|
||||||
though real cartridges might not have the full 32K: We have no way to
|
though real cartridges might not have the full 32K: We have no way to
|
||||||
|
@ -58,10 +56,10 @@ class System;
|
||||||
may add a stella.pro property for this), but for now it shouldn't cause
|
may add a stella.pro property for this), but for now it shouldn't cause
|
||||||
any problems. (Famous last words...)
|
any problems. (Famous last words...)
|
||||||
|
|
||||||
@author B. Watson
|
@author B. Watson, Thomas Jentzsch
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class Cartridge3E : public Cartridge
|
class Cartridge3E : public CartridgeEnhanced
|
||||||
{
|
{
|
||||||
friend class Cartridge3EWidget;
|
friend class Cartridge3EWidget;
|
||||||
|
|
||||||
|
@ -79,10 +77,6 @@ class Cartridge3E : public Cartridge
|
||||||
virtual ~Cartridge3E() = default;
|
virtual ~Cartridge3E() = default;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
|
||||||
Reset device to its power-on state
|
|
||||||
*/
|
|
||||||
void reset() override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Install cartridge in the specified system. Invoked by the system
|
Install cartridge in the specified system. Invoked by the system
|
||||||
|
@ -92,66 +86,6 @@ class Cartridge3E : public Cartridge
|
||||||
*/
|
*/
|
||||||
void install(System& system) override;
|
void install(System& system) override;
|
||||||
|
|
||||||
/**
|
|
||||||
Install pages for the specified bank in the system.
|
|
||||||
|
|
||||||
@param bank The bank that should be installed in the system
|
|
||||||
*/
|
|
||||||
bool bank(uInt16 bank) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get the current bank.
|
|
||||||
|
|
||||||
@param address The address to use when querying the bank
|
|
||||||
*/
|
|
||||||
uInt16 getBank(uInt16 address = 0) const override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Query the number of banks supported by the cartridge.
|
|
||||||
*/
|
|
||||||
uInt16 bankCount() const override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get the size of a bank.
|
|
||||||
|
|
||||||
@param bank The bank to get the size for
|
|
||||||
@return The bank's size
|
|
||||||
*/
|
|
||||||
virtual uInt16 bankSize(uInt16 bank = 0) const override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Patch the cartridge ROM.
|
|
||||||
|
|
||||||
@param address The ROM address to patch
|
|
||||||
@param value The value to place into the address
|
|
||||||
@return Success or failure of the patch operation
|
|
||||||
*/
|
|
||||||
bool patch(uInt16 address, uInt8 value) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Access the internal ROM image for this cartridge.
|
|
||||||
|
|
||||||
@param size Set to the size of the internal ROM image data
|
|
||||||
@return A pointer to the internal ROM image data
|
|
||||||
*/
|
|
||||||
const uInt8* getImage(size_t& size) const override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Save the current state of this cart to the given Serializer.
|
|
||||||
|
|
||||||
@param out The Serializer object to use
|
|
||||||
@return False on any errors, else true
|
|
||||||
*/
|
|
||||||
bool save(Serializer& out) const override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Load the current state of this cart from the given Serializer.
|
|
||||||
|
|
||||||
@param in The Serializer object to use
|
|
||||||
@return False on any errors, else true
|
|
||||||
*/
|
|
||||||
bool load(Serializer& in) override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get a descriptor for the device name (used in error checking).
|
Get a descriptor for the device name (used in error checking).
|
||||||
|
|
||||||
|
@ -179,27 +113,21 @@ class Cartridge3E : public Cartridge
|
||||||
*/
|
*/
|
||||||
uInt8 peek(uInt16 address) override;
|
uInt8 peek(uInt16 address) override;
|
||||||
|
|
||||||
/**
|
|
||||||
Change the byte at the specified address to the given value
|
|
||||||
|
|
||||||
@param address The address where the value should be stored
|
|
||||||
@param value The value to be stored at the address
|
|
||||||
@return True if the poke changed the device address space, else false
|
|
||||||
*/
|
|
||||||
bool poke(uInt16 address, uInt8 value) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Pointer to a dynamically allocated ROM image of the cartridge
|
bool checkSwitchBank(uInt16 address, uInt8 value) override;
|
||||||
ByteBuffer myImage;
|
|
||||||
|
|
||||||
// RAM contents. For now every ROM gets all 32K of potential RAM
|
protected:
|
||||||
std::array<uInt8, 32_KB> myRAM;
|
// log(ROM bank segment size) / log(2)
|
||||||
|
static constexpr uInt16 BANK_SHIFT = 11; // = 2K = 0x0800
|
||||||
|
|
||||||
// Size of the ROM image
|
// The number of RAM banks
|
||||||
size_t mySize{0};
|
static constexpr uInt16 RAM_BANKS = 32;
|
||||||
|
|
||||||
// Indicates which bank is currently active for the first segment
|
// RAM size
|
||||||
uInt16 myCurrentBank{0};
|
static constexpr size_t RAM_SIZE = RAM_BANKS << (BANK_SHIFT - 1); // = 32K = 0x8000;
|
||||||
|
|
||||||
|
// Write port for extra RAM is at high address
|
||||||
|
static constexpr bool RAM_HIGH_WP = true;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
|
|
|
@ -22,339 +22,63 @@
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Cartridge3EPlus::Cartridge3EPlus(const ByteBuffer& image, size_t size,
|
Cartridge3EPlus::Cartridge3EPlus(const ByteBuffer& image, size_t size,
|
||||||
const string& md5, const Settings& settings)
|
const string& md5, const Settings& settings)
|
||||||
: Cartridge(settings, md5),
|
: Cartridge3E(image, size, md5, settings)
|
||||||
mySize(size)
|
|
||||||
{
|
{
|
||||||
// Allocate array for the ROM image
|
myBankShift = BANK_SHIFT;
|
||||||
myImage = make_unique<uInt8[]>(mySize);
|
myRamSize = RAM_SIZE;
|
||||||
|
myRamBankCount = RAM_BANKS;
|
||||||
// Copy the ROM image into my buffer
|
|
||||||
std::copy_n(image.get(), mySize, myImage.get());
|
|
||||||
createRomAccessArrays(mySize + myRAM.size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Cartridge3EPlus::reset()
|
void Cartridge3EPlus::reset()
|
||||||
{
|
{
|
||||||
initializeRAM(myRAM.data(), myRAM.size());
|
CartridgeEnhanced::reset();
|
||||||
|
|
||||||
// Remember startup bank (0 per spec, rather than last per 3E scheme).
|
// 1st segment in mapped to start bank in CartridgeEnhanced
|
||||||
// Set this to go to 3rd 1K Bank.
|
bank(mySystem->randGenerator().next() % romBankCount(), 1);
|
||||||
initializeStartBank(0);
|
bank(mySystem->randGenerator().next() % romBankCount(), 2);
|
||||||
|
bank(startBank(), 3);
|
||||||
// Initialise bank values for all ROM/RAM access
|
|
||||||
// This is used to reverse-lookup from address to bank location
|
|
||||||
for(auto& b: bankInUse)
|
|
||||||
b = BANK_UNDEFINED; // bank is undefined and inaccessible!
|
|
||||||
|
|
||||||
initializeBankState();
|
|
||||||
|
|
||||||
// We'll map the startup banks 0 and 3 from the image into the third 1K bank upon reset
|
|
||||||
bankROM((0 << BANK_BITS) | 0);
|
|
||||||
bankROM((3 << BANK_BITS) | 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Cartridge3EPlus::install(System& system)
|
bool Cartridge3EPlus::checkSwitchBank(uInt16 address, uInt8 value)
|
||||||
{
|
{
|
||||||
mySystem = &system;
|
// Switch banks if necessary
|
||||||
|
if(address == 0x003F) {
|
||||||
System::PageAccess access(this, System::PageAccessType::READWRITE);
|
// Switch ROM bank into segment 0
|
||||||
|
bank(value & 0b111111, value >> 6);
|
||||||
// The hotspots are in TIA address space, so we claim it here
|
return true;
|
||||||
for(uInt16 addr = 0x00; addr < 0x40; addr += System::PAGE_SIZE)
|
}
|
||||||
mySystem->setPageAccess(addr, access);
|
else if(address == 0x003E)
|
||||||
|
{
|
||||||
// Initialise bank values for all ROM/RAM access
|
// Switch RAM bank into segment 0
|
||||||
// This is used to reverse-lookup from address to bank location
|
bank((value & 0b111111) + romBankCount(), value >> 6);
|
||||||
for(auto& b: bankInUse)
|
return true;
|
||||||
b = BANK_UNDEFINED; // bank is undefined and inaccessible!
|
}
|
||||||
|
return false;
|
||||||
initializeBankState();
|
|
||||||
|
|
||||||
// Setup the last segment (of 4, each 1K) to point to the first ROM slice
|
|
||||||
// Actually we DO NOT want "always". It's just on bootup, and can be out switched later
|
|
||||||
bankROM((0 << BANK_BITS) | 0);
|
|
||||||
bankROM((3 << BANK_BITS) | 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt16 Cartridge3EPlus::getBank(uInt16 address) const
|
|
||||||
{
|
|
||||||
return bankInUse[(address & 0xFFF) >> 10]; // 1K slices
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
uInt16 Cartridge3EPlus::bankCount() const
|
|
||||||
{
|
|
||||||
return uInt16(mySize >> 10); // 1K slices
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt8 Cartridge3EPlus::peek(uInt16 address)
|
uInt8 Cartridge3EPlus::peek(uInt16 address)
|
||||||
{
|
{
|
||||||
uInt16 peekAddress = address;
|
uInt16 peekAddress = address;
|
||||||
address &= 0x0FFF; // restrict to 4K address range
|
address &= ROM_MASK;
|
||||||
|
|
||||||
uInt8 value = 0;
|
if(address < 0x0040) // TIA peek
|
||||||
uInt32 bank = (address >> (ROM_BANK_TO_POWER - 1)) & 7; // convert to 512 byte bank index (0-7)
|
return mySystem->tia().peek(address);
|
||||||
uInt16 imageBank = bankInUse[bank]; // the ROM/RAM bank that's here
|
|
||||||
|
|
||||||
if(imageBank == BANK_UNDEFINED) // an uninitialised bank?
|
return CartridgeEnhanced::peek(peekAddress);
|
||||||
{
|
|
||||||
// accessing invalid bank, so return should be... random?
|
|
||||||
value = mySystem->randGenerator().next();
|
|
||||||
|
|
||||||
}
|
|
||||||
else if(imageBank & BITMASK_ROMRAM) // a RAM bank
|
|
||||||
{
|
|
||||||
Int32 ramBank = imageBank & BIT_BANK_MASK; // discard irrelevant bits
|
|
||||||
Int32 offset = ramBank << RAM_BANK_TO_POWER; // base bank address in RAM
|
|
||||||
offset += (address & BITMASK_RAM_BANK); // + byte offset in RAM bank
|
|
||||||
|
|
||||||
return peekRAM(myRAM[offset], peekAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool Cartridge3EPlus::poke(uInt16 address, uInt8 value)
|
bool Cartridge3EPlus::poke(uInt16 address, uInt8 value)
|
||||||
{
|
{
|
||||||
bool changed = false;
|
if(CartridgeEnhanced::poke(address, value))
|
||||||
|
return true;
|
||||||
|
|
||||||
// Check for write to the bank switch address. RAM/ROM and bank # are encoded in 'value'
|
if(address < 0x0040) // TIA poke
|
||||||
// There are NO mirrored hotspots.
|
|
||||||
|
|
||||||
if(address == BANK_SWITCH_HOTSPOT_RAM)
|
|
||||||
changed = bankRAM(value);
|
|
||||||
else if(address == BANK_SWITCH_HOTSPOT_ROM)
|
|
||||||
changed = bankROM(value);
|
|
||||||
|
|
||||||
if(!(address & 0x1000))
|
|
||||||
{
|
|
||||||
// Handle TIA space that we claimed above
|
// Handle TIA space that we claimed above
|
||||||
changed = changed || mySystem->tia().poke(address, value);
|
return mySystem->tia().poke(address, value);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
uInt32 bankNumber = (address >> RAM_BANK_TO_POWER) & 7; // now 512 byte bank # (ie: 0-7)
|
|
||||||
Int16 whichBankIsThere = bankInUse[bankNumber]; // ROM or RAM bank reference
|
|
||||||
|
|
||||||
if(whichBankIsThere & BITMASK_ROMRAM)
|
|
||||||
{
|
|
||||||
if(address & RAM_BANK_SIZE)
|
|
||||||
{
|
|
||||||
uInt32 byteOffset = address & BITMASK_RAM_BANK;
|
|
||||||
uInt32 baseAddress = ((whichBankIsThere & BIT_BANK_MASK) << RAM_BANK_TO_POWER) + byteOffset;
|
|
||||||
pokeRAM(myRAM[baseAddress], address, value);
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Writing to the read port should be ignored, but trigger a break if option enabled
|
|
||||||
uInt8 dummy;
|
|
||||||
|
|
||||||
pokeRAM(dummy, address, value);
|
|
||||||
myRamWriteAccess = address;
|
|
||||||
changed = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool Cartridge3EPlus::bankRAM(uInt8 bank)
|
|
||||||
{
|
|
||||||
if(bankLocked()) // debugger can lock RAM
|
|
||||||
return false;
|
|
||||||
|
|
||||||
//cerr << "bankRAM " << int(bank) << endl;
|
|
||||||
|
|
||||||
// Each RAM bank uses two slots, separated by 0x200 in memory -- one read, one write.
|
|
||||||
bankRAMSlot(bank | BITMASK_ROMRAM | 0);
|
|
||||||
bankRAMSlot(bank | BITMASK_ROMRAM | BITMASK_LOWERUPPER);
|
|
||||||
|
|
||||||
return myBankChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void Cartridge3EPlus::bankRAMSlot(uInt16 bank)
|
|
||||||
{
|
|
||||||
uInt16 bankNumber = (bank >> BANK_BITS) & 3; // which bank # we are switching TO (BITS D6,D7) to 512 byte block
|
|
||||||
uInt16 currentBank = bank & BIT_BANK_MASK; // Wrap around/restrict to valid range
|
|
||||||
bool upper = bank & BITMASK_LOWERUPPER; // is this the read or write port
|
|
||||||
|
|
||||||
uInt32 startCurrentBank = currentBank << RAM_BANK_TO_POWER; // Effectively * 512 bytes
|
|
||||||
//cerr << "raw bank=" << std::dec << currentBank << endl
|
|
||||||
// << "startCurrentBank=$" << std::hex << startCurrentBank << endl;
|
|
||||||
// Setup the page access methods for the current bank
|
|
||||||
System::PageAccess access(this, System::PageAccessType::READ);
|
|
||||||
|
|
||||||
if(upper) // We're mapping the write port
|
|
||||||
{
|
|
||||||
bankInUse[bankNumber * 2 + 1] = Int16(bank);
|
|
||||||
access.type = System::PageAccessType::WRITE;
|
|
||||||
}
|
|
||||||
else // We're mapping the read port
|
|
||||||
{
|
|
||||||
bankInUse[bankNumber * 2] = Int16(bank);
|
|
||||||
access.type = System::PageAccessType::READ;
|
|
||||||
}
|
|
||||||
|
|
||||||
uInt16 start = 0x1000 + (bankNumber << (RAM_BANK_TO_POWER+1)) + (upper ? RAM_WRITE_OFFSET : 0);
|
|
||||||
uInt16 end = start + RAM_BANK_SIZE - 1;
|
|
||||||
|
|
||||||
//cerr << "bank RAM: " << bankNumber << " -> " << (bankNumber * 2 + (upper ? 1 : 0)) << (upper ? " (W)" : " (R)") << endl
|
|
||||||
// << "start=" << std::hex << start << ", end=" << end << endl << endl;
|
|
||||||
for(uInt16 addr = start; addr <= end; addr += System::PAGE_SIZE)
|
|
||||||
{
|
|
||||||
if(!upper)
|
|
||||||
access.directPeekBase = &myRAM[startCurrentBank + (addr & (RAM_BANK_SIZE - 1))];
|
|
||||||
|
|
||||||
access.romAccessBase = &myRomAccessBase[mySize + startCurrentBank + (addr & (RAM_BANK_SIZE - 1))];
|
|
||||||
mySystem->setPageAccess(addr, access);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool Cartridge3EPlus::bankROM(uInt8 bank)
|
|
||||||
{
|
|
||||||
if(bankLocked()) // debugger can lock ROM
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Map ROM bank image into the system into the correct slot
|
|
||||||
// Memory map is 1K slots at 0x1000, 0x1400, 0x1800, 0x1C00
|
|
||||||
// Each ROM uses 2 consecutive 512 byte slots
|
|
||||||
bankROMSlot(bank | 0);
|
|
||||||
bankROMSlot(bank | BITMASK_LOWERUPPER);
|
|
||||||
|
|
||||||
return myBankChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void Cartridge3EPlus::bankROMSlot(uInt16 bank)
|
|
||||||
{
|
|
||||||
uInt16 bankNumber = (bank >> BANK_BITS) & 3; // which bank # we are switching TO (BITS D6,D7)
|
|
||||||
uInt16 currentBank = bank & BIT_BANK_MASK; // Wrap around/restrict to valid range
|
|
||||||
bool upper = bank & BITMASK_LOWERUPPER; // is this the lower or upper 512b
|
|
||||||
|
|
||||||
bankInUse[bankNumber * 2 + (upper ? 1 : 0)] = Int16(bank); // Record which bank switched in (as ROM)
|
|
||||||
|
|
||||||
uInt32 startCurrentBank = currentBank << ROM_BANK_TO_POWER; // Effectively *1K
|
|
||||||
|
|
||||||
// Setup the page access methods for the current bank
|
|
||||||
System::PageAccess access(this, System::PageAccessType::READ);
|
|
||||||
|
|
||||||
uInt16 start = 0x1000 + (bankNumber << ROM_BANK_TO_POWER) + (upper ? ROM_BANK_SIZE / 2 : 0);
|
|
||||||
uInt16 end = start + ROM_BANK_SIZE / 2 - 1;
|
|
||||||
|
|
||||||
for(uInt16 addr = start; addr <= end; addr += System::PAGE_SIZE)
|
|
||||||
{
|
|
||||||
access.directPeekBase = &myImage[startCurrentBank + (addr & (ROM_BANK_SIZE - 1))];
|
|
||||||
access.romAccessBase = &myRomAccessBase[startCurrentBank + (addr & (ROM_BANK_SIZE - 1))];
|
|
||||||
mySystem->setPageAccess(addr, access);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void Cartridge3EPlus::initializeBankState()
|
|
||||||
{
|
|
||||||
// Switch in each 512b slot
|
|
||||||
for(uInt32 b = 0; b < 8; ++b)
|
|
||||||
{
|
|
||||||
if(bankInUse[b] == BANK_UNDEFINED)
|
|
||||||
{
|
|
||||||
// All accesses point to peek/poke above
|
|
||||||
System::PageAccess access(this, System::PageAccessType::READ);
|
|
||||||
uInt16 start = 0x1000 + (b << RAM_BANK_TO_POWER);
|
|
||||||
uInt16 end = start + RAM_BANK_SIZE - 1;
|
|
||||||
for(uInt16 addr = start; addr <= end; addr += System::PAGE_SIZE)
|
|
||||||
mySystem->setPageAccess(addr, access);
|
|
||||||
}
|
|
||||||
else if (bankInUse[b] & BITMASK_ROMRAM)
|
|
||||||
bankRAMSlot(bankInUse[b]);
|
|
||||||
else
|
|
||||||
bankROMSlot(bankInUse[b]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool Cartridge3EPlus::patch(uInt16 address, uInt8 value)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
// Patch the cartridge ROM (for debugger)
|
|
||||||
|
|
||||||
myBankChanged = true;
|
|
||||||
|
|
||||||
uInt32 bankNumber = (address >> RAM_BANK_TO_POWER) & 7; // now 512 byte bank # (ie: 0-7)
|
|
||||||
uInt16 whichBankIsThere = bankInUse[bankNumber]; // ROM or RAM bank reference
|
|
||||||
|
|
||||||
if (whichBankIsThere == BANK_UNDEFINED) {
|
|
||||||
|
|
||||||
// We're trying to access undefined memory (no bank here yet). Fail!
|
|
||||||
myBankChanged = false;
|
|
||||||
|
|
||||||
} else if (whichBankIsThere & BITMASK_ROMRAM) { // patching RAM (512 byte banks)
|
|
||||||
|
|
||||||
uInt32 byteOffset = address & BITMASK_RAM_BANK;
|
|
||||||
uInt32 baseAddress = ((whichBankIsThere & BIT_BANK_MASK) << RAM_BANK_TO_POWER) + byteOffset;
|
|
||||||
myRAM[baseAddress] = value; // write to RAM
|
|
||||||
|
|
||||||
// TODO: Stephen -- should we set 'myBankChanged' true when there's a RAM write?
|
|
||||||
|
|
||||||
} else { // patching ROM (1K banks)
|
|
||||||
|
|
||||||
uInt32 byteOffset = address & BITMASK_ROM_BANK;
|
|
||||||
uInt32 baseAddress = (whichBankIsThere << ROM_BANK_TO_POWER) + byteOffset;
|
|
||||||
myImage[baseAddress] = value; // write to the image
|
|
||||||
}
|
|
||||||
|
|
||||||
return myBankChanged;
|
|
||||||
#else
|
|
||||||
return false;
|
return false;
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const uInt8* Cartridge3EPlus::getImage(size_t& size) const
|
|
||||||
{
|
|
||||||
size = mySize;
|
|
||||||
return myImage.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool Cartridge3EPlus::save(Serializer& out) const
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
out.putShortArray(bankInUse.data(), bankInUse.size());
|
|
||||||
out.putByteArray(myRAM.data(), myRAM.size());
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
cerr << "ERROR: Cartridge3EPlus::save" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool Cartridge3EPlus::load(Serializer& in)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
in.getShortArray(bankInUse.data(), bankInUse.size());
|
|
||||||
in.getByteArray(myRAM.data(), myRAM.size());
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
cerr << "ERROR: Cartridge3EPlus::load" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
initializeBankState();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
class System;
|
class System;
|
||||||
|
|
||||||
#include "bspf.hxx"
|
#include "bspf.hxx"
|
||||||
#include "Cart.hxx"
|
#include "Cart3E.hxx"
|
||||||
|
|
||||||
#ifdef DEBUGGER_SUPPORT
|
#ifdef DEBUGGER_SUPPORT
|
||||||
class Cartridge3EPlusWidget;
|
class Cartridge3EPlusWidget;
|
||||||
|
@ -29,19 +29,67 @@ class Cartridge3EPlusWidget;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Cartridge class from Thomas Jentzsch, mostly based on the 'DASH' scheme
|
Cartridge class for new tiling engine "Boulder Dash" format games with RAM.
|
||||||
with the following changes:
|
Kind of a combination of 3F and 3E, with better switchability.
|
||||||
|
B.Watson's Cart3E was used as a template for building this implementation.
|
||||||
|
|
||||||
RAM areas:
|
The destination bank (0-3) is held in the top bits of the value written to
|
||||||
- read $x000, write $x200
|
$3E (for RAM switching) or $3F (for ROM switching). The low 6 bits give
|
||||||
- read $x400, write $x600
|
the actual bank number (0-63) corresponding to 512 byte blocks for RAM and
|
||||||
- read $x800, write $xa00
|
1024 byte blocks for ROM. The maximum size is therefore 32K RAM and 64K ROM.
|
||||||
- read $xc00, write $xe00
|
|
||||||
|
|
||||||
@author Thomas Jentzsch and Stephen Anthony
|
D7D6 indicate the bank number (0-3)
|
||||||
|
D5D4D3D2D1D0 indicate the actual # (0-63) from the image/ram
|
||||||
|
|
||||||
|
ROM:
|
||||||
|
|
||||||
|
Note: in descriptions $F000 is equivalent to $1000 -- that is, we only deal
|
||||||
|
with the low 13 bits of addressing. Stella code uses $1000, I'm used to $F000
|
||||||
|
So, mask with top bits clear :) when reading this document.
|
||||||
|
|
||||||
|
In this scheme, the 4K address space is broken into four 1K ROM/512b RAM segments
|
||||||
|
living at 0x1000, 0x1400, 0x1800, 0x1C00 (or, same thing, 0xF000... etc.),
|
||||||
|
|
||||||
|
The last 1K ROM ($FC00-$FFFF) segment in the 6502 address space (ie: $1C00-$1FFF)
|
||||||
|
is initialised to point to the FIRST 1K of the ROM image, so the reset vectors
|
||||||
|
must be placed at the end of the first 1K in the ROM image. Note, this is
|
||||||
|
DIFFERENT to 3E which switches in the UPPER bank and this bank is fixed. This
|
||||||
|
allows variable sized ROM without having to detect size. First bank (0) in ROM is
|
||||||
|
the default fixed bank mapped to $FC00.
|
||||||
|
|
||||||
|
The system requires the reset vectors to be valid on a reset, so either the
|
||||||
|
hardware first switches in the first bank, or the programmer must ensure
|
||||||
|
that the reset vector is present in ALL ROM banks which might be switched
|
||||||
|
into the last bank area. Currently the latter (programmer onus) is required,
|
||||||
|
but it would be nice for the cartridge hardware to auto-switch on reset.
|
||||||
|
|
||||||
|
ROM switching (write of block+bank number to $3F) D7D6 upper 2 bits of bank #
|
||||||
|
indicates the destination segment (0-3, corresponding to $F000, $F400, $F800,
|
||||||
|
$FC00), and lower 6 bits indicate the 1K bank to switch in. Can handle 64
|
||||||
|
x 1K ROM banks (64K total).
|
||||||
|
|
||||||
|
D7 D6 D5D4D3D2D1D0
|
||||||
|
0 0 x x x x x x switch a 1K ROM bank xxxxxx to $F000
|
||||||
|
0 1 switch a 1K ROM bank xxxxxx to $F400
|
||||||
|
1 0 switch a 1K ROM bank xxxxxx to $F800
|
||||||
|
1 1 switch a 1K ROM bank xxxxxx to $FC00
|
||||||
|
|
||||||
|
RAM switching (write of segment+bank number to $3E) with D7D6 upper 2 bits of
|
||||||
|
bank # indicates the destination RAM segment (0-3, corresponding to $F000,
|
||||||
|
$F400, $F800, $FC00).
|
||||||
|
|
||||||
|
Can handle 64 x 512 byte RAM banks (32K total)
|
||||||
|
|
||||||
|
D7 D6 D5D4D3D2D1D0
|
||||||
|
0 0 x x x x x x switch a 512 byte RAM bank xxxxxx to $F000 with write @ $F200
|
||||||
|
0 1 switch a 512 byte RAM bank xxxxxx to $F400 with write @ $F600
|
||||||
|
1 0 switch a 512 byte RAM bank xxxxxx to $F800 with write @ $FA00
|
||||||
|
1 1 switch a 512 byte RAM bank xxxxxx to $FC00 with write @ $FE00
|
||||||
|
|
||||||
|
@author Thomas Jentzsch and Stephen Anthony
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class Cartridge3EPlus: public Cartridge
|
class Cartridge3EPlus: public Cartridge3E
|
||||||
{
|
{
|
||||||
friend class Cartridge3EPlusWidget;
|
friend class Cartridge3EPlusWidget;
|
||||||
|
|
||||||
|
@ -62,59 +110,6 @@ class Cartridge3EPlus: public Cartridge
|
||||||
/** Reset device to its power-on state */
|
/** Reset device to its power-on state */
|
||||||
void reset() override;
|
void reset() override;
|
||||||
|
|
||||||
/**
|
|
||||||
Install cartridge in the specified system. Invoked by the system
|
|
||||||
when the cartridge is attached to it.
|
|
||||||
|
|
||||||
@param system The system the device should install itself in
|
|
||||||
*/
|
|
||||||
void install(System& system) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get the current bank.
|
|
||||||
|
|
||||||
@param address The address to use when querying the bank
|
|
||||||
*/
|
|
||||||
uInt16 getBank(uInt16 address = 0) const override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Query the number of banks supported by the cartridge.
|
|
||||||
*/
|
|
||||||
uInt16 bankCount() const override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Patch the cartridge ROM.
|
|
||||||
|
|
||||||
@param address The ROM address to patch
|
|
||||||
@param value The value to place into the address
|
|
||||||
@return Success or failure of the patch operation
|
|
||||||
*/
|
|
||||||
bool patch(uInt16 address, uInt8 value) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Access the internal ROM image for this cartridge.
|
|
||||||
|
|
||||||
@param size Set to the size of the internal ROM image data
|
|
||||||
@return A pointer to the internal ROM image data
|
|
||||||
*/
|
|
||||||
const uInt8* getImage(size_t& size) const override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Save the current state of this cart to the given Serializer.
|
|
||||||
|
|
||||||
@param out The Serializer object to use
|
|
||||||
@return False on any errors, else true
|
|
||||||
*/
|
|
||||||
bool save(Serializer& out) const override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Load the current state of this cart from the given Serializer.
|
|
||||||
|
|
||||||
@param in The Serializer object to use
|
|
||||||
@return False on any errors, else true
|
|
||||||
*/
|
|
||||||
bool load(Serializer& in) override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get a descriptor for the device name (used in error checking).
|
Get a descriptor for the device name (used in error checking).
|
||||||
|
|
||||||
|
@ -152,47 +147,17 @@ class Cartridge3EPlus: public Cartridge
|
||||||
bool poke(uInt16 address, uInt8 value) override;
|
bool poke(uInt16 address, uInt8 value) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool bankRAM(uInt8 bank); // switch a RAM bank
|
bool checkSwitchBank(uInt16 address, uInt8 value) override;
|
||||||
bool bankROM(uInt8 bank); // switch a ROM bank
|
|
||||||
|
|
||||||
void bankRAMSlot(uInt16 bank); // switch in a 512b RAM slot (lower or upper 1/2 bank)
|
private:
|
||||||
void bankROMSlot(uInt16 bank); // switch in a 512b RAM slot (read or write port)
|
// log(ROM bank segment size) / log(2)
|
||||||
|
static constexpr uInt16 BANK_SHIFT = 10; // = 1K = 0x0400
|
||||||
|
|
||||||
void initializeBankState(); // set all banks according to current bankInUse state
|
// The size of extra RAM in ROM address space
|
||||||
|
static constexpr uInt16 RAM_BANKS = 64;
|
||||||
|
|
||||||
// We have an array that indicates for each of the 8 512 byte areas of the address space, which ROM/RAM
|
// RAM size
|
||||||
// bank is used in that area. ROM switches 1K so occupies 2 successive entries for each switch. RAM occupies
|
static constexpr size_t RAM_SIZE = RAM_BANKS << (BANK_SHIFT - 1); // = 32K = 0x4000;
|
||||||
// two as well, one 512 byte for read and one for write. The RAM locations are +0x800 apart, and the ROM
|
|
||||||
// are consecutive. This allows us to determine on a read/write exactly where the data is.
|
|
||||||
|
|
||||||
static constexpr uInt16 BANK_UNDEFINED = 0x8000; // bank is undefined and inaccessible
|
|
||||||
std::array<uInt16, 8> bankInUse; // bank being used for ROM/RAM (eight 512 byte areas)
|
|
||||||
|
|
||||||
static constexpr uInt16 BANK_SWITCH_HOTSPOT_RAM = 0x3E; // writes to this address cause bankswitching
|
|
||||||
static constexpr uInt16 BANK_SWITCH_HOTSPOT_ROM = 0x3F; // writes to this address cause bankswitching
|
|
||||||
|
|
||||||
static constexpr uInt8 BANK_BITS = 6; // # bits for bank
|
|
||||||
static constexpr uInt8 BIT_BANK_MASK = (1 << BANK_BITS) - 1; // mask for those bits
|
|
||||||
static constexpr uInt16 BITMASK_LOWERUPPER = 0x100; // flags lower or upper section of bank (1==upper)
|
|
||||||
static constexpr uInt16 BITMASK_ROMRAM = 0x200; // flags ROM or RAM bank switching (1==RAM)
|
|
||||||
|
|
||||||
static constexpr uInt16 MAXIMUM_BANK_COUNT = (1 << BANK_BITS);
|
|
||||||
static constexpr uInt16 RAM_BANK_TO_POWER = 9; // 2^n = 512
|
|
||||||
static constexpr uInt16 RAM_BANK_SIZE = (1 << RAM_BANK_TO_POWER);
|
|
||||||
static constexpr uInt16 BITMASK_RAM_BANK = (RAM_BANK_SIZE - 1);
|
|
||||||
static constexpr uInt32 RAM_TOTAL_SIZE = MAXIMUM_BANK_COUNT * RAM_BANK_SIZE;
|
|
||||||
|
|
||||||
static constexpr uInt16 ROM_BANK_TO_POWER = 10; // 2^n = 1024
|
|
||||||
static constexpr uInt16 ROM_BANK_SIZE = (1 << ROM_BANK_TO_POWER);
|
|
||||||
static constexpr uInt16 BITMASK_ROM_BANK = (ROM_BANK_SIZE - 1);
|
|
||||||
|
|
||||||
static constexpr uInt16 ROM_BANK_COUNT = 64;
|
|
||||||
|
|
||||||
static constexpr uInt16 RAM_WRITE_OFFSET = 0x200;
|
|
||||||
|
|
||||||
ByteBuffer myImage; // Pointer to a dynamically allocated ROM image of the cartridge
|
|
||||||
size_t mySize{0}; // Size of the ROM image
|
|
||||||
std::array<uInt8, RAM_TOTAL_SIZE> myRAM;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// SSSS tt lll lll
|
||||||
|
// SS SS tt ll ll
|
||||||
|
// SS tttttt eeee ll ll aaaa
|
||||||
|
// SSSS tt ee ee ll ll aa
|
||||||
|
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||||
|
// SS SS tt ee ll ll aa aa
|
||||||
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
|
//
|
||||||
|
// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
|
||||||
|
// and the Stella Team
|
||||||
|
//
|
||||||
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
#include "Cart3EX.hxx"
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Cartridge3EX::Cartridge3EX(const ByteBuffer& image, size_t size,
|
||||||
|
const string& md5, const Settings& settings)
|
||||||
|
: Cartridge3E(image, size, md5, settings)
|
||||||
|
{
|
||||||
|
// 0xFFFA contains RAM bank count - 1;
|
||||||
|
myRamBankCount = image[size - 6] + 1;
|
||||||
|
myRamSize = (myBankSize >> 1) * myRamBankCount;
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// SSSS tt lll lll
|
||||||
|
// SS SS tt ll ll
|
||||||
|
// SS tttttt eeee ll ll aaaa
|
||||||
|
// SSSS tt ee ee ll ll aa
|
||||||
|
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||||
|
// SS SS tt ee ll ll aa aa
|
||||||
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
|
//
|
||||||
|
// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
|
||||||
|
// and the Stella Team
|
||||||
|
//
|
||||||
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
#ifndef CARTRIDGE3EX_HXX
|
||||||
|
#define CARTRIDGE3EX_HXX
|
||||||
|
|
||||||
|
class System;
|
||||||
|
|
||||||
|
#include "Cart3E.hxx"
|
||||||
|
|
||||||
|
/**
|
||||||
|
This is an enhanced version of 3E which supports up to 256KB RAM.
|
||||||
|
|
||||||
|
@author Thomas Jentzsch
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Cartridge3EX : public Cartridge3E
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
Create a new cartridge using the specified image and size
|
||||||
|
|
||||||
|
@param image Pointer to the ROM image
|
||||||
|
@param size The size of the ROM image
|
||||||
|
@param md5 The md5sum of the ROM image
|
||||||
|
@param settings A reference to the various settings (read-only)
|
||||||
|
*/
|
||||||
|
Cartridge3EX(const ByteBuffer& image, size_t size, const string& md5,
|
||||||
|
const Settings& settings);
|
||||||
|
virtual ~Cartridge3EX() = default;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
Get a descriptor for the device name (used in error checking).
|
||||||
|
|
||||||
|
@return The name of the object
|
||||||
|
*/
|
||||||
|
string name() const override { return "Cartridge3EX"; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
// RAM size
|
||||||
|
static constexpr size_t RAM_SIZE = RAM_BANKS << (BANK_SHIFT - 1); // = 256K = 0x40000;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Following constructors and assignment operators not supported
|
||||||
|
Cartridge3EX() = delete;
|
||||||
|
Cartridge3EX(const Cartridge3EX&) = delete;
|
||||||
|
Cartridge3EX(Cartridge3EX&&) = delete;
|
||||||
|
Cartridge3EX& operator=(const Cartridge3EX&) = delete;
|
||||||
|
Cartridge3EX& operator=(Cartridge3EX&&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue