diff --git a/src/emucore/Bankswitch.cxx b/src/emucore/Bankswitch.cxx index b5c0da75f..dbdec5e2b 100644 --- a/src/emucore/Bankswitch.cxx +++ b/src/emucore/Bankswitch.cxx @@ -132,6 +132,7 @@ Bankswitch::BSList = {{ { "WDSW" , "WDSW (Pink Panther, bad)" }, { "WF8" , "WF8 (Coleco, white carts)" }, { "X07" , "X07 (64K AtariAge)" }, + { "ELF" , "ELF (ARM bus stuffing)" }, #if defined(CUSTOM_ARM) { "CUSTOM" , "CUSTOM (ARM)" } #endif @@ -198,6 +199,7 @@ Bankswitch::Sizes = {{ { 8_KB, 8_KB+5 }, // _WDSW { 8_KB, 8_KB }, // _WF8 { 64_KB, 64_KB }, // _X07 + { 4_KB, Bankswitch::any_KB }, // ELF #if defined(CUSTOM_ARM) { Bankswitch::any_KB, Bankswitch::any_KB } #endif @@ -293,7 +295,8 @@ Bankswitch::ExtensionMap Bankswitch::ourExtensions = { { "WD" , Bankswitch::Type::_WD }, { "WDSW" , Bankswitch::Type::_WDSW }, { "WF8" , Bankswitch::Type::_WF8 }, - { "X07" , Bankswitch::Type::_X07 } + { "X07" , Bankswitch::Type::_X07 }, + { "ELF" , Bankswitch::Type::_ELF } }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -355,5 +358,6 @@ Bankswitch::NameToTypeMap Bankswitch::ourNameToTypes = { { "WD" , Bankswitch::Type::_WD }, { "WDSW" , Bankswitch::Type::_WDSW }, { "WF8" , Bankswitch::Type::_WF8 }, - { "X07" , Bankswitch::Type::_X07 } + { "X07" , Bankswitch::Type::_X07 }, + { "ELF" , Bankswitch::Type::_ELF } }; diff --git a/src/emucore/Bankswitch.hxx b/src/emucore/Bankswitch.hxx index 45427410e..6cd43face 100644 --- a/src/emucore/Bankswitch.hxx +++ b/src/emucore/Bankswitch.hxx @@ -44,8 +44,8 @@ class Bankswitch _CM, _CTY, _CV, _DF, _DFSC, _DPC, _DPCP, _E0, _E7, _EF, _EFSC, _F0, _F4, _F4SC, _F6, _F6SC, _F8, _F8SC, _FA, _FA2, _FC, _FE, _GL, _JANE, - _MDM, _MVC, _SB, _TVBOY, _UA, _UASW, _WD, _WDSW, - _WF8, _X07, + _MDM, _MVC, _SB, _TVBOY, _UA, _UASW, _WD, _WDSW, + _WF8, _X07, _ELF, #ifdef CUSTOM_ARM _CUSTOM, #endif diff --git a/src/emucore/CartCreator.cxx b/src/emucore/CartCreator.cxx index df6180c04..508776f3a 100644 --- a/src/emucore/CartCreator.cxx +++ b/src/emucore/CartCreator.cxx @@ -65,6 +65,7 @@ #include "CartWD.hxx" #include "CartWF8.hxx" #include "CartX07.hxx" +#include "CartELF.hxx" #include "MD5.hxx" #include "Settings.hxx" @@ -284,6 +285,7 @@ CartCreator::createFromImage(const ByteBuffer& image, size_t size, case _WDSW: return make_unique(image, size, md5, settings); case _WF8: return make_unique(image, size, md5, settings); case _X07: return make_unique(image, size, md5, settings); + case _ELF: return make_unique(image, size, md5, settings); default: return nullptr; // The remaining types have already been handled } } diff --git a/src/emucore/CartDetector.cxx b/src/emucore/CartDetector.cxx index dfff762c2..8a5b8d17d 100755 --- a/src/emucore/CartDetector.cxx +++ b/src/emucore/CartDetector.cxx @@ -27,7 +27,10 @@ Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t si // Guess type based on size Bankswitch::Type type = Bankswitch::Type::_AUTO; - if((size % 8448) == 0 || size == 6_KB) + if (size >= 4_KB && isProbablyELF(image, size)) { + type =Bankswitch::Type::_ELF; + } + else if ((size % 8448) == 0 || size == 6_KB) { if(size == 6_KB && isProbablyGL(image, size)) type = Bankswitch::Type::_GL; @@ -855,6 +858,27 @@ bool CartDetector::isProbablyX07(const ByteBuffer& image, size_t size) return false; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool CartDetector::isProbablyELF(const ByteBuffer& image, size_t size) { + // Min ELF header size + if (size < 52) return false; + + // Must start with ELF magic + static constexpr uInt8 signature[] = { 0x7f, 'E', 'L', 'F' }; + if (!searchForBytes(image, sizeof(signature), signature, sizeof(signature), 1)) return false; + + // We require little endian + if (image[0x05] != 1) return false; + + // Type must be ET_REL (relocatable ELF) + if (image[0x10] != 0x01) return false; + + // Arch must be ARM + if (image[0x12] != 0x28) return false; + + return true; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartDetector::isProbablyPlusROM(const ByteBuffer& image, size_t size) { diff --git a/src/emucore/CartDetector.hxx b/src/emucore/CartDetector.hxx index 47cc1cc69..995e7c046 100644 --- a/src/emucore/CartDetector.hxx +++ b/src/emucore/CartDetector.hxx @@ -251,6 +251,11 @@ class CartDetector */ static bool isProbablyX07(const ByteBuffer& image, size_t size); + /** + Returns true if the image is probably an ELF cartridge + */ + static bool isProbablyELF(const ByteBuffer& image, size_t size); + private: // Following constructors and assignment operators not supported CartDetector() = delete; diff --git a/src/emucore/CartELF.cxx b/src/emucore/CartELF.cxx new file mode 100644 index 000000000..77415eb37 --- /dev/null +++ b/src/emucore/CartELF.cxx @@ -0,0 +1,68 @@ +//============================================================================ +// +// 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-2024 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 "CartELF.hxx" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +CartridgeELF::CartridgeELF(const ByteBuffer& image, size_t size, string_view md5, + const Settings& settings) + : Cartridge(settings, md5), myImageSize(size) +{ + myImage = make_unique(size); + std::memcpy(myImage.get(), image.get(), size); +} + + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +CartridgeELF::~CartridgeELF() {} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void CartridgeELF::reset() {} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void CartridgeELF::install(System& system) {} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool CartridgeELF::save(Serializer& out) const +{ + return false; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool CartridgeELF::load(Serializer& in) +{ + return false; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +uInt8 CartridgeELF::peek(uInt16 address) +{ + return 0; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool CartridgeELF::poke(uInt16 address, uInt8 value) +{ + return false; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +const ByteBuffer& CartridgeELF::getImage(size_t& size) const +{ + size = myImageSize; + return myImage; +} diff --git a/src/emucore/CartELF.hxx b/src/emucore/CartELF.hxx new file mode 100644 index 000000000..dd2a16dc6 --- /dev/null +++ b/src/emucore/CartELF.hxx @@ -0,0 +1,59 @@ +//============================================================================ +// +// 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-2024 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 CARTRIDGE_ELF +#define CARTRIDGE_ELF + +#include "bspf.hxx" +#include "Cart.hxx" + +class CartridgeELF: public Cartridge { + public: + CartridgeELF(const ByteBuffer& image, size_t size, string_view md5, + const Settings& settings); + virtual ~CartridgeELF(); + + // Methods from Device + public: + void reset() override; + + void install(System& system) override; + + bool save(Serializer& out) const override; + + bool load(Serializer& in) override; + + uInt8 peek(uInt16 address) override; + + bool poke(uInt16 address, uInt8 value) override; + + // Methods from Cartridge + public: + bool bankChanged() override { return false; } + + bool patch(uInt16 address, uInt8 value) override { return false; } + + const ByteBuffer& getImage(size_t& size) const override; + + string name() const override { return "CartridgeELF"; }; + + private: + ByteBuffer myImage; + size_t myImageSize{0}; +}; + +#endif // CARTRIDGE_ELF diff --git a/src/emucore/module.mk b/src/emucore/module.mk index 534ebdf58..902eb1f15 100644 --- a/src/emucore/module.mk +++ b/src/emucore/module.mk @@ -55,8 +55,9 @@ MODULE_OBJS := \ src/emucore/CartTVBoy.o \ src/emucore/CartUA.o \ src/emucore/CartWD.o \ - src/emucore/CartWF8.o \ + src/emucore/CartWF8.o \ src/emucore/CartX07.o \ + src/emucore/CartELF.o \ src/emucore/CompuMate.o \ src/emucore/Console.o \ src/emucore/Control.o \