14
14
// See the file "License.txt" for information on usage and redistribution of
15
15
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
17
// $Id: CartFA2.cxx 2435 2012-03-30 21:07:57Z stephena $
17
// $Id: CartFA2.cxx 2499 2012-05-25 12:41:19Z stephena $
18
18
//============================================================================
23
#include "OSystem.hxx"
24
#include "Serializer.hxx"
23
25
#include "System.hxx"
24
26
#include "CartFA2.hxx"
26
28
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
27
CartridgeFA2::CartridgeFA2(const uInt8* image, uInt32 size, const Settings& settings)
28
: Cartridge(settings),
29
CartridgeFA2::CartridgeFA2(const uInt8* image, uInt32 size, const OSystem& osystem)
30
: Cartridge(osystem.settings()),
32
myRamAccessTimeout(0),
31
35
// Allocate array for the ROM image
231
247
System::PageAccess access(0, 0, 0, this, System::PA_READ);
233
249
// Set the page accessing methods for the hot spots
234
for(uInt32 i = (0x1FF5 & ~mask); i < 0x2000; i += (1 << shift))
250
for(uInt32 i = (0x1FF4 & ~mask); i < 0x2000; i += (1 << shift))
236
252
access.codeAccessBase = &myCodeAccessBase[offset + (i & 0x0FFF)];
237
253
mySystem->setPageAccess(i >> shift, access);
240
256
// Setup the page access methods for the current bank
241
for(uInt32 address = 0x1200; address < (0x1FF5U & ~mask);
257
for(uInt32 address = 0x1200; address < (0x1FF4U & ~mask);
242
258
address += (1 << shift))
244
260
access.directPeekBase = &myImage[offset + (address & 0x0FFF)];
293
309
out.putString(name());
294
out.putInt(myCurrentBank);
296
// The 256 bytes of RAM
298
for(uInt32 i = 0; i < 256; ++i)
299
out.putByte((char)myRAM[i]);
310
out.putShort(myCurrentBank);
311
out.putByteArray(myRAM, 256);
301
catch(const char* msg)
303
cerr << "ERROR: CartridgeFA2::save" << endl << " " << msg << endl;
315
cerr << "ERROR: CartridgeFA2::save" << endl;
315
327
if(in.getString() != name())
318
myCurrentBank = (uInt16) in.getInt();
320
uInt32 limit = (uInt32) in.getInt();
321
for(uInt32 i = 0; i < limit; ++i)
322
myRAM[i] = (uInt8) in.getByte();
330
myCurrentBank = in.getShort();
331
in.getByteArray(myRAM, 256);
324
catch(const char* msg)
326
cerr << "ERROR: CartridgeFA2::load" << endl << " " << msg << endl;
335
cerr << "ERROR: CartridgeFA2::load" << endl;
345
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
346
void CartridgeFA2::setRomName(const string& name)
348
myFlashFile = myOSystem.eepromDir() + name + "_flash.dat";
351
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
352
uInt8 CartridgeFA2::ramReadWrite()
354
/* The following algorithm implements accessing Harmony cart flash
356
1. Wait for an access to hotspot location $1FF4 (return 1 in bit 6
359
2. Read byte 256 of RAM+ memory to determine the operation requested
360
(1 = read, 2 = write).
362
3. Save or load the entire 256 bytes of RAM+ memory to a file.
364
4. Set byte 256 of RAM+ memory to zero to indicate success (will
365
always happen in emulation).
367
5. Return 0 (in bit 6) on the next access to $1FF4, if enough time has
368
passed to complete the operation on a real system (0.5 ms for read,
372
// First access sets the timer
373
if(myRamAccessTimeout == 0)
375
// Remember when the first access was made
376
myRamAccessTimeout = myOSystem.getTicks();
378
// We go ahead and do the access now, and only return when a sufficient
379
// amount of time has passed
380
Serializer serializer(myFlashFile);
381
if(serializer.isValid())
383
if(myRAM[255] == 1) // read
387
serializer.getByteArray(myRAM, 256);
391
memset(myRAM, 0, 256);
393
myRamAccessTimeout += 500; // Add 0.5 ms delay for read
395
else if(myRAM[255] == 2) // write
399
serializer.putByteArray(myRAM, 256);
403
// Maybe add logging here that save failed?
404
cerr << name() << ": ERROR saving score table" << endl;
406
myRamAccessTimeout += 101000; // Add 101 ms delay for write
410
return myImage[(myCurrentBank << 12) + 0xFF4] | 0x40;
414
// Have we reached the timeout value yet?
415
if(myOSystem.getTicks() >= myRamAccessTimeout)
417
myRamAccessTimeout = 0; // Turn off timer
418
myRAM[255] = 0; // Successful operation
420
// Bit 6 is 0, ready/success
421
return myImage[(myCurrentBank << 12) + 0xFF4] & ~0x40;
425
return myImage[(myCurrentBank << 12) + 0xFF4] | 0x40;