added message display for PlusROMs (TODO: update screenshots)

renamed message display setting
extended PlusROM support to ARM carts (TODO: test)
This commit is contained in:
Thomas Jentzsch 2021-10-10 12:06:01 +02:00
parent 7c670bbfc3
commit d049326c8d
16 changed files with 154 additions and 33 deletions

View File

@ -3621,9 +3621,9 @@
Note: Mode X (3) is for testing only. It reduces Flash memory access
clock cycles to always 1.</td>
</tr><tr>
<td><pre>-&lt;plr.|dev.&gt;eepromaccess &lt;1|0&gt;</pre></td>
<td>When enabled, each read or write access to the AtariVox/SaveKey EEPROM is
signalled by a message.</td>
<td><pre>-&lt;plr.|dev.&gt;extaccess &lt;1|0&gt;</pre></td>
<td>When enabled, each external access (AtariVox/SaveKey EEPROM, PlusROM, Supercharger...)
is signalled by a message.</td>
</tr><tr>
<td><pre>-dev.tia.type &lt;standard|koolaidman|cosmicark|</br> pesco|quickstep|indy500|heman|custom&gt;</pre></td>
<td>Set emulated TIA type.</td>
@ -4341,9 +4341,15 @@
<td>-plr.stats<br/>-dev.stats</td></tr>
<tr>
<td>Detected settings info</td>
<td>Display detected settings when a ROM is loaded.</td>
<td>Display detected settings when a ROM is loaded</td>
<td>-plr.detectedinfo<br/>-dev.detectedinfo</td>
</tr>
<tr>
<td>Display external access message</td>
<td>Display a message for any external access
(AtariVox/SaveKey EEPROM, PlusROM, Supercharger...)</td>
<td>-plr.extaccess<br/>-dev.extaccess</td>
</tr>
<tr>
<td>Console</td>
<td>Select the console type, this affects Color/B&W/Pause key
@ -4391,11 +4397,6 @@
<td>Thumb ARM emulation throws an exception and enters the debugger on fatal errors</td>
<td><span style="white-space:nowrap">-dev.thumb.trapfatal</span></td>
</tr>
<tr>
<td>Display AtariVox...</td>
<td>Display a message when the AtariVox/SaveKey EEPROM is read or written</td>
<td>-plr.eepromaccess<br/>-dev.eepromaccess</td>
</tr>
</table>
</td>
</tr>

View File

@ -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;
}

View File

@ -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(...)
{

View File

@ -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<Thumbulator> myThumbEmulator;
// Handle PlusROM functionality, if available
unique_ptr<PlusROM> myPlusROM;
// ARM code increases 6507 cycles
bool myIncCycles{false};

View File

@ -113,6 +113,11 @@ CartridgeCDF::CartridgeCDF(const ByteBuffer& image, size_t size,
this);
setInitialState();
myPlusROM = make_unique<PlusROM>(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)
{

View File

@ -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};

View File

@ -79,6 +79,11 @@ CartridgeDPCPlus::CartridgeDPCPlus(const ByteBuffer& image, size_t size,
myFractionalLowMask = 0x0F0000;
setInitialState();
myPlusROM = make_unique<PlusROM>(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))

View File

@ -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
/**

View File

@ -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

View File

@ -957,7 +957,7 @@ unique_ptr<Controller> 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<AtariVox>(port, myEvent, *mySystem,
@ -970,7 +970,7 @@ unique_ptr<Controller> 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<SaveKey>(port, myEvent, *mySystem, nvramfile, callback);

View File

@ -636,7 +636,7 @@ unique_ptr<Console> 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);
};

View File

@ -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;
}

View File

@ -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<shared_ptr<PlusROMRequest>> myPendingRequests;
// Callback to output messages
Cartridge::messageCallback myMsgCallback{nullptr};
private:
// Following constructors and assignment operators not supported
PlusROM(const PlusROM&) = delete;

View File

@ -71,7 +71,7 @@ unique_ptr<Controller> 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);
};

View File

@ -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 <standard|custom| Selects a TIA type\n"
<< " koolaidman|\n"
<< " cosmicark|pesco|\n"

View File

@ -123,9 +123,9 @@ void DeveloperDialog::addEmulationTab(const GUI::Font& font)
// AtariVox/SaveKey/PlusROM access
myExternAccessWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1,
"Display AtariVox/SaveKey and PlusROM access");
myExternAccessWidget->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)