Added state save/load support.
This commit is contained in:
parent
92c6ae00ea
commit
b6f06c7cba
2
Makefile
2
Makefile
|
@ -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
|
||||
|
|
107
src/apple2.cpp
107
src/apple2.cpp
|
@ -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");
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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__
|
||||
|
||||
|
|
103
src/floppy.cpp
103
src/floppy.cpp
|
@ -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
|
||||
|
||||
/*
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue