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.
|
||||
|
||||
* Added 3EX bank switching type.
|
||||
|
||||
* Removed unused CV+ and DASH bank switching types.
|
||||
|
||||
-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
|
||||
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">
|
||||
|
||||
<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>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>2K </td><td>32-2048 byte Atari </td><td>.2K </td></tr>
|
||||
<tr><td>3E </td><td>32K Tigervision </td><td>.3E </td></tr>
|
||||
<tr><td>3E+ </td><td>3E+ (TJ modified DASH) </td><td>.3EP, .3E+ </td></tr>
|
||||
<tr><td>2K </td><td>32-2048 bytes Atari </td><td>.2K </td></tr>
|
||||
<tr><td>3E </td><td>512K Tigervision + 32K RAM</td><td>.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>4A50 ²</td><td>64K 4A50 + RAM </td><td>.4A5, .4A50 </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>CM ¹</td><td>Spectravideo CompuMate </td><td>.CM </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>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>CV </td><td>CommaVid extra RAM </td><td>.CV </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>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>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>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>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>
|
||||
|
@ -3927,11 +3928,15 @@ Ms Pac-Man (Stella extended codes):
|
|||
</tr>
|
||||
|
||||
</table>
|
||||
</br>
|
||||
<!--
|
||||
<p><b>Note:</b> Items marked as '*' are deprecated, and will probably be
|
||||
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">
|
||||
<tr>
|
||||
<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>
|
||||
</tr>
|
||||
</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">
|
||||
<tr>
|
||||
<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).
|
||||
-->
|
||||
</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">
|
||||
<tr>
|
||||
<td VALIGN="TOP"><i>Cartridge.Name:</i></td>
|
||||
|
|
|
@ -84,6 +84,7 @@ using ByteArray = std::vector<uInt8>;
|
|||
using ShortArray = std::vector<uInt16>;
|
||||
using StringList = std::vector<std::string>;
|
||||
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
|
||||
constexpr uInt32 operator "" _KB(unsigned long long size)
|
||||
|
|
|
@ -79,7 +79,10 @@ CartDebug::CartDebug(Debugger& dbg, Console& console, const OSystem& osystem)
|
|||
|
||||
BankInfo info;
|
||||
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);
|
||||
|
||||
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();
|
||||
// ROM/RAM bank or ZP-RAM?
|
||||
int bank = (PC & 0x1000) ? getBank(PC) : int(myBankInfo.size()) - 1;
|
||||
|
||||
return disassemble(bank, PC, force);
|
||||
|
@ -418,7 +422,7 @@ bool CartDebug::addDirective(Device::AccessType type,
|
|||
bank = (myDebugger.cpuDebug().pc() & 0x1000) ?
|
||||
getBank(myDebugger.cpuDebug().pc()) : int(myBankInfo.size())-1;
|
||||
|
||||
bank = std::min(bank, bankCount());
|
||||
bank = std::min(bank, romBankCount());
|
||||
BankInfo& info = myBankInfo[bank];
|
||||
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();
|
||||
|
||||
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 << "config file '" << node.getShortPath() << "' loaded OK";
|
||||
return retVal.str();
|
||||
|
@ -994,14 +998,14 @@ string CartDebug::saveConfigFile()
|
|||
out << "// Stella.pro: \"" << name << "\"" << endl
|
||||
<< "// MD5: " << md5 << endl
|
||||
<< endl;
|
||||
for(uInt32 b = 0; b < myConsole.cartridge().bankCount(); ++b)
|
||||
for(uInt32 b = 0; b < myConsole.cartridge().romBankCount(); ++b)
|
||||
{
|
||||
out << "[" << b << "]" << endl;
|
||||
getBankDirectives(out, myBankInfo[b]);
|
||||
}
|
||||
|
||||
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 << "config file '" << cfg.getShortPath() << "' saved OK";
|
||||
return retVal.str();
|
||||
|
@ -1062,14 +1066,14 @@ string CartDebug::saveDisassembly()
|
|||
|
||||
Disassembly disasm;
|
||||
disasm.list.reserve(2048);
|
||||
uInt16 bankCount = myConsole.cartridge().bankCount();
|
||||
uInt16 romBankCount = myConsole.cartridge().romBankCount();
|
||||
uInt16 oldBank = myConsole.cartridge().getBank();
|
||||
|
||||
// prepare for switching banks
|
||||
myConsole.cartridge().unlockBank();
|
||||
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
|
||||
myConsole.cartridge().unlockBank();
|
||||
|
@ -1086,8 +1090,8 @@ string CartDebug::saveDisassembly()
|
|||
|
||||
buf << "\n\n;***********************************************************\n"
|
||||
<< "; Bank " << bank;
|
||||
if (bankCount > 1)
|
||||
buf << " / 0.." << bankCount - 1;
|
||||
if (romBankCount > 1)
|
||||
buf << " / 0.." << romBankCount - 1;
|
||||
buf << "\n;***********************************************************\n\n";
|
||||
|
||||
|
||||
|
@ -1101,7 +1105,7 @@ string CartDebug::saveDisassembly()
|
|||
|
||||
buf << " SEG CODE\n";
|
||||
|
||||
if(bankCount == 1)
|
||||
if(romBankCount == 1)
|
||||
buf << " ORG $" << Base::HEX4 << info.offset << "\n\n";
|
||||
else
|
||||
buf << " ORG $" << Base::HEX4 << origin << "\n"
|
||||
|
@ -1331,7 +1335,7 @@ string CartDebug::saveDisassembly()
|
|||
out << buf.str();
|
||||
|
||||
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 << "saved " << node.getShortPath() << " OK";
|
||||
return retVal.str();
|
||||
|
@ -1371,8 +1375,8 @@ string CartDebug::saveAccessFile()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string CartDebug::listConfig(int bank)
|
||||
{
|
||||
uInt32 startbank = 0, endbank = bankCount();
|
||||
if(bank >= 0 && bank < bankCount())
|
||||
uInt32 startbank = 0, endbank = romBankCount();
|
||||
if(bank >= 0 && bank < romBankCount())
|
||||
{
|
||||
startbank = bank;
|
||||
endbank = startbank + 1;
|
||||
|
@ -1396,7 +1400,7 @@ string CartDebug::listConfig(int bank)
|
|||
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;
|
||||
|
||||
return buf.str();
|
||||
|
@ -1405,8 +1409,8 @@ string CartDebug::listConfig(int bank)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string CartDebug::clearConfig(int bank)
|
||||
{
|
||||
uInt32 startbank = 0, endbank = bankCount();
|
||||
if(bank >= 0 && bank < bankCount())
|
||||
uInt32 startbank = 0, endbank = romBankCount();
|
||||
if(bank >= 0 && bank < romBankCount())
|
||||
{
|
||||
startbank = bank;
|
||||
endbank = startbank + 1;
|
||||
|
|
|
@ -95,7 +95,7 @@ class CartDebug : public DebuggerSystem
|
|||
int lastWriteBaseAddress();
|
||||
|
||||
// TODO
|
||||
bool disassemble(bool force = false);
|
||||
bool disassemblePC(bool force = false);
|
||||
bool disassembleBank(int bank);
|
||||
|
||||
// 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.
|
||||
*/
|
||||
int bankCount() const;
|
||||
int romBankCount() const;
|
||||
|
||||
/**
|
||||
Add a label and associated address.
|
||||
|
|
|
@ -763,7 +763,7 @@ void DebuggerParser::executeBreak()
|
|||
{
|
||||
uInt16 addr;
|
||||
uInt8 bank;
|
||||
uInt32 bankCount = debugger.cartDebug().bankCount();
|
||||
uInt32 romBankCount = debugger.cartDebug().romBankCount();
|
||||
|
||||
if(argCount == 0)
|
||||
addr = debugger.cpuDebug().pc();
|
||||
|
@ -775,7 +775,7 @@ void DebuggerParser::executeBreak()
|
|||
else
|
||||
{
|
||||
bank = args[1];
|
||||
if(bank >= bankCount && bank != 0xff)
|
||||
if(bank >= romBankCount && bank != 0xff)
|
||||
{
|
||||
commandResult << red("invalid bank");
|
||||
return;
|
||||
|
@ -791,12 +791,12 @@ void DebuggerParser::executeBreak()
|
|||
commandResult << "cleared";
|
||||
|
||||
commandResult << " breakpoint at $" << Base::HEX4 << addr << " + mirrors";
|
||||
if(bankCount > 1)
|
||||
if(romBankCount > 1)
|
||||
commandResult << " in bank #" << std::dec << int(bank);
|
||||
}
|
||||
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);
|
||||
|
||||
|
@ -809,7 +809,7 @@ void DebuggerParser::executeBreak()
|
|||
commandResult << "cleared";
|
||||
|
||||
commandResult << " breakpoint at $" << Base::HEX4 << addr << " + mirrors";
|
||||
if(bankCount > 1)
|
||||
if(romBankCount > 1)
|
||||
commandResult << " in bank #" << std::dec << int(bank);
|
||||
}
|
||||
}
|
||||
|
@ -1459,11 +1459,11 @@ void DebuggerParser::executeListbreaks()
|
|||
{
|
||||
stringstream buf;
|
||||
int count = 0;
|
||||
uInt32 bankCount = debugger.cartDebug().bankCount();
|
||||
uInt32 romBankCount = debugger.cartDebug().romBankCount();
|
||||
|
||||
for(const auto& bp : debugger.breakPoints().getBreakpoints())
|
||||
{
|
||||
if(bankCount == 1)
|
||||
if(romBankCount == 1)
|
||||
{
|
||||
buf << debugger.cartDebug().getLabel(bp.addr, true, 4) << " ";
|
||||
if(!(++count % 8)) buf << endl;
|
||||
|
|
|
@ -16,80 +16,25 @@
|
|||
//============================================================================
|
||||
|
||||
#include "Cart0840.hxx"
|
||||
#include "PopUpWidget.hxx"
|
||||
#include "Cart0840Widget.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Cartridge0840Widget::Cartridge0840Widget(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h, Cartridge0840& cart)
|
||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart)
|
||||
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||
{
|
||||
uInt16 size = 2 * 4096;
|
||||
myHotspotDelta = 0x40;
|
||||
initialize();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string Cartridge0840Widget::description()
|
||||
{
|
||||
ostringstream info;
|
||||
info << "0840 ECONObanking, two 4K banks\n"
|
||||
<< "Startup bank = " << cart.startBank() << "\n";
|
||||
|
||||
// Eventually, we should query this from the debugger/disassembler
|
||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0x800; i < 2;
|
||||
++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";
|
||||
}
|
||||
info << "0840 ECONObanking, two 4K banks\n";
|
||||
info << CartridgeEnhancedWidget::description();
|
||||
|
||||
int xpos = 2,
|
||||
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();
|
||||
return info.str();
|
||||
}
|
||||
|
|
|
@ -19,11 +19,10 @@
|
|||
#define CARTRIDGE0840_WIDGET_HXX
|
||||
|
||||
class Cartridge0840;
|
||||
class PopUpWidget;
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
#include "CartEnhancedWidget.hxx"
|
||||
|
||||
class Cartridge0840Widget : public CartDebugWidget
|
||||
class Cartridge0840Widget : public CartridgeEnhancedWidget
|
||||
{
|
||||
public:
|
||||
Cartridge0840Widget(GuiObject* boss, const GUI::Font& lfont,
|
||||
|
@ -33,17 +32,11 @@ class Cartridge0840Widget : public CartDebugWidget
|
|||
virtual ~Cartridge0840Widget() = default;
|
||||
|
||||
private:
|
||||
Cartridge0840& myCart;
|
||||
PopUpWidget* myBank{nullptr};
|
||||
string manufacturer() override { return "Fred X. Quimby"; }
|
||||
|
||||
enum { kBankChanged = 'bkCH' };
|
||||
string description() override;
|
||||
|
||||
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
|
||||
Cartridge0840Widget() = delete;
|
||||
Cartridge0840Widget(const Cartridge0840Widget&) = delete;
|
||||
|
|
|
@ -22,15 +22,18 @@
|
|||
Cartridge2KWidget::Cartridge2KWidget(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
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
|
||||
size_t size = cart.mySize;
|
||||
uInt16 start = (cart.myImage[size-3] << 8) | cart.myImage[size-4];
|
||||
start -= start % size;
|
||||
|
||||
ostringstream info;
|
||||
info << "Standard 2K cartridge, non-bankswitched\n"
|
||||
<< "Accessible @ $" << Common::Base::HEX4 << start << " - " << "$" << (start + size - 1);
|
||||
addBaseInformation(size, "Atari", info.str());
|
||||
initialize();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string Cartridge2KWidget::description()
|
||||
{
|
||||
ostringstream info;
|
||||
|
||||
info << "Standard 2K cartridge, non-bankswitched\n";
|
||||
info << CartridgeEnhancedWidget::description();
|
||||
|
||||
return info.str();
|
||||
}
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
|
||||
class Cartridge2K;
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
#include "CartEnhancedWidget.hxx"
|
||||
|
||||
class Cartridge2KWidget : public CartDebugWidget
|
||||
class Cartridge2KWidget : public CartridgeEnhancedWidget
|
||||
{
|
||||
public:
|
||||
Cartridge2KWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||
|
@ -32,10 +32,11 @@ class Cartridge2KWidget : public CartDebugWidget
|
|||
virtual ~Cartridge2KWidget() = default;
|
||||
|
||||
private:
|
||||
// No implementation for non-bankswitched ROMs
|
||||
void loadConfig() override { }
|
||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override { }
|
||||
string manufacturer() override { return "Atari"; }
|
||||
|
||||
string description() override;
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
Cartridge2KWidget() = delete;
|
||||
Cartridge2KWidget(const Cartridge2KWidget&) = delete;
|
||||
|
|
|
@ -18,121 +18,124 @@
|
|||
#include "Cart3EPlus.hxx"
|
||||
#include "EditTextWidget.hxx"
|
||||
#include "PopUpWidget.hxx"
|
||||
#include "Cart3EPlusWidget.hxx"
|
||||
#include "CartEnhancedWidget.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Cartridge3EPlusWidget::Cartridge3EPlusWidget(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h, Cartridge3EPlus& cart)
|
||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart)
|
||||
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart),
|
||||
myCart3EP(cart)
|
||||
{
|
||||
size_t size = cart.mySize;
|
||||
|
||||
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;
|
||||
}
|
||||
initialize();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
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)
|
||||
myOldState.internalram.push_back(myCart.myRAM[i]);
|
||||
info << "3E+ cartridge - (4..64K ROM + RAM)\n"
|
||||
<< " " << 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()
|
||||
{
|
||||
CartridgeEnhancedWidget::loadConfig();
|
||||
updateUIState();
|
||||
CartDebugWidget::loadConfig();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -159,178 +162,79 @@ void Cartridge3EPlusWidget::handleCommand(CommandSender* sender,
|
|||
}
|
||||
|
||||
// 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)
|
||||
return;
|
||||
|
||||
uInt8 bank = (segment << myCart.BANK_BITS) |
|
||||
(myBankNumber[segment]->getSelected() & myCart.BIT_BANK_MASK);
|
||||
uInt8 bank = myBankWidgets[segment]->getSelected();
|
||||
|
||||
myCart.unlockBank();
|
||||
|
||||
if(myBankType[segment]->getSelectedTag() == "ROM")
|
||||
myCart.bankROM(bank);
|
||||
myCart.bank(bank, segment);
|
||||
else
|
||||
myCart.bankRAM(bank);
|
||||
myCart.bank(bank + myCart.romBankCount(), segment);
|
||||
|
||||
myCart.lockBank();
|
||||
invalidate();
|
||||
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()
|
||||
{
|
||||
// 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)
|
||||
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");
|
||||
if(i % 2 == 0)
|
||||
{
|
||||
myBankNumber[i/2]->clearSelection();
|
||||
myBankType[i/2]->clearSelection();
|
||||
}
|
||||
uInt16 ramBank = bank - myCart.romBankCount();
|
||||
|
||||
buf << "RAM @ $" << Common::Base::HEX4
|
||||
<< (ramBank << myCart3EP.myBankShift) << " (R)";
|
||||
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
|
||||
{
|
||||
ostringstream buf;
|
||||
int bankno = bank & myCart.BIT_BANK_MASK;
|
||||
buf << "ROM @ $" << Common::Base::HEX4
|
||||
<< ((bank << myCart3EP.myBankShift));
|
||||
myBankState[seg * 2]->setText(buf.str());
|
||||
|
||||
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());
|
||||
}
|
||||
buf.str("");
|
||||
buf << "ROM @ $" << Common::Base::HEX4
|
||||
<< ((bank << myCart3EP.myBankShift) + myCart3EP.myBankSize);
|
||||
myBankState[seg * 2 + 1]->setText(buf.str());
|
||||
|
||||
if(i % 2 == 0)
|
||||
{
|
||||
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");
|
||||
}
|
||||
}
|
||||
myBankWidgets[seg]->setSelectedIndex(bank);
|
||||
myBankType[seg]->setSelected("ROM");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 Cartridge3EPlusWidget::internalRamSize()
|
||||
{
|
||||
return 32*1024;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 Cartridge3EPlusWidget::internalRamRPort(int start)
|
||||
{
|
||||
return 0x0000 + start;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string Cartridge3EPlusWidget::internalRamDescription()
|
||||
{
|
||||
ostringstream desc;
|
||||
|
||||
desc << "Accessible 512b at a time via:\n"
|
||||
<< " $f000/$f400/$f800/$fc00 for Read Access\n"
|
||||
<< " $f200/$f600/$fa00/$fe00 for Write Access (+$200)";
|
||||
<< " $f000/$f400/$f800/$fc00 for read access\n"
|
||||
<< " $f200/$f600/$fa00/$fe00 for write access";
|
||||
|
||||
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 = {
|
||||
kBank0Changed, kBank1Changed, kBank2Changed, kBank3Changed
|
||||
|
|
|
@ -23,9 +23,9 @@ class ButtonWidget;
|
|||
class EditTextWidget;
|
||||
class PopUpWidget;
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
#include "CartEnhancedWidget.hxx"
|
||||
|
||||
class Cartridge3EPlusWidget : public CartDebugWidget
|
||||
class Cartridge3EPlusWidget : public CartridgeEnhancedWidget
|
||||
{
|
||||
public:
|
||||
Cartridge3EPlusWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||
|
@ -35,21 +35,27 @@ class Cartridge3EPlusWidget : public CartDebugWidget
|
|||
virtual ~Cartridge3EPlusWidget() = default;
|
||||
|
||||
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();
|
||||
|
||||
private:
|
||||
Cartridge3EPlus& myCart;
|
||||
void loadConfig() override;
|
||||
|
||||
string internalRamDescription() override;
|
||||
|
||||
private:
|
||||
Cartridge3EPlus& myCart3EP;
|
||||
|
||||
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',
|
||||
|
@ -59,22 +65,6 @@ class Cartridge3EPlusWidget : public CartDebugWidget
|
|||
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
|
||||
Cartridge3EPlusWidget() = delete;
|
||||
Cartridge3EPlusWidget(const Cartridge3EPlusWidget&) = delete;
|
||||
|
|
|
@ -23,129 +23,134 @@
|
|||
Cartridge3EWidget::Cartridge3EWidget(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h, Cartridge3E& cart)
|
||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart),
|
||||
myNumRomBanks(uInt32(cart.mySize >> 11)),
|
||||
myNumRamBanks(32)
|
||||
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||
{
|
||||
size_t size = cart.mySize;
|
||||
|
||||
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);
|
||||
initialize();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
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()
|
||||
{
|
||||
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);
|
||||
myRAMBank->setSelectedMax(myOldState.bank >= 256);
|
||||
myBankWidgets[0]->setSelectedIndex(bank, oldBank != bank);
|
||||
myBankWidgets[1]->setSelectedMax(oldBank >= myCart.romBankCount());
|
||||
}
|
||||
else
|
||||
{
|
||||
myROMBank->setSelectedMax(myOldState.bank < 256);
|
||||
myRAMBank->setSelectedIndex(myCart.myCurrentBank - 256, myOldState.bank != myCart.myCurrentBank);
|
||||
myBankWidgets[0]->setSelectedMax(oldBank < myCart.romBankCount());
|
||||
myBankWidgets[1]->setSelectedIndex(bank - myCart.romBankCount(), oldBank != bank);
|
||||
}
|
||||
|
||||
CartDebugWidget::loadConfig();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Cartridge3EWidget::handleCommand(CommandSender* sender,
|
||||
int cmd, int data, int id)
|
||||
void Cartridge3EWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
|
||||
{
|
||||
uInt16 bank = 0;
|
||||
|
||||
if(cmd == kROMBankChanged)
|
||||
if(cmd == kBankChanged)
|
||||
{
|
||||
if(myROMBank->getSelected() < int(myNumRomBanks))
|
||||
if(myBankWidgets[0]->getSelected() < myCart.romBankCount())
|
||||
{
|
||||
bank = myROMBank->getSelected();
|
||||
myRAMBank->setSelectedMax();
|
||||
bank = myBankWidgets[0]->getSelected();
|
||||
myBankWidgets[1]->setSelectedMax();
|
||||
}
|
||||
else
|
||||
{
|
||||
bank = 256; // default to first RAM bank
|
||||
myRAMBank->setSelectedIndex(0);
|
||||
bank = myCart.romBankCount(); // default to first RAM bank
|
||||
myBankWidgets[1]->setSelectedIndex(0);
|
||||
}
|
||||
}
|
||||
else if(cmd == kRAMBankChanged)
|
||||
{
|
||||
if(myRAMBank->getSelected() < int(myNumRamBanks))
|
||||
if(myBankWidgets[1]->getSelected() < myCart.ramBankCount())
|
||||
{
|
||||
myROMBank->setSelectedMax();
|
||||
bank = myRAMBank->getSelected() + 256;
|
||||
myBankWidgets[0]->setSelectedMax();
|
||||
bank = myBankWidgets[1]->getSelected() + myCart.romBankCount();
|
||||
}
|
||||
else
|
||||
{
|
||||
bank = 0; // default to first ROM bank
|
||||
myROMBank->setSelectedIndex(0);
|
||||
myBankWidgets[0]->setSelectedIndex(0);
|
||||
}
|
||||
}
|
||||
|
||||
myCart.unlockBank();
|
||||
myCart.bank(bank);
|
||||
myCart.lockBank();
|
||||
|
@ -156,65 +161,13 @@ void Cartridge3EWidget::handleCommand(CommandSender* sender,
|
|||
string Cartridge3EWidget::bankState()
|
||||
{
|
||||
ostringstream& buf = buffer();
|
||||
uInt16 bank = myCart.getBank();
|
||||
|
||||
uInt16& bank = myCart.myCurrentBank;
|
||||
if(bank < 256)
|
||||
buf << "ROM bank #" << std::dec << bank % myNumRomBanks << ", RAM inactive";
|
||||
if(bank < myCart.romBankCount())
|
||||
buf << "ROM bank #" << std::dec << bank % myCart.romBankCount() << ", RAM inactive";
|
||||
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();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
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
|
||||
|
||||
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:
|
||||
Cartridge3EWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||
|
@ -33,39 +34,28 @@ class Cartridge3EWidget : public CartDebugWidget
|
|||
virtual ~Cartridge3EWidget() = default;
|
||||
|
||||
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 {
|
||||
kROMBankChanged = 'rmCH',
|
||||
kRAMBankChanged = 'raCH'
|
||||
};
|
||||
|
||||
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 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
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
Cartridge3EWidget() = delete;
|
||||
Cartridge3EWidget(const Cartridge3EWidget&) = delete;
|
||||
|
|
|
@ -16,79 +16,33 @@
|
|||
//============================================================================
|
||||
|
||||
#include "Cart3F.hxx"
|
||||
#include "PopUpWidget.hxx"
|
||||
#include "Cart3FWidget.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Cartridge3FWidget::Cartridge3FWidget(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h, Cartridge3F& cart)
|
||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart)
|
||||
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||
{
|
||||
size_t size = cart.mySize;
|
||||
myHotspotDelta = 0;
|
||||
initialize();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string Cartridge3FWidget::description()
|
||||
{
|
||||
ostringstream info;
|
||||
info << "Tigervision 3F cartridge, 2-256 2K banks\n"
|
||||
<< "Startup bank = " << cart.startBank() << " or undetermined\n"
|
||||
<< "First 2K bank selected by writing to $3F\n"
|
||||
<< "Last 2K always points to last 2K of ROM\n";
|
||||
size_t size;
|
||||
const uInt8* image = myCart.getImage(size);
|
||||
|
||||
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
|
||||
uInt16 start = (cart.myImage[size-3] << 8) | cart.myImage[size-4];
|
||||
uInt16 start = (image[size-3] << 8) | image[size-4];
|
||||
start -= start % 0x1000;
|
||||
info << "Bank RORG" << " = $" << Common::Base::HEX4 << start << "\n";
|
||||
info << "Bank RORG $" << Common::Base::HEX4 << start << "\n";
|
||||
|
||||
int xpos = 2,
|
||||
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();
|
||||
return info.str();
|
||||
}
|
||||
|
|
|
@ -19,11 +19,10 @@
|
|||
#define CARTRIDGE3F_WIDGET_HXX
|
||||
|
||||
class Cartridge3F;
|
||||
class PopUpWidget;
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
#include "CartEnhancedWidget.hxx"
|
||||
|
||||
class Cartridge3FWidget : public CartDebugWidget
|
||||
class Cartridge3FWidget : public CartridgeEnhancedWidget
|
||||
{
|
||||
public:
|
||||
Cartridge3FWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||
|
@ -33,17 +32,13 @@ class Cartridge3FWidget : public CartDebugWidget
|
|||
virtual ~Cartridge3FWidget() = default;
|
||||
|
||||
private:
|
||||
Cartridge3F& myCart;
|
||||
PopUpWidget* myBank{nullptr};
|
||||
string manufacturer() override { return "TigerVision"; }
|
||||
|
||||
enum { kBankChanged = 'bkCH' };
|
||||
string description() override;
|
||||
|
||||
uInt16 bankSegs() override { return 1; }
|
||||
|
||||
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
|
||||
Cartridge3FWidget() = delete;
|
||||
Cartridge3FWidget(const Cartridge3FWidget&) = delete;
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//============================================================================
|
||||
|
||||
#include "Debugger.hxx"
|
||||
#include "CartDebug.hxx"
|
||||
#include "Cart4KSC.hxx"
|
||||
#include "Cart4KSCWidget.hxx"
|
||||
|
||||
|
@ -24,87 +22,18 @@
|
|||
Cartridge4KSCWidget::Cartridge4KSCWidget(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h, Cartridge4KSC& cart)
|
||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart)
|
||||
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||
{
|
||||
// Eventually, we should query this from the debugger/disassembler
|
||||
uInt16 start = (cart.myImage[0xFFD] << 8) | cart.myImage[0xFFC];
|
||||
start -= start % 0x1000;
|
||||
initialize();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string Cartridge4KSCWidget::description()
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
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);
|
||||
info << "4KSC cartridge, non-bankswitched\n";
|
||||
info << CartridgeEnhancedWidget::description();
|
||||
|
||||
return info.str();
|
||||
}
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
|
||||
class Cartridge4KSC;
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
#include "CartEnhancedWidget.hxx"
|
||||
|
||||
class Cartridge4KSCWidget : public CartDebugWidget
|
||||
class Cartridge4KSCWidget : public CartridgeEnhancedWidget
|
||||
{
|
||||
public:
|
||||
Cartridge4KSCWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||
|
@ -32,30 +32,11 @@ class Cartridge4KSCWidget : public CartDebugWidget
|
|||
virtual ~Cartridge4KSCWidget() = default;
|
||||
|
||||
private:
|
||||
Cartridge4KSC& myCart;
|
||||
struct CartState {
|
||||
ByteArray internalram;
|
||||
};
|
||||
CartState myOldState;
|
||||
string manufacturer() override { return "homebrew intermediate format"; }
|
||||
|
||||
string description() override;
|
||||
|
||||
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
|
||||
Cartridge4KSCWidget() = delete;
|
||||
Cartridge4KSCWidget(const Cartridge4KSCWidget&) = delete;
|
||||
|
|
|
@ -22,15 +22,29 @@
|
|||
Cartridge4KWidget::Cartridge4KWidget(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
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
|
||||
uInt16 start = (cart.myImage[0xFFD] << 8) | cart.myImage[0xFFC];
|
||||
start -= start % 0x1000;
|
||||
initialize();
|
||||
|
||||
ostringstream info;
|
||||
info << "Standard 4K cartridge, non-bankswitched\n"
|
||||
<< "Accessible @ $" << Common::Base::HEX4 << start << " - "
|
||||
<< "$" << (start + 0xFFF);
|
||||
addBaseInformation(4096, "Atari", info.str());
|
||||
//// Eventually, we should query this from the debugger/disassembler
|
||||
//uInt16 start = (cart.myImage[0xFFD] << 8) | cart.myImage[0xFFC];
|
||||
//start -= start % 0x1000;
|
||||
|
||||
//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;
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
#include "CartEnhanced.hxx"
|
||||
|
||||
class Cartridge4KWidget : public CartDebugWidget
|
||||
class Cartridge4KWidget : public CartridgeEnhancedWidget
|
||||
{
|
||||
public:
|
||||
Cartridge4KWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||
|
@ -32,10 +32,11 @@ class Cartridge4KWidget : public CartDebugWidget
|
|||
virtual ~Cartridge4KWidget() = default;
|
||||
|
||||
private:
|
||||
// No implementation for non-bankswitched ROMs
|
||||
void loadConfig() override { }
|
||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override { }
|
||||
string manufacturer() override { return "Atari"; }
|
||||
|
||||
string description() override;
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
Cartridge4KWidget() = delete;
|
||||
Cartridge4KWidget(const Cartridge4KWidget&) = delete;
|
||||
|
|
|
@ -15,221 +15,25 @@
|
|||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//============================================================================
|
||||
|
||||
#include "Debugger.hxx"
|
||||
#include "CartDebug.hxx"
|
||||
#include "CartBFSC.hxx"
|
||||
#include "PopUpWidget.hxx"
|
||||
#include "CartBFSCWidget.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartridgeBFSCWidget::CartridgeBFSCWidget(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h, CartridgeBFSC& cart)
|
||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart)
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h, CartridgeBFSC& cart)
|
||||
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||
{
|
||||
uInt32 size = 64 * 4096;
|
||||
initialize();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string CartridgeBFSCWidget::description()
|
||||
{
|
||||
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
|
||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0xF80; i < 64; ++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 + 0x100)
|
||||
<< " - " << "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n";
|
||||
}
|
||||
info << "256K BFSC + RAM, 64 4K banks\n";
|
||||
info << CartridgeEnhancedWidget::description();
|
||||
|
||||
int xpos = 2,
|
||||
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);
|
||||
return info.str();
|
||||
}
|
||||
|
|
|
@ -19,11 +19,10 @@
|
|||
#define CARTRIDGEBFSC_WIDGET_HXX
|
||||
|
||||
class CartridgeBFSC;
|
||||
class PopUpWidget;
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
#include "CartEnhancedWidget.hxx"
|
||||
|
||||
class CartridgeBFSCWidget : public CartDebugWidget
|
||||
class CartridgeBFSCWidget : public CartridgeEnhancedWidget
|
||||
{
|
||||
public:
|
||||
CartridgeBFSCWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||
|
@ -33,35 +32,11 @@ class CartridgeBFSCWidget : public CartDebugWidget
|
|||
virtual ~CartridgeBFSCWidget() = default;
|
||||
|
||||
private:
|
||||
CartridgeBFSC& myCart;
|
||||
PopUpWidget* myBank{nullptr};
|
||||
string manufacturer() override { return "CPUWIZ"; }
|
||||
|
||||
struct CartState {
|
||||
ByteArray internalram;
|
||||
uInt16 bank{0};
|
||||
};
|
||||
CartState myOldState;
|
||||
|
||||
enum { kBankChanged = 'bkCH' };
|
||||
string description() override;
|
||||
|
||||
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
|
||||
CartridgeBFSCWidget() = delete;
|
||||
CartridgeBFSCWidget(const CartridgeBFSCWidget&) = delete;
|
||||
|
|
|
@ -16,151 +16,24 @@
|
|||
//============================================================================
|
||||
|
||||
#include "CartBF.hxx"
|
||||
#include "PopUpWidget.hxx"
|
||||
#include "CartBFWidget.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartridgeBFWidget::CartridgeBFWidget(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h, CartridgeBF& cart)
|
||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart)
|
||||
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||
{
|
||||
uInt32 size = 64 * 4096;
|
||||
initialize();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string CartridgeBFWidget::description()
|
||||
{
|
||||
ostringstream info;
|
||||
info << "BF cartridge, 64 4K banks\n"
|
||||
<< "Startup bank = " << cart.startBank() << "\n";
|
||||
|
||||
// Eventually, we should query this from the debugger/disassembler
|
||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0xF80; i < 64; ++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) << " (hotspot = $F" << (spot+i) << ")\n";
|
||||
}
|
||||
info << "256K BF cartridge, 64 4K banks\n";
|
||||
info << CartridgeEnhancedWidget::description();
|
||||
|
||||
int xpos = 2,
|
||||
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();
|
||||
return info.str();
|
||||
}
|
||||
|
|
|
@ -19,11 +19,10 @@
|
|||
#define CARTRIDGEBF_WIDGET_HXX
|
||||
|
||||
class CartridgeBF;
|
||||
class PopUpWidget;
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
#include "CartEnhancedWidget.hxx"
|
||||
|
||||
class CartridgeBFWidget : public CartDebugWidget
|
||||
class CartridgeBFWidget : public CartridgeEnhancedWidget
|
||||
{
|
||||
public:
|
||||
CartridgeBFWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||
|
@ -33,17 +32,11 @@ class CartridgeBFWidget : public CartDebugWidget
|
|||
virtual ~CartridgeBFWidget() = default;
|
||||
|
||||
private:
|
||||
CartridgeBF& myCart;
|
||||
PopUpWidget* myBank{nullptr};
|
||||
string manufacturer() override { return "CPUWIZ"; }
|
||||
|
||||
enum { kBankChanged = 'bkCH' };
|
||||
string description() override;
|
||||
|
||||
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
|
||||
CartridgeBFWidget() = delete;
|
||||
CartridgeBFWidget(const CartridgeBFWidget&) = delete;
|
||||
|
|
|
@ -238,7 +238,7 @@ void CartridgeBUSWidget::saveOldState()
|
|||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
@ -438,18 +438,18 @@ const ByteArray& CartridgeBUSWidget::internalRamCurrent(int start, int count)
|
|||
{
|
||||
myRamCurrent.clear();
|
||||
for(int i = 0; i < count; i++)
|
||||
myRamCurrent.push_back(myCart.myBUSRAM[start + i]);
|
||||
myRamCurrent.push_back(myCart.myRAM[start + i]);
|
||||
return myRamCurrent;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeBUSWidget::internalRamSetValue(int addr, uInt8 value)
|
||||
{
|
||||
myCart.myBUSRAM[addr] = value;
|
||||
myCart.myRAM[addr] = value;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
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)
|
||||
myOldState.internalram.push_back(myCart.myCDFRAM[i]);
|
||||
myOldState.internalram.push_back(myCart.myRAM[i]);
|
||||
|
||||
myOldState.samplepointer.push_back(myCart.getSample());
|
||||
}
|
||||
|
@ -437,20 +437,20 @@ const ByteArray& CartridgeCDFWidget::internalRamCurrent(int start, int count)
|
|||
{
|
||||
myRamCurrent.clear();
|
||||
for(int i = 0; i < count; i++)
|
||||
myRamCurrent.push_back(myCart.myCDFRAM[start + i]);
|
||||
myRamCurrent.push_back(myCart.myRAM[start + i]);
|
||||
return myRamCurrent;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeCDFWidget::internalRamSetValue(int addr, uInt8 value)
|
||||
{
|
||||
myCart.myCDFRAM[addr] = value;
|
||||
myCart.myRAM[addr] = value;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
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(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h, CartridgeCV& cart)
|
||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart)
|
||||
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||
{
|
||||
// Eventually, we should query this from the debugger/disassembler
|
||||
uInt16 size = 2048;
|
||||
uInt16 start = (cart.myImage[size-3] << 8) | cart.myImage[size-4];
|
||||
start -= start % size;
|
||||
initialize();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string CartridgeCVWidget::description()
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
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);
|
||||
info << "CV 2K ROM + 1K RAM, non-bankswitched\n";
|
||||
info << CartridgeEnhancedWidget::description();
|
||||
|
||||
return info.str();
|
||||
}
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
|
||||
class CartridgeCV;
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
#include "CartEnhancedWidget.hxx"
|
||||
|
||||
class CartridgeCVWidget : public CartDebugWidget
|
||||
class CartridgeCVWidget : public CartridgeEnhancedWidget
|
||||
{
|
||||
public:
|
||||
CartridgeCVWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||
|
@ -32,30 +32,11 @@ class CartridgeCVWidget : public CartDebugWidget
|
|||
virtual ~CartridgeCVWidget() = default;
|
||||
|
||||
private:
|
||||
CartridgeCV& myCart;
|
||||
struct CartState {
|
||||
ByteArray internalram;
|
||||
};
|
||||
CartState myOldState;
|
||||
string manufacturer() override { return "CommaVid"; }
|
||||
|
||||
string description() override;
|
||||
|
||||
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
|
||||
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.
|
||||
//============================================================================
|
||||
|
||||
#include "Debugger.hxx"
|
||||
#include "CartDebug.hxx"
|
||||
#include "CartDFSC.hxx"
|
||||
#include "PopUpWidget.hxx"
|
||||
#include "CartDFSCWidget.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartridgeDFSCWidget::CartridgeDFSCWidget(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h, CartridgeDFSC& cart)
|
||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart)
|
||||
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||
{
|
||||
uInt32 size = 32 * 4096;
|
||||
initialize();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string CartridgeDFSCWidget::description()
|
||||
{
|
||||
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
|
||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0xFC0; i < 32; ++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 + 0x100)
|
||||
<< " - " << "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n";
|
||||
}
|
||||
info << "128K DFSC + RAM, 32 4K banks\n";
|
||||
info << CartridgeEnhancedWidget::description();
|
||||
|
||||
int xpos = 2,
|
||||
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);
|
||||
return info.str();
|
||||
}
|
||||
|
|
|
@ -19,11 +19,10 @@
|
|||
#define CARTRIDGEDFSC_WIDGET_HXX
|
||||
|
||||
class CartridgeDFSC;
|
||||
class PopUpWidget;
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
#include "CartEnhancedWidget.hxx"
|
||||
|
||||
class CartridgeDFSCWidget : public CartDebugWidget
|
||||
class CartridgeDFSCWidget : public CartridgeEnhancedWidget
|
||||
{
|
||||
public:
|
||||
CartridgeDFSCWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||
|
@ -33,35 +32,11 @@ class CartridgeDFSCWidget : public CartDebugWidget
|
|||
virtual ~CartridgeDFSCWidget() = default;
|
||||
|
||||
private:
|
||||
CartridgeDFSC& myCart;
|
||||
PopUpWidget* myBank{nullptr};
|
||||
string manufacturer() override { return "CPUWIZ"; }
|
||||
|
||||
struct CartState {
|
||||
ByteArray internalram;
|
||||
uInt16 bank{0};
|
||||
};
|
||||
CartState myOldState;
|
||||
|
||||
enum { kBankChanged = 'bkCH' };
|
||||
string description() override;
|
||||
|
||||
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
|
||||
CartridgeDFSCWidget() = delete;
|
||||
CartridgeDFSCWidget(const CartridgeDFSCWidget&) = delete;
|
||||
|
|
|
@ -16,115 +16,24 @@
|
|||
//============================================================================
|
||||
|
||||
#include "CartDF.hxx"
|
||||
#include "PopUpWidget.hxx"
|
||||
#include "CartDFWidget.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartridgeDFWidget::CartridgeDFWidget(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h, CartridgeDF& cart)
|
||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart)
|
||||
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||
{
|
||||
uInt32 size = 32 * 4096;
|
||||
initialize();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string CartridgeDFWidget::description()
|
||||
{
|
||||
ostringstream info;
|
||||
info << "EF 2 cartridge, 32 4K banks\n"
|
||||
<< "Startup bank = " << cart.startBank() << "\n";
|
||||
|
||||
// Eventually, we should query this from the debugger/disassembler
|
||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0xFD0; i < 32; ++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) << " (hotspot = $F" << (spot+i) << ")\n";
|
||||
}
|
||||
info << "128K DF, 32 4K banks\n";
|
||||
info << CartridgeEnhancedWidget::description();
|
||||
|
||||
int xpos = 2,
|
||||
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();
|
||||
return info.str();
|
||||
}
|
||||
|
|
|
@ -19,11 +19,10 @@
|
|||
#define CARTRIDGEDF_WIDGET_HXX
|
||||
|
||||
class CartridgeDF;
|
||||
class PopUpWidget;
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
#include "CartEnhancedWidget.hxx"
|
||||
|
||||
class CartridgeDFWidget : public CartDebugWidget
|
||||
class CartridgeDFWidget : public CartridgeEnhancedWidget
|
||||
{
|
||||
public:
|
||||
CartridgeDFWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||
|
@ -33,17 +32,11 @@ class CartridgeDFWidget : public CartDebugWidget
|
|||
virtual ~CartridgeDFWidget() = default;
|
||||
|
||||
private:
|
||||
CartridgeDF& myCart;
|
||||
PopUpWidget* myBank{nullptr};
|
||||
string manufacturer() override { return "CPUWIZ"; }
|
||||
|
||||
enum { kBankChanged = 'bkCH' };
|
||||
string description() override;
|
||||
|
||||
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
|
||||
CartridgeDFWidget() = delete;
|
||||
CartridgeDFWidget(const CartridgeDFWidget&) = delete;
|
||||
|
|
|
@ -27,12 +27,13 @@ CartridgeDPCWidget::CartridgeDPCWidget(
|
|||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart)
|
||||
{
|
||||
const int V_GAP = 4;
|
||||
size_t size = cart.mySize;
|
||||
|
||||
ostringstream info;
|
||||
|
||||
info << "DPC cartridge, two 4K banks + 2K display bank\n"
|
||||
<< "DPC registers accessible @ $F000 - $F07F\n"
|
||||
<< " $F000 - $F03F (R), $F040 - $F07F (W)\n"
|
||||
<< "DPC registers accessible @ $" << Common::Base::HEX4 << 0xF000 << " - $" << 0xF07F << "\n"
|
||||
<< " $" << 0xF000 << " - " << 0xF03F << " (R), $" << 0xF040 << " - $" << 0xF07F << " (W)\n"
|
||||
|
||||
<< "Startup bank = " << cart.startBank() << " or undetermined\n";
|
||||
|
||||
|
@ -42,7 +43,7 @@ CartridgeDPCWidget::CartridgeDPCWidget(
|
|||
uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset];
|
||||
start -= start % 0x1000;
|
||||
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,
|
||||
|
@ -50,26 +51,30 @@ CartridgeDPCWidget::CartridgeDPCWidget(
|
|||
myLineHeight;
|
||||
|
||||
VariantList items;
|
||||
VarList::push_back(items, "0 ($FFF8)");
|
||||
VarList::push_back(items, "1 ($FFF9)");
|
||||
for(int bank = 0; bank < 2; ++bank)
|
||||
{
|
||||
ostringstream buf;
|
||||
|
||||
buf << "#" << std::dec << bank << " ($" << Common::Base::HEX4 << (0xFFF8 + bank) << ")";
|
||||
VarList::push_back(items, buf.str());
|
||||
}
|
||||
|
||||
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 ",
|
||||
0, kBankChanged);
|
||||
myBank->setTarget(this);
|
||||
addFocusWidget(myBank);
|
||||
ypos += myLineHeight + 8;
|
||||
ypos += myLineHeight + V_GAP * 3;
|
||||
|
||||
// Data fetchers
|
||||
int lwidth = _font.getStringWidth("Data Fetchers ");
|
||||
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
||||
myFontHeight, "Data Fetchers ", TextAlign::Left);
|
||||
int lwidth = _font.getStringWidth("Data fetchers ");
|
||||
new StaticTextWidget(boss, _font, xpos, ypos, "Data fetchers ");
|
||||
|
||||
// Top registers
|
||||
lwidth = _font.getStringWidth("Counter Registers ");
|
||||
xpos = 18; ypos += myLineHeight + 4;
|
||||
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
||||
myFontHeight, "Top Registers ", TextAlign::Left);
|
||||
lwidth = _font.getStringWidth("Counter registers ");
|
||||
xpos = 2 + _font.getMaxCharWidth() * 2; ypos += myLineHeight + 4;
|
||||
new StaticTextWidget(boss, _font, xpos, ypos, "Top registers ");
|
||||
xpos += lwidth;
|
||||
|
||||
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);
|
||||
|
||||
// Bottom registers
|
||||
xpos = 10; ypos += myLineHeight + 4;
|
||||
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
||||
myFontHeight, "Bottom Registers ", TextAlign::Left);
|
||||
xpos = 2 + _font.getMaxCharWidth() * 2; ypos += myLineHeight + 4;
|
||||
new StaticTextWidget(boss, _font, xpos, ypos, "Bottom registers ");
|
||||
xpos += lwidth;
|
||||
|
||||
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);
|
||||
|
||||
// Counter registers
|
||||
xpos = 10; ypos += myLineHeight + 4;
|
||||
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
||||
myFontHeight, "Counter Registers ", TextAlign::Left);
|
||||
xpos = 2 + _font.getMaxCharWidth() * 2; ypos += myLineHeight + 4;
|
||||
new StaticTextWidget(boss, _font, xpos, ypos, "Counter registers ");
|
||||
xpos += lwidth;
|
||||
|
||||
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);
|
||||
|
||||
// Flag registers
|
||||
xpos = 10; ypos += myLineHeight + 4;
|
||||
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
||||
myFontHeight, "Flag Registers ", TextAlign::Left);
|
||||
xpos = 2 + _font.getMaxCharWidth() * 2; ypos += myLineHeight + 4;
|
||||
new StaticTextWidget(boss, _font, xpos, ypos, "Flag registers ");
|
||||
xpos += lwidth;
|
||||
|
||||
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);
|
||||
|
||||
// Music mode
|
||||
xpos = 2; ypos += myLineHeight + 12;
|
||||
xpos = 2; ypos += myLineHeight + V_GAP * 3;
|
||||
lwidth = _font.getStringWidth("Music mode (DF5/DF6/DF7) ");
|
||||
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
||||
myFontHeight, "Music mode (DF5/DF6/DF7) ", TextAlign::Left);
|
||||
new StaticTextWidget(boss, _font, xpos, ypos, "Music mode (DF5/DF6/DF7) ");
|
||||
xpos += lwidth;
|
||||
|
||||
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);
|
||||
|
||||
// Current random number
|
||||
xpos = 10; ypos += myLineHeight + 4;
|
||||
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
||||
myFontHeight, "Current random number ", TextAlign::Left);
|
||||
xpos = 2; ypos += myLineHeight + V_GAP * 3;
|
||||
new StaticTextWidget(boss, _font, xpos, ypos, "Current random number ");
|
||||
xpos += lwidth;
|
||||
|
||||
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();
|
||||
|
||||
static constexpr std::array<const char*, 2> spot = { "$FFF8", "$FFF9" };
|
||||
buf << "Bank = " << std::dec << myCart.getBank()
|
||||
<< ", hotspot = " << spot[myCart.getBank()];
|
||||
buf << "Bank #" << std::dec << myCart.getBank()
|
||||
<< " (hotspot $" << Common::Base::HEX4 << (0xFFF8 + myCart.getBank()) << ")";
|
||||
|
||||
return buf.str();
|
||||
}
|
||||
|
@ -252,10 +251,9 @@ uInt32 CartridgeDPCWidget::internalRamRPort(int start)
|
|||
string CartridgeDPCWidget::internalRamDescription()
|
||||
{
|
||||
ostringstream desc;
|
||||
desc << "$0000 - $07FF - 2K display data\n"
|
||||
<< " indirectly accessible to 6507\n"
|
||||
<< " via DPC+'s Data Fetcher\n"
|
||||
<< " registers\n";
|
||||
desc << "2K display data @ $0000 - $" << Common::Base::HEX4 << 0x07FF << "\n"
|
||||
<< " indirectly accessible to 6507 via DPC's\n"
|
||||
<< " data fetcher registers\n";
|
||||
|
||||
return desc.str();
|
||||
}
|
||||
|
|
|
@ -75,6 +75,7 @@ class CartridgeDPCWidget : public CartDebugWidget
|
|||
const ByteArray& internalRamCurrent(int start, int count) override;
|
||||
void internalRamSetValue(int addr, uInt8 value) override;
|
||||
uInt8 internalRamGetValue(int addr) override;
|
||||
string tabLabel() override { return " DPC Display Data "; }
|
||||
// end of functions for Cartridge RAM tab
|
||||
|
||||
// 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 int lwidth = _font.getStringWidth("Manufacturer "),
|
||||
fwidth = _w - lwidth - 20;
|
||||
fwidth = _w - lwidth - 12;
|
||||
EditTextWidget* w = nullptr;
|
||||
ostringstream buf;
|
||||
|
||||
int x = 2, y = 8;
|
||||
|
||||
// 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";
|
||||
if(bytes >= 1024)
|
||||
buf << " / " << (bytes/1024) << "KB";
|
||||
|
|
|
@ -58,7 +58,7 @@ class CartDebugWidget : public Widget, public CommandSender
|
|||
virtual string bankState() { return "0 (non-bankswitched)"; }
|
||||
|
||||
// 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 internalRamRPort(int start) { return 0; }
|
||||
virtual string internalRamDescription() { return EmptyString; }
|
||||
|
@ -67,6 +67,7 @@ class CartDebugWidget : public Widget, public CommandSender
|
|||
virtual void internalRamSetValue(int addr, uInt8 value) { }
|
||||
virtual uInt8 internalRamGetValue(int addr) { return 0; }
|
||||
virtual string internalRamLabel(int addr) { return "Not available/applicable"; }
|
||||
virtual string tabLabel() { return " Cartridge RAM "; }
|
||||
|
||||
protected:
|
||||
// Arrays used to hold current and previous internal RAM values
|
||||
|
|
|
@ -16,129 +16,59 @@
|
|||
//============================================================================
|
||||
|
||||
#include "CartE0.hxx"
|
||||
#include "PopUpWidget.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(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h, CartridgeE0& cart)
|
||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart)
|
||||
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||
{
|
||||
uInt32 size = 8 * 1024;
|
||||
initialize();
|
||||
}
|
||||
|
||||
string info =
|
||||
"E0 cartridge, eight 1K slices\n"
|
||||
"Segment 0 accessible @ $F000 - $F3FF\n"
|
||||
" Hotspots $FE0 to $FE7\n"
|
||||
"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";
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string CartridgeE0Widget::description()
|
||||
{
|
||||
ostringstream info;
|
||||
|
||||
#if 0
|
||||
// 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" << " = $" << HEX4 << start << "\n";
|
||||
#endif
|
||||
int xpos = 2,
|
||||
ypos = addBaseInformation(size, "Parker Brothers", info) + myLineHeight;
|
||||
info << "E0 cartridge,\n eight 1K banks mapped into four segments\n";
|
||||
info << CartridgeEnhancedWidget::description();
|
||||
|
||||
VariantList items0, items1, items2;
|
||||
for(int i = 0; i < 8; ++i)
|
||||
return info.str();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string CartridgeE0Widget::romDescription()
|
||||
{
|
||||
ostringstream info;
|
||||
|
||||
for(int seg = 0; seg < 4; ++seg)
|
||||
{
|
||||
VarList::push_back(items0, seg0[i]);
|
||||
VarList::push_back(items1, seg1[i]);
|
||||
VarList::push_back(items2, seg2[i]);
|
||||
uInt16 segmentOffset = seg << 10; // myCart.myBankShift;
|
||||
|
||||
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 ");
|
||||
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);
|
||||
return info.str();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeE0Widget::loadConfig()
|
||||
string CartridgeE0Widget::hotspotStr(int bank, int segment, bool noBrackets)
|
||||
{
|
||||
mySlice0->setSelectedIndex(myCart.myCurrentSlice[0]);
|
||||
mySlice1->setSelectedIndex(myCart.myCurrentSlice[1]);
|
||||
mySlice2->setSelectedIndex(myCart.myCurrentSlice[2]);
|
||||
ostringstream info;
|
||||
uInt16 hotspot = myCart.hotspot();
|
||||
|
||||
CartDebugWidget::loadConfig();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeE0Widget::handleCommand(CommandSender* sender,
|
||||
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();
|
||||
info << (noBrackets ? "" : "(");
|
||||
info << "$" << Common::Base::HEX1 << (hotspot + bank + segment * 8);
|
||||
info << (noBrackets ? "" : ")");
|
||||
|
||||
return info.str();
|
||||
}
|
||||
|
|
|
@ -19,11 +19,10 @@
|
|||
#define CARTRIDGEE0_WIDGET_HXX
|
||||
|
||||
class CartridgeE0;
|
||||
class PopUpWidget;
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
#include "CartEnhancedWidget.hxx"
|
||||
|
||||
class CartridgeE0Widget : public CartDebugWidget
|
||||
class CartridgeE0Widget : public CartridgeEnhancedWidget
|
||||
{
|
||||
public:
|
||||
CartridgeE0Widget(GuiObject* boss, const GUI::Font& lfont,
|
||||
|
@ -33,21 +32,17 @@ class CartridgeE0Widget : public CartDebugWidget
|
|||
virtual ~CartridgeE0Widget() = default;
|
||||
|
||||
private:
|
||||
CartridgeE0& myCart;
|
||||
PopUpWidget *mySlice0{nullptr}, *mySlice1{nullptr}, *mySlice2{nullptr};
|
||||
string manufacturer() override { return "Parker Brothers"; }
|
||||
|
||||
enum {
|
||||
kSlice0Changed = 's0CH',
|
||||
kSlice1Changed = 's1CH',
|
||||
kSlice2Changed = 's2CH'
|
||||
};
|
||||
string description() override;
|
||||
|
||||
string romDescription() override;
|
||||
|
||||
string hotspotStr(int bank, int segment, bool noBrackets = false) override;
|
||||
|
||||
uInt16 bankSegs() override { return 3; }
|
||||
|
||||
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
|
||||
CartridgeE0Widget() = delete;
|
||||
CartridgeE0Widget(const CartridgeE0Widget&) = delete;
|
||||
|
|
|
@ -27,17 +27,18 @@ CartridgeE78KWidget::CartridgeE78KWidget(
|
|||
: CartridgeMNetworkWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||
{
|
||||
ostringstream info;
|
||||
info << "E78K cartridge, 4 2K slices ROM + 2 1K RAM\n"
|
||||
<< "Lower 2K accessible @ $F000 - $F7FF\n"
|
||||
<< " Slice 0 - 2 of ROM (hotspots $FE4 to $FE6)\n"
|
||||
<< " Slice 7 (1K) of RAM (hotspot $FE7)\n"
|
||||
<< " $F400 - $F7FF (R), $F000 - $F3FF (W)\n"
|
||||
<< "256B RAM accessible @ $F800 - $F9FF\n"
|
||||
<< " Hotspots $FE8 - $FEB (256B of RAM slice 1)\n"
|
||||
<< " $F900 - $F9FF (R), $F800 - $F8FF (W)\n"
|
||||
<< "Upper 1.5K ROM accessible @ $FA00 - $FFFF\n"
|
||||
<< " Always points to last 1.5K of ROM\n"
|
||||
<< "Startup slices = 0 / 0 or undetermined\n";
|
||||
info << "E78K cartridge, four 2K banks ROM + 2K RAM,\n"
|
||||
<< " mapped into three segments\n"
|
||||
<< "Lower 2K accessible @ $F000 - $F7FF\n"
|
||||
<< " ROM banks 0 - 2 (hotspots $FFE4 to $FFE6)\n"
|
||||
<< " 1K RAM bank 3 (hotspot $FFE7)\n"
|
||||
<< " $F400 - $F7FF (R), $F000 - $F3FF (W)\n"
|
||||
<< "256B RAM accessible @ $F800 - $F9FF\n"
|
||||
<< " RAM banks 0 - 3 (hotspots $FFE8 - $FFEB)\n"
|
||||
<< " $F900 - $F9FF (R), $F800 - $F8FF (W)\n"
|
||||
<< "Upper 1.5K ROM accessible @ $FA00 - $FFFF\n"
|
||||
<< " Always points to last 1.5K of ROM\n"
|
||||
<< "Startup segments = 0 / 0 or undetermined\n";
|
||||
|
||||
#if 0
|
||||
// Eventually, we should query this from the debugger/disassembler
|
||||
|
@ -53,7 +54,7 @@ CartridgeE78KWidget::CartridgeE78KWidget(
|
|||
const char* CartridgeE78KWidget::getSpotLower(int idx)
|
||||
{
|
||||
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];
|
||||
|
@ -63,7 +64,7 @@ const char* CartridgeE78KWidget::getSpotLower(int idx)
|
|||
const char* CartridgeE78KWidget::getSpotUpper(int idx)
|
||||
{
|
||||
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];
|
||||
|
|
|
@ -26,17 +26,18 @@ CartridgeE7Widget::CartridgeE7Widget(
|
|||
: CartridgeMNetworkWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||
{
|
||||
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"
|
||||
<< " Slice 0 - 6 of ROM (hotspots $FE0 to $FE6)\n"
|
||||
<< " Slice 7 (1K) of RAM (hotspot $FE7)\n"
|
||||
<< " ROM Banks 0 - 6 (hotspots $FFE0 to $FFE6)\n"
|
||||
<< " 1K RAM Bank 7 (hotspot $FFE7)\n"
|
||||
<< " $F400 - $F7FF (R), $F000 - $F3FF (W)\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"
|
||||
<< "Upper 1.5K ROM accessible @ $FA00 - $FFFF\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
|
||||
// Eventually, we should query this from the debugger/disassembler
|
||||
|
@ -52,8 +53,8 @@ CartridgeE7Widget::CartridgeE7Widget(
|
|||
const char* CartridgeE7Widget::getSpotLower(int idx)
|
||||
{
|
||||
static constexpr std::array<const char*, 8> spot_lower = {
|
||||
"0 - ROM ($FFE0)", "1 - ROM ($FFE1)", "2 - ROM ($FFE2)", "3 - ROM ($FFE3)",
|
||||
"4 - ROM ($FFE4)", "5 - ROM ($FFE5)", "6 - ROM ($FFE6)", "7 - RAM ($FFE7)"
|
||||
"#0 - ROM ($FFE0)", "#1 - ROM ($FFE1)", "#2 - ROM ($FFE2)", "#3 - ROM ($FFE3)",
|
||||
"#4 - ROM ($FFE4)", "#5 - ROM ($FFE5)", "#6 - ROM ($FFE6)", "#7 - RAM ($FFE7)"
|
||||
};
|
||||
|
||||
return spot_lower[idx];
|
||||
|
@ -63,7 +64,7 @@ const char* CartridgeE7Widget::getSpotLower(int idx)
|
|||
const char* CartridgeE7Widget::getSpotUpper(int idx)
|
||||
{
|
||||
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];
|
||||
|
|
|
@ -15,167 +15,25 @@
|
|||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//============================================================================
|
||||
|
||||
#include "Debugger.hxx"
|
||||
#include "CartDebug.hxx"
|
||||
#include "CartEFSC.hxx"
|
||||
#include "PopUpWidget.hxx"
|
||||
#include "CartEFSCWidget.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartridgeEFSCWidget::CartridgeEFSCWidget(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h, CartridgeEFSC& cart)
|
||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart)
|
||||
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||
{
|
||||
uInt32 size = 16 * 4096;
|
||||
initialize();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string CartridgeEFSCWidget::description()
|
||||
{
|
||||
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
|
||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0xFE0; 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 + 0x100)
|
||||
<< " - " << "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n";
|
||||
}
|
||||
info << "64K H. Runner EFSC + RAM, 16 4K banks\n";
|
||||
info << CartridgeEnhancedWidget::description();
|
||||
|
||||
int xpos = 2,
|
||||
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);
|
||||
return info.str();
|
||||
}
|
||||
|
|
|
@ -19,11 +19,10 @@
|
|||
#define CARTRIDGEEFSC_WIDGET_HXX
|
||||
|
||||
class CartridgeEFSC;
|
||||
class PopUpWidget;
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
#include "CartEnhancedWidget.hxx"
|
||||
|
||||
class CartridgeEFSCWidget : public CartDebugWidget
|
||||
class CartridgeEFSCWidget : public CartridgeEnhancedWidget
|
||||
{
|
||||
public:
|
||||
CartridgeEFSCWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||
|
@ -33,35 +32,11 @@ class CartridgeEFSCWidget : public CartDebugWidget
|
|||
virtual ~CartridgeEFSCWidget() = default;
|
||||
|
||||
private:
|
||||
CartridgeEFSC& myCart;
|
||||
PopUpWidget* myBank{nullptr};
|
||||
string manufacturer() override { return "Paul Slocum / Homestar Runner"; }
|
||||
|
||||
struct CartState {
|
||||
ByteArray internalram;
|
||||
uInt16 bank{0};
|
||||
};
|
||||
CartState myOldState;
|
||||
|
||||
enum { kBankChanged = 'bkCH' };
|
||||
string description() override;
|
||||
|
||||
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
|
||||
CartridgeEFSCWidget() = delete;
|
||||
CartridgeEFSCWidget(const CartridgeEFSCWidget&) = delete;
|
||||
|
|
|
@ -16,97 +16,24 @@
|
|||
//============================================================================
|
||||
|
||||
#include "CartEF.hxx"
|
||||
#include "PopUpWidget.hxx"
|
||||
#include "CartEFWidget.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartridgeEFWidget::CartridgeEFWidget(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h, CartridgeEF& cart)
|
||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart)
|
||||
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||
{
|
||||
uInt32 size = 16 * 4096;
|
||||
initialize();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string CartridgeEFWidget::description()
|
||||
{
|
||||
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
|
||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0xFE0; 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) << " (hotspot = $F" << (spot+i) << ")\n";
|
||||
}
|
||||
info << "64K H. Runner EF cartridge, 16 4K banks\n";
|
||||
info << CartridgeEnhancedWidget::description();
|
||||
|
||||
int xpos = 2,
|
||||
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();
|
||||
return info.str();
|
||||
}
|
||||
|
|
|
@ -19,11 +19,10 @@
|
|||
#define CARTRIDGEEF_WIDGET_HXX
|
||||
|
||||
class CartridgeEF;
|
||||
class PopUpWidget;
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
#include "CartEnhancedWidget.hxx"
|
||||
|
||||
class CartridgeEFWidget : public CartDebugWidget
|
||||
class CartridgeEFWidget : public CartridgeEnhancedWidget
|
||||
{
|
||||
public:
|
||||
CartridgeEFWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||
|
@ -33,17 +32,11 @@ class CartridgeEFWidget : public CartDebugWidget
|
|||
virtual ~CartridgeEFWidget() = default;
|
||||
|
||||
private:
|
||||
CartridgeEF& myCart;
|
||||
PopUpWidget* myBank{nullptr};
|
||||
string manufacturer() override { return "Paul Slocum / Homestar Runner"; }
|
||||
|
||||
enum { kBankChanged = 'bkCH' };
|
||||
string description() override;
|
||||
|
||||
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
|
||||
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.
|
||||
//============================================================================
|
||||
|
||||
#ifndef CARTRIDGECVPlus_WIDGET_HXX
|
||||
#define CARTRIDGECVPlus_WIDGET_HXX
|
||||
#ifndef CART_ENHANCED_WIDGET_HXX
|
||||
#define CART_ENHANCED_WIDGET_HXX
|
||||
|
||||
class CartridgeCVPlus;
|
||||
class CartridgeEnhanced;
|
||||
class PopUpWidget;
|
||||
|
||||
namespace GUI {
|
||||
class Font;
|
||||
}
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
|
||||
class CartridgeCVPlusWidget : public CartDebugWidget
|
||||
class CartridgeEnhancedWidget : public CartDebugWidget
|
||||
{
|
||||
public:
|
||||
CartridgeCVPlusWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||
const GUI::Font& nfont,
|
||||
int x, int y, int w, int h,
|
||||
CartridgeCVPlus& cart);
|
||||
virtual ~CartridgeCVPlusWidget() = default;
|
||||
CartridgeEnhancedWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||
const GUI::Font& nfont,
|
||||
int x, int y, int w, int h,
|
||||
CartridgeEnhanced& cart);
|
||||
virtual ~CartridgeEnhancedWidget() = default;
|
||||
|
||||
private:
|
||||
CartridgeCVPlus& myCart;
|
||||
PopUpWidget* myBank{nullptr};
|
||||
struct CartState {
|
||||
ByteArray internalram;
|
||||
uInt16 bank{0};
|
||||
};
|
||||
CartState myOldState;
|
||||
protected:
|
||||
int initialize();
|
||||
|
||||
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 handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
||||
|
||||
string bankState() override;
|
||||
|
||||
void saveOldState() override;
|
||||
|
||||
// start of functions for Cartridge RAM tab
|
||||
uInt32 internalRamSize() override;
|
||||
uInt32 internalRamRPort(int start) override;
|
||||
|
@ -62,12 +77,34 @@ class CartridgeCVPlusWidget : public CartDebugWidget
|
|||
string internalRamLabel(int addr) override;
|
||||
// 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
|
||||
CartridgeCVPlusWidget() = delete;
|
||||
CartridgeCVPlusWidget(const CartridgeCVPlusWidget&) = delete;
|
||||
CartridgeCVPlusWidget(CartridgeCVPlusWidget&&) = delete;
|
||||
CartridgeCVPlusWidget& operator=(const CartridgeCVPlusWidget&) = delete;
|
||||
CartridgeCVPlusWidget& operator=(CartridgeCVPlusWidget&&) = delete;
|
||||
CartridgeEnhancedWidget() = delete;
|
||||
CartridgeEnhancedWidget(const CartridgeEnhancedWidget&) = delete;
|
||||
CartridgeEnhancedWidget(CartridgeEnhancedWidget&&) = delete;
|
||||
CartridgeEnhancedWidget& operator=(const CartridgeEnhancedWidget&) = delete;
|
||||
CartridgeEnhancedWidget& operator=(CartridgeEnhancedWidget&&) = delete;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -16,85 +16,28 @@
|
|||
//============================================================================
|
||||
|
||||
#include "CartF0.hxx"
|
||||
#include "PopUpWidget.hxx"
|
||||
#include "CartF0Widget.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartridgeF0Widget::CartridgeF0Widget(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h, CartridgeF0& cart)
|
||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart)
|
||||
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||
{
|
||||
uInt32 size = 16 * 4096;
|
||||
myHotspotDelta = 0;
|
||||
initialize();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string CartridgeF0Widget::description()
|
||||
{
|
||||
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
|
||||
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";
|
||||
}
|
||||
info << "Megaboy F0 cartridge, 16 4K banks\n"
|
||||
<< "Startup bank = #" << myCart.startBank() << " or undetermined\n"
|
||||
<< "Bankswitch triggered by accessing $" << Common::Base::HEX4 << 0xFFF0 << "\n";
|
||||
|
||||
int xpos = 2,
|
||||
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();
|
||||
}
|
||||
return info.str();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -102,7 +45,8 @@ string CartridgeF0Widget::bankState()
|
|||
{
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -19,11 +19,10 @@
|
|||
#define CARTRIDGEF0_WIDGET_HXX
|
||||
|
||||
class CartridgeF0;
|
||||
class PopUpWidget;
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
#include "CartEnhancedWidget.hxx"
|
||||
|
||||
class CartridgeF0Widget : public CartDebugWidget
|
||||
class CartridgeF0Widget : public CartridgeEnhancedWidget
|
||||
{
|
||||
public:
|
||||
CartridgeF0Widget(GuiObject* boss, const GUI::Font& lfont,
|
||||
|
@ -33,17 +32,13 @@ class CartridgeF0Widget : public CartDebugWidget
|
|||
virtual ~CartridgeF0Widget() = default;
|
||||
|
||||
private:
|
||||
CartridgeF0& myCart;
|
||||
PopUpWidget* myBank{nullptr};
|
||||
string manufacturer() override { return "Dynacom Megaboy"; }
|
||||
|
||||
enum { kBankChanged = 'bkCH' };
|
||||
|
||||
private:
|
||||
void loadConfig() override;
|
||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
||||
string description() override;
|
||||
|
||||
string bankState() override;
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
CartridgeF0Widget() = delete;
|
||||
CartridgeF0Widget(const CartridgeF0Widget&) = delete;
|
||||
|
|
|
@ -15,157 +15,25 @@
|
|||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//============================================================================
|
||||
|
||||
#include "Debugger.hxx"
|
||||
#include "CartDebug.hxx"
|
||||
#include "CartF4SC.hxx"
|
||||
#include "PopUpWidget.hxx"
|
||||
#include "CartF4SCWidget.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartridgeF4SCWidget::CartridgeF4SCWidget(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h, CartridgeF4SC& cart)
|
||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart)
|
||||
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||
{
|
||||
uInt16 size = 8 * 4096;
|
||||
initialize();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string CartridgeF4SCWidget::description()
|
||||
{
|
||||
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
|
||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0xFF4; i < 8; ++i, offset += 0x1000)
|
||||
{
|
||||
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";
|
||||
}
|
||||
info << "Standard F4SC cartridge, eight 4K banks\n";
|
||||
info << CartridgeEnhancedWidget::description();
|
||||
|
||||
int xpos = 2,
|
||||
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);
|
||||
return info.str();
|
||||
}
|
||||
|
|
|
@ -19,11 +19,10 @@
|
|||
#define CARTRIDGEF4SC_WIDGET_HXX
|
||||
|
||||
class CartridgeF4SC;
|
||||
class PopUpWidget;
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
#include "CartEnhancedWidget.hxx"
|
||||
|
||||
class CartridgeF4SCWidget : public CartDebugWidget
|
||||
class CartridgeF4SCWidget : public CartridgeEnhancedWidget
|
||||
{
|
||||
public:
|
||||
CartridgeF4SCWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||
|
@ -33,36 +32,11 @@ class CartridgeF4SCWidget : public CartDebugWidget
|
|||
virtual ~CartridgeF4SCWidget() = default;
|
||||
|
||||
private:
|
||||
CartridgeF4SC& myCart;
|
||||
PopUpWidget* myBank{nullptr};
|
||||
string manufacturer() override { return "Atari"; }
|
||||
|
||||
struct CartState {
|
||||
ByteArray internalram;
|
||||
uInt16 bank{0};
|
||||
};
|
||||
CartState myOldState;
|
||||
|
||||
|
||||
enum { kBankChanged = 'bkCH' };
|
||||
string description() override;
|
||||
|
||||
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
|
||||
CartridgeF4SCWidget() = delete;
|
||||
CartridgeF4SCWidget(const CartridgeF4SCWidget&) = delete;
|
||||
|
|
|
@ -16,87 +16,24 @@
|
|||
//============================================================================
|
||||
|
||||
#include "CartF4.hxx"
|
||||
#include "PopUpWidget.hxx"
|
||||
#include "CartF4Widget.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartridgeF4Widget::CartridgeF4Widget(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h, CartridgeF4& cart)
|
||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart)
|
||||
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||
{
|
||||
uInt16 size = 8 * 4096;
|
||||
initialize();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string CartridgeF4Widget::description()
|
||||
{
|
||||
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
|
||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0xFF4; i < 8; ++i, offset += 0x1000)
|
||||
{
|
||||
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";
|
||||
}
|
||||
info << "Standard F4 cartridge, eight 4K banks\n";
|
||||
info << CartridgeEnhancedWidget::description();
|
||||
|
||||
int xpos = 2,
|
||||
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();
|
||||
return info.str();
|
||||
}
|
||||
|
|
|
@ -19,11 +19,10 @@
|
|||
#define CARTRIDGEF4_WIDGET_HXX
|
||||
|
||||
class CartridgeF4;
|
||||
class PopUpWidget;
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
#include "CartEnhancedWidget.hxx"
|
||||
|
||||
class CartridgeF4Widget : public CartDebugWidget
|
||||
class CartridgeF4Widget : public CartridgeEnhancedWidget
|
||||
{
|
||||
public:
|
||||
CartridgeF4Widget(GuiObject* boss, const GUI::Font& lfont,
|
||||
|
@ -33,17 +32,11 @@ class CartridgeF4Widget : public CartDebugWidget
|
|||
virtual ~CartridgeF4Widget() = default;
|
||||
|
||||
private:
|
||||
CartridgeF4& myCart;
|
||||
PopUpWidget* myBank{nullptr};
|
||||
string manufacturer() override { return "Atari"; }
|
||||
|
||||
enum { kBankChanged = 'bkCH' };
|
||||
string description() override;
|
||||
|
||||
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
|
||||
CartridgeF4Widget() = delete;
|
||||
CartridgeF4Widget(const CartridgeF4Widget&) = delete;
|
||||
|
|
|
@ -15,151 +15,25 @@
|
|||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//============================================================================
|
||||
|
||||
#include "Debugger.hxx"
|
||||
#include "CartDebug.hxx"
|
||||
#include "CartF6SC.hxx"
|
||||
#include "PopUpWidget.hxx"
|
||||
#include "CartF6SCWidget.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartridgeF6SCWidget::CartridgeF6SCWidget(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h, CartridgeF6SC& cart)
|
||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart)
|
||||
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||
{
|
||||
uInt16 size = 4 * 4096;
|
||||
initialize();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string CartridgeF6SCWidget::description()
|
||||
{
|
||||
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
|
||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0xFF6; i < 4; ++i, offset += 0x1000)
|
||||
{
|
||||
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";
|
||||
}
|
||||
info << "Standard F6SC cartridge, four 4K banks\n";
|
||||
info << CartridgeEnhancedWidget::description();
|
||||
|
||||
int xpos = 2,
|
||||
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);
|
||||
return info.str();
|
||||
}
|
||||
|
|
|
@ -19,11 +19,10 @@
|
|||
#define CARTRIDGEF6SC_WIDGET_HXX
|
||||
|
||||
class CartridgeF6SC;
|
||||
class PopUpWidget;
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
#include "CartEnhancedWidget.hxx"
|
||||
|
||||
class CartridgeF6SCWidget : public CartDebugWidget
|
||||
class CartridgeF6SCWidget : public CartridgeEnhancedWidget
|
||||
{
|
||||
public:
|
||||
CartridgeF6SCWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||
|
@ -33,34 +32,11 @@ class CartridgeF6SCWidget : public CartDebugWidget
|
|||
virtual ~CartridgeF6SCWidget() = default;
|
||||
|
||||
private:
|
||||
struct CartState {
|
||||
ByteArray internalram;
|
||||
uInt16 bank{0};
|
||||
};
|
||||
CartridgeF6SC& myCart;
|
||||
PopUpWidget* myBank{nullptr};
|
||||
CartState myOldState;
|
||||
string manufacturer() override { return "Atari"; }
|
||||
|
||||
enum { kBankChanged = 'bkCH' };
|
||||
string description() override;
|
||||
|
||||
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
|
||||
CartridgeF6SCWidget() = delete;
|
||||
CartridgeF6SCWidget(const CartridgeF6SCWidget&) = delete;
|
||||
|
|
|
@ -16,81 +16,24 @@
|
|||
//============================================================================
|
||||
|
||||
#include "CartF6.hxx"
|
||||
#include "PopUpWidget.hxx"
|
||||
#include "CartF6Widget.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartridgeF6Widget::CartridgeF6Widget(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h, CartridgeF6& cart)
|
||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart)
|
||||
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||
{
|
||||
uInt16 size = 4 * 4096;
|
||||
initialize();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string CartridgeF6Widget::description()
|
||||
{
|
||||
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
|
||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0xFF6; i < 4; ++i, offset += 0x1000)
|
||||
{
|
||||
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";
|
||||
}
|
||||
info << "Standard F6 cartridge, four 4K banks\n";
|
||||
info << CartridgeEnhancedWidget::description();
|
||||
|
||||
int xpos = 2,
|
||||
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();
|
||||
return info.str();
|
||||
}
|
||||
|
|
|
@ -19,11 +19,10 @@
|
|||
#define CARTRIDGEF6_WIDGET_HXX
|
||||
|
||||
class CartridgeF6;
|
||||
class PopUpWidget;
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
#include "CartEnhancedWidget.hxx"
|
||||
|
||||
class CartridgeF6Widget : public CartDebugWidget
|
||||
class CartridgeF6Widget : public CartridgeEnhancedWidget
|
||||
{
|
||||
public:
|
||||
CartridgeF6Widget(GuiObject* boss, const GUI::Font& lfont,
|
||||
|
@ -33,17 +32,11 @@ class CartridgeF6Widget : public CartDebugWidget
|
|||
virtual ~CartridgeF6Widget() = default;
|
||||
|
||||
private:
|
||||
CartridgeF6& myCart;
|
||||
PopUpWidget* myBank{nullptr};
|
||||
string manufacturer() override { return "Atari"; }
|
||||
|
||||
enum { kBankChanged = 'bkCH' };
|
||||
string description() override;
|
||||
|
||||
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
|
||||
CartridgeF6Widget() = delete;
|
||||
CartridgeF6Widget(const CartridgeF6Widget&) = delete;
|
||||
|
|
|
@ -15,149 +15,25 @@
|
|||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//============================================================================
|
||||
|
||||
#include "Debugger.hxx"
|
||||
#include "CartDebug.hxx"
|
||||
#include "CartF8SC.hxx"
|
||||
#include "PopUpWidget.hxx"
|
||||
#include "CartF8SCWidget.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartridgeF8SCWidget::CartridgeF8SCWidget(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h, CartridgeF8SC& cart)
|
||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart)
|
||||
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||
{
|
||||
uInt16 size = 8192;
|
||||
initialize();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string CartridgeF8SCWidget::description()
|
||||
{
|
||||
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
|
||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0xFF8; i < 2; ++i, offset += 0x1000)
|
||||
{
|
||||
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";
|
||||
}
|
||||
info << "Standard F8SC cartridge, two 4K banks\n";
|
||||
info << CartridgeEnhancedWidget::description();
|
||||
|
||||
int xpos = 2,
|
||||
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);
|
||||
return info.str();
|
||||
}
|
||||
|
|
|
@ -19,11 +19,10 @@
|
|||
#define CARTRIDGEF8SC_WIDGET_HXX
|
||||
|
||||
class CartridgeF8SC;
|
||||
class PopUpWidget;
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
#include "CartEnhancedWidget.hxx"
|
||||
|
||||
class CartridgeF8SCWidget : public CartDebugWidget
|
||||
class CartridgeF8SCWidget : public CartridgeEnhancedWidget
|
||||
{
|
||||
public:
|
||||
CartridgeF8SCWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||
|
@ -33,35 +32,11 @@ class CartridgeF8SCWidget : public CartDebugWidget
|
|||
virtual ~CartridgeF8SCWidget() = default;
|
||||
|
||||
private:
|
||||
CartridgeF8SC& myCart;
|
||||
PopUpWidget* myBank{nullptr};
|
||||
string manufacturer() override { return "Atari"; }
|
||||
|
||||
struct CartState {
|
||||
ByteArray internalram;
|
||||
uInt16 bank{0};
|
||||
};
|
||||
CartState myOldState;
|
||||
|
||||
enum { kBankChanged = 'bkCH' };
|
||||
string description() override;
|
||||
|
||||
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
|
||||
CartridgeF8SCWidget() = delete;
|
||||
CartridgeF8SCWidget(const CartridgeF8SCWidget&) = delete;
|
||||
|
|
|
@ -16,79 +16,24 @@
|
|||
//============================================================================
|
||||
|
||||
#include "CartF8.hxx"
|
||||
#include "PopUpWidget.hxx"
|
||||
#include "CartF8Widget.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartridgeF8Widget::CartridgeF8Widget(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h, CartridgeF8& cart)
|
||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart)
|
||||
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||
{
|
||||
uInt16 size = 2 * 4096;
|
||||
initialize();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string CartridgeF8Widget::description()
|
||||
{
|
||||
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
|
||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0xFF8; i < 2; ++i, offset += 0x1000)
|
||||
{
|
||||
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";
|
||||
}
|
||||
info << "Standard F8 cartridge, two 4K banks\n";
|
||||
info << CartridgeEnhancedWidget::description();
|
||||
|
||||
int xpos = 2,
|
||||
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();
|
||||
return info.str();
|
||||
}
|
||||
|
|
|
@ -21,9 +21,9 @@
|
|||
class CartridgeF8;
|
||||
class PopUpWidget;
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
#include "CartEnhancedWidget.hxx"
|
||||
|
||||
class CartridgeF8Widget : public CartDebugWidget
|
||||
class CartridgeF8Widget : public CartridgeEnhancedWidget
|
||||
{
|
||||
public:
|
||||
CartridgeF8Widget(GuiObject* boss, const GUI::Font& lfont,
|
||||
|
@ -33,17 +33,11 @@ class CartridgeF8Widget : public CartDebugWidget
|
|||
virtual ~CartridgeF8Widget() = default;
|
||||
|
||||
private:
|
||||
CartridgeF8& myCart;
|
||||
PopUpWidget* myBank{nullptr};
|
||||
string manufacturer() override { return "Atari"; }
|
||||
|
||||
enum { kBankChanged = 'bkCH' };
|
||||
string description() override;
|
||||
|
||||
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
|
||||
CartridgeF8Widget() = delete;
|
||||
CartridgeF8Widget(const CartridgeF8Widget&) = delete;
|
||||
|
|
|
@ -15,65 +15,26 @@
|
|||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//============================================================================
|
||||
|
||||
#include "Debugger.hxx"
|
||||
#include "CartDebug.hxx"
|
||||
#include "CartFA2.hxx"
|
||||
#include "PopUpWidget.hxx"
|
||||
#include "CartFA2Widget.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartridgeFA2Widget::CartridgeFA2Widget(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h, CartridgeFA2& cart)
|
||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart)
|
||||
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, 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,
|
||||
ypos = addBaseInformation(size, "Chris D. Walton (Star Castle 2600)",
|
||||
info.str(), 15) + myLineHeight;
|
||||
ypos = initialize();
|
||||
|
||||
VariantList items;
|
||||
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;
|
||||
ypos += 12;
|
||||
|
||||
const int bwidth = _font.getStringWidth("Erase") + 20;
|
||||
|
||||
StaticTextWidget* t = new StaticTextWidget(boss, _font, xpos, ypos,
|
||||
_font.getStringWidth("Harmony Flash "),
|
||||
myFontHeight, "Harmony Flash ", TextAlign::Left);
|
||||
_font.getStringWidth("Harmony flash memory "),
|
||||
myFontHeight, "Harmony flash memory ", TextAlign::Left);
|
||||
|
||||
xpos += t->getWidth() + 4;
|
||||
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)
|
||||
myOldState.internalram.push_back(myCart.myRAM[i]);
|
||||
info << "Modified FA RAM+, six or seven 4K banks\n";
|
||||
info << "RAM+ can be loaded/saved to Harmony flash memory by accessing $"
|
||||
<< Common::Base::HEX4 << 0xFFF4 << "\n";
|
||||
info << CartridgeEnhancedWidget::description();
|
||||
|
||||
myOldState.bank = myCart.getBank();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeFA2Widget::loadConfig()
|
||||
{
|
||||
myBank->setSelectedIndex(myCart.getBank(), myCart.getBank() != myOldState.bank);
|
||||
|
||||
CartDebugWidget::loadConfig();
|
||||
return info.str();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -122,99 +77,19 @@ void CartridgeFA2Widget::handleCommand(CommandSender* sender,
|
|||
{
|
||||
switch(cmd)
|
||||
{
|
||||
case kBankChanged:
|
||||
myCart.unlockBank();
|
||||
myCart.bank(myBank->getSelected());
|
||||
myCart.lockBank();
|
||||
invalidate();
|
||||
break;
|
||||
|
||||
case kFlashErase:
|
||||
myCart.flash(0);
|
||||
myCartFA2.flash(0);
|
||||
break;
|
||||
|
||||
case kFlashLoad:
|
||||
myCart.flash(1);
|
||||
myCartFA2.flash(1);
|
||||
break;
|
||||
|
||||
case kFlashSave:
|
||||
myCart.flash(2);
|
||||
myCartFA2.flash(2);
|
||||
break;
|
||||
|
||||
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 ButtonWidget;
|
||||
class PopUpWidget;
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
#include "CartEnhancedWidget.hxx"
|
||||
|
||||
class CartridgeFA2Widget : public CartDebugWidget
|
||||
class CartridgeFA2Widget : public CartridgeEnhancedWidget
|
||||
{
|
||||
public:
|
||||
CartridgeFA2Widget(GuiObject* boss, const GUI::Font& lfont,
|
||||
|
@ -34,41 +33,25 @@ class CartridgeFA2Widget : public CartDebugWidget
|
|||
virtual ~CartridgeFA2Widget() = default;
|
||||
|
||||
private:
|
||||
CartridgeFA2& myCart;
|
||||
PopUpWidget* myBank{nullptr};
|
||||
CartridgeFA2& myCartFA2;
|
||||
|
||||
ButtonWidget *myFlashErase{nullptr}, *myFlashLoad{nullptr}, *myFlashSave{nullptr};
|
||||
|
||||
struct CartState {
|
||||
ByteArray internalram;
|
||||
uInt16 bank{0};
|
||||
};
|
||||
CartState myOldState;
|
||||
|
||||
enum {
|
||||
kBankChanged = 'bkCH',
|
||||
kFlashErase = 'flER',
|
||||
kFlashLoad = 'flLD',
|
||||
kFlashSave = 'flSV'
|
||||
};
|
||||
|
||||
private:
|
||||
void saveOldState() override;
|
||||
void loadConfig() override;
|
||||
string manufacturer() override { return "Chris D. Walton (Star Castle 2600 Arcade)"; }
|
||||
|
||||
string description() override;
|
||||
|
||||
private:
|
||||
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
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
CartridgeFA2Widget() = delete;
|
||||
CartridgeFA2Widget(const CartridgeFA2Widget&) = delete;
|
||||
|
|
|
@ -15,150 +15,25 @@
|
|||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//============================================================================
|
||||
|
||||
#include "Debugger.hxx"
|
||||
#include "CartDebug.hxx"
|
||||
#include "CartFA.hxx"
|
||||
#include "PopUpWidget.hxx"
|
||||
#include "CartFAWidget.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartridgeFAWidget::CartridgeFAWidget(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h, CartridgeFA& cart)
|
||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart)
|
||||
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||
{
|
||||
uInt16 size = 3 * 4096;
|
||||
initialize();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string CartridgeFAWidget::description()
|
||||
{
|
||||
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
|
||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0xFF8; i < 3; ++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";
|
||||
}
|
||||
info << "CBS RAM+ FA cartridge, three 4K banks\n";
|
||||
info << CartridgeEnhancedWidget::description();
|
||||
|
||||
int xpos = 2,
|
||||
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);
|
||||
return info.str();
|
||||
}
|
||||
|
|
|
@ -19,11 +19,10 @@
|
|||
#define CARTRIDGEFA_WIDGET_HXX
|
||||
|
||||
class CartridgeFA;
|
||||
class PopUpWidget;
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
#include "CartEnhancedWidget.hxx"
|
||||
|
||||
class CartridgeFAWidget : public CartDebugWidget
|
||||
class CartridgeFAWidget : public CartridgeEnhancedWidget
|
||||
{
|
||||
public:
|
||||
CartridgeFAWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||
|
@ -33,35 +32,11 @@ class CartridgeFAWidget : public CartDebugWidget
|
|||
virtual ~CartridgeFAWidget() = default;
|
||||
|
||||
private:
|
||||
CartridgeFA& myCart;
|
||||
PopUpWidget* myBank{nullptr};
|
||||
string manufacturer() override { return "CBS"; }
|
||||
|
||||
struct CartState {
|
||||
ByteArray internalram;
|
||||
uInt16 bank{0};
|
||||
};
|
||||
CartState myOldState;
|
||||
|
||||
enum { kBankChanged = 'bkCH' };
|
||||
string description() override;
|
||||
|
||||
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
|
||||
CartridgeFAWidget() = delete;
|
||||
CartridgeFAWidget(const CartridgeFAWidget&) = delete;
|
||||
|
|
|
@ -16,80 +16,44 @@
|
|||
//============================================================================
|
||||
|
||||
#include "CartFC.hxx"
|
||||
#include "PopUpWidget.hxx"
|
||||
#include "CartFCWidget.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartridgeFCWidget::CartridgeFCWidget(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h, CartridgeFC& cart)
|
||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart)
|
||||
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||
{
|
||||
uInt16 size = cart.bankCount() * 4096;
|
||||
initialize();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string CartridgeFCWidget::description()
|
||||
{
|
||||
ostringstream info;
|
||||
info << "FC cartridge, up to eight 4K banks\n"
|
||||
<< "Startup bank = " << cart.startBank() << " or undetermined\n";
|
||||
uInt16 hotspot = myCart.hotspot() | ADDR_BASE;
|
||||
|
||||
// Eventually, we should query this from the debugger/disassembler
|
||||
info << "FC cartridge, up to eight 4K banks\n";
|
||||
info << "Bank selected by hotspots\n"
|
||||
<< " $FFF8 (defines low 2 bits)\n"
|
||||
<< " $FFF9 (defines high bits)\n"
|
||||
<< " $FFFC (triggers bank switch)";
|
||||
<< " $" << Common::Base::HEX4 << hotspot << " (defines low 2 bits)\n"
|
||||
<< " $" << Common::Base::HEX4 << (hotspot + 1) << " (defines high bits)\n"
|
||||
<< " $" << Common::Base::HEX4 << (hotspot + 4) << " (triggers bank switch)\n";
|
||||
|
||||
int xpos = 2,
|
||||
ypos = addBaseInformation(size, "Amiga Corp.", info.str()) + myLineHeight;
|
||||
info << CartridgeEnhancedWidget::description();
|
||||
|
||||
VariantList items;
|
||||
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);
|
||||
return info.str();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeFCWidget::loadConfig()
|
||||
string CartridgeFCWidget::hotspotStr(int bank, int, bool prefix)
|
||||
{
|
||||
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());
|
||||
ostringstream info;
|
||||
uInt16 hotspot = myCart.hotspot() | ADDR_BASE;
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
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();
|
||||
return info.str();
|
||||
}
|
||||
|
|
|
@ -19,11 +19,10 @@
|
|||
#define CARTRIDGEFC_WIDGET_HXX
|
||||
|
||||
class CartridgeFC;
|
||||
class PopUpWidget;
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
#include "CartEnhancedWidget.hxx"
|
||||
|
||||
class CartridgeFCWidget : public CartDebugWidget
|
||||
class CartridgeFCWidget : public CartridgeEnhancedWidget
|
||||
{
|
||||
public:
|
||||
CartridgeFCWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||
|
@ -33,17 +32,13 @@ class CartridgeFCWidget : public CartDebugWidget
|
|||
virtual ~CartridgeFCWidget() = default;
|
||||
|
||||
private:
|
||||
CartridgeFC& myCart;
|
||||
PopUpWidget* myBank{nullptr};
|
||||
string manufacturer() override { return "Amiga Corp."; }
|
||||
|
||||
enum { kBankChanged = 'bkCH' };
|
||||
string description() override;
|
||||
|
||||
string hotspotStr(int bank, int seg = 0, bool prefix = false) override;
|
||||
|
||||
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
|
||||
CartridgeFCWidget() = delete;
|
||||
CartridgeFCWidget(const CartridgeFCWidget&) = delete;
|
||||
|
|
|
@ -16,72 +16,36 @@
|
|||
//============================================================================
|
||||
|
||||
#include "CartFE.hxx"
|
||||
#include "PopUpWidget.hxx"
|
||||
#include "CartFEWidget.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartridgeFEWidget::CartridgeFEWidget(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h, CartridgeFE& cart)
|
||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart)
|
||||
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||
{
|
||||
string info =
|
||||
"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);
|
||||
initialize();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeFEWidget::loadConfig()
|
||||
string CartridgeFEWidget::description()
|
||||
{
|
||||
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());
|
||||
ostringstream info;
|
||||
|
||||
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,
|
||||
int cmd, int data, int id)
|
||||
string CartridgeFEWidget::hotspotStr(int bank, int, bool)
|
||||
{
|
||||
if(cmd == kBankChanged)
|
||||
{
|
||||
myCart.unlockBank();
|
||||
myCart.bank(myBank->getSelected());
|
||||
myCart.lockBank();
|
||||
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();
|
||||
ostringstream info;
|
||||
|
||||
info << "(DATA = 11" << !bank << ", D5 = " << !bank << ")";
|
||||
|
||||
return info.str();
|
||||
}
|
||||
|
|
|
@ -19,11 +19,10 @@
|
|||
#define CARTRIDGEFE_WIDGET_HXX
|
||||
|
||||
class CartridgeFE;
|
||||
class PopUpWidget;
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
#include "CartEnhancedWidget.hxx"
|
||||
|
||||
class CartridgeFEWidget : public CartDebugWidget
|
||||
class CartridgeFEWidget : public CartridgeEnhancedWidget
|
||||
{
|
||||
public:
|
||||
CartridgeFEWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||
|
@ -33,18 +32,13 @@ class CartridgeFEWidget : public CartDebugWidget
|
|||
virtual ~CartridgeFEWidget() = default;
|
||||
|
||||
private:
|
||||
CartridgeFE& myCart;
|
||||
PopUpWidget* myBank{nullptr};
|
||||
string manufacturer() override { return "Activision"; }
|
||||
|
||||
enum { kBankChanged = 'bkCH' };
|
||||
string description() override;
|
||||
|
||||
string hotspotStr(int bank, int, bool) override;
|
||||
|
||||
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
|
||||
CartridgeFEWidget() = delete;
|
||||
CartridgeFEWidget(const CartridgeFEWidget&) = delete;
|
||||
|
|
|
@ -17,44 +17,39 @@
|
|||
|
||||
#include "CartMDM.hxx"
|
||||
#include "PopUpWidget.hxx"
|
||||
#include "Widget.hxx"
|
||||
#include "CartMDMWidget.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartridgeMDMWidget::CartridgeMDMWidget(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h, CartridgeMDM& cart)
|
||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart)
|
||||
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart),
|
||||
myCartMDM(cart)
|
||||
{
|
||||
size_t size = myCart.mySize;
|
||||
initialize();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string CartridgeMDMWidget::description()
|
||||
{
|
||||
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,
|
||||
ypos = addBaseInformation(size, "Edwin Blink", info.str(), 15) + myLineHeight;
|
||||
info << "Menu Driven Megacart, " << myCart.romBankCount() << " 4K banks\n"
|
||||
<< "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;
|
||||
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());
|
||||
}
|
||||
return info.str();
|
||||
}
|
||||
|
||||
myBank =
|
||||
new PopUpWidget(boss, _font, xpos, ypos, _font.getStringWidth("xxx ($0FFF)"),
|
||||
myLineHeight, items, "Set bank ",
|
||||
0, kBankChanged);
|
||||
myBank->setTarget(this);
|
||||
addFocusWidget(myBank);
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeMDMWidget::bankSelect(int& ypos)
|
||||
{
|
||||
CartridgeEnhancedWidget::bankSelect(ypos);
|
||||
int xpos = myBankWidgets[0]->getRight() + 20;
|
||||
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",
|
||||
kBankDisabled);
|
||||
myBankDisabled->setTarget(this);
|
||||
|
@ -64,39 +59,21 @@ CartridgeMDMWidget::CartridgeMDMWidget(
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeMDMWidget::loadConfig()
|
||||
{
|
||||
myBank->setSelectedIndex(myCart.getBank());
|
||||
myBank->setEnabled(!myCart.myBankingDisabled);
|
||||
myBankDisabled->setState(myCart.myBankingDisabled);
|
||||
myBankWidgets[0]->setEnabled(!myCartMDM.myBankingDisabled);
|
||||
myBankDisabled->setState(myCartMDM.myBankingDisabled);
|
||||
|
||||
CartDebugWidget::loadConfig();
|
||||
CartridgeEnhancedWidget::loadConfig();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeMDMWidget::handleCommand(CommandSender* sender,
|
||||
int cmd, int data, int id)
|
||||
{
|
||||
if(cmd == kBankChanged)
|
||||
if(cmd == kBankDisabled)
|
||||
{
|
||||
myCart.unlockBank();
|
||||
myCart.bank(myBank->getSelected());
|
||||
myCart.lockBank();
|
||||
invalidate();
|
||||
}
|
||||
else if(cmd == kBankDisabled)
|
||||
{
|
||||
myCart.myBankingDisabled = myBankDisabled->getState();
|
||||
myBank->setEnabled(!myCart.myBankingDisabled);
|
||||
myCartMDM.myBankingDisabled = myBankDisabled->getState();
|
||||
myBankWidgets[0]->setEnabled(!myCartMDM.myBankingDisabled);
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string CartridgeMDMWidget::bankState()
|
||||
{
|
||||
ostringstream& buf = buffer();
|
||||
|
||||
buf << "Bank = " << std::dec << myCart.getBank()
|
||||
<< ", hotspot = " << "$" << Common::Base::HEX4
|
||||
<< (myCart.getBank()+0x800);
|
||||
|
||||
return buf.str();
|
||||
else
|
||||
CartridgeEnhancedWidget::handleCommand(sender, cmd, data, id);
|
||||
}
|
||||
|
|
|
@ -20,11 +20,10 @@
|
|||
|
||||
class CartridgeMDM;
|
||||
class CheckboxWidget;
|
||||
class PopUpWidget;
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
#include "CartEnhancedWidget.hxx"
|
||||
|
||||
class CartridgeMDMWidget : public CartDebugWidget
|
||||
class CartridgeMDMWidget : public CartridgeEnhancedWidget
|
||||
{
|
||||
public:
|
||||
CartridgeMDMWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||
|
@ -34,18 +33,24 @@ class CartridgeMDMWidget : public CartDebugWidget
|
|||
virtual ~CartridgeMDMWidget() = default;
|
||||
|
||||
private:
|
||||
CartridgeMDM& myCart;
|
||||
PopUpWidget* myBank{nullptr};
|
||||
string manufacturer() override { return "Edwin Blink"; }
|
||||
|
||||
string description() override;
|
||||
|
||||
void bankSelect(int& ypos) override;
|
||||
|
||||
CartridgeMDM& myCartMDM;
|
||||
CheckboxWidget* myBankDisabled{nullptr};
|
||||
|
||||
enum { kBankChanged = 'bkCH', kBankDisabled = 'bkDI' };
|
||||
enum {
|
||||
kBankDisabled = 'bkDI'
|
||||
};
|
||||
|
||||
private:
|
||||
void loadConfig() override;
|
||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
||||
|
||||
string bankState() override;
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
CartridgeMDMWidget() = delete;
|
||||
CartridgeMDMWidget(const CartridgeMDMWidget&) = delete;
|
||||
|
|
|
@ -35,30 +35,30 @@ CartridgeMNetworkWidget::CartridgeMNetworkWidget(
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
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,
|
||||
ypos = addBaseInformation(size, "M-Network", info.str(), 15) +
|
||||
myLineHeight;
|
||||
|
||||
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));
|
||||
for(int i = 0; i < 4; ++i)
|
||||
VarList::push_back(items1, getSpotUpper(i));
|
||||
|
||||
const int lwidth = _font.getStringWidth("Set slice for upper 256B "),
|
||||
fwidth = _font.getStringWidth("3 - RAM ($FFEB)");
|
||||
const int lwidth = _font.getStringWidth("Set bank for upper 256B segment "),
|
||||
fwidth = _font.getStringWidth("#3 - RAM ($FFEB)");
|
||||
myLower2K =
|
||||
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);
|
||||
addFocusWidget(myLower2K);
|
||||
ypos += myLower2K->getHeight() + 4;
|
||||
|
||||
myUpper256B =
|
||||
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);
|
||||
addFocusWidget(myUpper256B);
|
||||
}
|
||||
|
@ -71,14 +71,14 @@ void CartridgeMNetworkWidget::saveOldState()
|
|||
for(uInt32 i = 0; i < internalRamSize(); ++i)
|
||||
myOldState.internalram.push_back(myCart.myRAM[i]);
|
||||
|
||||
myOldState.lowerBank = myCart.myCurrentSlice[0];
|
||||
myOldState.lowerBank = myCart.myCurrentBank[0];
|
||||
myOldState.upperBank = myCart.myCurrentRAM;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
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);
|
||||
|
||||
CartDebugWidget::loadConfig();
|
||||
|
@ -111,8 +111,8 @@ string CartridgeMNetworkWidget::bankState()
|
|||
{
|
||||
ostringstream& buf = buffer();
|
||||
|
||||
buf << "Slices: " << std::dec
|
||||
<< getSpotLower(myCart.myCurrentSlice[0]) << " / "
|
||||
buf << "Segments: " << std::dec
|
||||
<< getSpotLower(myCart.myCurrentBank[0]) << " / "
|
||||
<< getSpotUpper(myCart.myCurrentRAM);
|
||||
|
||||
return buf.str();
|
||||
|
@ -135,11 +135,11 @@ string CartridgeMNetworkWidget::internalRamDescription()
|
|||
{
|
||||
ostringstream desc;
|
||||
desc << "First 1K accessible via:\n"
|
||||
<< " $F000 - $F3FF used for Write Access\n"
|
||||
<< " $F400 - $F7FF used for Read Access\n"
|
||||
<< "256K of second 1K accessible via:\n"
|
||||
<< " $F800 - $F8FF used for Write Access\n"
|
||||
<< " $F900 - $F9FF used for Read Access";
|
||||
<< " $F000 - $F3FF used for write access\n"
|
||||
<< " $F400 - $F7FF used for read access\n"
|
||||
<< "256 bytes of second 1K accessible via:\n"
|
||||
<< " $F800 - $F8FF used for write access\n"
|
||||
<< " $F900 - $F9FF used for read access";
|
||||
|
||||
return desc.str();
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ CartRamWidget::CartRamWidget(
|
|||
int xpos = 2, ypos = 8;
|
||||
|
||||
// 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();
|
||||
buf << ramsize << " bytes";
|
||||
|
@ -65,13 +65,14 @@ CartRamWidget::CartRamWidget(
|
|||
StringParser bs(desc, (fwidth - ScrollBarWidget::scrollBarWidth(_font)) / myFontWidth);
|
||||
const StringList& sl = bs.stringList();
|
||||
uInt32 lines = uInt32(sl.size());
|
||||
if(lines < 3) lines = 3;
|
||||
if(lines < 2) lines = 2;
|
||||
if(lines > maxlines) lines = maxlines;
|
||||
|
||||
new StaticTextWidget(_boss, _font, xpos, ypos + 1, "Description ");
|
||||
myDesc = new StringListWidget(boss, nfont, xpos+lwidth, ypos - 1,
|
||||
fwidth, lines * myLineHeight, false);
|
||||
myDesc->setEditable(false);
|
||||
myDesc->setEnabled(false);
|
||||
myDesc->setList(sl);
|
||||
addFocusWidget(myDesc);
|
||||
|
||||
|
|
|
@ -16,85 +16,27 @@
|
|||
//============================================================================
|
||||
|
||||
#include "CartSB.hxx"
|
||||
#include "PopUpWidget.hxx"
|
||||
#include "CartSBWidget.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartridgeSBWidget::CartridgeSBWidget(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h, CartridgeSB& cart)
|
||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart)
|
||||
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||
{
|
||||
size_t size = myCart.mySize;
|
||||
|
||||
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);
|
||||
initialize();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeSBWidget::loadConfig()
|
||||
string CartridgeSBWidget::description()
|
||||
{
|
||||
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());
|
||||
ostringstream info;
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
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();
|
||||
return info.str();
|
||||
}
|
||||
|
|
|
@ -19,11 +19,10 @@
|
|||
#define CARTRIDGESB_WIDGET_HXX
|
||||
|
||||
class CartridgeSB;
|
||||
class PopUpWidget;
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
#include "CartEnhancedWidget.hxx"
|
||||
|
||||
class CartridgeSBWidget : public CartDebugWidget
|
||||
class CartridgeSBWidget : public CartridgeEnhancedWidget
|
||||
{
|
||||
public:
|
||||
CartridgeSBWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||
|
@ -33,17 +32,11 @@ class CartridgeSBWidget : public CartDebugWidget
|
|||
virtual ~CartridgeSBWidget() = default;
|
||||
|
||||
private:
|
||||
CartridgeSB& myCart;
|
||||
PopUpWidget* myBank{nullptr};
|
||||
string manufacturer() override { return "Fred X. Quimby"; }
|
||||
|
||||
enum { kBankChanged = 'bkCH' };
|
||||
string description() override;
|
||||
|
||||
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
|
||||
CartridgeSBWidget() = delete;
|
||||
CartridgeSBWidget(const CartridgeSBWidget&) = delete;
|
||||
|
|
|
@ -16,89 +16,39 @@
|
|||
//============================================================================
|
||||
|
||||
#include "CartUA.hxx"
|
||||
#include "PopUpWidget.hxx"
|
||||
#include "CartUAWidget.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartridgeUAWidget::CartridgeUAWidget(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h, CartridgeUA& cart, bool swapHotspots)
|
||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart),
|
||||
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart),
|
||||
mySwappedHotspots(swapHotspots)
|
||||
{
|
||||
uInt16 size = 2 * 4096;
|
||||
myHotspotDelta = 0x20;
|
||||
initialize();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string CartridgeUAWidget::description()
|
||||
{
|
||||
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
|
||||
for(uInt32 i = 0, offset = 0xFFC, spot = mySwappedHotspots ? 0x240 : 0x220; i < 2;
|
||||
++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";
|
||||
}
|
||||
info << "8K UA cartridge" << (mySwappedHotspots ? " (swapped banks)" : "") << ", two 4K banks\n";
|
||||
info << CartridgeEnhancedWidget::description();
|
||||
|
||||
int xpos = 2,
|
||||
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);
|
||||
return info.str();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeUAWidget::loadConfig()
|
||||
string CartridgeUAWidget::hotspotStr(int bank, int, bool prefix)
|
||||
{
|
||||
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());
|
||||
ostringstream info;
|
||||
uInt16 hotspot = myCart.hotspot() + (bank ^ (mySwappedHotspots ? 1 : 0)) * myHotspotDelta;
|
||||
|
||||
myBank->setSelectedIndex(myCart.getBank(), state.bank != oldstate.bank);
|
||||
info << "(" << (prefix ? "hotspot " : "");
|
||||
info << "$" << Common::Base::HEX1 << hotspot << ", $" << (hotspot | 0x80);
|
||||
info << ")";
|
||||
|
||||
CartDebugWidget::loadConfig();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
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();
|
||||
return info.str();
|
||||
}
|
||||
|
|
|
@ -19,11 +19,10 @@
|
|||
#define CARTRIDGEUA_WIDGET_HXX
|
||||
|
||||
class CartridgeUA;
|
||||
class PopUpWidget;
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
#include "CartEnhancedWidget.hxx"
|
||||
|
||||
class CartridgeUAWidget : public CartDebugWidget
|
||||
class CartridgeUAWidget : public CartridgeEnhancedWidget
|
||||
{
|
||||
public:
|
||||
CartridgeUAWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||
|
@ -33,19 +32,16 @@ class CartridgeUAWidget : public CartDebugWidget
|
|||
virtual ~CartridgeUAWidget() = default;
|
||||
|
||||
private:
|
||||
CartridgeUA& myCart;
|
||||
PopUpWidget* myBank{nullptr};
|
||||
string manufacturer() override { return "UA Limited"; }
|
||||
|
||||
bool mySwappedHotspots;
|
||||
string description() override;
|
||||
|
||||
enum { kBankChanged = 'bkCH' };
|
||||
string hotspotStr(int bank, int seg, bool prefix = false) override;
|
||||
|
||||
private:
|
||||
void loadConfig() override;
|
||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
||||
|
||||
string bankState() override;
|
||||
const bool mySwappedHotspots;
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
CartridgeUAWidget() = delete;
|
||||
CartridgeUAWidget(const CartridgeUAWidget&) = delete;
|
||||
|
|
|
@ -15,157 +15,45 @@
|
|||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//============================================================================
|
||||
|
||||
#include "Debugger.hxx"
|
||||
#include "CartDebug.hxx"
|
||||
#include "CartWD.hxx"
|
||||
#include "PopUpWidget.hxx"
|
||||
#include "CartWDWidget.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartridgeWDWidget::CartridgeWDWidget(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h, CartridgeWD& cart)
|
||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart)
|
||||
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart),
|
||||
myCartWD(cart)
|
||||
{
|
||||
string info =
|
||||
"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);
|
||||
initialize();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeWDWidget::saveOldState()
|
||||
string CartridgeWDWidget::description()
|
||||
{
|
||||
myOldState.internalram.clear();
|
||||
ostringstream info;
|
||||
|
||||
for(uInt32 i = 0; i < internalRamSize(); ++i)
|
||||
myOldState.internalram.push_back(myCart.myRAM[i]);
|
||||
info << "8K + RAM Wickstead Design cartridge, \n"
|
||||
<< " 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();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeWDWidget::handleCommand(CommandSender* sender,
|
||||
int cmd, int data, int id)
|
||||
{
|
||||
if(cmd == kBankChanged)
|
||||
{
|
||||
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);
|
||||
info << "(" << (prefix ? "hotspot " : "")
|
||||
<< "$" << Common::Base::HEX1 << (myCart.hotspot() + bank) << ") ["
|
||||
<< uInt16(banks.zero) << ", "
|
||||
<< uInt16(banks.one) << ", "
|
||||
<< uInt16(banks.two) << ", "
|
||||
<< uInt16(banks.three) << "]";
|
||||
|
||||
return info.str();
|
||||
}
|
||||
|
|
|
@ -19,11 +19,10 @@
|
|||
#define CARTRIDGEWD_WIDGET_HXX
|
||||
|
||||
class CartridgeWD;
|
||||
class PopUpWidget;
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
#include "CartEnhancedWidget.hxx"
|
||||
|
||||
class CartridgeWDWidget : public CartDebugWidget
|
||||
class CartridgeWDWidget : public CartridgeEnhancedWidget
|
||||
{
|
||||
public:
|
||||
CartridgeWDWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||
|
@ -32,36 +31,19 @@ class CartridgeWDWidget : public CartDebugWidget
|
|||
CartridgeWD& cart);
|
||||
virtual ~CartridgeWDWidget() = default;
|
||||
|
||||
private:
|
||||
CartridgeWD& myCart;
|
||||
PopUpWidget* myBank{nullptr};
|
||||
|
||||
struct CartState {
|
||||
ByteArray internalram;
|
||||
uInt16 bank{0}; // Current banking layout
|
||||
};
|
||||
CartState myOldState;
|
||||
|
||||
enum { kBankChanged = 'bkCH' };
|
||||
private:
|
||||
CartridgeWD& myCartWD;
|
||||
|
||||
private:
|
||||
void saveOldState() override;
|
||||
void loadConfig() override;
|
||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
||||
string manufacturer() override { return "Wickstead Design"; }
|
||||
|
||||
string bankState() override;
|
||||
string description() 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
|
||||
string hotspotStr(int bank, int seg = 0, bool prefix = false) override;
|
||||
|
||||
uInt16 bankSegs() override { return 1; }
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
CartridgeWDWidget() = delete;
|
||||
CartridgeWDWidget(const CartridgeWDWidget&) = delete;
|
||||
|
|
|
@ -16,94 +16,26 @@
|
|||
//============================================================================
|
||||
|
||||
#include "CartX07.hxx"
|
||||
#include "PopUpWidget.hxx"
|
||||
#include "CartX07Widget.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartridgeX07Widget::CartridgeX07Widget(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h, CartridgeX07& cart)
|
||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart)
|
||||
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||
{
|
||||
uInt32 size = 16 * 4096;
|
||||
initialize();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string CartridgeX07Widget::description()
|
||||
{
|
||||
ostringstream info;
|
||||
|
||||
info << "64K X07 cartridge, 16 4K banks\n"
|
||||
<< "Startup bank = " << cart.startBank() << "\n"
|
||||
<< "Multiple hotspots, all below $1000\n"
|
||||
<< "See documentation for further details\n";
|
||||
info << CartridgeEnhancedWidget::description();
|
||||
|
||||
// Eventually, we should query this from the debugger/disassembler
|
||||
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();
|
||||
return info.str();
|
||||
}
|
||||
|
|
|
@ -19,11 +19,10 @@
|
|||
#define CARTRIDGEX07_WIDGET_HXX
|
||||
|
||||
class CartridgeX07;
|
||||
class PopUpWidget;
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
#include "CartEnhancedWidget.hxx"
|
||||
|
||||
class CartridgeX07Widget : public CartDebugWidget
|
||||
class CartridgeX07Widget : public CartridgeEnhancedWidget
|
||||
{
|
||||
public:
|
||||
CartridgeX07Widget(GuiObject* boss, const GUI::Font& lfont,
|
||||
|
@ -33,17 +32,11 @@ class CartridgeX07Widget : public CartDebugWidget
|
|||
virtual ~CartridgeX07Widget() = default;
|
||||
|
||||
private:
|
||||
CartridgeX07& myCart;
|
||||
PopUpWidget* myBank{nullptr};
|
||||
string manufacturer() override { return "AtariAge / John Payson / Fred Quimby"; }
|
||||
|
||||
enum { kBankChanged = 'bkCH' };
|
||||
string description() override;
|
||||
|
||||
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
|
||||
CartridgeX07Widget() = delete;
|
||||
CartridgeX07Widget(const CartridgeX07Widget&) = delete;
|
||||
|
|
|
@ -621,7 +621,7 @@ void DebuggerDialog::addRomArea()
|
|||
|
||||
// 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(
|
||||
myRomTab, *myLFont, *myNFont, 2, 2, tabWidth - 1,
|
||||
tabHeight - myRomTab->getTabHeight() - 2);
|
||||
|
@ -644,7 +644,7 @@ void DebuggerDialog::addRomArea()
|
|||
// The cartridge RAM tab
|
||||
if (myCartDebug->internalRamSize() > 0)
|
||||
{
|
||||
tabID = myRomTab->addTab(" Cartridge RAM ", TabWidget::AUTO_WIDTH);
|
||||
tabID = myRomTab->addTab(myCartDebug->tabLabel(), TabWidget::AUTO_WIDTH);
|
||||
myCartRam =
|
||||
new CartRamWidget(myRomTab, *myLFont, *myNFont, 2, 2, tabWidth - 1,
|
||||
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
|
||||
xpos = x; ypos = y + 7;
|
||||
t = new StaticTextWidget(boss, lfont, xpos, ypos,
|
||||
lfont.getStringWidth("Bank"),
|
||||
lfont.getFontHeight(),
|
||||
"Bank", TextAlign::Left);
|
||||
t = new StaticTextWidget(boss, lfont, xpos, ypos, "Info ");
|
||||
|
||||
xpos += t->getWidth() + 5;
|
||||
xpos += t->getRight();
|
||||
myBank = new EditTextWidget(boss, nfont, xpos, ypos-2,
|
||||
_w - 2 - xpos, nfont.getLineHeight());
|
||||
myBank->setEditable(false);
|
||||
|
@ -68,7 +65,7 @@ void RomWidget::loadConfig()
|
|||
const CartState& oldstate = static_cast<const CartState&>(cart.getOldState());
|
||||
|
||||
// Fill romlist the current bank of source or disassembly
|
||||
myListIsDirty |= cart.disassemble(myListIsDirty);
|
||||
myListIsDirty |= cart.disassemblePC(myListIsDirty);
|
||||
if(myListIsDirty)
|
||||
{
|
||||
myRomList->setList(cart.disassembly());
|
||||
|
|
|
@ -22,14 +22,13 @@ MODULE_OBJS := \
|
|||
src/debugger/gui/CartCDFInfoWidget.o \
|
||||
src/debugger/gui/CartCMWidget.o \
|
||||
src/debugger/gui/CartCTYWidget.o \
|
||||
src/debugger/gui/CartCVPlusWidget.o \
|
||||
src/debugger/gui/CartCVWidget.o \
|
||||
src/debugger/gui/CartDASHWidget.o \
|
||||
src/debugger/gui/CartDFSCWidget.o \
|
||||
src/debugger/gui/CartDFWidget.o \
|
||||
src/debugger/gui/CartDPCPlusWidget.o \
|
||||
src/debugger/gui/CartDPCWidget.o \
|
||||
src/debugger/gui/CartE0Widget.o \
|
||||
src/debugger/gui/CartEnhancedWidget.o \
|
||||
src/debugger/gui/CartMNetworkWidget.o \
|
||||
src/debugger/gui/CartE7Widget.o \
|
||||
src/debugger/gui/CartE78KWidget.o \
|
||||
|
|
|
@ -104,8 +104,9 @@ Bankswitch::BSList = {{
|
|||
{ "64IN1" , "64IN1 Multicart (128/256K)" },
|
||||
{ "128IN1" , "128IN1 Multicart (256/512K)" },
|
||||
{ "2K" , "2K (32-2048 bytes Atari)" },
|
||||
{ "3E" , "3E (32K Tigervision)" },
|
||||
{ "3E+" , "3E+ (TJ modified DASH)" },
|
||||
{ "3E" , "3E (Tigervision, 32K RAM)" },
|
||||
{ "3EX" , "3EX (Tigervision, 256K RAM)" },
|
||||
{ "3E+" , "3E+ (TJ modified 3E)" },
|
||||
{ "3F" , "3F (512K Tigervision)" },
|
||||
{ "4A50" , "4A50 (64K 4A50 + RAM)" },
|
||||
{ "4K" , "4K (4K Atari)" },
|
||||
|
@ -118,8 +119,6 @@ Bankswitch::BSList = {{
|
|||
{ "CM" , "CM (SpectraVideo CompuMate)" },
|
||||
{ "CTY" , "CTY (CDW - Chetiry)" },
|
||||
{ "CV" , "CV (Commavid extra RAM)" },
|
||||
{ "CV+" , "CV+ (Extended Commavid)" },
|
||||
{ "DASH" , "DASH (Experimental)" },
|
||||
{ "DF" , "DF (CPUWIZ 128K)" },
|
||||
{ "DFSC" , "DFSC (CPUWIZ 128K + RAM)" },
|
||||
{ "DPC" , "DPC (Pitfall II)" },
|
||||
|
@ -180,6 +179,7 @@ Bankswitch::ExtensionMap Bankswitch::ourExtensions = {
|
|||
{ "128N1" , Bankswitch::Type::_128IN1 },
|
||||
{ "2K" , Bankswitch::Type::_2K },
|
||||
{ "3E" , Bankswitch::Type::_3E },
|
||||
{ "3EX" , Bankswitch::Type::_3EX },
|
||||
{ "3EP" , Bankswitch::Type::_3EP },
|
||||
{ "3E+" , Bankswitch::Type::_3EP },
|
||||
{ "3F" , Bankswitch::Type::_3F },
|
||||
|
@ -197,9 +197,6 @@ Bankswitch::ExtensionMap Bankswitch::ourExtensions = {
|
|||
{ "CM" , Bankswitch::Type::_CM },
|
||||
{ "CTY" , Bankswitch::Type::_CTY },
|
||||
{ "CV" , Bankswitch::Type::_CV },
|
||||
{ "CVP" , Bankswitch::Type::_CVP },
|
||||
{ "DAS" , Bankswitch::Type::_DASH },
|
||||
{ "DASH" , Bankswitch::Type::_DASH },
|
||||
{ "DF" , Bankswitch::Type::_DF },
|
||||
{ "DFS" , Bankswitch::Type::_DFSC },
|
||||
{ "DFSC" , Bankswitch::Type::_DFSC },
|
||||
|
@ -250,6 +247,7 @@ Bankswitch::NameToTypeMap Bankswitch::ourNameToTypes = {
|
|||
{ "2K" , Bankswitch::Type::_2K },
|
||||
{ "3E" , Bankswitch::Type::_3E },
|
||||
{ "3E+" , Bankswitch::Type::_3EP },
|
||||
{ "3EX" , Bankswitch::Type::_3EX },
|
||||
{ "3F" , Bankswitch::Type::_3F },
|
||||
{ "4A50" , Bankswitch::Type::_4A50 },
|
||||
{ "4K" , Bankswitch::Type::_4K },
|
||||
|
@ -262,8 +260,6 @@ Bankswitch::NameToTypeMap Bankswitch::ourNameToTypes = {
|
|||
{ "CM" , Bankswitch::Type::_CM },
|
||||
{ "CTY" , Bankswitch::Type::_CTY },
|
||||
{ "CV" , Bankswitch::Type::_CV },
|
||||
{ "CV+" , Bankswitch::Type::_CVP },
|
||||
{ "DASH" , Bankswitch::Type::_DASH },
|
||||
{ "DF" , Bankswitch::Type::_DF },
|
||||
{ "DFSC" , Bankswitch::Type::_DFSC },
|
||||
{ "DPC" , Bankswitch::Type::_DPC },
|
||||
|
|
|
@ -38,14 +38,14 @@ class Bankswitch
|
|||
public:
|
||||
// Currently supported bankswitch schemes
|
||||
enum class Type {
|
||||
_AUTO, _0840, _2IN1, _4IN1, _8IN1, _16IN1, _32IN1,
|
||||
_64IN1, _128IN1, _2K, _3E, _3EP, _3F, _4A50,
|
||||
_4K, _4KSC, _AR, _BF, _BFSC, _BUS, _CDF,
|
||||
_CM, _CTY, _CV, _CVP, _DASH, _DF, _DFSC,
|
||||
_DPC, _DPCP, _E0, _E7, _E78K, _EF, _EFSC,
|
||||
_F0, _F4, _F4SC, _F6, _F6SC, _F8, _F8SC,
|
||||
_FA, _FA2, _FC, _FE, _MDM, _SB, _UA,
|
||||
_UASW, _WD, _WDSW, _X07,
|
||||
_AUTO, _0840, _2IN1, _4IN1, _8IN1, _16IN1, _32IN1,
|
||||
_64IN1, _128IN1, _2K, _3E, _3EX, _3EP, _3F,
|
||||
_4A50, _4K, _4KSC, _AR, _BF, _BFSC, _BUS,
|
||||
_CDF, _CM, _CTY, _CV, _DF, _DFSC, _DPC,
|
||||
_DPCP, _E0, _E7, _E78K, _EF, _EFSC, _F0,
|
||||
_F4, _F4SC, _F6, _F6SC, _F8, _F8SC, _FA,
|
||||
_FA2, _FC, _FE, _MDM, _SB, _UA, _UASW,
|
||||
_WD, _WDSW, _X07,
|
||||
#ifdef CUSTOM_ARM
|
||||
_CUSTOM,
|
||||
#endif
|
||||
|
|
|
@ -83,7 +83,7 @@ uInt16 Cartridge::bankSize(uInt16 bank) const
|
|||
|
||||
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;
|
||||
uInt32 offset = 0;
|
||||
|
||||
for(uInt16 bank = 0; bank < bankCount(); ++bank)
|
||||
for(uInt16 bank = 0; bank < romBankCount(); ++bank)
|
||||
{
|
||||
uInt16 origin = bankOrigin(bank);
|
||||
uInt16 bankSize = this->bankSize(bank);
|
||||
|
||||
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)
|
||||
{
|
||||
out << Common::Base::HEX4 << (addr | origin) << ","
|
||||
|
@ -159,7 +159,7 @@ string Cartridge::getAccessCounters() const
|
|||
}
|
||||
out << "\n";
|
||||
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)
|
||||
{
|
||||
out << Common::Base::HEX4 << (addr | origin) << ","
|
||||
|
@ -230,11 +230,11 @@ uInt16 Cartridge::initializeStartBank(uInt16 defaultBank)
|
|||
int propsBank = myStartBankFromPropsFunc();
|
||||
|
||||
if(randomStartBank())
|
||||
return myStartBank = mySystem->randGenerator().next() % bankCount();
|
||||
return myStartBank = mySystem->randGenerator().next() % romBankCount();
|
||||
else if(propsBank >= 0)
|
||||
return myStartBank = BSPF::clamp(propsBank, 0, bankCount() - 1);
|
||||
return myStartBank = BSPF::clamp(propsBank, 0, romBankCount() - 1);
|
||||
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; }
|
||||
|
||||
/**
|
||||
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
|
||||
what a 'bank' is.
|
||||
|
||||
|
@ -189,10 +189,18 @@ class Cartridge : public Device
|
|||
cases where ROMs have 2K blocks in some preset area, the bankCount
|
||||
is the number of such blocks. Finally, in some esoteric schemes,
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
|
|
|
@ -21,25 +21,14 @@
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Cartridge0840::Cartridge0840(const ByteBuffer& image, size_t size,
|
||||
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)
|
||||
{
|
||||
mySystem = &system;
|
||||
CartridgeEnhanced::install(system);
|
||||
|
||||
// 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
|
||||
|
@ -56,32 +45,34 @@ void Cartridge0840::install(System& system)
|
|||
System::PageAccess access(this, System::PageAccessType::READ);
|
||||
for(uInt16 addr = 0x0800; addr < 0x0FFF; addr += System::PAGE_SIZE)
|
||||
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)
|
||||
{
|
||||
address &= 0x1840;
|
||||
|
||||
// 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;
|
||||
}
|
||||
checkSwitchBank(address);
|
||||
|
||||
// Because of the way we've set up accessing above, we can only
|
||||
// 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)
|
||||
{
|
||||
address &= 0x1840;
|
||||
|
||||
// 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;
|
||||
}
|
||||
checkSwitchBank(address);
|
||||
|
||||
// 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
|
||||
|
@ -121,85 +95,3 @@ bool Cartridge0840::poke(uInt16 address, uInt8 value)
|
|||
|
||||
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
|
||||
|
||||
#include "bspf.hxx"
|
||||
#include "Cart.hxx"
|
||||
#include "CartEnhanced.hxx"
|
||||
#include "System.hxx"
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
#include "Cart0840Widget.hxx"
|
||||
|
@ -30,9 +30,9 @@
|
|||
are two 4K banks, which are switched by accessing $0800 (bank 0) and
|
||||
$0840 (bank 1).
|
||||
|
||||
@author Fred X. Quimby
|
||||
@author Fred X. Quimby, Thomas Jentzsch
|
||||
*/
|
||||
class Cartridge0840 : public Cartridge
|
||||
class Cartridge0840 : public CartridgeEnhanced
|
||||
{
|
||||
friend class Cartridge0840Widget;
|
||||
|
||||
|
@ -50,11 +50,6 @@ class Cartridge0840 : public Cartridge
|
|||
virtual ~Cartridge0840() = default;
|
||||
|
||||
public:
|
||||
/**
|
||||
Reset device 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.
|
||||
|
@ -63,58 +58,6 @@ class Cartridge0840 : public Cartridge
|
|||
*/
|
||||
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).
|
||||
|
||||
|
@ -152,12 +95,11 @@ class Cartridge0840 : public Cartridge
|
|||
bool poke(uInt16 address, uInt8 value) override;
|
||||
|
||||
private:
|
||||
// The 8K ROM image of the cartridge
|
||||
std::array<uInt8, 8_KB> myImage;
|
||||
bool checkSwitchBank(uInt16 address, uInt8 value = 0) override;
|
||||
|
||||
// Indicates the offset into the ROM image (aligns to current bank)
|
||||
uInt16 myBankOffset{0};
|
||||
uInt16 hotspot() const override { return 0x0840; }
|
||||
|
||||
private:
|
||||
// Previous Device's page access
|
||||
std::array<System::PageAccess, 8> myHotSpotPageAccess;
|
||||
|
||||
|
|
|
@ -21,15 +21,19 @@
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Cartridge2K::Cartridge2K(const ByteBuffer& image, size_t size,
|
||||
const string& md5, const Settings& settings)
|
||||
: Cartridge(settings, md5)
|
||||
: CartridgeEnhanced(image, size, md5, settings)
|
||||
{
|
||||
// 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
|
||||
mySize = 1;
|
||||
mySize = 1; myBankShift = 0;
|
||||
while(mySize < size)
|
||||
{
|
||||
mySize <<= 1;
|
||||
myBankShift++;
|
||||
}
|
||||
|
||||
// Initialize ROM with illegal 6502 opcode that causes a real 6502 to jam
|
||||
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)
|
||||
std::copy_n(image.get(), mySize, myImage.get() + i);
|
||||
mySize = System::PAGE_SIZE;
|
||||
}
|
||||
|
||||
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);
|
||||
myBankShift = 6;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
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;
|
||||
|
||||
#include "bspf.hxx"
|
||||
#include "Cart.hxx"
|
||||
#include "CartEnhanced.hxx"
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
#include "Cart2KWidget.hxx"
|
||||
#endif
|
||||
|
@ -33,9 +33,9 @@ class System;
|
|||
data repeats in intervals based on the size of the ROM (which will
|
||||
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;
|
||||
|
||||
|
@ -53,52 +53,6 @@ class Cartridge2K : public Cartridge
|
|||
virtual ~Cartridge2K() = default;
|
||||
|
||||
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).
|
||||
|
||||
|
@ -118,22 +72,8 @@ class Cartridge2K : public Cartridge
|
|||
}
|
||||
#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:
|
||||
// Pointer to a dynamically allocated ROM image of the cartridge
|
||||
ByteBuffer myImage;
|
||||
|
||||
// Size of the ROM image
|
||||
size_t mySize{0};
|
||||
|
||||
// Mask to use for mirroring
|
||||
uInt16 myMask{0};
|
||||
bool checkSwitchBank(uInt16 address, uInt8 value = 0) override { return false; }
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
|
|
|
@ -22,268 +22,52 @@
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Cartridge3E::Cartridge3E(const ByteBuffer& image, size_t size,
|
||||
const string& md5, const Settings& settings)
|
||||
: Cartridge(settings, md5),
|
||||
mySize(size)
|
||||
: CartridgeEnhanced(image, size, md5, settings)
|
||||
{
|
||||
// Allocate array for the ROM image
|
||||
myImage = make_unique<uInt8[]>(mySize);
|
||||
|
||||
// Copy the ROM image into my buffer
|
||||
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());
|
||||
myBankShift = BANK_SHIFT;
|
||||
myRamSize = RAM_SIZE;
|
||||
myRamBankCount = RAM_BANKS;
|
||||
myRamWpHigh = RAM_HIGH_WP;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
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
|
||||
for(uInt16 addr = 0x00; addr < 0x40; addr += System::PAGE_SIZE)
|
||||
mySystem->setPageAccess(addr, access);
|
||||
}
|
||||
|
||||
// Setup the second segment to always point to the last ROM slice
|
||||
access.type = System::PageAccessType::READ;
|
||||
for(uInt16 addr = 0x1800; addr < 0x2000; addr += System::PAGE_SIZE)
|
||||
{
|
||||
access.directPeekBase = &myImage[(mySize - 2048) + (addr & 0x07FF)];
|
||||
access.romAccessBase = &myRomAccessBase[(mySize - 2048) + (addr & 0x07FF)];
|
||||
access.romPeekCounter = &myRomAccessCounter[(mySize - 2048) + (addr & 0x07FF)];
|
||||
access.romPokeCounter = &myRomAccessCounter[(mySize - 2048) + (addr & 0x07FF) + myAccessSize];
|
||||
mySystem->setPageAccess(addr, access);
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool Cartridge3E::checkSwitchBank(uInt16 address, uInt8 value)
|
||||
{
|
||||
// Switch banks if necessary
|
||||
if(address == 0x003F) {
|
||||
// Switch ROM bank into segment 0
|
||||
bank(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Install pages for the startup bank into the first segment
|
||||
bank(startBank());
|
||||
else if(address == 0x003E)
|
||||
{
|
||||
// Switch RAM bank into segment 0
|
||||
bank(value + romBankCount());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt8 Cartridge3E::peek(uInt16 address)
|
||||
{
|
||||
uInt16 peekAddress = address;
|
||||
address &= 0x0FFF;
|
||||
|
||||
// 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
|
||||
address &= ROM_MASK;
|
||||
|
||||
if(address < 0x0040) // TIA access
|
||||
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 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;
|
||||
return CartridgeEnhanced::peek(peekAddress);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
class System;
|
||||
|
||||
#include "bspf.hxx"
|
||||
#include "Cart.hxx"
|
||||
#include "CartEnhanced.hxx"
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
#include "Cart3EWidget.hxx"
|
||||
#endif
|
||||
|
@ -47,10 +47,8 @@ class System;
|
|||
by storing its value into $3F. To map RAM in the first 2K segment
|
||||
instead, store the RAM bank number into $3E.
|
||||
|
||||
This implementation of 3E bankswitching numbers the ROM banks 0 to
|
||||
255, and the RAM banks 256 to 287. This is done because the public
|
||||
bankswitching interface requires us to use one bank number, not one
|
||||
bank number plus the knowledge of whether it's RAM or ROM.
|
||||
This implementation of 3E bankswitching numbers the RAM banks (up to 32)
|
||||
after the ROM banks (up to 256).
|
||||
|
||||
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
|
||||
|
@ -58,10 +56,10 @@ class System;
|
|||
may add a stella.pro property for this), but for now it shouldn't cause
|
||||
any problems. (Famous last words...)
|
||||
|
||||
@author B. Watson
|
||||
@author B. Watson, Thomas Jentzsch
|
||||
*/
|
||||
|
||||
class Cartridge3E : public Cartridge
|
||||
class Cartridge3E : public CartridgeEnhanced
|
||||
{
|
||||
friend class Cartridge3EWidget;
|
||||
|
||||
|
@ -79,10 +77,6 @@ class Cartridge3E : public Cartridge
|
|||
virtual ~Cartridge3E() = default;
|
||||
|
||||
public:
|
||||
/**
|
||||
Reset device to its power-on state
|
||||
*/
|
||||
void reset() override;
|
||||
|
||||
/**
|
||||
Install cartridge in the specified system. Invoked by the system
|
||||
|
@ -92,66 +86,6 @@ class Cartridge3E : public Cartridge
|
|||
*/
|
||||
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).
|
||||
|
||||
|
@ -179,27 +113,21 @@ class Cartridge3E : public Cartridge
|
|||
*/
|
||||
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:
|
||||
// Pointer to a dynamically allocated ROM image of the cartridge
|
||||
ByteBuffer myImage;
|
||||
bool checkSwitchBank(uInt16 address, uInt8 value) override;
|
||||
|
||||
// RAM contents. For now every ROM gets all 32K of potential RAM
|
||||
std::array<uInt8, 32_KB> myRAM;
|
||||
protected:
|
||||
// log(ROM bank segment size) / log(2)
|
||||
static constexpr uInt16 BANK_SHIFT = 11; // = 2K = 0x0800
|
||||
|
||||
// Size of the ROM image
|
||||
size_t mySize{0};
|
||||
// The number of RAM banks
|
||||
static constexpr uInt16 RAM_BANKS = 32;
|
||||
|
||||
// Indicates which bank is currently active for the first segment
|
||||
uInt16 myCurrentBank{0};
|
||||
// RAM size
|
||||
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:
|
||||
// Following constructors and assignment operators not supported
|
||||
|
|
|
@ -22,339 +22,63 @@
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Cartridge3EPlus::Cartridge3EPlus(const ByteBuffer& image, size_t size,
|
||||
const string& md5, const Settings& settings)
|
||||
: Cartridge(settings, md5),
|
||||
mySize(size)
|
||||
: Cartridge3E(image, size, md5, settings)
|
||||
{
|
||||
// Allocate array for the ROM image
|
||||
myImage = make_unique<uInt8[]>(mySize);
|
||||
|
||||
// Copy the ROM image into my buffer
|
||||
std::copy_n(image.get(), mySize, myImage.get());
|
||||
createRomAccessArrays(mySize + myRAM.size());
|
||||
myBankShift = BANK_SHIFT;
|
||||
myRamSize = RAM_SIZE;
|
||||
myRamBankCount = RAM_BANKS;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Cartridge3EPlus::reset()
|
||||
{
|
||||
initializeRAM(myRAM.data(), myRAM.size());
|
||||
CartridgeEnhanced::reset();
|
||||
|
||||
// Remember startup bank (0 per spec, rather than last per 3E scheme).
|
||||
// Set this to go to 3rd 1K Bank.
|
||||
initializeStartBank(0);
|
||||
|
||||
// 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);
|
||||
// 1st segment in mapped to start bank in CartridgeEnhanced
|
||||
bank(mySystem->randGenerator().next() % romBankCount(), 1);
|
||||
bank(mySystem->randGenerator().next() % romBankCount(), 2);
|
||||
bank(startBank(), 3);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Cartridge3EPlus::install(System& system)
|
||||
bool Cartridge3EPlus::checkSwitchBank(uInt16 address, uInt8 value)
|
||||
{
|
||||
mySystem = &system;
|
||||
|
||||
System::PageAccess access(this, System::PageAccessType::READWRITE);
|
||||
|
||||
// The hotspots are in TIA address space, so we claim it here
|
||||
for(uInt16 addr = 0x00; addr < 0x40; addr += System::PAGE_SIZE)
|
||||
mySystem->setPageAccess(addr, access);
|
||||
|
||||
// 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();
|
||||
|
||||
// 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
|
||||
// Switch banks if necessary
|
||||
if(address == 0x003F) {
|
||||
// Switch ROM bank into segment 0
|
||||
bank(value & 0b111111, value >> 6);
|
||||
return true;
|
||||
}
|
||||
else if(address == 0x003E)
|
||||
{
|
||||
// Switch RAM bank into segment 0
|
||||
bank((value & 0b111111) + romBankCount(), value >> 6);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt8 Cartridge3EPlus::peek(uInt16 address)
|
||||
{
|
||||
uInt16 peekAddress = address;
|
||||
address &= 0x0FFF; // restrict to 4K address range
|
||||
address &= ROM_MASK;
|
||||
|
||||
uInt8 value = 0;
|
||||
uInt32 bank = (address >> (ROM_BANK_TO_POWER - 1)) & 7; // convert to 512 byte bank index (0-7)
|
||||
uInt16 imageBank = bankInUse[bank]; // the ROM/RAM bank that's here
|
||||
if(address < 0x0040) // TIA peek
|
||||
return mySystem->tia().peek(address);
|
||||
|
||||
if(imageBank == BANK_UNDEFINED) // an uninitialised bank?
|
||||
{
|
||||
// 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;
|
||||
return CartridgeEnhanced::peek(peekAddress);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
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'
|
||||
// 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))
|
||||
{
|
||||
if(address < 0x0040) // TIA poke
|
||||
// Handle TIA space that we claimed above
|
||||
changed = changed || 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
|
||||
return mySystem->tia().poke(address, value);
|
||||
|
||||
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;
|
||||
#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;
|
||||
|
||||
#include "bspf.hxx"
|
||||
#include "Cart.hxx"
|
||||
#include "Cart3E.hxx"
|
||||
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
class Cartridge3EPlusWidget;
|
||||
|
@ -29,19 +29,67 @@ class Cartridge3EPlusWidget;
|
|||
#endif
|
||||
|
||||
/**
|
||||
Cartridge class from Thomas Jentzsch, mostly based on the 'DASH' scheme
|
||||
with the following changes:
|
||||
Cartridge class for new tiling engine "Boulder Dash" format games with RAM.
|
||||
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:
|
||||
- read $x000, write $x200
|
||||
- read $x400, write $x600
|
||||
- read $x800, write $xa00
|
||||
- read $xc00, write $xe00
|
||||
The destination bank (0-3) is held in the top bits of the value written to
|
||||
$3E (for RAM switching) or $3F (for ROM switching). The low 6 bits give
|
||||
the actual bank number (0-63) corresponding to 512 byte blocks for RAM and
|
||||
1024 byte blocks for ROM. The maximum size is therefore 32K RAM and 64K ROM.
|
||||
|
||||
@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;
|
||||
|
||||
|
@ -62,59 +110,6 @@ class Cartridge3EPlus: public Cartridge
|
|||
/** Reset device 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;
|
||||
|
||||
/**
|
||||
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).
|
||||
|
||||
|
@ -152,47 +147,17 @@ class Cartridge3EPlus: public Cartridge
|
|||
bool poke(uInt16 address, uInt8 value) override;
|
||||
|
||||
private:
|
||||
bool bankRAM(uInt8 bank); // switch a RAM bank
|
||||
bool bankROM(uInt8 bank); // switch a ROM bank
|
||||
bool checkSwitchBank(uInt16 address, uInt8 value) override;
|
||||
|
||||
void bankRAMSlot(uInt16 bank); // switch in a 512b RAM slot (lower or upper 1/2 bank)
|
||||
void bankROMSlot(uInt16 bank); // switch in a 512b RAM slot (read or write port)
|
||||
private:
|
||||
// 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
|
||||
// bank is used in that area. ROM switches 1K so occupies 2 successive entries for each switch. RAM occupies
|
||||
// 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;
|
||||
// RAM size
|
||||
static constexpr size_t RAM_SIZE = RAM_BANKS << (BANK_SHIFT - 1); // = 32K = 0x4000;
|
||||
|
||||
private:
|
||||
// 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