diff --git a/stella/src/emucore/Cart.cxx b/stella/src/emucore/Cart.cxx index 66e340f17..30da607c3 100644 --- a/stella/src/emucore/Cart.cxx +++ b/stella/src/emucore/Cart.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: Cart.cxx,v 1.40 2008-02-27 14:14:38 estolberg Exp $ +// $Id: Cart.cxx,v 1.41 2008-02-27 20:13:55 stephena Exp $ //============================================================================ #include @@ -215,6 +215,8 @@ string Cartridge::autodetectType(const uInt8* image, uInt32 size) type = "UA"; else if(isProbablyFE(image, size)) type = "FE"; + else if(isProbably0840(image, size)) + type = "0840"; else type = "F8"; } @@ -445,6 +447,13 @@ bool Cartridge::isProbablySB(const uInt8* image, uInt32 size) return false; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool Cartridge::isProbably0840(const uInt8* image, uInt32 size) +{ + // TODO - add autodetection for this type + return false; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool Cartridge::isProbablyCV(const uInt8* image, uInt32 size) { diff --git a/stella/src/emucore/Cart.hxx b/stella/src/emucore/Cart.hxx index 696625db0..62d1fe993 100644 --- a/stella/src/emucore/Cart.hxx +++ b/stella/src/emucore/Cart.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: Cart.hxx,v 1.22 2008-02-06 13:45:20 stephena Exp $ +// $Id: Cart.hxx,v 1.23 2008-02-27 20:13:55 stephena Exp $ //============================================================================ #ifndef CARTRIDGE_HXX @@ -34,7 +34,7 @@ class Settings; game and handles any bankswitching performed by the cartridge. @author Bradford W. Mott - @version $Id: Cart.hxx,v 1.22 2008-02-06 13:45:20 stephena Exp $ + @version $Id: Cart.hxx,v 1.23 2008-02-27 20:13:55 stephena Exp $ */ class Cartridge : public Device { @@ -212,6 +212,11 @@ class Cartridge : public Device */ static bool isProbablySB(const uInt8* image, uInt32 size); + /** + Returns true if the image is probably a 0840 bankswitching cartridge + */ + static bool isProbably0840(const uInt8* image, uInt32 size); + /** Returns true if the image is probably a CV bankswitching cartridge */ diff --git a/stella/src/emucore/Cart0840.cxx b/stella/src/emucore/Cart0840.cxx index d05099ac9..8fc827dfc 100644 --- a/stella/src/emucore/Cart0840.cxx +++ b/stella/src/emucore/Cart0840.cxx @@ -24,6 +24,11 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge0840::Cartridge0840(const uInt8* image) { + // Copy the ROM image into my buffer + for(uInt32 addr = 0; addr < 8192; ++addr) + { + myImage[addr] = image[addr]; + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -34,62 +39,211 @@ Cartridge0840::~Cartridge0840() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Cartridge0840::reset() { + // Upon reset we switch to bank 0 + bank(0); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Cartridge0840::install(System& system) { + mySystem = &system; + uInt16 shift = mySystem->pageShift(); + uInt16 mask = mySystem->pageMask(); + + // Make sure the system we're being installed in has a page size that'll work + assert((0x1000 & mask) == 0); + + // 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 + myHotSpotPageAccess[0] = mySystem->getPageAccess(0x0800 >> shift); + myHotSpotPageAccess[1] = mySystem->getPageAccess(0x0900 >> shift); + myHotSpotPageAccess[2] = mySystem->getPageAccess(0x0A00 >> shift); + myHotSpotPageAccess[3] = mySystem->getPageAccess(0x0B00 >> shift); + myHotSpotPageAccess[4] = mySystem->getPageAccess(0x0C00 >> shift); + myHotSpotPageAccess[5] = mySystem->getPageAccess(0x0D00 >> shift); + myHotSpotPageAccess[6] = mySystem->getPageAccess(0x0E00 >> shift); + myHotSpotPageAccess[7] = mySystem->getPageAccess(0x0F00 >> shift); + + // Set the page accessing methods for the hot spots + System::PageAccess access; + for(uInt32 i = 0x0800; i < 0x0FFF; i += (1 << shift)) + { + access.directPeekBase = 0; + access.directPokeBase = 0; + access.device = this; + mySystem->setPageAccess(i >> shift, access); + } + + // Install pages for bank 0 + bank(0); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt8 Cartridge0840::peek(uInt16 address) { + 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; + } + + if(!(address & 0x1000)) + { + // Because of the way we've set up accessing above, we can only + // get here when the addresses are from 0x800 - 0xFFF + int hotspot = ((address & 0x0F00) >> 8) - 8; + return myHotSpotPageAccess[hotspot].device->peek(address); + } + return 0; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Cartridge0840::poke(uInt16 address, uInt8 value) { + 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; + } + + if(!(address & 0x1000)) + { + // Because of the way we've set up accessing above, we can only + // get here when the addresses are from 0x800 - 0xFFF + int hotspot = ((address & 0x0F00) >> 8) - 8; + myHotSpotPageAccess[hotspot].device->poke(address, value); + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Cartridge0840::bank(uInt16 bank) { + if(bankLocked) return; + + // Remember what bank we're in + myCurrentBank = bank; + uInt16 offset = myCurrentBank * 4096; + uInt16 shift = mySystem->pageShift(); + + // Setup the page access methods for the current bank + System::PageAccess access; + access.device = this; + access.directPokeBase = 0; + + // Map ROM image into the system + for(uInt32 address = 0x1000; address < 0x2000; address += (1 << shift)) + { + access.directPeekBase = &myImage[offset + (address & 0x0FFF)]; + mySystem->setPageAccess(address >> shift, access); + } + } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - int Cartridge0840::bank() { - return 0; + return myCurrentBank; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - int Cartridge0840::bankCount() { - return 1; + return 2; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool Cartridge0840::patch(uInt16 address, uInt8 value) { - return false; + address &= 0x0fff; + myImage[myCurrentBank * 4096] = value; + bank(myCurrentBank); // TODO: see if this is really necessary + + return true; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt8* Cartridge0840::getImage(int& size) { - size = 0; - return 0; + size = 8192; + return &myImage[0]; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool Cartridge0840::save(Serializer& out) const { - return false; + string cart = name(); + + try + { + out.putString(cart); + out.putInt(myCurrentBank); + } + catch(char *msg) + { + cerr << msg << endl; + return false; + } + catch(...) + { + cerr << "Unknown error in save state for " << cart << endl; + return false; + } + + return true; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool Cartridge0840::load(Deserializer& in) { - return false; + string cart = name(); + + try + { + if(in.getString() != cart) + return false; + + myCurrentBank = (uInt16)in.getInt(); + } + catch(char *msg) + { + cerr << msg << endl; + return false; + } + catch(...) + { + cerr << "Unknown error in load state for " << cart << endl; + return false; + } + + // Remember what bank we were in + bank(myCurrentBank); + + return true; } diff --git a/stella/src/emucore/Cart0840.hxx b/stella/src/emucore/Cart0840.hxx index 7340cb862..997dd4639 100644 --- a/stella/src/emucore/Cart0840.hxx +++ b/stella/src/emucore/Cart0840.hxx @@ -19,12 +19,9 @@ #ifndef CARTRIDGE0840_HXX #define CARTRIDGE0840_HXX -class System; -class Serializer; -class Deserializer; - #include "bspf.hxx" #include "Cart.hxx" +#include "System.hxx" /** Cartridge class used for 0840 "Econobanking" 8K bankswitched games. There @@ -135,6 +132,16 @@ class Cartridge0840 : public Cartridge @param value The value to be stored at the address */ virtual void poke(uInt16 address, uInt8 value); + + private: + // The 8K ROM image of the cartridge + uInt8 myImage[8192]; + + // Indicates which bank is currently active + uInt16 myCurrentBank; + + // Previous Device's page access + System::PageAccess myHotSpotPageAccess[8]; }; #endif diff --git a/stella/src/emucore/CartSB.hxx b/stella/src/emucore/CartSB.hxx index dd7c108e7..d60963615 100644 --- a/stella/src/emucore/CartSB.hxx +++ b/stella/src/emucore/CartSB.hxx @@ -19,10 +19,9 @@ #ifndef CARTRIDGESB_HXX #define CARTRIDGESB_HXX -class System; - #include "bspf.hxx" #include "Cart.hxx" +#include "System.hxx" /** Cartridge class used for SB "SUPERbanking" 128k-256k bankswitched games. diff --git a/stella/src/gui/GameInfoDialog.cxx b/stella/src/gui/GameInfoDialog.cxx index f05547016..a895d4d85 100644 --- a/stella/src/gui/GameInfoDialog.cxx +++ b/stella/src/gui/GameInfoDialog.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: GameInfoDialog.cxx,v 1.48 2008-02-27 14:16:52 estolberg Exp $ +// $Id: GameInfoDialog.cxx,v 1.49 2008-02-27 20:13:55 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -119,7 +119,7 @@ GameInfoDialog::GameInfoDialog( pwidth = font.getStringWidth("SB (128-256k SUPERbanking)"); myType = new PopUpWidget(myTab, font, xpos+lwidth, ypos, pwidth, lineHeight, "", 0, 0); - for(i = 0; i < 24; ++i) + for(i = 0; i < kNumCartTypes; ++i) myType->appendEntry(ourCartridgeList[i][0], i+1); wid.push_back(myType); @@ -387,12 +387,12 @@ void GameInfoDialog::loadView() mySound->setSelectedTag(0); s = myGameProperties.get(Cartridge_Type); - for(i = 0; i < 24; ++i) + for(i = 0; i < kNumCartTypes; ++i) { if(s == ourCartridgeList[i][1]) break; } - i = (i == 24) ? 0: i + 1; + i = (i == kNumCartTypes) ? 0: i + 1; myType->setSelectedTag(i); // Console properties @@ -539,7 +539,7 @@ void GameInfoDialog::saveConfig() myGameProperties.set(Cartridge_Sound, s); tag = myType->getSelectedTag(); - for(i = 0; i < 24; ++i) + for(i = 0; i < kNumCartTypes; ++i) { if(i == tag-1) { @@ -672,7 +672,7 @@ void GameInfoDialog::handleCommand(CommandSender* sender, int cmd, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const char* GameInfoDialog::ourControllerList[5][2] = { +const char* GameInfoDialog::ourControllerList[kNumControllerTypes][2] = { { "Booster-Grip", "BOOSTER-GRIP" }, { "Driving", "DRIVING" }, { "Keyboard", "KEYBOARD" }, @@ -681,7 +681,7 @@ const char* GameInfoDialog::ourControllerList[5][2] = { }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const char* GameInfoDialog::ourCartridgeList[24][2] = { +const char* GameInfoDialog::ourCartridgeList[kNumCartTypes][2] = { { "Auto-detect", "AUTO-DETECT" }, { "2K (2K Atari)", "2K" }, { "3E (32K Tigervision)", "3E" }, @@ -705,5 +705,6 @@ const char* GameInfoDialog::ourCartridgeList[24][2] = { { "MC (C. Wilkson Megacart)", "MC" }, { "SB (128-256k SUPERbanking)", "SB" }, { "UA (8K UA Ltd.)", "UA" }, - { "X07 (64K AtariAge)", "X07" } + { "X07 (64K AtariAge)", "X07" }, + { "0840 (8K ECONObanking)", "0840" } }; diff --git a/stella/src/gui/GameInfoDialog.hxx b/stella/src/gui/GameInfoDialog.hxx index dbdb0b50e..e00f3f7da 100644 --- a/stella/src/gui/GameInfoDialog.hxx +++ b/stella/src/gui/GameInfoDialog.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: GameInfoDialog.hxx,v 1.28 2008-02-27 14:16:52 estolberg Exp $ +// $Id: GameInfoDialog.hxx,v 1.29 2008-02-27 20:13:55 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -94,7 +94,9 @@ class GameInfoDialog : public Dialog, public CommandSender enum { kPhosphorChanged = 'PPch', - kPPBlendChanged = 'PBch' + kPPBlendChanged = 'PBch', + kNumCartTypes = 25, + kNumControllerTypes = 5 }; /** Game properties for currently loaded ROM */ @@ -107,10 +109,10 @@ class GameInfoDialog : public Dialog, public CommandSender bool myDefaultsSelected; /** Holds static strings for Cartridge type */ - static const char* ourCartridgeList[24][2]; + static const char* ourCartridgeList[kNumCartTypes][2]; /** Holds static strings for Controller type */ - static const char* ourControllerList[5][2]; + static const char* ourControllerList[kNumControllerTypes][2]; }; #endif