#
# 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
}
+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;
}
//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");
// 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,
// 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,
#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__
}
+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
/*
#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 };
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);