mirror of https://github.com/stella-emu/stella.git
Improvements to the FA2 Harmony flash load/save functionality:
- delays are now emulated (0.5 ms for reads, 101 ms for writes) - the flash file is now saved according to the ROM name - correctly return values with bit 6 set to zero or one, instead of just using 0x00 or 0xff git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2440 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
967fb73d2d
commit
1dbefe043d
|
@ -62,7 +62,7 @@
|
|||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Cartridge* Cartridge::create(const uInt8* image, uInt32 size, string& md5,
|
||||
string& dtype, string& id, const OSystem& system, Settings& settings)
|
||||
string& dtype, string& id, const OSystem& osystem, Settings& settings)
|
||||
{
|
||||
Cartridge* cartridge = 0;
|
||||
string type = dtype;
|
||||
|
@ -177,8 +177,7 @@ Cartridge* Cartridge::create(const uInt8* image, uInt32 size, string& md5,
|
|||
else if(type == "FA" || type == "FASC")
|
||||
cartridge = new CartridgeFA(image, size, settings);
|
||||
else if(type == "FA2")
|
||||
cartridge = new CartridgeFA2(image, size, settings,
|
||||
system.eepromDir() + "FA2_flash.dat");
|
||||
cartridge = new CartridgeFA2(image, size, osystem);
|
||||
else if(type == "FE")
|
||||
cartridge = new CartridgeFE(image, size, settings);
|
||||
else if(type == "MC")
|
||||
|
|
|
@ -191,6 +191,14 @@ class Cartridge : public Device
|
|||
*/
|
||||
virtual string name() const = 0;
|
||||
|
||||
/**
|
||||
Informs the cartridge about the name of the ROM file used when
|
||||
creating this cart.
|
||||
|
||||
@param name The properties file name of the ROM
|
||||
*/
|
||||
virtual void setRomName(const string& name) { }
|
||||
|
||||
protected:
|
||||
/**
|
||||
Add the given area to the RamArea list for this cart.
|
||||
|
|
|
@ -20,16 +20,16 @@
|
|||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
#include "OSystem.hxx"
|
||||
#include "Serializer.hxx"
|
||||
#include "System.hxx"
|
||||
#include "CartFA2.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartridgeFA2::CartridgeFA2(const uInt8* image, uInt32 size,
|
||||
const Settings& settings, const string& flashfile)
|
||||
: Cartridge(settings),
|
||||
myRamRWFlag(false),
|
||||
myFlashFile(flashfile),
|
||||
CartridgeFA2::CartridgeFA2(const uInt8* image, uInt32 size, const OSystem& osystem)
|
||||
: Cartridge(osystem.settings()),
|
||||
myOSystem(osystem),
|
||||
myRamAccessTimeout(0),
|
||||
mySize(size)
|
||||
{
|
||||
// Allocate array for the ROM image
|
||||
|
@ -349,24 +349,41 @@ bool CartridgeFA2::load(Serializer& in)
|
|||
return true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeFA2::setRomName(const string& name)
|
||||
{
|
||||
myFlashFile = myOSystem.eepromDir() + name + "_flash.dat";
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt8 CartridgeFA2::ramReadWrite()
|
||||
{
|
||||
/* The following algorithm implements accessing Harmony cart flash
|
||||
|
||||
1. Wait for an access to hotspot location $1FF4 (return 1 on first access).
|
||||
1. Wait for an access to hotspot location $1FF4 (return 1 in bit 6
|
||||
while busy).
|
||||
|
||||
2. Read byte 256 of RAM+ memory to determine the operation requested
|
||||
(1 = read, 2 = write).
|
||||
|
||||
3. Save or load the entire 256 bytes of RAM+ memory to a file.
|
||||
|
||||
4. Set byte 256 of RAM+ memory to zero to indicate success.
|
||||
4. Set byte 256 of RAM+ memory to zero to indicate success (will
|
||||
always happen in emulation).
|
||||
|
||||
5. Return 0 on the next access to $1FF4.
|
||||
5. Return 0 (in bit 6) on the next access to $1FF4, if enough time has
|
||||
passed to complete the operation on a real system (0.5 ms for read,
|
||||
101 ms for write).
|
||||
*/
|
||||
if(!myRamRWFlag)
|
||||
|
||||
// First access sets the timer
|
||||
if(myRamAccessTimeout == 0)
|
||||
{
|
||||
// Remember when the first access was made
|
||||
myRamAccessTimeout = myOSystem.getTicks();
|
||||
|
||||
// We go ahead and do the access now, and only return when a sufficient
|
||||
// amount of time has passed
|
||||
Serializer serializer(myFlashFile);
|
||||
if(serializer.isValid())
|
||||
{
|
||||
|
@ -381,6 +398,7 @@ uInt8 CartridgeFA2::ramReadWrite()
|
|||
{
|
||||
memset(myRAM, 0, 256);
|
||||
}
|
||||
myRamAccessTimeout += 500; // Add 0.5 ms delay for read
|
||||
}
|
||||
else if(myRAM[255] == 2) // write
|
||||
{
|
||||
|
@ -391,15 +409,27 @@ uInt8 CartridgeFA2::ramReadWrite()
|
|||
}
|
||||
catch(const char* msg)
|
||||
{
|
||||
// Maybe add logging here?
|
||||
// Maybe add logging here that save failed?
|
||||
}
|
||||
myRamAccessTimeout += 101000; // Add 101 ms delay for write
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
// Bit 6 is 1, busy
|
||||
return myImage[(myCurrentBank << 12) + 0xFF4] | 0x40;
|
||||
}
|
||||
else
|
||||
{
|
||||
myRamRWFlag = false;
|
||||
return 0;
|
||||
// Have we reached the timeout value yet?
|
||||
if(myOSystem.getTicks() >= myRamAccessTimeout)
|
||||
{
|
||||
myRamAccessTimeout = 0; // Turn off timer
|
||||
myRAM[255] = 0; // Successful operation
|
||||
|
||||
// Bit 6 is 0, ready/success
|
||||
return myImage[(myCurrentBank << 12) + 0xFF4] & ~0x40;
|
||||
}
|
||||
else
|
||||
// Bit 6 is 1, busy
|
||||
return myImage[(myCurrentBank << 12) + 0xFF4] | 0x40;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,9 @@ class System;
|
|||
This is an extended version of the CBS RAM Plus bankswitching scheme
|
||||
supported by the Harmony cartridge.
|
||||
|
||||
There are six (or seven) 4K banks and 256 bytes of RAM.
|
||||
There are six (or seven) 4K banks and 256 bytes of RAM. The 256 bytes
|
||||
of RAM can be loaded/saved to Harmony cart flash, which is emulated by
|
||||
storing in a file.
|
||||
|
||||
@author Chris D. Walton
|
||||
@version $Id$
|
||||
|
@ -42,11 +44,9 @@ class CartridgeFA2 : public Cartridge
|
|||
|
||||
@param image Pointer to the ROM image
|
||||
@param size The size of the ROM image
|
||||
@param settings A reference to the various settings (read-only)
|
||||
@param flashfile The full pathname for the flash file storing internal RAM
|
||||
@param osystem A reference to the OSystem currently in use
|
||||
*/
|
||||
CartridgeFA2(const uInt8* image, uInt32 size, const Settings& settings,
|
||||
const string& flashfile);
|
||||
CartridgeFA2(const uInt8* image, uInt32 size, const OSystem& osystem);
|
||||
|
||||
/**
|
||||
Destructor
|
||||
|
@ -124,6 +124,14 @@ class CartridgeFA2 : public Cartridge
|
|||
*/
|
||||
string name() const { return "CartridgeFA2"; }
|
||||
|
||||
/**
|
||||
Informs the cartridge about the name of the ROM file used when
|
||||
creating this cart.
|
||||
|
||||
@param name The properties file name of the ROM
|
||||
*/
|
||||
void setRomName(const string& name);
|
||||
|
||||
public:
|
||||
/**
|
||||
Get the byte at the specified address.
|
||||
|
@ -145,10 +153,16 @@ class CartridgeFA2 : public Cartridge
|
|||
/**
|
||||
Either load or save internal RAM to Harmony flash (represented by
|
||||
a file in emulation).
|
||||
|
||||
@return The value at $FF4 with bit 6 set or cleared (depending on
|
||||
whether the RAM access was busy or successful)
|
||||
*/
|
||||
uInt8 ramReadWrite();
|
||||
|
||||
private:
|
||||
// OSsytem currently in use
|
||||
const OSystem& myOSystem;
|
||||
|
||||
// Indicates which bank is currently active
|
||||
uInt16 myCurrentBank;
|
||||
|
||||
|
@ -158,8 +172,11 @@ class CartridgeFA2 : public Cartridge
|
|||
// The 256 bytes of RAM on the cartridge
|
||||
uInt8 myRAM[256];
|
||||
|
||||
// An access has been made to load/save internal RAM
|
||||
bool myRamRWFlag;
|
||||
// The time after which the first request of a load/save operation
|
||||
// will actually be completed
|
||||
// Due to flash RAM constraints, a read/write isn't instantaneous,
|
||||
// so we need to emulate the delay as well
|
||||
uInt64 myRamAccessTimeout;
|
||||
|
||||
// Full pathname of the file to use when emulating load/save
|
||||
// of internal RAM to Harmony cart flash
|
||||
|
|
|
@ -214,6 +214,8 @@ Console::Console(OSystem* osystem, Cartridge* cart, const Properties& props)
|
|||
myConsoleInfo.Control0 = myControllers[0]->about();
|
||||
myConsoleInfo.Control1 = myControllers[1]->about();
|
||||
myConsoleInfo.BankSwitch = cart->about();
|
||||
|
||||
myCart->setRomName(myConsoleInfo.CartName);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
Loading…
Reference in New Issue