diff --git a/Changes.txt b/Changes.txt
index e1f8a30b9..865583bc9 100644
--- a/Changes.txt
+++ b/Changes.txt
@@ -39,6 +39,8 @@
* Enhanced support for CDFJ+ bankswitching type.
+ * Added 0FA0 bankswitching for Mania ROMs
+
* Added ARM chip auto detection.
* Fixed Stella crash due to invalid ZIP files.
diff --git a/docs/index.html b/docs/index.html
index 41920433e..469f6c02f 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -21,7 +21,7 @@
A multi-platform Atari 2600 VCS emulator
- Release 6.6
+ Release 6.7
User's Guide
@@ -354,7 +354,6 @@
the following:
- i386 or x86_64 class machine, with 32 or 64-bit distribution
- - OpenGL capable video card
- Other architectures (MIPS, PPC, PPC64, etc.) have been confirmed to work,
but aren't as well tested as i386/x86_64
- GNU g++ v/7 or Clang v/5 (with C++17 support) and the make utility are required for compiling the Stella source code
@@ -368,7 +367,6 @@
- macOS 10.7 or above
- 64-bit Intel processor
- - OpenGL capable video card
- Xcode 8.0 is required to compile the Stella source code
@@ -379,7 +377,6 @@
with the following:
- - Direct3D or OpenGL capable video card
- Visual C++ 2017/2019 Community is required to compile the Stella source code
@@ -2759,7 +2756,7 @@
- -video <direct3d|opengl|opengles2|opengles|software> |
+ -video <direct3d|metal|opengl|opengles2|opengles|software> |
Use the given rendering backend (where applicable); default is the best available
mode detected. |
@@ -5064,7 +5061,8 @@ Ms Pac-Man (Stella extended codes):
are not fully supported in the debugger.
Type | Description | File Extension (to force type) |
- 0840 | 8K ECONObanking | .084, .0840 |
+ 0840 | 8K ECONObanking | .084, .0840 |
+ 0FA0 | 8K Mania | .0FA, .0FA0 |
2IN1 ¹ | 4-64K Multicart (2 games) | .2N1 |
4IN1 ¹ | 8-64K Multicart (4 games) | .4N1 |
8IN1 ¹ | 16-64K Multicart (8 games) | .8N1 |
diff --git a/src/debugger/gui/CartUAWidget.cxx b/src/debugger/gui/CartUAWidget.cxx
index 2d775f7a4..1fe186b5d 100644
--- a/src/debugger/gui/CartUAWidget.cxx
+++ b/src/debugger/gui/CartUAWidget.cxx
@@ -48,8 +48,7 @@ string CartridgeUAWidget::hotspotStr(int bank, int, bool prefix)
const uInt16 hotspot = myCart.hotspot() + (bank ^ (mySwappedHotspots ? 1 : 0)) * myHotspotDelta;
info << "(" << (prefix ? "hotspot " : "")
- << "$" << Common::Base::HEX1 << hotspot << ", $" << (hotspot | 0x80)
- << ", $" << (hotspot | 0xf80) << ")";
+ << "$" << Common::Base::HEX1 << hotspot << ", $" << (hotspot | 0x80) << ")";
return info.str();
}
diff --git a/src/debugger/gui/module.mk b/src/debugger/gui/module.mk
index e1c1ae7c9..41d4e55a7 100644
--- a/src/debugger/gui/module.mk
+++ b/src/debugger/gui/module.mk
@@ -7,6 +7,7 @@ MODULE_OBJS := \
src/debugger/gui/AudioWidget.o \
src/debugger/gui/BoosterWidget.o \
src/debugger/gui/Cart0840Widget.o \
+ src/debugger/gui/Cart0FA0Widget.o \
src/debugger/gui/Cart2KWidget.o \
src/debugger/gui/Cart3EPlusWidget.o \
src/debugger/gui/Cart3EWidget.o \
diff --git a/src/emucore/Bankswitch.cxx b/src/emucore/Bankswitch.cxx
index 4457857e1..5e5f2fd51 100644
--- a/src/emucore/Bankswitch.cxx
+++ b/src/emucore/Bankswitch.cxx
@@ -96,6 +96,7 @@ const std::array(Bankswitch::Type::Num
Bankswitch::BSList = {{
{ "AUTO" , "Auto-detect" },
{ "0840" , "0840 (8K ECONObank)" },
+ { "0FA0" , "0FA0 (8K Mania)" },
{ "2IN1" , "2IN1 Multicart (4-64K)" },
{ "4IN1" , "4IN1 Multicart (8-64K)" },
{ "8IN1" , "8IN1 Multicart (16-64K)" },
@@ -167,6 +168,8 @@ Bankswitch::ExtensionMap Bankswitch::ourExtensions = {
// All bankswitch types (those that UnoCart and HarmonyCart support have the same name)
{ "084" , Bankswitch::Type::_0840 },
{ "0840" , Bankswitch::Type::_0840 },
+ { "0FA" , Bankswitch::Type::_0FA0 },
+ { "0FA0" , Bankswitch::Type::_0FA0 },
{ "2N1" , Bankswitch::Type::_2IN1 },
{ "4N1" , Bankswitch::Type::_4IN1 },
{ "8N1" , Bankswitch::Type::_8IN1 },
@@ -241,6 +244,7 @@ Bankswitch::ExtensionMap Bankswitch::ourExtensions = {
Bankswitch::NameToTypeMap Bankswitch::ourNameToTypes = {
{ "AUTO" , Bankswitch::Type::_AUTO },
{ "0840" , Bankswitch::Type::_0840 },
+ { "0FA0" , Bankswitch::Type::_0FA0 },
{ "2IN1" , Bankswitch::Type::_2IN1 },
{ "4IN1" , Bankswitch::Type::_4IN1 },
{ "8IN1" , Bankswitch::Type::_8IN1 },
diff --git a/src/emucore/Bankswitch.hxx b/src/emucore/Bankswitch.hxx
index 4c459fd10..5ec54982b 100644
--- a/src/emucore/Bankswitch.hxx
+++ b/src/emucore/Bankswitch.hxx
@@ -38,14 +38,13 @@ class Bankswitch
public:
// Currently supported bankswitch schemes
enum class Type {
- _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, _EF, _EFSC, _F0, _F4,
- _F4SC, _F6, _F6SC, _F8, _F8SC, _FA, _FA2,
- _FC, _FE, _MDM, _MVC, _SB, _TVBOY, _UA,
- _UASW, _WD, _WDSW, _X07,
+ _AUTO, _0840, _0FA0, _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,
+ _EF, _EFSC, _F0, _F4, _F4SC, _F6, _F6SC, _F8,
+ _F8SC, _FA, _FA2, _FC, _FE, _MDM, _MVC, _SB,
+ _TVBOY, _UA, _UASW, _WD, _WDSW, _X07,
#ifdef CUSTOM_ARM
_CUSTOM,
#endif
diff --git a/src/emucore/Cart0FA0.cxx b/src/emucore/Cart0FA0.cxx
new file mode 100644
index 000000000..e0badf027
--- /dev/null
+++ b/src/emucore/Cart0FA0.cxx
@@ -0,0 +1,104 @@
+//============================================================================
+//
+// 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-2022 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 "System.hxx"
+#include "Cart0FA0.hxx"
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Cartridge0FA0::Cartridge0FA0(const ByteBuffer& image, size_t size,
+ const string& md5, const Settings& settings)
+ : CartridgeEnhanced(image, size, md5, settings, 8_KB)
+{
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void Cartridge0FA0::install(System& 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
+ myHotSpotPageAccess = mySystem->getPageAccess(0x06a0);
+
+ // Set the page accessing methods for the hot spots
+ const System::PageAccess access(this, System::PageAccessType::READ);
+ // Map all potential addresses
+ // - A11 and A8 are not connected to RIOT
+ // - A10, A9 and A7 are the fixed part of the hotspot address
+ // - A6 and A5 determine bank
+ for(uInt16 a11 = 0; a11 <= 1; ++a11)
+ for(uInt16 a8 = 0; a8 <= 1; ++a8)
+ {
+ const uInt16 addr = (a11 << 11) + (a8 << 8);
+
+ mySystem->setPageAccess(0x06a0 | addr, access);
+ mySystem->setPageAccess(0x06c0 | addr, access);
+ }
+ // Install pages for the startup bank
+ bank(startBank());
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+bool Cartridge0FA0::checkSwitchBank(uInt16 address, uInt8)
+{
+ // Switch banks if necessary
+ switch(address & 0x16e0)
+ {
+ case 0x06a0:
+ // Set the current bank to the lower 4k bank
+ bank(0);
+ return true;
+
+ case 0x06c0:
+ // Set the current bank to the upper 4k bank
+ bank(1);
+ return true;
+
+ default:
+ break;
+ }
+ return false;
+}
+
+//// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+uInt8 Cartridge0FA0::peek(uInt16 address)
+{
+ address &= myBankMask;
+
+ checkSwitchBank(address);
+
+ // Because of the way accessing is set up, we will only get here
+ // when doing a TIA read
+ return myHotSpotPageAccess.device->peek(address);
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+bool Cartridge0FA0::poke(uInt16 address, uInt8 value)
+{
+ address &= myBankMask;
+
+ checkSwitchBank(address);
+
+ // Because of the way accessing is set up, we will may get here by
+ // doing a write to TIA or cart; we ignore the cart write
+ if (!(address & 0x1000))
+ {
+ myHotSpotPageAccess.device->poke(address, value);
+ }
+
+ return false;
+}
diff --git a/src/emucore/Cart0FA0.hxx b/src/emucore/Cart0FA0.hxx
new file mode 100644
index 000000000..788d2ef63
--- /dev/null
+++ b/src/emucore/Cart0FA0.hxx
@@ -0,0 +1,127 @@
+//============================================================================
+//
+// 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-2022 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 CARTRIDGEBR_HXX
+#define CARTRIDGEBR_HXX
+
+#include "bspf.hxx"
+#include "CartEnhanced.hxx"
+#include "System.hxx"
+#ifdef DEBUGGER_SUPPORT
+#include "Cart0FA0Widget.hxx"
+#endif
+
+/**
+ Cartridge class used for some brazilian 8K bankswitched games. There
+ are two 4K banks, which are switched by accessing
+ (address & $16A0) = $06a0 (bank 0) and = $06c0 (bank 1).
+ Actual addresses used by these carts are e.g. $0FA0, $0FC0 and $EFC0.
+ The code accepts further potential hotspot addresses.
+
+ @author Thomas Jentzsch
+*/
+class Cartridge0FA0 : public CartridgeEnhanced
+{
+ friend class Cartridge0FA0Widget;
+
+ public:
+ /**
+ Create a new cartridge using the specified image
+
+ @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)
+ */
+ Cartridge0FA0(const ByteBuffer& image, size_t size, const string& md5,
+ const Settings& settings);
+ ~Cartridge0FA0() override = default;
+
+ public:
+ /**
+ 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 a descriptor for the device name (used in error checking).
+
+ @return The name of the object
+ */
+ string name() const override {
+ return "Cartridge0FA0";
+ }
+
+ #ifdef DEBUGGER_SUPPORT
+ /**
+ Get debugger widget responsible for accessing the inner workings
+ of the cart.
+ */
+ CartDebugWidget* debugWidget(GuiObject* boss, const GUI::Font& lfont,
+ const GUI::Font& nfont, int x, int y, int w, int h) override
+ {
+ return new Cartridge0FA0Widget(boss, lfont, nfont, x, y, w, h, *this);
+ }
+ #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:
+ /**
+ Checks if startup bank randomization is enabled. For this scheme,
+ randomization is not supported (see above).
+ */
+ bool randomStartBank() const override { return false; }
+
+ bool checkSwitchBank(uInt16 address, uInt8 value = 0) override;
+
+ uInt16 hotspot() const override { return 0x06a0; }
+
+ uInt16 getStartBank() const override { return 1; }
+
+ private:
+ // Previous Device's page access
+ System::PageAccess myHotSpotPageAccess;
+
+ private:
+ // Following constructors and assignment operators not supported
+ Cartridge0FA0() = delete;
+ Cartridge0FA0(const Cartridge0FA0&) = delete;
+ Cartridge0FA0(Cartridge0FA0&&) = delete;
+ Cartridge0FA0& operator=(const Cartridge0FA0&) = delete;
+ Cartridge0FA0& operator=(Cartridge0FA0&&) = delete;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/emucore/Cart0FA0Widget.cxx b/src/emucore/Cart0FA0Widget.cxx
new file mode 100644
index 000000000..96a166103
--- /dev/null
+++ b/src/emucore/Cart0FA0Widget.cxx
@@ -0,0 +1,53 @@
+//============================================================================
+//
+// 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-2022 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 "Cart0FA0.hxx"
+#include "Cart0FA0Widget.hxx"
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Cartridge0FA0Widget::Cartridge0FA0Widget(
+ GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
+ int x, int y, int w, int h, Cartridge0FA0& cart)
+ : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
+{
+ myHotspotDelta = 0x20;
+ initialize();
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+string Cartridge0FA0Widget::description()
+{
+ ostringstream info;
+
+ info << "8K BR cartridge, two 4K banks\n"
+ << CartridgeEnhancedWidget::description();
+
+ return info.str();
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+string Cartridge0FA0Widget::hotspotStr(int bank, int, bool prefix)
+{
+ ostringstream info;
+ const uInt16 hotspot = myCart.hotspot() + bank * myHotspotDelta;
+
+ info << "(" << (prefix ? "hotspot " : "")
+ << "$" << Common::Base::HEX1 << hotspot
+ << ", $" << (hotspot | 0xf80) << ")";
+
+ return info.str();
+}
diff --git a/src/emucore/Cart0FA0Widget.hxx b/src/emucore/Cart0FA0Widget.hxx
new file mode 100644
index 000000000..fec1c8097
--- /dev/null
+++ b/src/emucore/Cart0FA0Widget.hxx
@@ -0,0 +1,50 @@
+//============================================================================
+//
+// 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-2022 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 CARTRIDGEBR_WIDGET_HXX
+#define CARTRIDGEBR_WIDGET_HXX
+
+class Cartridge0FA0;
+
+#include "CartEnhancedWidget.hxx"
+
+class Cartridge0FA0Widget : public CartridgeEnhancedWidget
+{
+public:
+ Cartridge0FA0Widget(GuiObject* boss, const GUI::Font& lfont,
+ const GUI::Font& nfont,
+ int x, int y, int w, int h,
+ Cartridge0FA0& cart);
+ ~Cartridge0FA0Widget() override = default;
+
+private:
+ string manufacturer() override { return "Mania"; }
+
+ string description() override;
+
+ string hotspotStr(int bank, int seg, bool prefix = false) override;
+
+private:
+ // Following constructors and assignment operators not supported
+ Cartridge0FA0Widget() = delete;
+ Cartridge0FA0Widget(const Cartridge0FA0Widget&) = delete;
+ Cartridge0FA0Widget(Cartridge0FA0Widget&&) = delete;
+ Cartridge0FA0Widget& operator=(const Cartridge0FA0Widget&) = delete;
+ Cartridge0FA0Widget& operator=(Cartridge0FA0Widget&&) = delete;
+};
+
+#endif
diff --git a/src/emucore/CartCreator.cxx b/src/emucore/CartCreator.cxx
index 6184d1e65..d15039a00 100644
--- a/src/emucore/CartCreator.cxx
+++ b/src/emucore/CartCreator.cxx
@@ -18,6 +18,7 @@
#include "bspf.hxx"
#include "Cart.hxx"
#include "Cart0840.hxx"
+#include "Cart0FA0.hxx"
#include "Cart2K.hxx"
#include "Cart3E.hxx"
#include "Cart3EX.hxx"
@@ -245,7 +246,7 @@ CartCreator::createFromMultiCart(const ByteBuffer& image, size_t& size,
type = Bankswitch::Type::_2K;
else if(size == 4_KB)
type = Bankswitch::Type::_4K;
- else if(size == 8_KB || size == 16_KB || size == 32_KB || size == 64_KB)
+ else if(size == 8_KB || size == 16_KB || size == 32_KB || size == 64_KB || size == 128_KB)
type = CartDetector::autodetectType(slice, size);
else /* default */
type = Bankswitch::Type::_4K;
@@ -263,6 +264,8 @@ CartCreator::createFromImage(const ByteBuffer& image, size_t size, Bankswitch::T
{
case Bankswitch::Type::_0840:
return make_unique(image, size, md5, settings);
+ case Bankswitch::Type::_0FA0:
+ return make_unique(image, size, md5, settings);
case Bankswitch::Type::_2K:
return make_unique(image, size, md5, settings);
case Bankswitch::Type::_3E:
diff --git a/src/emucore/CartDetector.cxx b/src/emucore/CartDetector.cxx
index 73116ba5d..241ae601d 100644
--- a/src/emucore/CartDetector.cxx
+++ b/src/emucore/CartDetector.cxx
@@ -75,6 +75,8 @@ Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t si
type = Bankswitch::Type::_3F;
else if(isProbablyUA(image, size))
type = Bankswitch::Type::_UA;
+ else if(isProbably0FA0(image, size))
+ type = Bankswitch::Type::_0FA0;
else if(isProbablyFE(image, size) && !f8)
type = Bankswitch::Type::_FE;
else if(isProbably0840(image, size))
@@ -344,6 +346,25 @@ bool CartDetector::isProbably0840(const ByteBuffer& image, size_t size)
return false;
}
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+bool CartDetector::isProbably0FA0(const ByteBuffer& image, size_t size)
+{
+ // Other Brazilian (Atari Mania) ROM's bankswitching switches to bank 1 by
+ // accessing address 0xFC0 using 'BIT $FC0', 'BIT $FC0' or 'STA $FC0'
+ // Also a game (Motocross) using 'BIT $EFC0' has been found
+ static constexpr uInt8 signature[4][3] = {
+ { 0x2C, 0xC0, 0x0F }, // BIT $FC0 (H.E.R.O., Kung-Fu Master)
+ { 0x8D, 0xC0, 0x0F }, // STA $FC0 (Pole Position, Subterranea)
+ { 0xAD, 0xC0, 0x0F }, // LDA $FC0 (Front Line, Zaxxon)
+ { 0x2C, 0xC0, 0xEF } // BIT $EFC0 (Motocross)
+ };
+ for(uInt32 i = 0; i < 4; ++i)
+ if(searchForBytes(image, size, signature[i], 3))
+ return true;
+
+ return false;
+}
+
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartDetector::isProbably3E(const ByteBuffer& image, size_t size)
{
@@ -755,25 +776,18 @@ bool CartDetector::isProbablyTVBoy(const ByteBuffer& image, size_t size)
bool CartDetector::isProbablyUA(const ByteBuffer& image, size_t size)
{
// UA cart bankswitching switches to bank 1 by accessing address 0x240
- // using 'STA $240' or 'LDA $240'
- // Similar Brazilian (Digivison) cart bankswitching switches to bank 1 by accessing address 0x2C0
+ // using 'STA $240' or 'LDA $240'.
+ // Brazilian (Digivison) cart bankswitching switches to bank 1 by accessing address 0x2C0
// using 'BIT $2C0', 'STA $2C0' or 'LDA $2C0'
- // Other Brazilian (Atari Mania) ROM's bankswitching switches to bank 1 by accessing address 0xFC0
- // using 'BIT $FA0', 'BIT $FC0' or 'STA $FC0'
- // Also a game (Motocross) using 'BIT $EFC0' has been found
- static constexpr uInt8 signature[10][3] = {
+ static constexpr uInt8 signature[6][3] = {
{ 0x8D, 0x40, 0x02 }, // STA $240 (Funky Fish, Pleiades)
{ 0xAD, 0x40, 0x02 }, // LDA $240 (???)
{ 0xBD, 0x1F, 0x02 }, // LDA $21F,X (Gingerbread Man)
{ 0x2C, 0xC0, 0x02 }, // BIT $2C0 (Time Pilot)
{ 0x8D, 0xC0, 0x02 }, // STA $2C0 (Fathom, Vanguard)
{ 0xAD, 0xC0, 0x02 }, // LDA $2C0 (Mickey)
- { 0x2C, 0xC0, 0x0F }, // BIT $FC0 (H.E.R.O., Kung-Fu Master)
- { 0x8D, 0xC0, 0x0F }, // STA $FC0 (Pole Position, Subterranea)
- { 0xAD, 0xC0, 0x0F }, // LDA $FC0 (Front Line, Zaxxon)
- { 0x2C, 0xC0, 0xEF } // BIT $EFC0 (Motocross)
};
- for(uInt32 i = 0; i < 10; ++i)
+ for(uInt32 i = 0; i < 6; ++i)
if(searchForBytes(image, size, signature[i], 3))
return true;
diff --git a/src/emucore/CartDetector.hxx b/src/emucore/CartDetector.hxx
index cd9740c0d..4e2a623fe 100644
--- a/src/emucore/CartDetector.hxx
+++ b/src/emucore/CartDetector.hxx
@@ -91,6 +91,11 @@ class CartDetector
*/
static bool isProbably0840(const ByteBuffer& image, size_t size);
+ /**
+ Returns true if the image is probably a BRazilian bankswitching cartridge
+ */
+ static bool isProbably0FA0(const ByteBuffer& image, size_t size);
+
/**
Returns true if the image is probably a 3E bankswitching cartridge
*/
diff --git a/src/emucore/CartUA.cxx b/src/emucore/CartUA.cxx
index 1d6d5cd58..ba2aca628 100644
--- a/src/emucore/CartUA.cxx
+++ b/src/emucore/CartUA.cxx
@@ -43,7 +43,7 @@ void CartridgeUA::install(System& system)
// - A11, A10 and A8 are not connected to RIOT
// - A9 is the fixed part of the hotspot address
// - A7 is used by Brazilian carts
- // - A5 and A4 determine bank
+ // - A6 and A5 determine bank
for(uInt16 a11 = 0; a11 <= 1; ++a11)
for(uInt16 a10 = 0; a10 <= 1; ++a10)
for(uInt16 a8 = 0; a8 <= 1; ++a8)
diff --git a/src/emucore/CartUA.hxx b/src/emucore/CartUA.hxx
index 854706584..fb0434bac 100644
--- a/src/emucore/CartUA.hxx
+++ b/src/emucore/CartUA.hxx
@@ -29,8 +29,7 @@
Cartridge class used for UA Limited's 8K bankswitched games. There
are two 4K banks, which are switched by accessing $0220 (bank 0) and
$0240 (bank 1). Similar addresses are used by Brazilian carts, e.g.
- $02A0, $02C0 and $0FA0, $0FC0. The code accepts further potential
- hotspot addresses.
+ $02A0 and $02C0. The code accepts further potential hotspot addresses.
@author Bradford W. Mott, Thomas Jentzsch
*/
diff --git a/src/emucore/module.mk b/src/emucore/module.mk
index c8f0d96bd..40626cdf7 100644
--- a/src/emucore/module.mk
+++ b/src/emucore/module.mk
@@ -10,6 +10,7 @@ MODULE_OBJS := \
src/emucore/CartDetector.o \
src/emucore/CartEnhanced.o \
src/emucore/Cart0840.o \
+ src/emucore/Cart0FA0.o \
src/emucore/Cart2K.o \
src/emucore/Cart3E.o \
src/emucore/Cart3EPlus.o \
diff --git a/src/libretro/Makefile.common b/src/libretro/Makefile.common
index 0a4769c35..e162bb1dc 100644
--- a/src/libretro/Makefile.common
+++ b/src/libretro/Makefile.common
@@ -49,6 +49,7 @@ SOURCES_CXX := \
$(CORE_DIR)/emucore/CartDetector.cxx \
$(CORE_DIR)/emucore/CartEnhanced.cxx \
$(CORE_DIR)/emucore/Cart0840.cxx \
+ $(CORE_DIR)/emucore/Cart0FA0.cxx \
$(CORE_DIR)/emucore/Cart2K.cxx \
$(CORE_DIR)/emucore/Cart3E.cxx \
$(CORE_DIR)/emucore/Cart3EPlus.cxx \
diff --git a/src/libretro/Stella.vcxproj b/src/libretro/Stella.vcxproj
index b1ebab8b6..43472ef65 100644
--- a/src/libretro/Stella.vcxproj
+++ b/src/libretro/Stella.vcxproj
@@ -225,6 +225,7 @@
+
@@ -385,6 +386,7 @@
+
diff --git a/src/windows/Stella.vcxproj b/src/windows/Stella.vcxproj
index dc548cc86..904c00660 100755
--- a/src/windows/Stella.vcxproj
+++ b/src/windows/Stella.vcxproj
@@ -857,6 +857,8 @@
+
+
@@ -2048,6 +2050,7 @@
+
@@ -2064,6 +2067,7 @@
+
diff --git a/src/windows/Stella.vcxproj.filters b/src/windows/Stella.vcxproj.filters
index 9c57b20a8..5d659ec3a 100644
--- a/src/windows/Stella.vcxproj.filters
+++ b/src/windows/Stella.vcxproj.filters
@@ -1131,6 +1131,12 @@
Source Files\gui
+
+ Source Files\emucore
+
+
+ Source Files\debugger
+
@@ -2342,6 +2348,12 @@
Header Files\emucore
+
+ Header Files\emucore
+
+
+ Header Files\debugger
+
diff --git a/test/roms/bankswitching/0FA0/Motocross (JVP).bin b/test/roms/bankswitching/0FA0/Motocross (JVP).bin
new file mode 100644
index 000000000..fa7fbcf20
Binary files /dev/null and b/test/roms/bankswitching/0FA0/Motocross (JVP).bin differ
diff --git a/test/roms/bankswitching/0FA0/Pole Position (Mania).bin b/test/roms/bankswitching/0FA0/Pole Position (Mania).bin
new file mode 100644
index 000000000..ac8172f9e
Binary files /dev/null and b/test/roms/bankswitching/0FA0/Pole Position (Mania).bin differ
diff --git a/test/roms/bankswitching/0FA0/Subterranea (Mania).bin b/test/roms/bankswitching/0FA0/Subterranea (Mania).bin
new file mode 100644
index 000000000..50a4fc602
Binary files /dev/null and b/test/roms/bankswitching/0FA0/Subterranea (Mania).bin differ
diff --git a/test/roms/bankswitching/XIN1/16 in 1 Digitel Brazil (Mania).bin b/test/roms/bankswitching/XIN1/16 in 1 Digitel Brazil (Mania).bin
new file mode 100644
index 000000000..f55242b3c
Binary files /dev/null and b/test/roms/bankswitching/XIN1/16 in 1 Digitel Brazil (Mania).bin differ
diff --git a/test/roms/bankswitching/XIN1/2 in 1 - Kung Fu Master (Irem, Activision) - H.E.R.O. (Mania RJ).BIN b/test/roms/bankswitching/XIN1/2 in 1 - Kung Fu Master (Irem, Activision) - H.E.R.O. (Mania RJ).BIN
new file mode 100644
index 000000000..3c1a3e040
Binary files /dev/null and b/test/roms/bankswitching/XIN1/2 in 1 - Kung Fu Master (Irem, Activision) - H.E.R.O. (Mania RJ).BIN differ
diff --git a/test/roms/bankswitching/XIN1/2 in 1 - Phoenix - H.E.R.O. (Rentacom).bin b/test/roms/bankswitching/XIN1/2 in 1 - Phoenix - H.E.R.O. (Rentacom).bin
new file mode 100644
index 000000000..76a6393db
Binary files /dev/null and b/test/roms/bankswitching/XIN1/2 in 1 - Phoenix - H.E.R.O. (Rentacom).bin differ
diff --git a/test/roms/bankswitching/XIN1/2 in 1 - Time Pilot - Vanguard (Rentacom).bin b/test/roms/bankswitching/XIN1/2 in 1 - Time Pilot - Vanguard (Rentacom).bin
new file mode 100644
index 000000000..8d37d8ec7
Binary files /dev/null and b/test/roms/bankswitching/XIN1/2 in 1 - Time Pilot - Vanguard (Rentacom).bin differ