Added state save/load support.

This commit is contained in:
Shamus Hammons 2014-04-02 13:00:00 -05:00
parent 92c6ae00ea
commit b6f06c7cba
6 changed files with 225 additions and 7 deletions

View File

@ -3,7 +3,7 @@
#
# by James Hammons
# (C) 2005 Underground Software
# This software is licensed under the GPL v2
# This software is licensed under the GPL v3
#
FIND = find

View File

@ -245,14 +245,118 @@ bool LoadImg(char * filename, uint8_t * ram, int size)
}
const uint8_t stateHeader[19] = "APPLE2SAVESTATE1.0";
static void SaveApple2State(const char * filename)
{
WriteLog("Main: Saving Apple2 state...\n");
FILE * file = fopen(filename, "wb");
if (!file)
{
WriteLog("Could not open file \"%s\" for writing!\n", filename);
return;
}
// Write out header
fwrite(stateHeader, 1, 18, file);
// Write out CPU state
fwrite(&mainCPU, 1, sizeof(mainCPU), file);
// Write out main memory
fwrite(ram, 1, 0x10000, file);
fwrite(ram2, 1, 0x10000, file);
// Write out state variables
fputc((uint8_t)keyDown, file);
fputc((uint8_t)openAppleDown, file);
fputc((uint8_t)closedAppleDown, file);
fputc((uint8_t)store80Mode, file);
fputc((uint8_t)vbl, file);
fputc((uint8_t)slotCXROM, file);
fputc((uint8_t)slotC3ROM, file);
fputc((uint8_t)ramrd, file);
fputc((uint8_t)ramwrt, file);
fputc((uint8_t)altzp, file);
fputc((uint8_t)ioudis, file);
fputc((uint8_t)dhires, file);
fputc((uint8_t)flash, file);
fputc((uint8_t)textMode, file);
fputc((uint8_t)mixedMode, file);
fputc((uint8_t)displayPage2, file);
fputc((uint8_t)hiRes, file);
fputc((uint8_t)alternateCharset, file);
fputc((uint8_t)col80Mode, file);
fputc(lcState, file);
// Write out floppy state
floppyDrive.SaveState(file);
fclose(file);
}
static bool LoadApple2State(const char * filename)
{
return false;
WriteLog("Main: Loading Apple2 state...\n");
FILE * file = fopen(filename, "rb");
if (!file)
{
WriteLog("Could not open file \"%s\" for reading!\n", filename);
return false;
}
uint8_t buffer[18];
fread(buffer, 1, 18, file);
// Sanity check...
if (memcmp(buffer, stateHeader, 18) != 0)
{
fclose(file);
WriteLog("File \"%s\" is not a valid Apple2 save state file!\n", filename);
return false;
}
// Read CPU state
fread(&mainCPU, 1, sizeof(mainCPU), file);
// Read main memory
fread(ram, 1, 0x10000, file);
fread(ram2, 1, 0x10000, file);
// Read in state variables
keyDown = (bool)fgetc(file);
openAppleDown = (bool)fgetc(file);
closedAppleDown = (bool)fgetc(file);
store80Mode = (bool)fgetc(file);
vbl = (bool)fgetc(file);
slotCXROM = (bool)fgetc(file);
slotC3ROM = (bool)fgetc(file);
ramrd = (bool)fgetc(file);
ramwrt = (bool)fgetc(file);
altzp = (bool)fgetc(file);
ioudis = (bool)fgetc(file);
dhires = (bool)fgetc(file);
flash = (bool)fgetc(file);
textMode = (bool)fgetc(file);
mixedMode = (bool)fgetc(file);
displayPage2 = (bool)fgetc(file);
hiRes = (bool)fgetc(file);
alternateCharset = (bool)fgetc(file);
col80Mode = (bool)fgetc(file);
lcState = fgetc(file);
// Read in floppy state
floppyDrive.LoadState(file);
fclose(file);
// Make sure things are in a sane state before execution :-P
mainCPU.RdMem = AppleReadMem;
mainCPU.WrMem = AppleWriteMem;
ResetMMUPointers();
return true;
}
@ -322,7 +426,6 @@ int main(int /*argc*/, char * /*argv*/[])
//Load up disk image from config file (for now)...
floppyDrive.LoadImage(settings.diskImagePath1, 0);
floppyDrive.LoadImage(settings.diskImagePath2, 1);
// floppyDrive.LoadImage("./disks/temp.nib", 1); // Load temp .nib file into second drive...
WriteLog("About to initialize video...\n");

View File

@ -10,7 +10,9 @@
// Apple II character set has 64 chars (56 bytes for each character)
char textChar[0x0E00] = {
#include <stdint.h>
uint8_t textChar[0x0E00] = {
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -79,7 +81,7 @@ char textChar[0x0E00] = {
// Apple IIe/IIc character set has 256 chars (56 bytes for each character)
char textChar2e[0x3800] = {
uint8_t textChar2e[0x3800] = {
0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,

View File

@ -1,8 +1,10 @@
#ifndef __CHARSET_H__
#define __CHARSET_H__
extern char textChar[];
extern char textChar2e[];
#include <stdint.h>
extern uint8_t textChar[];
extern uint8_t textChar2e[];
#endif // __CHARSET_H__

View File

@ -611,6 +611,109 @@ int FloppyDrive::DriveLightStatus(uint8_t driveNum/*= 0*/)
}
void FloppyDrive::SaveState(FILE * file)
{
// Internal state vars
fputc(motorOn, file);
fputc(activeDrive, file);
fputc(ioMode, file);
fputc(latchValue, file);
fputc(phase, file);
fputc(track, file);
fputc((ioHappened ? 1 : 0), file);
WriteLong(file, currentPos);
// Disk #1
if (disk[0] != NULL)
{
WriteLong(file, diskSize[0]);
WriteLong(file, diskType[0]);
fputc((imageDirty[0] ? 1 : 0), file);
fputc((writeProtected[0] ? 1 : 0), file);
fwrite(nybblizedImage[0], 1, 232960, file);
fwrite(imageName[0], 1, MAX_PATH, file);
}
else
WriteLong(file, 0);
// Disk #2
if (disk[1] != NULL)
{
WriteLong(file, diskSize[1]);
WriteLong(file, diskType[1]);
fputc((imageDirty[1] ? 1 : 0), file);
fputc((writeProtected[1] ? 1 : 0), file);
fwrite(nybblizedImage[1], 1, 232960, file);
fwrite(imageName[1], 1, MAX_PATH, file);
}
else
WriteLong(file, 0);
}
void FloppyDrive::LoadState(FILE * file)
{
// Eject images if they're loaded
EjectImage(0);
EjectImage(1);
// Read internal state variables
motorOn = fgetc(file);
activeDrive = fgetc(file);
ioMode = fgetc(file);
latchValue = fgetc(file);
phase = fgetc(file);
track = fgetc(file);
ioHappened = (fgetc(file) == 1 ? true : false);
currentPos = ReadLong(file);
diskSize[0] = ReadLong(file);
if (diskSize[0])
{
disk[0] = new uint8_t[diskSize[0]];
diskType[0] = (uint8_t)ReadLong(file);
imageDirty[0] = (fgetc(file) == 1 ? true : false);
writeProtected[0] = (fgetc(file) == 1 ? true : false);
fread(nybblizedImage[0], 1, 232960, file);
fread(imageName[0], 1, MAX_PATH, file);
}
diskSize[1] = ReadLong(file);
if (diskSize[1])
{
disk[1] = new uint8_t[diskSize[1]];
diskType[1] = (uint8_t)ReadLong(file);
imageDirty[1] = (fgetc(file) == 1 ? true : false);
writeProtected[1] = (fgetc(file) == 1 ? true : false);
fread(nybblizedImage[1], 1, 232960, file);
fread(imageName[1], 1, MAX_PATH, file);
}
}
uint32_t FloppyDrive::ReadLong(FILE * file)
{
uint32_t r = 0;
for(int i=0; i<4; i++)
r = (r << 8) | fgetc(file);
return r;
}
void FloppyDrive::WriteLong(FILE * file, uint32_t l)
{
for(int i=0; i<4; i++)
{
fputc((l >> 24) & 0xFF, file);
l = l << 8;
}
}
// Memory mapped I/O functions
/*

View File

@ -13,6 +13,7 @@
#include <stdlib.h> // for MAX_PATH on MinGW/Darwin
#endif
#include <stdint.h>
#include <stdio.h>
enum { DFT_UNKNOWN, DT_DOS33, DT_DOS33_HDR, DT_PRODOS, DT_NYBBLE };
enum { DLS_OFF, DLS_READ, DLS_WRITE };
@ -34,9 +35,16 @@ class FloppyDrive
bool IsWriteProtected(uint8_t driveNum = 0);
void SetWriteProtect(bool, uint8_t driveNum = 0);
int DriveLightStatus(uint8_t driveNum = 0);
void SaveState(FILE *);
void LoadState(FILE *);
private:
uint32_t ReadLong(FILE *);
void WriteLong(FILE *, uint32_t);
// I/O functions ($C0Ex accesses)
public:
void ControlStepper(uint8_t addr);
void ControlMotor(uint8_t addr);
void DriveEnable(uint8_t addr);