diff --git a/docs/index.html b/docs/index.html
index 66532ffc8..920e43e1b 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -3621,9 +3621,9 @@
Note: Mode X (3) is for testing only. It reduces Flash memory access
clock cycles to always 1.
- -<plr.|dev.>eepromaccess <1|0> |
- When enabled, each read or write access to the AtariVox/SaveKey EEPROM is
- signalled by a message. |
+ -<plr.|dev.>extaccess <1|0> |
+ When enabled, each external access (AtariVox/SaveKey EEPROM, PlusROM, Supercharger...)
+ is signalled by a message. |
-dev.tia.type <standard|koolaidman|cosmicark| pesco|quickstep|indy500|heman|custom> |
Set emulated TIA type. |
@@ -4341,9 +4341,15 @@
-plr.stats -dev.stats |
Detected settings info |
- Display detected settings when a ROM is loaded. |
+ Display detected settings when a ROM is loaded |
-plr.detectedinfo -dev.detectedinfo |
+
+ Display external access message |
+ Display a message for any external access
+ (AtariVox/SaveKey EEPROM, PlusROM, Supercharger...) |
+ -plr.extaccess -dev.extaccess |
+
Console |
Select the console type, this affects Color/B&W/Pause key
@@ -4391,11 +4397,6 @@
| Thumb ARM emulation throws an exception and enters the debugger on fatal errors |
-dev.thumb.trapfatal |
-
- Display AtariVox... |
- Display a message when the AtariVox/SaveKey EEPROM is read or written |
- -plr.eepromaccess -dev.eepromaccess |
-
diff --git a/src/emucore/Cart.hxx b/src/emucore/Cart.hxx
index 2922e54f2..05d874a76 100644
--- a/src/emucore/Cart.hxx
+++ b/src/emucore/Cart.hxx
@@ -144,7 +144,7 @@ class Cartridge : public Device
/**
Set the callback for displaying messages
*/
- void setMessageCallback(const messageCallback& callback)
+ virtual void setMessageCallback(const messageCallback& callback)
{
myMsgCallback = callback;
}
diff --git a/src/emucore/CartARM.cxx b/src/emucore/CartARM.cxx
index 4459bdc29..791ba858a 100644
--- a/src/emucore/CartARM.cxx
+++ b/src/emucore/CartARM.cxx
@@ -25,6 +25,13 @@ CartridgeARM::CartridgeARM(const string& md5, const Settings& settings)
{
}
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void CartridgeARM::reset()
+{
+ if(myPlusROM->isValid())
+ myPlusROM->reset();
+}
+
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeARM::setInitialState()
{
@@ -96,6 +103,9 @@ bool CartridgeARM::save(Serializer& out) const
out.putInt(myPrevStats.instructions);
out.putInt(myCycles);
out.putInt(myStats.instructions);
+
+ if(myPlusROM->isValid() && !myPlusROM->save(out))
+ return false;
}
catch(...)
{
@@ -116,6 +126,9 @@ bool CartridgeARM::load(Serializer& in)
myPrevStats.instructions = in.getInt();
myCycles = in.getInt();
myStats.instructions = in.getInt();
+
+ if(myPlusROM->isValid() && !myPlusROM->load(in))
+ return false;
}
catch(...)
{
diff --git a/src/emucore/CartARM.hxx b/src/emucore/CartARM.hxx
index d43b4e17d..2ebdf43dd 100644
--- a/src/emucore/CartARM.hxx
+++ b/src/emucore/CartARM.hxx
@@ -19,6 +19,7 @@
#define CARTRIDGE_ARM_HXX
#include "Thumbulator.hxx"
+#include "PlusROM.hxx"
#include "Cart.hxx"
/**
@@ -34,6 +35,11 @@ class CartridgeARM : public Cartridge
CartridgeARM(const string& md5, const Settings& settings);
~CartridgeARM() override = default;
+ /**
+ Reset device to its power-on state
+ */
+ void reset() override;
+
protected:
/**
Notification method invoked by the system when the console type
@@ -85,10 +91,23 @@ class CartridgeARM : public Cartridge
void setMamMode(Thumbulator::MamModeType mamMode) { myThumbEmulator->setMamMode(mamMode); }
Thumbulator::MamModeType mamMode() const { return myThumbEmulator->mamMode(); }
+ /**
+ Set the callback for displaying messages
+ */
+ void setMessageCallback(const messageCallback& callback) override
+ {
+ Cartridge::setMessageCallback(callback);
+ if(myPlusROM->isValid())
+ myPlusROM->setMessageCallback(myMsgCallback);
+ }
+
protected:
// Pointer to the Thumb ARM emulator object
unique_ptr myThumbEmulator;
+ // Handle PlusROM functionality, if available
+ unique_ptr myPlusROM;
+
// ARM code increases 6507 cycles
bool myIncCycles{false};
diff --git a/src/emucore/CartCDF.cxx b/src/emucore/CartCDF.cxx
index 1aba0ab12..fa46611be 100644
--- a/src/emucore/CartCDF.cxx
+++ b/src/emucore/CartCDF.cxx
@@ -113,6 +113,11 @@ CartridgeCDF::CartridgeCDF(const ByteBuffer& image, size_t size,
this);
setInitialState();
+
+ myPlusROM = make_unique(mySettings);
+
+ // Determine whether we have a PlusROM cart
+ myPlusROM->initialize(myImage, mySize);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -130,6 +135,8 @@ void CartridgeCDF::reset()
// Upon reset we switch to the startup bank
bank(startBank());
+
+ CartridgeARM::reset();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -213,6 +220,14 @@ inline void CartridgeCDF::callFunction(uInt8 value)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 CartridgeCDF::peek(uInt16 address)
{
+ // Is this a PlusROM?
+ if(myPlusROM->isValid())
+ {
+ uInt8 value = 0;
+ if(myPlusROM->peekHotspot(address, value))
+ return value;
+ }
+
address &= 0x0FFF;
uInt8 peekvalue = myProgramImage[myBankOffset + address];
@@ -356,6 +371,10 @@ bool CartridgeCDF::poke(uInt16 address, uInt8 value)
{
uInt32 pointer;
+ // Is this a PlusROM?
+ if(myPlusROM->isValid() && myPlusROM->pokeHotspot(address, value))
+ return true;
+
address &= 0x0FFF;
switch(address)
{
diff --git a/src/emucore/CartCDF.hxx b/src/emucore/CartCDF.hxx
index 621873e9f..fea1c0165 100644
--- a/src/emucore/CartCDF.hxx
+++ b/src/emucore/CartCDF.hxx
@@ -253,6 +253,14 @@ class CartridgeCDF : public CartridgeARM
uInt32 getSample();
void setupVersion();
+ /**
+ Answer whether this is a PlusROM cart. Note that until the
+ initialize method has been called, this will always return false.
+
+ @return Whether this is actually a PlusROM cart
+ */
+ bool isPlusROM() const override { return myPlusROM->isValid(); }
+
private:
// The ROM image of the cartridge
ByteBuffer myImage{nullptr};
diff --git a/src/emucore/CartDPCPlus.cxx b/src/emucore/CartDPCPlus.cxx
index 7fac7dda3..377928ae6 100644
--- a/src/emucore/CartDPCPlus.cxx
+++ b/src/emucore/CartDPCPlus.cxx
@@ -79,6 +79,11 @@ CartridgeDPCPlus::CartridgeDPCPlus(const ByteBuffer& image, size_t size,
myFractionalLowMask = 0x0F0000;
setInitialState();
+
+ myPlusROM = make_unique(mySettings);
+
+ // Determine whether we have a PlusROM cart
+ myPlusROM->initialize(myImage, mySize);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -91,6 +96,8 @@ void CartridgeDPCPlus::reset()
// Upon reset we switch to the startup bank
bank(startBank());
+
+ CartridgeARM::reset();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -218,6 +225,14 @@ inline void CartridgeDPCPlus::callFunction(uInt8 value)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 CartridgeDPCPlus::peek(uInt16 address)
{
+ // Is this a PlusROM?
+ if(myPlusROM->isValid())
+ {
+ uInt8 value = 0;
+ if(myPlusROM->peekHotspot(address, value))
+ return value;
+ }
+
address &= 0x0FFF;
uInt8 peekvalue = myProgramImage[myBankOffset + address];
@@ -405,6 +420,10 @@ uInt8 CartridgeDPCPlus::peek(uInt16 address)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeDPCPlus::poke(uInt16 address, uInt8 value)
{
+ // Is this a PlusROM?
+ if(myPlusROM->isValid() && myPlusROM->pokeHotspot(address, value))
+ return true;
+
address &= 0x0FFF;
if((address >= 0x0028) && (address < 0x0080))
diff --git a/src/emucore/CartDPCPlus.hxx b/src/emucore/CartDPCPlus.hxx
index a52ba8338..37fad81fb 100644
--- a/src/emucore/CartDPCPlus.hxx
+++ b/src/emucore/CartDPCPlus.hxx
@@ -149,6 +149,13 @@ class CartridgeDPCPlus : public CartridgeARM
*/
uInt8 internalRamGetValue(uInt16 addr) const override;
+ /**
+ Answer whether this is a PlusROM cart. Note that until the
+ initialize method has been called, this will always return false.
+
+ @return Whether this is actually a PlusROM cart
+ */
+ bool isPlusROM() const override { return myPlusROM->isValid(); }
#ifdef DEBUGGER_SUPPORT
/**
diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx
index ea8438ee5..2ee3b5a75 100644
--- a/src/emucore/CartEnhanced.hxx
+++ b/src/emucore/CartEnhanced.hxx
@@ -157,6 +157,14 @@ class CartridgeEnhanced : public Cartridge
*/
bool poke(uInt16 address, uInt8 value) override;
+ /**
+ Get the hotspot in ROM address space.
+
+ @return The first hotspot address (usually in ROM) space or 0
+ */
+ virtual uInt16 hotspot() const { return 0; }
+ // TODO: handle cases where there the hotspots cover multiple pages
+
/**
Answer whether this is a PlusROM cart. Note that until the
initialize method has been called, this will always return false.
@@ -166,12 +174,14 @@ class CartridgeEnhanced : public Cartridge
bool isPlusROM() const override { return myPlusROM->isValid(); }
/**
- Get the hotspot in ROM address space.
-
- @return The first hotspot address (usually in ROM) space or 0
+ Set the callback for displaying messages
*/
- virtual uInt16 hotspot() const { return 0; }
- // TODO: handle cases where there the hotspots cover multiple pages
+ void setMessageCallback(const messageCallback& callback) override
+ {
+ Cartridge::setMessageCallback(callback);
+ if(myPlusROM->isValid())
+ myPlusROM->setMessageCallback(myMsgCallback);
+ }
protected:
// The '2 ^ N = bank segment size' exponent
diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx
index 7787e6512..791e982dd 100644
--- a/src/emucore/Console.cxx
+++ b/src/emucore/Console.cxx
@@ -957,7 +957,7 @@ unique_ptr Console::getControllerPort(const Controller::Type type,
nvramfile /= "atarivox_eeprom.dat";
Controller::onMessageCallback callback = [&os = myOSystem](const string& msg) {
bool devSettings = os.settings().getBool("dev.settings");
- if(os.settings().getBool(devSettings ? "dev.eepromaccess" : "plr.eepromaccess"))
+ if(os.settings().getBool(devSettings ? "dev.extaccess" : "plr.extaccess"))
os.frameBuffer().showTextMessage(msg);
};
controller = make_unique(port, myEvent, *mySystem,
@@ -970,7 +970,7 @@ unique_ptr Console::getControllerPort(const Controller::Type type,
nvramfile /= "savekey_eeprom.dat";
Controller::onMessageCallback callback = [&os = myOSystem](const string& msg) {
bool devSettings = os.settings().getBool("dev.settings");
- if(os.settings().getBool(devSettings ? "dev.eepromaccess" : "plr.eepromaccess"))
+ if(os.settings().getBool(devSettings ? "dev.extaccess" : "plr.extaccess"))
os.frameBuffer().showTextMessage(msg);
};
controller = make_unique(port, myEvent, *mySystem, nvramfile, callback);
diff --git a/src/emucore/OSystem.cxx b/src/emucore/OSystem.cxx
index 8a2f3601f..a1be2412d 100644
--- a/src/emucore/OSystem.cxx
+++ b/src/emucore/OSystem.cxx
@@ -636,7 +636,7 @@ unique_ptr OSystem::openConsole(const FilesystemNode& romfile, string&
{
bool devSettings = os.settings().getBool("dev.settings");
- if(os.settings().getBool(devSettings ? "dev.eepromaccess" : "plr.eepromaccess"))
+ if(os.settings().getBool(devSettings ? "dev.extaccess" : "plr.extaccess"))
os.frameBuffer().showTextMessage(msg);
};
diff --git a/src/emucore/PlusROM.cxx b/src/emucore/PlusROM.cxx
index 78c13f945..3476dfd4c 100644
--- a/src/emucore/PlusROM.cxx
+++ b/src/emucore/PlusROM.cxx
@@ -382,7 +382,22 @@ void PlusROM::send()
// The lambda will retain a copy of the shared_ptr that is alive as long as the
// thread is running. Thus, the request can only be destructed once the thread has
// finished, and we can safely evict it from the deque at any time.
- std::thread thread([=]() { request->execute(); });
+ std::thread thread([=]() {
+ request->execute();
+ switch(request->getState())
+ {
+ case PlusROMRequest::State::failed:
+ myMsgCallback("PlusROM data sending failed!");
+ break;
+
+ case PlusROMRequest::State::done:
+ myMsgCallback("PlusROM data sent successfully");
+ break;
+
+ default:
+ break;
+ }
+ });
thread.detach();
}
@@ -398,14 +413,15 @@ void PlusROM::receive()
while (iter != myPendingRequests.end()) {
switch ((*iter)->getState()) {
case PlusROMRequest::State::failed:
+ myMsgCallback("PlusROM data receiving failed!");
// Request has failed? -> remove it and start over
myPendingRequests.erase(iter);
iter = myPendingRequests.begin();
-
continue;
case PlusROMRequest::State::done:
{
+ myMsgCallback("PlusROM data received successfully");
// Request has finished sucessfully? -> consume the response, remove it
// and start over
auto [responseSize, response] = (*iter)->getResponse();
@@ -415,7 +431,6 @@ void PlusROM::receive()
myPendingRequests.erase(iter);
iter = myPendingRequests.begin();
-
continue;
}
diff --git a/src/emucore/PlusROM.hxx b/src/emucore/PlusROM.hxx
index 19470b2b2..790307372 100644
--- a/src/emucore/PlusROM.hxx
+++ b/src/emucore/PlusROM.hxx
@@ -24,6 +24,7 @@ class Settings;
#include "bspf.hxx"
#include "Serializable.hxx"
+#include "Cart.hxx"
/**
Class used to emulate the 'PlusROM' meta-scheme, documented at
@@ -120,6 +121,14 @@ class PlusROM : public Serializable
*/
void reset();
+ /**
+ Set the callback for displaying messages
+ */
+ void setMessageCallback(const Cartridge::messageCallback& callback)
+ {
+ myMsgCallback = callback;
+ }
+
private:
bool isValidHost(const string& host) const;
bool isValidPath(const string& path) const;
@@ -145,6 +154,9 @@ class PlusROM : public Serializable
std::deque> myPendingRequests;
+ // Callback to output messages
+ Cartridge::messageCallback myMsgCallback{nullptr};
+
private:
// Following constructors and assignment operators not supported
PlusROM(const PlusROM&) = delete;
diff --git a/src/emucore/QuadTari.cxx b/src/emucore/QuadTari.cxx
index ce828aa05..63779cb96 100644
--- a/src/emucore/QuadTari.cxx
+++ b/src/emucore/QuadTari.cxx
@@ -71,7 +71,7 @@ unique_ptr QuadTari::addController(const Controller::Type type, bool
FilesystemNode nvramfile = myOSystem.nvramDir();
Controller::onMessageCallback callback = [&os = myOSystem](const string& msg) {
bool devSettings = os.settings().getBool("dev.settings");
- if(os.settings().getBool(devSettings ? "dev.eepromaccess" : "plr.eepromaccess"))
+ if(os.settings().getBool(devSettings ? "dev.extaccess" : "plr.extaccess"))
os.frameBuffer().showTextMessage(msg);
};
diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx
index 355f01e5a..c091f5756 100644
--- a/src/emucore/Settings.cxx
+++ b/src/emucore/Settings.cxx
@@ -220,7 +220,7 @@ Settings::Settings()
setPermanent("plr.tm.interval", "30f"); // = 0.5 seconds
setPermanent("plr.tm.horizon", "10m"); // = ~10 minutes
setPermanent("plr.detectedinfo", "false");
- setPermanent("plr.eepromaccess", "false");
+ setPermanent("plr.extaccess", "false");
// Developer settings
setPermanent("dev.settings", "false");
@@ -250,7 +250,7 @@ Settings::Settings()
setPermanent("dev.tm.interval", "1f"); // = 1 frame
setPermanent("dev.tm.horizon", "30s"); // = ~30 seconds
setPermanent("dev.detectedinfo", "true");
- setPermanent("dev.eepromaccess", "true");
+ setPermanent("dev.extaccess", "true");
// Thumb ARM emulation options
setPermanent("dev.thumb.trapfatal", "true");
#ifdef DEBUGGER_SUPPORT
@@ -684,8 +684,7 @@ void Settings::usage() const
<< " -plr.colorloss <1|0> Enable PAL color-loss effect\n"
<< " -plr.tv.jitter <1|0> Enable TV jitter effect\n"
<< " -plr.tv.jitter_recovery <1-20> Set recovery time for TV jitter effect\n"
- << " -plr.eepromaccess <1|0> Enable messages for AtariVox/SaveKey access\n"
- << " messages\n"
+ << " -plr.extaccess <1|0> Enable messages for external access\n"
<< endl
<< " The same parameters but for developer settings mode\n"
<< " -dev.stats <1|0> Overlay console info during emulation\n"
@@ -716,8 +715,7 @@ void Settings::usage() const
<< " -dev.thumb.chiptype <0|1> Selects the ARM chip type\n"
<< " -dev.thumb.mammode <0-3> Selects the LPC's MAM mode\n"
#endif
- << " -dev.eepromaccess <1|0> Enable messages for AtariVox/SaveKey access\n"
- << " messages\n"
+ << " -dev.extaccess <1|0> Enable messages for external access\n"
<< " -dev.tia.type setToolTip("Display message when AtariVox/SaveKey EEPROM\n"
- "is read or written or PlusROM is accessed.");
+ "Display external access message");
+ myExternAccessWidget->setToolTip("Display a message for any external access\n"
+ "AtariVox/SaveKey EEPROM, PlusROM, Supercharger...).");
wid.push_back(myExternAccessWidget);
ypos += lineHeight + VGAP;
@@ -687,7 +687,7 @@ void DeveloperDialog::loadSettings(SettingsSet set)
// Thumb ARM emulation exception
myThumbException[set] = devSettings ? instance().settings().getBool("dev.thumb.trapfatal") : false;
// AtariVox/SaveKey/PlusROM access
- myExternAccess[set] = instance().settings().getBool(prefix + "eepromaccess");
+ myExternAccess[set] = instance().settings().getBool(prefix + "extaccess");
// TIA tab
myTIAType[set] = devSettings ? instance().settings().getString("dev.tia.type") : "standard";
@@ -749,7 +749,7 @@ void DeveloperDialog::saveSettings(SettingsSet set)
}
// AtariVox/SaveKey/PlusROM access
- instance().settings().setValue(prefix + "eepromaccess", myExternAccess[set]);
+ instance().settings().setValue(prefix + "extaccess", myExternAccess[set]);
// TIA tab
if (devSettings)