From 053b79fc3eba5c06c986bf60aceee604fa2e3632 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 27 Nov 2017 22:49:53 +0100 Subject: [PATCH] E7 bankswitching classes refactored E78K bankswitching added --- src/debugger/gui/CartE7Widget.cxx | 154 ++-------------- src/debugger/gui/CartE7Widget.hxx | 41 +---- src/debugger/gui/module.mk | 2 + src/emucore/BSType.hxx | 8 +- src/emucore/CartDetector.cxx | 26 +++ src/emucore/CartDetector.hxx | 7 +- src/emucore/CartE7.cxx | 273 +---------------------------- src/emucore/CartE7.hxx | 130 +------------- src/emucore/module.mk | 2 + src/windows/Stella.vcxproj | 8 + src/windows/Stella.vcxproj.filters | 24 +++ 11 files changed, 105 insertions(+), 570 deletions(-) diff --git a/src/debugger/gui/CartE7Widget.cxx b/src/debugger/gui/CartE7Widget.cxx index e8b0b6252..fe28710dc 100644 --- a/src/debugger/gui/CartE7Widget.cxx +++ b/src/debugger/gui/CartE7Widget.cxx @@ -15,27 +15,16 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ -#include "CartE7.hxx" -#include "PopUpWidget.hxx" +#include "CartMNetwork.hxx" #include "CartE7Widget.hxx" -static const char* const 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)" -}; -static const char* const spot_upper[] = { - "0 - RAM ($FFE8)", "1 - RAM ($FFE9)", "2 - RAM ($FFEA)", "3 - RAM ($FFEB)" -}; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeE7Widget::CartridgeE7Widget( - GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, - int x, int y, int w, int h, CartridgeE7& 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, + CartridgeMNetwork& cart) + : CartridgeMNetworkWidget(boss, lfont, nfont, x, y, w, h, cart) { - uInt32 size = 8 * 2048; - ostringstream info; info << "E7 cartridge, 8 2K slices ROM + 2 1K RAM\n" << "Lower 2K accessible @ $F000 - $F7FF\n" @@ -55,136 +44,27 @@ CartridgeE7Widget::CartridgeE7Widget( start -= start % 0x1000; info << "Bank RORG" << " = $" << HEX4 << start << "\n"; #endif - int xpos = 10, - ypos = addBaseInformation(size, "M-Network", info.str(), 15) + - myLineHeight; - VariantList items0, items1; - for(int i = 0; i < 8; ++i) - VarList::push_back(items0, spot_lower[i]); - for(int i = 0; i < 4; ++i) - VarList::push_back(items1, spot_upper[i]); - - const int lwidth = _font.getStringWidth("Set slice for upper 256B "), - fwidth = _font.getStringWidth("3 - RAM ($FFEB)"); - myLower2K = - new PopUpWidget(boss, _font, xpos, ypos-2, fwidth, myLineHeight, items0, - "Set slice for lower 2K ", 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); - myUpper256B->setTarget(this); - addFocusWidget(myUpper256B); + initialize(boss, cart, info); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeE7Widget::saveOldState() +const char* CartridgeE7Widget::getSpotLower(int idx) { - myOldState.internalram.clear(); + static const char* const 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)" + }; - for(uInt32 i = 0; i < this->internalRamSize();i++) - { - myOldState.internalram.push_back(myCart.myRAM[i]); - } + return spot_lower[idx]; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeE7Widget::loadConfig() +const char* CartridgeE7Widget::getSpotUpper(int idx) { - myLower2K->setSelectedIndex(myCart.myCurrentSlice[0]); - myUpper256B->setSelectedIndex(myCart.myCurrentRAM); + static const char* const spot_upper[] = { + "0 - RAM ($FFE8)", "1 - RAM ($FFE9)", "2 - RAM ($FFEA)", "3 - RAM ($FFEB)" + }; - CartDebugWidget::loadConfig(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeE7Widget::handleCommand(CommandSender* sender, - int cmd, int data, int id) -{ - myCart.unlockBank(); - - switch(cmd) - { - case kLowerChanged: - myCart.bank(myLower2K->getSelected()); - break; - case kUpperChanged: - myCart.bankRAM(myUpper256B->getSelected()); - break; - } - - myCart.lockBank(); - invalidate(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeE7Widget::bankState() -{ - ostringstream& buf = buffer(); - - buf << "Slices: " << std::dec - << spot_lower[myCart.myCurrentSlice[0]] << " / " - << spot_upper[myCart.myCurrentRAM]; - - return buf.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 CartridgeE7Widget::internalRamSize() -{ - return 2048; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 CartridgeE7Widget::internalRamRPort(int start) -{ - return 0x0000 + start; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeE7Widget::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" ; - - return desc.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& CartridgeE7Widget::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& CartridgeE7Widget::internalRamCurrent(int start, int count) -{ - myRamCurrent.clear(); - for(int i = 0; i < count; i++) - myRamCurrent.push_back(myCart.myRAM[start + i]); - return myRamCurrent; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeE7Widget::internalRamSetValue(int addr, uInt8 value) -{ - myCart.myRAM[addr] = value; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeE7Widget::internalRamGetValue(int addr) -{ - return myCart.myRAM[addr]; + return spot_upper[idx]; } diff --git a/src/debugger/gui/CartE7Widget.hxx b/src/debugger/gui/CartE7Widget.hxx index 3206a0b57..c2d2b8f07 100644 --- a/src/debugger/gui/CartE7Widget.hxx +++ b/src/debugger/gui/CartE7Widget.hxx @@ -18,51 +18,22 @@ #ifndef CARTRIDGEE7_WIDGET_HXX #define CARTRIDGEE7_WIDGET_HXX -class CartridgeE7; -class PopUpWidget; +#include "CartMNetworkWidget.hxx" -#include "CartDebugWidget.hxx" - -class CartridgeE7Widget : public CartDebugWidget +class CartridgeE7Widget : public CartridgeMNetworkWidget { public: CartridgeE7Widget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, - CartridgeE7& cart); + CartridgeMNetwork& cart); virtual ~CartridgeE7Widget() = default; - private: - CartridgeE7& myCart; - PopUpWidget *myLower2K, *myUpper256B; - - struct CartState { - ByteArray internalram; - }; - CartState myOldState; - - enum { - kLowerChanged = 'lwCH', - kUpperChanged = 'upCH' - }; + protected: + const char* getSpotLower(int idx); + const char* getSpotUpper(int idx); 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 CartridgeE7Widget() = delete; CartridgeE7Widget(const CartridgeE7Widget&) = delete; diff --git a/src/debugger/gui/module.mk b/src/debugger/gui/module.mk index 95cd96088..081789bd6 100644 --- a/src/debugger/gui/module.mk +++ b/src/debugger/gui/module.mk @@ -29,7 +29,9 @@ MODULE_OBJS := \ src/debugger/gui/CartDPCPlusWidget.o \ src/debugger/gui/CartDPCWidget.o \ src/debugger/gui/CartE0Widget.o \ + src/debugger/gui/CartMNetworkWidget.o \ src/debugger/gui/CartE7Widget.o \ + src/debugger/gui/CartE78KWidget.o \ src/debugger/gui/CartEFSCWidget.o \ src/debugger/gui/CartEFWidget.o \ src/debugger/gui/CartF0Widget.o \ diff --git a/src/emucore/BSType.hxx b/src/emucore/BSType.hxx index 25c25d2a7..514485833 100644 --- a/src/emucore/BSType.hxx +++ b/src/emucore/BSType.hxx @@ -26,9 +26,10 @@ enum class BSType { _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, _EF, _EFSC, _F0, - _F4, _F4SC, _F6, _F6SC, _F8, _F8SC, _FA, - _FA2, _FE, _MDM, _SB, _UA, _WD, _X07, + _DPC, _DPCP, _E0, _E7, _E78K, _EF, _EFSC, + _F0, _F4, _F4SC, _F6, _F6SC, _F8, _F8SC, + _FA, _FA2, _FE, _MDM, _SB, _UA, _WD, + _X07, #ifdef CUSTOM_ARM _CUSTOM, #endif @@ -75,6 +76,7 @@ static BSDescription BSList[int(BSType::NumSchemes)] = { { "DPC+", "DPC+ (Enhanced DPC)" }, { "E0", "E0 (8K Parker Bros)" }, { "E7", "E7 (16K M-network)" }, + { "E78K", "E78K (8K M-network)" }, { "EF", "EF (64K H. Runner)" }, { "EFSC", "EFSC (64K H. Runner + ram)" }, { "F0", "F0 (Dynacom Megaboy)" }, diff --git a/src/emucore/CartDetector.cxx b/src/emucore/CartDetector.cxx index 0ff32824c..024a8fc1b 100644 --- a/src/emucore/CartDetector.cxx +++ b/src/emucore/CartDetector.cxx @@ -37,6 +37,7 @@ #include "CartDPCPlus.hxx" #include "CartE0.hxx" #include "CartE7.hxx" +#include "CartE78K.hxx" #include "CartEF.hxx" #include "CartEFSC.hxx" #include "CartBF.hxx" @@ -277,6 +278,8 @@ CartDetector::createFromImage(const BytePtr& image, uInt32 size, BSType type, return make_unique(image, size, osystem.settings()); case BSType::_E7: return make_unique(image, size, osystem.settings()); + case BSType::_E78K: + return make_unique(image, size, osystem.settings()); case BSType::_EF: return make_unique(image, size, osystem.settings()); case BSType::_EFSC: @@ -378,6 +381,8 @@ BSType CartDetector::autodetectType(const BytePtr& image, uInt32 size) type = BSType::_FE; else if(isProbably0840(image, size)) type = BSType::_0840; + else if(isProbablyE78K(image, size)) + type = BSType::_E78K; else type = BSType::_F8; } @@ -749,6 +754,27 @@ bool CartDetector::isProbablyE7(const BytePtr& image, uInt32 size) return false; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool CartDetector::isProbablyE78K(const BytePtr& image, uInt32 size) +{ + // E7 cart bankswitching is triggered by accessing addresses + // $FE0 to $FE6 using absolute non-indexed addressing + // To eliminate false positives (and speed up processing), we + // search for only certain known signatures + // Thanks to "stella@casperkitty.com" for this advice + // These signatures are attributed to the MESS project + uInt8 signature[3][3] = { + { 0xAD, 0xE4, 0xFF }, // LDA $FFE4 + { 0xAD, 0xE5, 0xFF }, // LDA $FFE5 + { 0xAD, 0xE6, 0x1F }, // LDA $1FE6 + }; + for(uInt32 i = 0; i < 3; ++i) + if(searchForBytes(image.get(), size, signature[i], 3, 1)) + return true; + + return false; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartDetector::isProbablyEF(const BytePtr& image, uInt32 size, BSType& type) { diff --git a/src/emucore/CartDetector.hxx b/src/emucore/CartDetector.hxx index d248cc3d6..871f70e62 100644 --- a/src/emucore/CartDetector.hxx +++ b/src/emucore/CartDetector.hxx @@ -204,6 +204,11 @@ class CartDetector */ static bool isProbablyE7(const BytePtr& image, uInt32 size); + /** + Returns true if the image is probably a E78K bankswitching cartridge + */ + static bool isProbablyE78K(const BytePtr& image, uInt32 size); + /** Returns true if the image is probably an EF/EFSC bankswitching cartridge */ @@ -212,7 +217,7 @@ class CartDetector /** Returns true if the image is probably an F6 bankswitching cartridge */ - static bool isProbablyF6(const BytePtr& image, uInt32 size); + //static bool isProbablyF6(const BytePtr& image, uInt32 size); /** Returns true if the image is probably an FA2 bankswitching cartridge diff --git a/src/emucore/CartE7.cxx b/src/emucore/CartE7.cxx index 57c680282..878d51ae5 100644 --- a/src/emucore/CartE7.cxx +++ b/src/emucore/CartE7.cxx @@ -21,65 +21,14 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeE7::CartridgeE7(const BytePtr& image, uInt32 size, const Settings& settings) - : Cartridge(settings), - myCurrentRAM(0) + : CartridgeMNetwork(image, size, settings) { - // Copy the ROM image into my buffer - memcpy(myImage, image.get(), std::min(16384u, size)); - createCodeAccessBase(16384 + 2048); - - // Remember startup bank - myStartBank = 0; + initialize(image, size); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeE7::reset() +void CartridgeE7::checkSwitchBank(uInt16 address) { - initializeRAM(myRAM, 2048); - - // Install some default banks for the RAM and first segment - bankRAM(0); - bank(myStartBank); - - myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeE7::install(System& system) -{ - mySystem = &system; - - System::PageAccess access(this, System::PA_READ); - - // Set the page accessing methods for the hot spots - for(uInt16 addr = (0x1FE0 & ~System::PAGE_MASK); addr < 0x2000; - addr += System::PAGE_SIZE) - { - access.codeAccessBase = &myCodeAccessBase[8128]; - mySystem->setPageAccess(addr, access); - } - - // Setup the second segment to always point to the last ROM slice - for(uInt16 addr = 0x1A00; addr < (0x1FE0U & ~System::PAGE_MASK); - addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[7 * 2048 + (addr & 0x07FF)]; - access.codeAccessBase = &myCodeAccessBase[7 * 2048 + (addr & 0x07FF)]; - mySystem->setPageAccess(addr, access); - } - myCurrentSlice[1] = 7; - - // Install some default banks for the RAM and first segment - bankRAM(0); - bank(myStartBank); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeE7::peek(uInt16 address) -{ - uInt16 peekAddress = address; - address &= 0x0FFF; - // Switch banks if necessary if((address >= 0x0FE0) && (address <= 0x0FE7)) { @@ -89,141 +38,6 @@ uInt8 CartridgeE7::peek(uInt16 address) { bankRAM(address & 0x0003); } - - if((myCurrentSlice[0] == 7) && (address < 0x0400)) - { - // Reading from the 1K write port @ $1000 triggers an unwanted write - uInt8 value = mySystem->getDataBusState(0xFF); - - if(bankLocked()) - return value; - else - { - triggerReadFromWritePort(peekAddress); - return myRAM[address & 0x03FF] = value; - } - } - else if((address >= 0x0800) && (address <= 0x08FF)) - { - // Reading from the 256B write port @ $1800 triggers an unwanted write - uInt8 value = mySystem->getDataBusState(0xFF); - - if(bankLocked()) - return value; - else - { - triggerReadFromWritePort(peekAddress); - return myRAM[1024 + (myCurrentRAM << 8) + (address & 0x00FF)] = value; - } - } - else - return myImage[(myCurrentSlice[address >> 11] << 11) + (address & 0x07FF)]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeE7::poke(uInt16 address, uInt8) -{ - address &= 0x0FFF; - - // Switch banks if necessary - if((address >= 0x0FE0) && (address <= 0x0FE7)) - { - bank(address & 0x0007); - } - else if((address >= 0x0FE8) && (address <= 0x0FEB)) - { - bankRAM(address & 0x0003); - } - - // NOTE: This does not handle writing to RAM, however, this - // method should never be called for RAM because of the - // way page accessing has been setup - return false; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeE7::bankRAM(uInt16 bank) -{ - if(bankLocked()) return; - - // Remember what bank we're in - myCurrentRAM = bank; - uInt16 offset = bank << 8; - - // Setup the page access methods for the current bank - System::PageAccess access(this, System::PA_WRITE); - - // Set the page accessing method for the 256 bytes of RAM writing pages - for(uInt16 addr = 0x1800; addr < 0x1900; addr += System::PAGE_SIZE) - { - access.directPokeBase = &myRAM[1024 + offset + (addr & 0x00FF)]; - access.codeAccessBase = &myCodeAccessBase[8192 + 1024 + offset + (addr & 0x00FF)]; - mySystem->setPageAccess(addr, access); - } - - // Set the page accessing method for the 256 bytes of RAM reading pages - access.directPokeBase = nullptr; - access.type = System::PA_READ; - for(uInt16 addr = 0x1900; addr < 0x1A00; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myRAM[1024 + offset + (addr & 0x00FF)]; - access.codeAccessBase = &myCodeAccessBase[8192 + 1024 + offset + (addr & 0x00FF)]; - mySystem->setPageAccess(addr, access); - } - myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeE7::bank(uInt16 slice) -{ - if(bankLocked()) return false; - - // Remember what bank we're in - myCurrentSlice[0] = slice; - uInt16 offset = slice << 11; - - // Setup the page access methods for the current bank - if(slice != 7) - { - System::PageAccess access(this, System::PA_READ); - - // Map ROM image into first segment - for(uInt16 addr = 0x1000; addr < 0x1800; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[offset + (addr & 0x07FF)]; - access.codeAccessBase = &myCodeAccessBase[offset + (addr & 0x07FF)]; - mySystem->setPageAccess(addr, access); - } - } - else - { - System::PageAccess access(this, System::PA_WRITE); - - // Set the page accessing method for the 1K slice of RAM writing pages - for(uInt16 addr = 0x1000; addr < 0x1400; addr += System::PAGE_SIZE) - { - access.directPokeBase = &myRAM[addr & 0x03FF]; - access.codeAccessBase = &myCodeAccessBase[8192 + (addr & 0x03FF)]; - mySystem->setPageAccess(addr, access); - } - - // Set the page accessing method for the 1K slice of RAM reading pages - access.directPokeBase = nullptr; - access.type = System::PA_READ; - for(uInt16 addr = 0x1400; addr < 0x1800; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myRAM[addr & 0x03FF]; - access.codeAccessBase = &myCodeAccessBase[8192 + (addr & 0x03FF)]; - mySystem->setPageAccess(addr, access); - } - } - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeE7::getBank() const -{ - return myCurrentSlice[0]; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -231,84 +45,3 @@ uInt16 CartridgeE7::bankCount() const { return 8; } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeE7::patch(uInt16 address, uInt8 value) -{ - address = address & 0x0FFF; - - if(address < 0x0800) - { - if(myCurrentSlice[0] == 7) - { - // Normally, a write to the read port won't do anything - // However, the patch command is special in that ignores such - // cart restrictions - myRAM[address & 0x03FF] = value; - } - else - myImage[(myCurrentSlice[0] << 11) + (address & 0x07FF)] = value; - } - else if(address < 0x0900) - { - // Normally, a write to the read port won't do anything - // However, the patch command is special in that ignores such - // cart restrictions - myRAM[1024 + (myCurrentRAM << 8) + (address & 0x00FF)] = value; - } - else - myImage[(myCurrentSlice[address >> 11] << 11) + (address & 0x07FF)] = value; - - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeE7::getImage(uInt32& size) const -{ - size = 16384; - return myImage; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeE7::save(Serializer& out) const -{ - try - { - out.putString(name()); - out.putShortArray(myCurrentSlice, 2); - out.putShort(myCurrentRAM); - out.putByteArray(myRAM, 2048); - } - catch(...) - { - cerr << "ERROR: CartridgeE7::save" << endl; - return false; - } - - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeE7::load(Serializer& in) -{ - try - { - if(in.getString() != name()) - return false; - - in.getShortArray(myCurrentSlice, 2); - myCurrentRAM = in.getShort(); - in.getByteArray(myRAM, 2048); - } - catch(...) - { - cerr << "ERROR: CartridgeE7::load" << endl; - return false; - } - - // Set up the previously used banks for the RAM and segment - bankRAM(myCurrentRAM); - bank(myCurrentSlice[0]); - - return true; -} diff --git a/src/emucore/CartE7.hxx b/src/emucore/CartE7.hxx index 86ec30a42..be14b5e3a 100644 --- a/src/emucore/CartE7.hxx +++ b/src/emucore/CartE7.hxx @@ -25,43 +25,15 @@ class System; #ifdef DEBUGGER_SUPPORT #include "CartE7Widget.hxx" #endif +#include "CartMNetwork.hxx" /** - This is the cartridge class for M-Network bankswitched games. - In this bankswitching scheme the 2600's 4K cartridge address - space is broken into two 2K segments. + This is the cartridge class for 16K M-Network bankswitched games. - Kevin Horton describes E7 as follows: - - Only M-Network used this scheme. This has to be the - most complex method used in any cart! :-) It allows - for the capability of 2K of RAM; although it doesn't - have to be used (in fact, only one cart used it). - There are now 8 2K banks, instead of 4. The last 2K - in the cart always points to the last 2K of the ROM - image, while the first 2K is selectable. You access - 1FE0 to 1FE6 to select which 2K bank. Note that you - cannot select the last 2K of the ROM image into the - lower 2K of the cart! Accessing 1FE7 selects 1K of - RAM at 1000-17FF instead of ROM! The 2K of RAM is - broken up into two 1K sections. One 1K section is - mapped in at 1000-17FF if 1FE7 has been accessed. - 1000-13FF is the write port, while 1400-17FF is the - read port. The second 1K of RAM appears at 1800-19FF. - 1800-18FF is the write port while 1900-19FF is the - read port. You select which 256 byte block appears - here by accessing 1FE8 to 1FEB. - - This cart reports having 8 banks; 1 for each of the possible 7 - slices in the lower 2K area, and the last for RAM in the lower - 2K area. - - @author Bradford W. Mott + @author Bradford W. Mott, Thomas Jentzsch */ -class CartridgeE7 : public Cartridge +class CartridgeE7 : public CartridgeMNetwork { - friend class CartridgeE7Widget; - public: /** Create a new cartridge using the specified image @@ -74,69 +46,11 @@ class CartridgeE7 : public Cartridge virtual ~CartridgeE7() = 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. - - @param system The system the device should install itself in - */ - 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. - */ - uInt16 getBank() 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(uInt32& 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). @@ -156,43 +70,11 @@ class CartridgeE7 : public Cartridge } #endif - public: - /** - Get the byte at the specified address. - - @return The byte at the specified address - */ - 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: /** - Install pages for the specified 256 byte bank of RAM - - @param bank The bank that should be installed in the system + Check hotspots and switch bank if triggered. */ - void bankRAM(uInt16 bank); - - private: - // The 16K ROM image of the cartridge - uInt8 myImage[16384]; - - // The 2048 bytes of RAM - uInt8 myRAM[2048]; - - // Indicates which slice is in the segment - uInt16 myCurrentSlice[2]; - - // Indicates which 256 byte bank of RAM is being used - uInt16 myCurrentRAM; + void checkSwitchBank(uInt16 address) override; private: // Following constructors and assignment operators not supported diff --git a/src/emucore/module.mk b/src/emucore/module.mk index 2bcbeaa7c..aa6394214 100644 --- a/src/emucore/module.mk +++ b/src/emucore/module.mk @@ -24,7 +24,9 @@ MODULE_OBJS := \ src/emucore/CartDPC.o \ src/emucore/CartDPCPlus.o \ src/emucore/CartE0.o \ + src/emucore/CartMNetwork.o \ src/emucore/CartE7.o \ + src/emucore/CartE78K.o \ src/emucore/CartEF.o \ src/emucore/CartEFSC.o \ src/emucore/CartBF.o \ diff --git a/src/windows/Stella.vcxproj b/src/windows/Stella.vcxproj index 8f4243ec2..5e3c4b4fc 100644 --- a/src/windows/Stella.vcxproj +++ b/src/windows/Stella.vcxproj @@ -268,6 +268,7 @@ + @@ -282,6 +283,7 @@ + @@ -314,6 +316,8 @@ + + @@ -549,6 +553,7 @@ + @@ -563,6 +568,7 @@ + @@ -602,6 +608,8 @@ + + diff --git a/src/windows/Stella.vcxproj.filters b/src/windows/Stella.vcxproj.filters index 6bbf70a81..b56548ada 100644 --- a/src/windows/Stella.vcxproj.filters +++ b/src/windows/Stella.vcxproj.filters @@ -873,6 +873,18 @@ Source Files\gui + + Source Files\emucore + + + Source Files\emucore + + + Source Files\debugger + + + Source Files\debugger + @@ -1784,6 +1796,18 @@ Header Files\emucore + + Header Files\emucore + + + Header Files\emucore + + + Header Files\debugger + + + Header Files\debugger +