Merge remote-tracking branch 'remotes/origin/refactor/cart'

This commit is contained in:
thrust26 2020-05-02 19:59:46 +02:00
commit 5c7bea8923
589 changed files with 13427 additions and 13363 deletions

View File

@ -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!

View File

@ -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 &#185;</td><td>64-128K Multicart (32 games) </td><td>.32N, .32N1 </td></tr>
<tr><td>64IN1 &#185;</td><td>64/128K Multicart </td><td>.64N, .64N1 </td></tr>
<tr><td>128IN1 &#185;</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 &#178;</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 &#185;</td><td>Spectravideo CompuMate </td><td>.CM </td></tr>
<tr><td>CTY &#178;</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>

View File

@ -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)

View File

@ -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;

View File

@ -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.

View File

@ -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;

View File

@ -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();
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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];
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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;

View File

@ -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];
}

View File

@ -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];
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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;

View File

@ -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
};

View File

@ -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

View File

@ -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();
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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

View File

@ -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";

View File

@ -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

View File

@ -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();
}

View File

@ -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;

View File

@ -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];

View File

@ -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];

View File

@ -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();
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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

View File

@ -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();
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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);

View File

@ -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();
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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;

View File

@ -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);

View File

@ -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());

View File

@ -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 \

View File

@ -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 },

View File

@ -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

View File

@ -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);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -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.

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

28
src/emucore/Cart3EX.cxx Normal file
View File

@ -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;
}

68
src/emucore/Cart3EX.hxx Normal file
View File

@ -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