diff --git a/src/debugger/gui/Cart4A50Widget.cxx b/src/debugger/gui/Cart4A50Widget.cxx new file mode 100644 index 000000000..14c0a9391 --- /dev/null +++ b/src/debugger/gui/Cart4A50Widget.cxx @@ -0,0 +1,277 @@ +//============================================================================ +// +// 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-2013 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. +// +// $Id$ +//============================================================================ + +#include "Cart4A50.hxx" +#include "PopUpWidget.hxx" +#include "Cart4A50Widget.hxx" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Cartridge4A50Widget::Cartridge4A50Widget( + GuiObject* boss, const GUI::Font& font, + int x, int y, int w, int h, Cartridge4A50& cart) + : CartDebugWidget(boss, font, x, y, w, h), + myCart(cart) +{ + string info = + "4A50 cartridge - 128K ROM and 32K RAM, split in various bank configurations\n" + "Multiple hotspots, see documentation for further details\n" + "Lower bank region (2K) : $F000 - $F7FF\n" + "Middle bank region (1.5K): $F800 - $FDFF\n" + "High bank region (256B) : $FE00 - $FEFF\n" + "Fixed (last 256B of ROM) : $FF00 - $FFFF\n"; + + int xpos = 10, + ypos = addBaseInformation(cart.mySize, "John Payson / Supercat", info) + + myLineHeight; + + StringMap items16, items32, items128, items256; + for(uInt32 i = 0; i < 16; ++i) + { + const string& b = BSPF_toString(i); + items16.push_back(b, b); + } + items16.push_back("Inactive", ""); + + for(uInt32 i = 0; i < 32; ++i) + { + const string& b = BSPF_toString(i); + items32.push_back(b, b); + } + items32.push_back("Inactive", ""); + + for(uInt32 i = 0; i < 128; ++i) + { + const string& b = BSPF_toString(i); + items128.push_back(b, b); + } + items128.push_back("Inactive", ""); + + for(uInt32 i = 0; i < 256; ++i) + { + const string& b = BSPF_toString(i); + items256.push_back(b, b); + } + items256.push_back("Inactive", ""); + + string lowerlabel = "Set lower 2K region ($F000 - $F7FF): "; + string middlelabel = "Set middle 1.5K region ($F800 - $FDFF): "; + string highlabel = "Set high 256B region ($FE00 - $FEFF): "; + const int lwidth = font.getStringWidth(middlelabel), + fwidth = font.getStringWidth("Inactive"), + flwidth = font.getStringWidth("ROM: "); + + // Lower bank/region configuration + xpos = 10; + new StaticTextWidget(_boss, _font, xpos, ypos, lwidth, + myFontHeight, lowerlabel, kTextAlignLeft); + ypos += myLineHeight + 8; + + xpos += 40; + myROMLower = + new PopUpWidget(boss, font, xpos, ypos-2, fwidth, myLineHeight, + items32, "ROM: ", flwidth, kROMLowerChanged); + myROMLower->setTarget(this); + addFocusWidget(myROMLower); + + xpos += myROMLower->getWidth() + 20; + myRAMLower = + new PopUpWidget(boss, font, xpos, ypos-2, fwidth, myLineHeight, + items16, "RAM: ", flwidth, kRAMLowerChanged); + myRAMLower->setTarget(this); + addFocusWidget(myRAMLower); + + // Middle bank/region configuration + xpos = 10; ypos += myLineHeight + 14; + new StaticTextWidget(_boss, _font, xpos, ypos, lwidth, + myFontHeight, middlelabel, kTextAlignLeft); + ypos += myLineHeight + 8; + + xpos += 40; + myROMMiddle = + new PopUpWidget(boss, font, xpos, ypos-2, fwidth, myLineHeight, + items32, "ROM: ", flwidth, kROMMiddleChanged); + myROMMiddle->setTarget(this); + addFocusWidget(myROMMiddle); + + xpos += myROMMiddle->getWidth() + 20; + myRAMMiddle = + new PopUpWidget(boss, font, xpos, ypos-2, fwidth, myLineHeight, + items16, "RAM: ", flwidth, kRAMMiddleChanged); + myRAMMiddle->setTarget(this); + addFocusWidget(myRAMMiddle); + + // High bank/region configuration + xpos = 10; ypos += myLineHeight + 14; + new StaticTextWidget(_boss, _font, xpos, ypos, lwidth, + myFontHeight, highlabel, kTextAlignLeft); + ypos += myLineHeight + 8; + + xpos += 40; + myROMHigh = + new PopUpWidget(boss, font, xpos, ypos-2, fwidth, myLineHeight, + items256, "ROM: ", flwidth, kROMHighChanged); + myROMHigh->setTarget(this); + addFocusWidget(myROMHigh); + + xpos += myROMHigh->getWidth() + 20; + myRAMHigh = + new PopUpWidget(boss, font, xpos, ypos-2, fwidth, myLineHeight, + items128, "RAM: ", flwidth, kRAMHighChanged); + myRAMHigh->setTarget(this); + addFocusWidget(myRAMHigh); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Cartridge4A50Widget::loadConfig() +{ + // Lower bank + if(myCart.myIsRomLow) // ROM active + { + myROMLower->setSelected((myCart.mySliceLow >> 11) & 0x1F); + myRAMLower->setSelectedMax(); + } + else // RAM active + { + myROMLower->setSelectedMax(); + myRAMLower->setSelected((myCart.mySliceLow >> 11) & 0x0F); + } + + // Middle bank + if(myCart.myIsRomMiddle) // ROM active + { + myROMMiddle->setSelected((myCart.mySliceMiddle >> 11) & 0x1F); + myRAMMiddle->setSelectedMax(); + } + else // RAM active + { + myROMMiddle->setSelectedMax(); + myRAMMiddle->setSelected((myCart.mySliceMiddle >> 11) & 0x0F); + } + + // High bank + if(myCart.myIsRomHigh) // ROM active + { + myROMHigh->setSelected((myCart.mySliceHigh >> 11) & 0xFF); + myRAMHigh->setSelectedMax(); + } + else // RAM active + { + myROMHigh->setSelectedMax(); + myRAMHigh->setSelected((myCart.mySliceHigh >> 11) & 0x7F); + } + + CartDebugWidget::loadConfig(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Cartridge4A50Widget::handleCommand(CommandSender* sender, + int cmd, int data, int id) +{ + myCart.unlockBank(); + + switch(cmd) + { + case kROMLowerChanged: + if(myROMLower->getSelected() < 32) + { + myCart.bankROMLower(myROMLower->getSelected()); + myRAMLower->setSelectedMax(); + } + else + { + // default to first RAM bank + myRAMLower->setSelected(0); + myCart.bankRAMLower(0); + } + break; + + case kRAMLowerChanged: + if(myRAMLower->getSelected() < 16) + { + myROMLower->setSelectedMax(); + myCart.bankRAMLower(myRAMLower->getSelected()); + } + else + { + // default to first ROM bank + myROMLower->setSelected(0); + myCart.bankROMLower(0); + } + break; + + case kROMMiddleChanged: + if(myROMMiddle->getSelected() < 32) + { + myCart.bankROMMiddle(myROMMiddle->getSelected()); + myRAMMiddle->setSelectedMax(); + } + else + { + // default to first RAM bank + myRAMMiddle->setSelected(0); + myCart.bankRAMMiddle(0); + } + break; + + case kRAMMiddleChanged: + if(myRAMMiddle->getSelected() < 16) + { + myROMMiddle->setSelectedMax(); + myCart.bankRAMMiddle(myRAMMiddle->getSelected()); + } + else + { + // default to first ROM bank + myROMMiddle->setSelected(0); + myCart.bankROMMiddle(0); + } + break; + + case kROMHighChanged: + if(myROMHigh->getSelected() < 256) + { + myCart.bankROMHigh(myROMHigh->getSelected()); + myRAMHigh->setSelectedMax(); + } + else + { + // default to first RAM bank + myRAMHigh->setSelected(0); + myCart.bankRAMHigh(0); + } + break; + + case kRAMHighChanged: + if(myRAMHigh->getSelected() < 128) + { + myROMHigh->setSelectedMax(); + myCart.bankRAMHigh(myRAMHigh->getSelected()); + } + else + { + // default to first ROM bank + myROMHigh->setSelected(0); + myCart.bankROMHigh(0); + } + break; + } + + myCart.lockBank(); + invalidate(); +} diff --git a/src/debugger/gui/Cart4A50Widget.hxx b/src/debugger/gui/Cart4A50Widget.hxx new file mode 100644 index 000000000..75a513a6a --- /dev/null +++ b/src/debugger/gui/Cart4A50Widget.hxx @@ -0,0 +1,55 @@ +//============================================================================ +// +// 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-2013 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. +// +// $Id$ +//============================================================================ + +#ifndef CARTRIDGE4A50_WIDGET_HXX +#define CARTRIDGE4A50_WIDGET_HXX + +class Cartridge4A50; +class PopUpWidget; + +#include "CartDebugWidget.hxx" + +class Cartridge4A50Widget : public CartDebugWidget +{ + public: + Cartridge4A50Widget(GuiObject* boss, const GUI::Font& font, + int x, int y, int w, int h, + Cartridge4A50& cart); + virtual ~Cartridge4A50Widget() { } + + void loadConfig(); + void handleCommand(CommandSender* sender, int cmd, int data, int id); + + private: + Cartridge4A50& myCart; + PopUpWidget *myROMLower, *myRAMLower; + PopUpWidget *myROMMiddle, *myRAMMiddle; + PopUpWidget *myROMHigh, *myRAMHigh; + + enum { + kROMLowerChanged = 'rmLW', + kRAMLowerChanged = 'raLW', + kROMMiddleChanged = 'rmMD', + kRAMMiddleChanged = 'raMD', + kROMHighChanged = 'rmHI', + kRAMHighChanged = 'raHI' + }; +}; + +#endif diff --git a/src/debugger/gui/module.mk b/src/debugger/gui/module.mk index 2999c6697..4c10d1e66 100644 --- a/src/debugger/gui/module.mk +++ b/src/debugger/gui/module.mk @@ -23,6 +23,7 @@ MODULE_OBJS := \ src/debugger/gui/Cart2KWidget.o \ src/debugger/gui/Cart3EWidget.o \ src/debugger/gui/Cart3FWidget.o \ + src/debugger/gui/Cart4A50Widget.o \ src/debugger/gui/Cart4KWidget.o \ src/debugger/gui/CartCVWidget.o \ src/debugger/gui/CartE0Widget.o \ diff --git a/src/emucore/Cart4A50.cxx b/src/emucore/Cart4A50.cxx index 4fb0f4f6a..20e3df862 100644 --- a/src/emucore/Cart4A50.cxx +++ b/src/emucore/Cart4A50.cxx @@ -28,7 +28,8 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge4A50::Cartridge4A50(const uInt8* image, uInt32 size, const Settings& settings) - : Cartridge(settings) + : Cartridge(settings), + mySize(size) { // Copy the ROM image into my buffer // Supported file sizes are 32/64/128K, which are duplicated if necessary @@ -275,41 +276,17 @@ void Cartridge4A50::checkBankSwitch(uInt16 address, uInt8 value) ((myLastAddress >= 0x1000) || (myLastAddress < 0x200))) { if((address & 0x0f00) == 0x0c00) // Enable 256B of ROM at 0x1e00 - 0x1eff - { - myIsRomHigh = true; - mySliceHigh = (address & 0xff) << 8; - myBankChanged = true; - } + bankROMHigh(address & 0xff); else if((address & 0x0f00) == 0x0d00) // Enable 256B of RAM at 0x1e00 - 0x1eff - { - myIsRomHigh = false; - mySliceHigh = (address & 0x7f) << 8; - myBankChanged = true; - } + bankRAMHigh(address & 0x7f); else if((address & 0x0f40) == 0x0e00) // Enable 2K of ROM at 0x1000 - 0x17ff - { - myIsRomLow = true; - mySliceLow = (address & 0x1f) << 11; - myBankChanged = true; - } + bankROMLower(address & 0x1f); else if((address & 0x0f40) == 0x0e40) // Enable 2K of RAM at 0x1000 - 0x17ff - { - myIsRomLow = false; - mySliceLow = (address & 0xf) << 11; - myBankChanged = true; - } + bankRAMLower(address & 0xf); else if((address & 0x0f40) == 0x0f00) // Enable 1.5K of ROM at 0x1800 - 0x1dff - { - myIsRomMiddle = true; - mySliceMiddle = (address & 0x1f) << 11; - myBankChanged = true; - } + bankROMMiddle(address & 0x1f); else if((address & 0x0f50) == 0x0f40) // Enable 1.5K of RAM at 0x1800 - 0x1dff - { - myIsRomMiddle = false; - mySliceMiddle = (address & 0xf) << 11; - myBankChanged = true; - } + bankRAMMiddle(address & 0xf); // Stella helper functions else if((address & 0x0f00) == 0x0400) // Toggle bit A11 of lower block address @@ -339,17 +316,9 @@ void Cartridge4A50::checkBankSwitch(uInt16 address, uInt8 value) // 0xf5, 0xf7, 0xfd, 0xff for RAM // 0x74 - 0x7f (0x80 bytes lower) if((address & 0xf75) == 0x74) // Enable 256B of ROM at 0x1e00 - 0x1eff - { - myIsRomHigh = true; - mySliceHigh = value << 8; - myBankChanged = true; - } + bankROMHigh(value); else if((address & 0xf75) == 0x75) // Enable 256B of RAM at 0x1e00 - 0x1eff - { - myIsRomHigh = false; - mySliceHigh = (value & 0x7f) << 8; - myBankChanged = true; - } + bankRAMHigh(value & 0x7f); // Zero-page hotspots for lower and middle blocks // 0xf8, 0xf9, 0xfa, 0xfb @@ -357,29 +326,13 @@ void Cartridge4A50::checkBankSwitch(uInt16 address, uInt8 value) else if((address & 0xf7c) == 0x78) { if((value & 0xf0) == 0) // Enable 2K of ROM at 0x1000 - 0x17ff - { - myIsRomLow = true; - mySliceLow = (value & 0xf) << 11; - myBankChanged = true; - } + bankROMLower(value & 0xf); else if((value & 0xf0) == 0x40) // Enable 2K of RAM at 0x1000 - 0x17ff - { - myIsRomLow = false; - mySliceLow = (value & 0xf) << 11; - myBankChanged = true; - } + bankRAMLower(value & 0xf); else if((value & 0xf0) == 0x90) // Enable 1.5K of ROM at 0x1800 - 0x1dff - { - myIsRomMiddle = true; - mySliceMiddle = ((value & 0xf) | 0x10) << 11; - myBankChanged = true; - } + bankROMMiddle((value & 0xf) | 0x10); else if((value & 0xf0) == 0xc0) // Enable 1.5K of RAM at 0x1800 - 0x1dff - { - myIsRomMiddle = false; - mySliceMiddle = (value & 0xf) << 11; - myBankChanged = true; - } + bankRAMMiddle(value & 0xf); } } @@ -440,7 +393,7 @@ bool Cartridge4A50::patch(uInt16 address, uInt8 value) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - const uInt8* Cartridge4A50::getImage(int& size) const { - size = 131072; + size = mySize; return myImage; } diff --git a/src/emucore/Cart4A50.hxx b/src/emucore/Cart4A50.hxx index d3100403a..093b382aa 100644 --- a/src/emucore/Cart4A50.hxx +++ b/src/emucore/Cart4A50.hxx @@ -24,6 +24,9 @@ class System; #include "bspf.hxx" #include "Cart.hxx" +#ifdef DEBUGGER_SUPPORT + #include "Cart4A50Widget.hxx" +#endif /** Bankswitching method as defined/created by John Payson (aka Supercat), @@ -48,6 +51,8 @@ class System; */ class Cartridge4A50 : public Cartridge { + friend class Cartridge4A50Widget; + public: /** Create a new cartridge using the specified image @@ -134,6 +139,18 @@ class Cartridge4A50 : public Cartridge */ string name() const { return "Cartridge4A50"; } + #ifdef DEBUGGER_SUPPORT + /** + Get debugger widget responsible for accessing the inner workings + of the cart. + */ + CartDebugWidget* debugWidget(GuiObject* boss, + const GUI::Font& font, int x, int y, int w, int h) + { + return new Cartridge4A50Widget(boss, font, x, y, w, h, *this); + } + #endif + public: /** Get the byte at the specified address. @@ -166,6 +183,51 @@ class Cartridge4A50 : public Cartridge */ void checkBankSwitch(uInt16 address, uInt8 value); + /** + Methods to perform all the ways that banks can be switched + */ + inline void bankROMLower(uInt16 value) + { + myIsRomLow = true; + mySliceLow = value << 11; + myBankChanged = true; + } + + inline void bankRAMLower(uInt16 value) + { + myIsRomLow = false; + mySliceLow = value << 11; + myBankChanged = true; + } + + inline void bankROMMiddle(uInt16 value) + { + myIsRomMiddle = true; + mySliceMiddle = value << 11; + myBankChanged = true; + } + + inline void bankRAMMiddle(uInt16 value) + { + myIsRomMiddle = false; + mySliceMiddle = value << 11; + myBankChanged = true; + } + + inline void bankROMHigh(uInt16 value) + { + myIsRomHigh = true; + mySliceHigh = value << 8; + myBankChanged = true; + } + + inline void bankRAMHigh(uInt16 value) + { + myIsRomHigh = false; + mySliceHigh = value << 8; + myBankChanged = true; + } + private: // The 128K ROM image of the cartridge uInt8 myImage[131072]; @@ -173,6 +235,9 @@ class Cartridge4A50 : public Cartridge // The 32K of RAM on the cartridge uInt8 myRAM[32768]; + // (Actual) Size of the ROM image + uInt32 mySize; + // Indicates the slice mapped into each of the three segments uInt16 mySliceLow; /* index pointer for $1000-$17ff slice */ uInt16 mySliceMiddle; /* index pointer for $1800-$1dff slice */