implement swapped hotspot option for UA (for Mickey)

This commit is contained in:
Thomas Jentzsch 2019-07-28 11:11:27 +02:00
parent bd39c0836f
commit db7def887d
7 changed files with 48 additions and 26 deletions

View File

@ -22,19 +22,20 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CartridgeUAWidget::CartridgeUAWidget( CartridgeUAWidget::CartridgeUAWidget(
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
int x, int y, int w, int h, CartridgeUA& cart) int x, int y, int w, int h, CartridgeUA& cart, bool swapHotspots)
: CartDebugWidget(boss, lfont, nfont, x, y, w, h), : CartDebugWidget(boss, lfont, nfont, x, y, w, h),
myCart(cart) myCart(cart),
mySwappedHotspots(swapHotspots)
{ {
uInt16 size = 2 * 4096; uInt16 size = 2 * 4096;
ostringstream info; ostringstream info;
info << "8K UA cartridge, two 4K banks\n" info << "8K UA cartridge" << (mySwappedHotspots ? " (swapped banks)" : "") << ", two 4K banks\n"
<< "Startup bank = " << cart.startBank() << " or undetermined\n"; << "Startup bank = " << cart.startBank() << " or undetermined\n";
// Eventually, we should query this from the debugger/disassembler // Eventually, we should query this from the debugger/disassembler
for(uInt32 i = 0, offset = 0xFFC, spot = 0x220; i < 2; for(uInt32 i = 0, offset = 0xFFC, spot = mySwappedHotspots ? 0x240 : 0x220; i < 2;
++i, offset += 0x1000, spot += 0x20) ++i, offset += 0x1000, spot += mySwappedHotspots ? -0x20 : 0x20)
{ {
uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset]; uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset];
start -= start % 0x1000; start -= start % 0x1000;
@ -46,8 +47,16 @@ CartridgeUAWidget::CartridgeUAWidget(
ypos = addBaseInformation(size, "UA Limited", info.str()) + myLineHeight; ypos = addBaseInformation(size, "UA Limited", info.str()) + myLineHeight;
VariantList items; VariantList items;
VarList::push_back(items, "0 ($220, $2A0)"); if (swapHotspots)
VarList::push_back(items, "1 ($240, $2C0)"); {
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 = myBank =
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("0 ($FFx, $FFx)"), new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("0 ($FFx, $FFx)"),
myLineHeight, items, "Set bank ", myLineHeight, items, "Set bank ",
@ -89,7 +98,7 @@ string CartridgeUAWidget::bankState()
static const char* const spot[] = { "$220, $2A0", "$240, $2C0" }; static const char* const spot[] = { "$220, $2A0", "$240, $2C0" };
buf << "Bank = " << std::dec << myCart.getBank() buf << "Bank = " << std::dec << myCart.getBank()
<< ", hotspots = " << spot[myCart.getBank()]; << ", hotspots = " << spot[myCart.getBank() ^ (mySwappedHotspots ? 1u : 0u)];
return buf.str(); return buf.str();
} }

View File

@ -29,13 +29,15 @@ class CartridgeUAWidget : public CartDebugWidget
CartridgeUAWidget(GuiObject* boss, const GUI::Font& lfont, CartridgeUAWidget(GuiObject* boss, const GUI::Font& lfont,
const GUI::Font& nfont, const GUI::Font& nfont,
int x, int y, int w, int h, int x, int y, int w, int h,
CartridgeUA& cart); CartridgeUA& cart, bool swapHotspots);
virtual ~CartridgeUAWidget() = default; virtual ~CartridgeUAWidget() = default;
private: private:
CartridgeUA& myCart; CartridgeUA& myCart;
PopUpWidget* myBank; PopUpWidget* myBank;
bool mySwappedHotspots;
enum { kBankChanged = 'bkCH' }; enum { kBankChanged = 'bkCH' };
private: private:

View File

@ -135,6 +135,7 @@ Bankswitch::Description Bankswitch::BSList[int(Bankswitch::Type::NumSchemes)] =
{ "MDM" , "MDM (Menu Driven Megacart)" }, { "MDM" , "MDM (Menu Driven Megacart)" },
{ "SB" , "SB (128-256K SUPERbank)" }, { "SB" , "SB (128-256K SUPERbank)" },
{ "UA" , "UA (8K UA Ltd.)" }, { "UA" , "UA (8K UA Ltd.)" },
{ "UASW" , "UASW (8K UA swapped banks)" },
{ "WD" , "WD (Experimental)" }, { "WD" , "WD (Experimental)" },
{ "X07" , "X07 (64K AtariAge)" }, { "X07" , "X07 (64K AtariAge)" },
#if defined(CUSTOM_ARM) #if defined(CUSTOM_ARM)
@ -219,6 +220,7 @@ Bankswitch::ExtensionMap Bankswitch::ourExtensions = {
{ "MDM" , Bankswitch::Type::_MDM }, { "MDM" , Bankswitch::Type::_MDM },
{ "SB" , Bankswitch::Type::_SB }, { "SB" , Bankswitch::Type::_SB },
{ "UA" , Bankswitch::Type::_UA }, { "UA" , Bankswitch::Type::_UA },
{ "UASW" , Bankswitch::Type::_UASW },
{ "WD" , Bankswitch::Type::_WD }, { "WD" , Bankswitch::Type::_WD },
{ "X07" , Bankswitch::Type::_X07 } { "X07" , Bankswitch::Type::_X07 }
}; };
@ -273,6 +275,7 @@ Bankswitch::NameToTypeMap Bankswitch::ourNameToTypes = {
{ "MDM" , Bankswitch::Type::_MDM }, { "MDM" , Bankswitch::Type::_MDM },
{ "SB" , Bankswitch::Type::_SB }, { "SB" , Bankswitch::Type::_SB },
{ "UA" , Bankswitch::Type::_UA }, { "UA" , Bankswitch::Type::_UA },
{ "UASW" , Bankswitch::Type::_UASW },
{ "WD" , Bankswitch::Type::_WD }, { "WD" , Bankswitch::Type::_WD },
{ "X07" , Bankswitch::Type::_X07 } { "X07" , Bankswitch::Type::_X07 }
}; };

View File

@ -44,8 +44,8 @@ class Bankswitch
_CM, _CTY, _CV, _CVP, _DASH, _DF, _DFSC, _CM, _CTY, _CV, _CVP, _DASH, _DF, _DFSC,
_DPC, _DPCP, _E0, _E7, _E78K, _EF, _EFSC, _DPC, _DPCP, _E0, _E7, _E78K, _EF, _EFSC,
_F0, _F4, _F4SC, _F6, _F6SC, _F8, _F8SC, _F0, _F4, _F4SC, _F6, _F6SC, _F8, _F8SC,
_FA, _FA2, _FE, _MDM, _SB, _UA, _WD, _FA, _FA2, _FE, _MDM, _SB, _UA, _UASW,
_X07, _WD, _X07,
#ifdef CUSTOM_ARM #ifdef CUSTOM_ARM
_CUSTOM, _CUSTOM,
#endif #endif

View File

@ -322,6 +322,8 @@ CartDetector::createFromImage(const ByteBuffer& image, uInt32 size, Bankswitch::
return make_unique<CartridgeMDM>(image, size, md5, settings); return make_unique<CartridgeMDM>(image, size, md5, settings);
case Bankswitch::Type::_UA: case Bankswitch::Type::_UA:
return make_unique<CartridgeUA>(image, size, md5, settings); return make_unique<CartridgeUA>(image, size, md5, settings);
case Bankswitch::Type::_UASW:
return make_unique<CartridgeUA>(image, size, md5, settings, true);
case Bankswitch::Type::_SB: case Bankswitch::Type::_SB:
return make_unique<CartridgeSB>(image, size, md5, settings); return make_unique<CartridgeSB>(image, size, md5, settings);
case Bankswitch::Type::_WD: case Bankswitch::Type::_WD:

View File

@ -20,9 +20,11 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CartridgeUA::CartridgeUA(const ByteBuffer& image, uInt32 size, CartridgeUA::CartridgeUA(const ByteBuffer& image, uInt32 size,
const string& md5, const Settings& settings) const string& md5, const Settings& settings,
bool swapHotspots)
: Cartridge(settings, md5), : Cartridge(settings, md5),
myBankOffset(0) myBankOffset(0),
mySwappedHotspots(swapHotspots)
{ {
// Copy the ROM image into my buffer // Copy the ROM image into my buffer
memcpy(myImage, image.get(), std::min(8192u, size)); memcpy(myImage, image.get(), std::min(8192u, size));
@ -68,12 +70,12 @@ uInt8 CartridgeUA::peek(uInt16 address)
{ {
case 0x0220: case 0x0220:
// Set the current bank to the lower 4k bank // Set the current bank to the lower 4k bank
bank(0); bank(mySwappedHotspots ? 1 : 0);
break; break;
case 0x0240: case 0x0240:
// Set the current bank to the upper 4k bank // Set the current bank to the upper 4k bank
bank(1); bank(mySwappedHotspots ? 0 : 1);
break; break;
default: default:
@ -96,12 +98,12 @@ bool CartridgeUA::poke(uInt16 address, uInt8 value)
{ {
case 0x0220: case 0x0220:
// Set the current bank to the lower 4k bank // Set the current bank to the lower 4k bank
bank(0); bank(mySwappedHotspots ? 1 : 0);
break; break;
case 0x0240: case 0x0240:
// Set the current bank to the upper 4k bank // Set the current bank to the upper 4k bank
bank(1); bank(mySwappedHotspots ? 0 : 1);
break; break;
default: default:
@ -175,7 +177,7 @@ bool CartridgeUA::save(Serializer& out) const
} }
catch(...) catch(...)
{ {
cerr << "ERROR: CartridgeUA::save" << endl; cerr << "ERROR: " << name() << "::save" << endl;
return false; return false;
} }
@ -191,7 +193,7 @@ bool CartridgeUA::load(Serializer& in)
} }
catch(...) catch(...)
{ {
cerr << "ERROR: CartridgeUA::load" << endl; cerr << "ERROR: " << name() << "::load" << endl;
return false; return false;
} }

View File

@ -40,13 +40,14 @@ class CartridgeUA : public Cartridge
/** /**
Create a new cartridge using the specified image Create a new cartridge using the specified image
@param image Pointer to the ROM image @param image Pointer to the ROM image
@param size The size of the ROM image @param size The size of the ROM image
@param md5 The md5sum of the ROM image @param md5 The md5sum of the ROM image
@param settings A reference to the various settings (read-only) @param settings A reference to the various settings (read-only)
@param swapHotspots Swap hotspots
*/ */
CartridgeUA(const ByteBuffer& image, uInt32 size, const string& md5, CartridgeUA(const ByteBuffer& image, uInt32 size, const string& md5,
const Settings& settings); const Settings& settings, bool swapHotspots = false);
virtual ~CartridgeUA() = default; virtual ~CartridgeUA() = default;
public: public:
@ -118,7 +119,7 @@ class CartridgeUA : public Cartridge
@return The name of the object @return The name of the object
*/ */
string name() const override { return "CartridgeUA"; } string name() const override { return mySwappedHotspots ? "CartridgeUASW" : "CartridgeUA"; }
#ifdef DEBUGGER_SUPPORT #ifdef DEBUGGER_SUPPORT
/** /**
@ -128,7 +129,7 @@ class CartridgeUA : public Cartridge
CartDebugWidget* debugWidget(GuiObject* boss, const GUI::Font& lfont, CartDebugWidget* debugWidget(GuiObject* boss, const GUI::Font& lfont,
const GUI::Font& nfont, int x, int y, int w, int h) override const GUI::Font& nfont, int x, int y, int w, int h) override
{ {
return new CartridgeUAWidget(boss, lfont, nfont, x, y, w, h, *this); return new CartridgeUAWidget(boss, lfont, nfont, x, y, w, h, *this, mySwappedHotspots);
} }
#endif #endif
@ -159,6 +160,9 @@ class CartridgeUA : public Cartridge
// Indicates the offset into the ROM image (aligns to current bank) // Indicates the offset into the ROM image (aligns to current bank)
uInt16 myBankOffset; uInt16 myBankOffset;
// Indicates if banks are swapped ("Mickey" cart)
bool mySwappedHotspots;
private: private:
// Following constructors and assignment operators not supported // Following constructors and assignment operators not supported
CartridgeUA() = delete; CartridgeUA() = delete;