Removed redundant binary v2 save-state code

Also:
. support new CpuType independently of Apple2Type
. save-state: don't save disk track image if no disk
. save-state: re-init AppleWin internals & UI to reflect changed Apple2Type
This commit is contained in:
tomcw 2016-02-14 16:01:30 +00:00
parent 2f6e86c0fa
commit 37ad1ebd63
47 changed files with 302 additions and 2499 deletions

View File

@ -782,10 +782,6 @@
RelativePath=".\source\SaveState_Structs_v1.h"
>
</File>
<File
RelativePath=".\source\SaveState_Structs_v2.h"
>
</File>
<File
RelativePath=".\source\SSI263Phonemes.h"
>

View File

@ -1134,159 +1134,6 @@ bool CAY8910::LoadSnapshot(YamlLoadHelper& yamlLoadHelper, std::string& suffix)
return true;
}
//
// disable warning C4200: zero-sized array in struct/union
#pragma warning(disable: 4200)
struct SS_AY8910
{
unsigned int ay_tone_tick[3], ay_tone_high[3], ay_noise_tick;
unsigned int ay_tone_subcycles, ay_env_subcycles;
unsigned int ay_env_internal_tick, ay_env_tick;
unsigned int ay_tick_incr;
unsigned int ay_tone_period[3], ay_noise_period, ay_env_period;
BYTE sound_ay_registers[16];
int rng;
int noise_toggle;
int env_first, env_rev, env_counter;
int ay_change_count;
void* ay_change[0]; // real type is ay_change_tag (but this is private)
};
UINT CAY8910::GetSnapshot(const HANDLE hFile)
{
const UINT uAYChangeLength = ay_change_count * sizeof(ay_change_tag);
const UINT uAYTotalLength = sizeof(SS_AY8910) + uAYChangeLength;
if (hFile == NULL)
return uAYTotalLength;
//
SS_AY8910 ay_state;
memcpy(ay_state.ay_tone_tick, ay_tone_tick, sizeof(ay_tone_tick));
memcpy(ay_state.ay_tone_high, ay_tone_high, sizeof(ay_tone_high));
ay_state.ay_noise_tick = ay_noise_tick;
ay_state.ay_tone_subcycles = ay_tone_subcycles;
ay_state.ay_env_subcycles = ay_env_subcycles;
ay_state.ay_env_internal_tick = ay_env_internal_tick;
ay_state.ay_env_tick = ay_env_tick;
ay_state.ay_tick_incr = ay_tick_incr;
memcpy(ay_state.ay_tone_period, ay_tone_period, sizeof(ay_tone_period));
ay_state.ay_noise_period = ay_noise_period;
ay_state.ay_env_period = ay_env_period;
memcpy(ay_state.sound_ay_registers, sound_ay_registers, sizeof(sound_ay_registers));
ay_state.rng = rng;
ay_state.noise_toggle = noise_toggle;
ay_state.env_first = env_first;
ay_state.env_rev = env_rev;
ay_state.env_counter = env_counter;
ay_state.ay_change_count = ay_change_count;
//
DWORD dwBytesWritten;
BOOL bRes = WriteFile( hFile,
&ay_state,
sizeof(SS_AY8910),
&dwBytesWritten,
NULL);
if(!bRes || (dwBytesWritten != sizeof(SS_AY8910)))
{
//dwError = GetLastError();
throw std::string("Save error: AY8910");
}
//
if (uAYChangeLength)
{
DWORD dwBytesWritten2;
BOOL bRes2 = WriteFile( hFile,
ay_change,
uAYChangeLength,
&dwBytesWritten2,
NULL);
if(!bRes2 || (dwBytesWritten2 != uAYChangeLength))
{
//dwError = GetLastError();
throw std::string("Save error: AY8910");
}
}
return uAYTotalLength;
}
UINT CAY8910::SetSnapshot(const HANDLE hFile)
{
SS_AY8910 ay_state;
DWORD dwBytesRead;
BOOL bRes = ReadFile( hFile,
&ay_state,
sizeof(SS_AY8910),
&dwBytesRead,
NULL);
if (dwBytesRead != sizeof(SS_AY8910))
throw std::string("Card: file corrupt");
if (ay_state.ay_change_count > AY_CHANGE_MAX)
throw std::string("Card: file corrupt");
//
memcpy(ay_tone_tick, ay_state.ay_tone_tick, sizeof(ay_tone_tick));
memcpy(ay_tone_high, ay_state.ay_tone_high, sizeof(ay_tone_high));
ay_noise_tick = ay_state.ay_noise_tick;
ay_tone_subcycles = ay_state.ay_tone_subcycles;
ay_env_subcycles = ay_state.ay_env_subcycles;
ay_env_internal_tick = ay_state.ay_env_internal_tick;
ay_env_tick = ay_state.ay_env_tick;
ay_tick_incr = ay_state.ay_tick_incr;
memcpy(ay_tone_period, ay_state.ay_tone_period, sizeof(ay_tone_period));
ay_noise_period = ay_state.ay_noise_period;
ay_env_period = ay_state.ay_env_period;
memcpy(sound_ay_registers, ay_state.sound_ay_registers, sizeof(sound_ay_registers));
rng = ay_state.rng;
noise_toggle = ay_state.noise_toggle;
env_first = ay_state.env_first;
env_rev = ay_state.env_rev;
env_counter = ay_state.env_counter;
ay_change_count = ay_state.ay_change_count;
//
const UINT uLength = ay_change_count * sizeof(ay_change_tag);
if (uLength)
{
DWORD dwBytesRead2;
BOOL bRes = ReadFile( hFile,
ay_change,
uLength,
&dwBytesRead2,
NULL);
if (dwBytesRead2 != uLength)
throw std::string("Card: file corrupt");
}
return dwBytesRead+uLength;
}
///////////////////////////////////////////////////////////////////////////////
// AY8910 interface
@ -1365,19 +1212,3 @@ UINT AY8910_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT uChip, std::string
return g_AY8910[uChip].LoadSnapshot(yamlLoadHelper, suffix) ? 1 : 0;
}
UINT AY8910_GetSnapshot(const HANDLE hFile, UINT uChip)
{
if (uChip >= MAX_8910)
return 0;
return g_AY8910[uChip].GetSnapshot(hFile);
}
UINT AY8910_SetSnapshot(const HANDLE hFile, UINT uChip)
{
if (uChip >= MAX_8910)
return 0;
return g_AY8910[uChip].SetSnapshot(hFile);
}

View File

@ -19,8 +19,6 @@ void AY8910UpdateSetCycles();
UINT AY8910_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, UINT uChip, std::string& suffix);
UINT AY8910_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT uChip, std::string& suffix);
UINT AY8910_GetSnapshot(const HANDLE hFile, UINT uChip);
UINT AY8910_SetSnapshot(const HANDLE hFile, UINT uChip);
//-------------------------------------
// FUSE stuff

View File

@ -99,8 +99,6 @@ CMouseInterface sg_Mouse;
SS_CARDTYPE g_Slot4 = CT_Empty;
SS_CARDTYPE g_Slot5 = CT_Empty;
eCPU g_ActiveCPU = CPU_6502;
HANDLE g_hCustomRomF8 = INVALID_HANDLE_VALUE; // Cmd-line specified custom ROM at $F800..$FFFF
static bool g_bCustomRomF8Failed = false; // Set if custom ROM file failed
@ -111,6 +109,17 @@ CSpeech g_Speech;
//===========================================================================
eApple2Type GetApple2Type(void)
{
return g_Apple2Type;
}
void SetApple2Type(eApple2Type type)
{
g_Apple2Type = type;
SetMainCpuDefault(type);
}
const UINT16* GetAppleWinVersion(void)
{
return &g_AppleWinVersion[0];
@ -375,17 +384,36 @@ static void LoadConfigOldJoystick(const UINT uJoyNum)
JoySetJoyType(uJoyNum, uNewJoyType);
}
//Sets the character set for the Apple model/clone
void SetCharsetType(void)
{
switch ( GetApple2Type() )
{
case A2TYPE_APPLE2: g_nCharsetType = 0; break;
case A2TYPE_APPLE2PLUS: g_nCharsetType = 0; break;
case A2TYPE_APPLE2E: g_nCharsetType = 0; break;
case A2TYPE_APPLE2EENHANCED:g_nCharsetType = 0; break;
case A2TYPE_PRAVETS82: g_nCharsetType = 1; break;
case A2TYPE_PRAVETS8A: g_nCharsetType = 2; break;
case A2TYPE_PRAVETS8M: g_nCharsetType = 3; break; //This charset has a very small difference with the PRAVETS82 one an probably has some misplaced characters. Still the Pravets82 charset is used, because setting charset to 3 results in some problems.
default:
_ASSERT(0);
g_nCharsetType = 0;
}
}
//Reads configuration from the registry entries
void LoadConfiguration(void)
{
DWORD dwComputerType;
eApple2Type apple2Type = A2TYPE_APPLE2EENHANCED;
if (REGLOAD(TEXT(REGVALUE_APPLE2_TYPE), &dwComputerType))
{
if ((dwComputerType >= A2TYPE_MAX) || (dwComputerType >= A2TYPE_UNDEFINED && dwComputerType < A2TYPE_CLONE))
dwComputerType = A2TYPE_APPLE2EENHANCED;
g_Apple2Type = (eApple2Type) dwComputerType;
apple2Type = (eApple2Type) dwComputerType;
}
else // Support older AppleWin registry entries
{
@ -393,24 +421,31 @@ void LoadConfiguration(void)
switch (dwComputerType)
{
// NB. No A2TYPE_APPLE2E (this is correct)
case 0: g_Apple2Type = A2TYPE_APPLE2;
case 1: g_Apple2Type = A2TYPE_APPLE2PLUS;
case 2: g_Apple2Type = A2TYPE_APPLE2EENHANCED;
default: g_Apple2Type = A2TYPE_APPLE2EENHANCED;
case 0: apple2Type = A2TYPE_APPLE2; break;
case 1: apple2Type = A2TYPE_APPLE2PLUS; break;
case 2: apple2Type = A2TYPE_APPLE2EENHANCED; break;
default: apple2Type = A2TYPE_APPLE2EENHANCED;
}
}
switch (g_Apple2Type) //Sets the character set for the Apple model/clone
SetApple2Type(apple2Type);
SetCharsetType();
//
DWORD dwCpuType;
eCpuType cpu = CPU_65C02;
if (REGLOAD(TEXT(REGVALUE_CPU_TYPE), &dwCpuType))
{
case A2TYPE_APPLE2: g_nCharsetType = 0; break;
case A2TYPE_APPLE2PLUS: g_nCharsetType = 0; break;
case A2TYPE_APPLE2E: g_nCharsetType = 0; break;
case A2TYPE_APPLE2EENHANCED:g_nCharsetType = 0; break;
case A2TYPE_PRAVETS82: g_nCharsetType = 1; break;
case A2TYPE_PRAVETS8A: g_nCharsetType = 2; break;
case A2TYPE_PRAVETS8M: g_nCharsetType = 3; break; //This charset has a very small difference with the PRAVETS82 one an probably has some misplaced characters. Still the Pravets82 charset is used, because setting charset to 3 results in some problems.
if (dwCpuType != CPU_6502 && dwCpuType != CPU_65C02)
dwCpuType = CPU_65C02;
cpu = (eCpuType) dwCpuType;
}
SetMainCpu(cpu);
//
DWORD dwJoyType;

View File

@ -5,6 +5,7 @@
void SetCurrentCLK6502();
void SetCurrentImageDir(const char* pszImageDir);
void SetCharsetType(void);
extern const UINT16* GetAppleWinVersion(void);
extern char VERSIONSTRING[]; // Constructed in WinMain()
@ -12,6 +13,8 @@ extern char VERSIONSTRING[]; // Constructed in WinMain()
extern TCHAR *g_pAppTitle;
extern eApple2Type g_Apple2Type;
eApple2Type GetApple2Type(void);
void SetApple2Type(eApple2Type type);
extern bool g_bFullSpeed;
@ -46,9 +49,6 @@ extern SS_CARDTYPE g_Slot5; // Mockingboard, Z80, in slot5
extern HANDLE g_hCustomRomF8; // NULL if no custom rom
enum eCPU {CPU_6502=1, CPU_Z80};
extern eCPU g_ActiveCPU;
#ifdef USE_SPEECH_API
class CSpeech;
extern CSpeech g_Speech;

View File

@ -102,7 +102,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "Z80VICE\z80mem.h"
#include "Debugger\Debug.h"
#include "SaveState_Structs_v2.h"
#include "YamlHelper.h"
@ -147,6 +146,54 @@ static volatile UINT32 g_bmIRQ = 0;
static volatile UINT32 g_bmNMI = 0;
static volatile BOOL g_bNmiFlank = FALSE; // Positive going flank on NMI line
//
static eCpuType g_MainCPU = CPU_65C02;
static eCpuType g_ActiveCPU = CPU_65C02;
eCpuType GetMainCpu(void)
{
return g_MainCPU;
}
void SetMainCpu(eCpuType cpu)
{
_ASSERT(cpu != CPU_Z80);
if (cpu == CPU_Z80)
return;
g_MainCPU = cpu;
}
static bool IsCpu6502(eApple2Type apple2Type)
{
return IS_APPLE2 ||
(apple2Type == A2TYPE_APPLE2E) ||
IS_CLONE(); // NB. All Pravets clones are 6502 (GH#307)
}
eCpuType ProbeMainCpuDefault(eApple2Type apple2Type)
{
return IsCpu6502(apple2Type) ? CPU_6502 : CPU_65C02;
}
void SetMainCpuDefault(eApple2Type apple2Type)
{
SetMainCpu( ProbeMainCpuDefault(apple2Type) );
}
eCpuType GetActiveCpu(void)
{
return g_ActiveCPU;
}
void SetActiveCpu(eCpuType cpu)
{
g_ActiveCPU = cpu;
}
//
#include "cpu/cpu_general.inl"
#include "cpu/cpu_instructions.inl"
@ -406,16 +453,9 @@ static __forceinline void CheckInterruptSources(ULONG uExecutedCycles)
//===========================================================================
static bool IsCpu6502(void)
{
return IS_APPLE2 ||
(g_Apple2Type == A2TYPE_APPLE2E) ||
IS_CLONE(); // NB. All Pravets clones are 6502 (GH#307)
}
static DWORD InternalCpuExecute (DWORD uTotalCycles)
{
if (IsCpu6502())
if (GetMainCpu() == CPU_6502)
return Cpu6502(uTotalCycles); // Apple ][, ][+, //e, Clones
else
return Cpu65C02(uTotalCycles); // Enhanced Apple //e
@ -645,7 +685,7 @@ void CpuReset()
regs.bJammed = 0;
g_ActiveCPU = CPU_6502;
SetActiveCpu( GetMainCpu() );
z80_reset();
}
@ -690,7 +730,7 @@ void CpuSaveSnapshot(YamlSaveHelper& yamlSaveHelper)
regs.ps |= (AF_RESERVED | AF_BREAK);
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", CpuGetSnapshotStructName().c_str());
yamlSaveHelper.Save("%s: %s # NB. Currently ignored\n", SS_YAML_KEY_CPU_TYPE, IsCpu6502() ? SS_YAML_VALUE_6502 : SS_YAML_VALUE_65C02);
yamlSaveHelper.Save("%s: %s\n", SS_YAML_KEY_CPU_TYPE, GetMainCpu() == CPU_6502 ? SS_YAML_VALUE_6502 : SS_YAML_VALUE_65C02);
yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGA, regs.a);
yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGX, regs.x);
yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGY, regs.y);
@ -705,7 +745,13 @@ void CpuLoadSnapshot(YamlLoadHelper& yamlLoadHelper)
if (!yamlLoadHelper.GetSubMap(CpuGetSnapshotStructName()))
return;
yamlLoadHelper.GetMapValueSTRING(SS_YAML_KEY_CPU_TYPE); // consume - not currently used
std::string cpuType = yamlLoadHelper.GetMapValueSTRING(SS_YAML_KEY_CPU_TYPE);
eCpuType cpu;
if (cpuType == SS_YAML_VALUE_6502) cpu = CPU_6502;
else if (cpuType == SS_YAML_VALUE_65C02) cpu = CPU_65C02;
else throw std::string("Load: Unknown main CPU type");
SetMainCpu(cpu);
regs.a = (BYTE) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGA);
regs.x = (BYTE) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGX);
regs.y = (BYTE) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGY);
@ -719,33 +765,3 @@ void CpuLoadSnapshot(YamlLoadHelper& yamlLoadHelper)
yamlLoadHelper.PopMap();
}
//
void CpuGetSnapshot(SS_CPU6502_v2& CPU)
{
regs.ps |= (AF_RESERVED | AF_BREAK);
CPU.A = regs.a;
CPU.X = regs.x;
CPU.Y = regs.y;
CPU.P = regs.ps;
CPU.S = (BYTE) regs.sp;
CPU.PC = regs.pc;
CPU.CumulativeCycles = g_nCumulativeCycles;
}
void CpuSetSnapshot(const SS_CPU6502_v2& CPU)
{
regs.a = CPU.A;
regs.x = CPU.X;
regs.y = CPU.Y;
regs.ps = CPU.P | (AF_RESERVED | AF_BREAK);
regs.sp = ((USHORT)CPU.S) | 0x100;
regs.pc = CPU.PC;
CpuIrqReset();
CpuNmiReset();
g_nCumulativeCycles = CPU.CumulativeCycles;
}

View File

@ -30,10 +30,17 @@ void CpuReset ();
void CpuSetSnapshot_v1(const BYTE A, const BYTE X, const BYTE Y, const BYTE P, const BYTE SP, const USHORT PC, const unsigned __int64 CumulativeCycles);
void CpuSaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
void CpuLoadSnapshot(class YamlLoadHelper& yamlLoadHelper);
void CpuGetSnapshot(struct SS_CPU6502_v2& CPU);
void CpuSetSnapshot(const struct SS_CPU6502_v2& CPU);
BYTE CpuRead(USHORT addr, ULONG uExecutedCycles);
void CpuWrite(USHORT addr, BYTE a, ULONG uExecutedCycles);
DWORD CpuGetEmulationTime_ms(void);
enum eCpuType {CPU_6502=1, CPU_65C02, CPU_Z80}; // Don't change! Persisted to Registry
eCpuType GetMainCpu(void);
void SetMainCpu(eCpuType cpu);
eCpuType ProbeMainCpuDefault(eApple2Type apple2Type);
void SetMainCpuDefault(eApple2Type apple2Type);
eCpuType GetActiveCpu(void);
void SetActiveCpu(eCpuType cpu);

View File

@ -43,7 +43,7 @@ static DWORD Cpu6502 (DWORD uTotalCycles)
UINT uExtraCycles = 0;
BYTE iOpcode;
if (g_ActiveCPU == CPU_Z80)
if (GetActiveCpu() == CPU_Z80)
{
const UINT uZ80Cycles = z80_mainloop(uTotalCycles, uExecutedCycles); CYC(uZ80Cycles)
}

View File

@ -46,7 +46,7 @@ static DWORD Cpu65C02 (DWORD uTotalCycles)
UINT uExtraCycles = 0;
BYTE iOpcode;
if (g_ActiveCPU == CPU_Z80)
if (GetActiveCpu() == CPU_Z80)
{
const UINT uZ80Cycles = z80_mainloop(uTotalCycles, uExecutedCycles); CYC(uZ80Cycles)
}

View File

@ -120,7 +120,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles)
UINT uExtraCycles = 0;
BYTE iOpcode;
if (g_ActiveCPU == CPU_Z80)
if (GetActiveCpu() == CPU_Z80)
{
const UINT uZ80Cycles = z80_mainloop(uTotalCycles, uExecutedCycles); CYC(uZ80Cycles)
}

View File

@ -69,6 +69,7 @@ enum AppMode_e
// Configuration
#define REG_CONFIG "Configuration"
#define REGVALUE_APPLE2_TYPE "Apple2 Type"
#define REGVALUE_CPU_TYPE "CPU Type"
#define REGVALUE_OLD_APPLE2_TYPE "Computer Emulation" // Deprecated
#define REGVALUE_CONFIRM_REBOOT "Confirm Reboot" // Added at 1.24.1 PageConfig
#define REGVALUE_SPKR_VOLUME "Speaker Volume"

View File

@ -1,6 +1,7 @@
#pragma once
#include "..\AppleWin.h"
#include "..\CPU.h"
#include "..\Disk.h" // BOOL enhancedisk
#include "..\HardDisk.h" // HD_CardIsEnabled()
@ -8,7 +9,8 @@ class CConfigNeedingRestart
{
public:
CConfigNeedingRestart(UINT bEnableTheFreezesF8Rom = false) :
m_Apple2Type(g_Apple2Type),
m_Apple2Type( GetApple2Type() ),
m_CpuType( GetMainCpu() ),
m_bEnhanceDisk(enhancedisk),
m_uSaveLoadStateMsg(0)
{
@ -23,6 +25,7 @@ public:
const CConfigNeedingRestart& operator= (const CConfigNeedingRestart& other)
{
m_Apple2Type = other.m_Apple2Type;
m_CpuType = other.m_CpuType;
memcpy(m_Slot, other.m_Slot, sizeof(m_Slot));
m_bEnhanceDisk = other.m_bEnhanceDisk;
m_bEnableHDD = other.m_bEnableHDD;
@ -34,6 +37,7 @@ public:
bool operator== (const CConfigNeedingRestart& other) const
{
return m_Apple2Type == other.m_Apple2Type &&
m_CpuType == other.m_CpuType &&
memcmp(m_Slot, other.m_Slot, sizeof(m_Slot)) == 0 &&
m_bEnhanceDisk == other.m_bEnhanceDisk &&
m_bEnableHDD == other.m_bEnableHDD &&
@ -47,6 +51,7 @@ public:
}
eApple2Type m_Apple2Type;
eCpuType m_CpuType;
SS_CARDTYPE m_Slot[NUM_SLOTS]; // 0..7
SS_CARDTYPE m_SlotAux;
BOOL m_bEnhanceDisk;

View File

@ -129,6 +129,7 @@ BOOL CPageConfig::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPARAM
const DWORD NewComputerMenuItem = (DWORD) SendDlgItemMessage(hWnd, IDC_COMPUTER, CB_GETCURSEL, 0, 0);
const eApple2Type NewApple2Type = GetApple2Type(NewComputerMenuItem);
m_PropertySheetHelper.GetConfigNew().m_Apple2Type = NewApple2Type;
m_PropertySheetHelper.GetConfigNew().m_CpuType = ProbeMainCpuDefault(NewApple2Type);
}
break;

View File

@ -102,6 +102,11 @@ void CPropertySheetHelper::SaveComputerType(eApple2Type NewApple2Type)
REGSAVE(TEXT(REGVALUE_APPLE2_TYPE), NewApple2Type);
}
void CPropertySheetHelper::SaveCpuType(eCpuType NewCpuType)
{
REGSAVE(TEXT(REGVALUE_CPU_TYPE), NewCpuType);
}
void CPropertySheetHelper::SetSlot4(SS_CARDTYPE NewCardType)
{
g_Slot4 = NewCardType;
@ -252,17 +257,34 @@ int CPropertySheetHelper::SaveStateSelectImage(HWND hWindow, TCHAR* pszTitle, bo
{
if (bSave) // Only for saving (allow loading of any file for backwards compatibility)
{
// Append .aws if it's not there
// Append .aws.yaml if it's not there
const char szAWS_EXT1[] = ".aws";
const char szAWS_EXT2[] = ".aws.yaml";
const char szAWS_EXT3[] = ".yaml";
const UINT uStrLenFile = strlen(&szFilename[ofn.nFileOffset]);
const char szAWS_EXT2[] = ".yaml";
const char szAWS_EXT3[] = ".aws.yaml";
const UINT uStrLenFile = strlen(&szFilename[ofn.nFileOffset]);
const UINT uStrLenExt1 = strlen(szAWS_EXT1);
const UINT uStrLenExt2 = strlen(szAWS_EXT2);
if ((uStrLenFile <= uStrLenExt1) || (strcmp(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt1], szAWS_EXT1) == 0))
strcpy(&szFilename[ofn.nFileOffset+uStrLenFile], szAWS_EXT3); // "file.aws" += ".yaml"
else if ((uStrLenFile <= uStrLenExt2) || (strcmp(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt2], szAWS_EXT2) != 0))
strcpy(&szFilename[ofn.nFileOffset+uStrLenFile], szAWS_EXT2); // "file" += "aws.yaml"
const UINT uStrLenExt3 = strlen(szAWS_EXT3);
if (uStrLenFile <= uStrLenExt1)
{
strcpy(&szFilename[ofn.nFileOffset+uStrLenFile], szAWS_EXT3); // "file" += ".aws.yaml"
}
else if (uStrLenFile <= uStrLenExt2)
{
if (strcmp(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt1], szAWS_EXT1) == 0)
strcpy(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt1], szAWS_EXT3); // "file.aws" -> "file" + ".aws.yaml"
else
strcpy(&szFilename[ofn.nFileOffset+uStrLenFile], szAWS_EXT3); // "file" += ".aws.yaml"
}
else if ((uStrLenFile <= uStrLenExt3) || (strcmp(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt3], szAWS_EXT3) != 0))
{
if (strcmp(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt1], szAWS_EXT1) == 0)
strcpy(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt1], szAWS_EXT3); // "file.aws" -> "file" + ".aws.yaml"
else if (strcmp(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt2], szAWS_EXT2) == 0)
strcpy(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt2], szAWS_EXT3); // "file.yaml" -> "file" + ".aws.yaml"
else
strcpy(&szFilename[ofn.nFileOffset+uStrLenFile], szAWS_EXT3); // "file" += ".aws.yaml"
}
}
strcpy(m_szSSNewFilename, &szFilename[ofn.nFileOffset]);
@ -342,6 +364,11 @@ void CPropertySheetHelper::ApplyNewConfig(const CConfigNeedingRestart& ConfigNew
SaveComputerType(ConfigNew.m_Apple2Type);
}
if (CONFIG_CHANGED_LOCAL(m_CpuType))
{
SaveCpuType(ConfigNew.m_CpuType);
}
if (CONFIG_CHANGED_LOCAL(m_Slot[4]))
SetSlot4(ConfigNew.m_Slot[4]);
@ -370,7 +397,8 @@ void CPropertySheetHelper::ApplyNewConfig(void)
void CPropertySheetHelper::SaveCurrentConfig(void)
{
// NB. clone-type is encoded in g_Apple2Type
m_ConfigOld.m_Apple2Type = g_Apple2Type;
m_ConfigOld.m_Apple2Type = GetApple2Type();
m_ConfigOld.m_CpuType = GetMainCpu();
m_ConfigOld.m_Slot[4] = g_Slot4;
m_ConfigOld.m_Slot[5] = g_Slot5;
m_ConfigOld.m_bEnhanceDisk = enhancedisk;
@ -388,7 +416,8 @@ void CPropertySheetHelper::SaveCurrentConfig(void)
void CPropertySheetHelper::RestoreCurrentConfig(void)
{
// NB. clone-type is encoded in g_Apple2Type
g_Apple2Type = m_ConfigOld.m_Apple2Type;
SetApple2Type(m_ConfigOld.m_Apple2Type);
SetMainCpu(m_ConfigOld.m_CpuType);
g_Slot4 = m_ConfigOld.m_Slot[4];
g_Slot5 = m_ConfigOld.m_Slot[5];
enhancedisk = m_ConfigOld.m_bEnhanceDisk;
@ -441,6 +470,9 @@ bool CPropertySheetHelper::HardwareConfigChanged(HWND hWnd)
if (CONFIG_CHANGED(m_Apple2Type))
strMsgMain += ". Emulated computer has changed\n";
if (CONFIG_CHANGED(m_CpuType))
strMsgMain += ". Emulated main CPU has changed\n";
if (CONFIG_CHANGED(m_Slot[4]))
strMsgMain += GetSlot(4);

View File

@ -42,6 +42,7 @@ private:
bool IsOkToSaveLoadState(HWND hWnd, const bool bConfigChanged);
bool IsOkToRestart(HWND hWnd);
void SaveComputerType(eApple2Type NewApple2Type);
void SaveCpuType(eCpuType NewCpuType);
bool HardwareConfigChanged(HWND hWnd);
bool CheckChangesForRestart(HWND hWnd);
void ApplyNewConfig(void);

View File

@ -1213,14 +1213,10 @@ static void DiskSaveSnapshotDisk2Unit(YamlSaveHelper& yamlSaveHelper, UINT unit)
yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_TRACK_IMAGE_DATA, g_aFloppyDisk[unit].trackimagedata);
yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_TRACK_IMAGE_DIRTY, g_aFloppyDisk[unit].trackimagedirty);
// New label
if (g_aFloppyDisk[unit].trackimage)
{
YamlSaveHelper::Label image(yamlSaveHelper, "%s:\n", SS_YAML_KEY_TRACK_IMAGE);
std::auto_ptr<BYTE> pNullTrack( new BYTE [NIBBLES_PER_TRACK] );
memset(pNullTrack.get(), 0, NIBBLES_PER_TRACK);
LPBYTE pTrack = g_aFloppyDisk[unit].trackimage ? g_aFloppyDisk[unit].trackimage : pNullTrack.get();
yamlSaveHelper.SaveMapValueMemory(pTrack, NIBBLES_PER_TRACK);
yamlSaveHelper.SaveMapValueMemory(g_aFloppyDisk[unit].trackimage, NIBBLES_PER_TRACK);
}
}
@ -1284,12 +1280,14 @@ static void DiskLoadSnapshotDriveUnit(YamlLoadHelper& yamlLoadHelper, UINT unit)
g_aFloppyDisk[unit].trackimagedata = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_TRACK_IMAGE_DATA);
g_aFloppyDisk[unit].trackimagedirty = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_TRACK_IMAGE_DIRTY);
if (!yamlLoadHelper.GetSubMap(SS_YAML_KEY_TRACK_IMAGE))
throw disk2UnitName + std::string(": Missing: ") + std::string(SS_YAML_KEY_TRACK_IMAGE);
std::auto_ptr<BYTE> pTrack( new BYTE [NIBBLES_PER_TRACK] );
yamlLoadHelper.GetMapValueMemory(pTrack.get(), NIBBLES_PER_TRACK);
memset(pTrack.get(), 0, NIBBLES_PER_TRACK);
if (yamlLoadHelper.GetSubMap(SS_YAML_KEY_TRACK_IMAGE))
{
yamlLoadHelper.GetMapValueMemory(pTrack.get(), NIBBLES_PER_TRACK);
yamlLoadHelper.PopMap();
}
yamlLoadHelper.PopMap();
yamlLoadHelper.PopMap();
//
@ -1343,194 +1341,3 @@ bool DiskLoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT vers
return true;
}
//---
struct DISK2_Unit_v2
{
char szFileName[MAX_PATH];
UINT Track;
UINT Phase;
UINT Byte;
BOOL WriteProtected;
BOOL TrackImageData;
BOOL TrackImageDirty;
DWORD Spinning;
DWORD WriteLight;
UINT Nibbles;
BYTE TrackImage[NIBBLES_PER_TRACK];
};
struct SS_CARD_DISK2_v2
{
SS_CARD_HDR Hdr;
DISK2_Unit_v2 Unit[2];
WORD Phases;
WORD CurrDrive;
BOOL DiskAccessed;
BOOL EnhanceDisk;
BYTE FloppyLatch;
BOOL FloppyMotorOn;
BOOL FloppyWriteMode;
};
void DiskGetSnapshot(const HANDLE hFile)
{
SS_CARD_DISK2_v2 CardDisk2;
SS_CARD_DISK2_v2* const pSS = &CardDisk2;
pSS->Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_DISK2);
pSS->Hdr.UnitHdr.hdr.v2.Type = UT_Card;
pSS->Hdr.UnitHdr.hdr.v2.Version = 1;
pSS->Hdr.Slot = g_uSlot;
pSS->Hdr.Type = CT_Disk2;
pSS->Phases = phases;
pSS->CurrDrive = currdrive;
pSS->DiskAccessed = diskaccessed;
pSS->EnhanceDisk = enhancedisk;
pSS->FloppyLatch = floppylatch;
pSS->FloppyMotorOn = floppymotoron;
pSS->FloppyWriteMode = floppywritemode;
for(UINT i=0; i<NUM_DRIVES; i++)
{
strcpy(pSS->Unit[i].szFileName, g_aFloppyDisk[i].fullname);
pSS->Unit[i].Track = g_aFloppyDisk[i].track;
pSS->Unit[i].Phase = g_aFloppyDisk[i].phase;
pSS->Unit[i].Byte = g_aFloppyDisk[i].byte;
pSS->Unit[i].WriteProtected = g_aFloppyDisk[i].bWriteProtected ? TRUE : FALSE;
pSS->Unit[i].TrackImageData = g_aFloppyDisk[i].trackimagedata;
pSS->Unit[i].TrackImageDirty = g_aFloppyDisk[i].trackimagedirty;
pSS->Unit[i].Spinning = g_aFloppyDisk[i].spinning;
pSS->Unit[i].WriteLight = g_aFloppyDisk[i].writelight;
pSS->Unit[i].Nibbles = g_aFloppyDisk[i].nibbles;
if(g_aFloppyDisk[i].trackimage)
memcpy(pSS->Unit[i].TrackImage, g_aFloppyDisk[i].trackimage, NIBBLES_PER_TRACK);
else
memset(pSS->Unit[i].TrackImage, 0, NIBBLES_PER_TRACK);
}
//
DWORD dwBytesWritten;
BOOL bRes = WriteFile( hFile,
&CardDisk2,
CardDisk2.Hdr.UnitHdr.hdr.v2.Length,
&dwBytesWritten,
NULL);
if(!bRes || (dwBytesWritten != CardDisk2.Hdr.UnitHdr.hdr.v2.Length))
{
//dwError = GetLastError();
throw std::string("Save error: Disk][");
}
}
void DiskSetSnapshot(const HANDLE hFile)
{
SS_CARD_DISK2_v2 CardDisk2;
DWORD dwBytesRead;
BOOL bRes = ReadFile( hFile,
&CardDisk2,
sizeof(CardDisk2),
&dwBytesRead,
NULL);
if (dwBytesRead != sizeof(CardDisk2))
throw std::string("Card: file corrupt");
if (CardDisk2.Hdr.Slot != 6) // fixme
throw std::string("Card: wrong slot");
if (CardDisk2.Hdr.UnitHdr.hdr.v2.Version > 1)
throw std::string("Card: wrong version");
if (CardDisk2.Hdr.UnitHdr.hdr.v2.Length != sizeof(SS_CARD_DISK2_v2))
throw std::string("Card: unit size mismatch");
const SS_CARD_DISK2_v2* const pSS = &CardDisk2;
phases = pSS->Phases;
currdrive = pSS->CurrDrive;
diskaccessed = pSS->DiskAccessed;
enhancedisk = pSS->EnhanceDisk;
floppylatch = pSS->FloppyLatch;
floppymotoron = pSS->FloppyMotorOn;
floppywritemode = pSS->FloppyWriteMode;
// Eject all disks first in case Drive-2 contains disk to be inserted into Drive-1
for(UINT i=0; i<NUM_DRIVES; i++)
{
DiskEject(i); // Remove any disk & update Registry to reflect empty drive
ZeroMemory(&g_aFloppyDisk[i], sizeof(Disk_t));
}
bool bResSelectImage = false;
for(UINT i=0; i<NUM_DRIVES; i++)
{
if(pSS->Unit[i].szFileName[0] == 0x00)
continue;
DWORD dwAttributes = GetFileAttributes(pSS->Unit[i].szFileName);
if(dwAttributes == INVALID_FILE_ATTRIBUTES)
{
// Get user to browse for file
bResSelectImage = DiskSelectImage(i, pSS->Unit[i].szFileName);
dwAttributes = GetFileAttributes(pSS->Unit[i].szFileName);
}
bool bImageError = (dwAttributes == INVALID_FILE_ATTRIBUTES);
if (!bImageError)
{
if(DiskInsert(i, pSS->Unit[i].szFileName, dwAttributes & FILE_ATTRIBUTE_READONLY, IMAGE_DONT_CREATE) != eIMAGE_ERROR_NONE)
bImageError = true;
// DiskInsert() sets up:
// . imagename
// . fullname
// . writeprotected
}
//
// strcpy(g_aFloppyDisk[i].fullname, pSS->Unit[i].szFileName);
g_aFloppyDisk[i].track = pSS->Unit[i].Track;
g_aFloppyDisk[i].phase = pSS->Unit[i].Phase;
g_aFloppyDisk[i].byte = pSS->Unit[i].Byte;
// g_aFloppyDisk[i].writeprotected = pSS->Unit[i].WriteProtected;
g_aFloppyDisk[i].trackimagedata = pSS->Unit[i].TrackImageData;
g_aFloppyDisk[i].trackimagedirty = pSS->Unit[i].TrackImageDirty;
g_aFloppyDisk[i].spinning = pSS->Unit[i].Spinning;
g_aFloppyDisk[i].writelight = pSS->Unit[i].WriteLight;
g_aFloppyDisk[i].nibbles = pSS->Unit[i].Nibbles;
//
if(!bImageError)
{
if((g_aFloppyDisk[i].trackimage == NULL) && g_aFloppyDisk[i].nibbles)
AllocTrack(i);
if(g_aFloppyDisk[i].trackimage == NULL)
bImageError = true;
else
memcpy(g_aFloppyDisk[i].trackimage, pSS->Unit[i].TrackImage, NIBBLES_PER_TRACK);
}
if(bImageError)
{
g_aFloppyDisk[i].trackimagedata = 0;
g_aFloppyDisk[i].trackimagedirty = 0;
g_aFloppyDisk[i].nibbles = 0;
}
}
FrameRefreshStatus(DRAW_LEDS | DRAW_BUTTON_DRIVES);
}

View File

@ -75,8 +75,6 @@ int DiskSetSnapshot_v1(const struct SS_CARD_DISK2* const pSS);
std::string DiskGetSnapshotCardName(void);
void DiskSaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
bool DiskLoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version);
void DiskGetSnapshot(const HANDLE hFile);
void DiskSetSnapshot(const HANDLE hFile);
void Disk_LoadLastDiskImage(const int iDrive);
void Disk_SaveLastDiskImage(const int iDrive);

View File

@ -178,7 +178,7 @@ static bool g_bFullScreen32Bit = true;
// Updates g_pAppTitle
// ====================================================================
void GetAppleWindowTitle()
static void GetAppleWindowTitle()
{
g_pAppTitle = g_pAppleWindowTitle;
@ -764,6 +764,14 @@ void FrameDrawDiskStatus( HDC passdc )
//===========================================================================
static void DrawStatusArea (HDC passdc, int drawflags)
{
if (g_hFrameWindow == NULL)
{
// TC: Fix drawing of drive buttons before frame created:
// . Main init loop: LoadConfiguration() called before FrameCreateWindow(), eg:
// LoadConfiguration() -> Disk_LoadLastDiskImage() -> DiskInsert() -> FrameRefreshStatus()
return;
}
FrameReleaseDC();
HDC dc = (passdc ? passdc : GetDC(g_hFrameWindow));
int x = buttonx;
@ -2010,7 +2018,7 @@ void ResetMachineState ()
MB_Reset();
SpkrReset();
sg_Mouse.Reset();
g_ActiveCPU = CPU_6502;
SetActiveCpu( GetMainCpu() );
#ifdef USE_SPEECH_API
g_Speech.Reset();
#endif
@ -2634,3 +2642,17 @@ void GetViewportCXCY(int& nViewportCX, int& nViewportCY)
nViewportCX = g_nViewportCX;
nViewportCY = g_nViewportCY;
}
// Call all funcs with dependency on g_Apple2Type
void FrameUpdateApple2Type(void)
{
DeleteGdiObjects();
CreateGdiObjects();
// DRAW_TITLE : calls GetAppleWindowTitle()
// DRAW_LEDS : update LEDs (eg. CapsLock varies on Apple2 type)
DrawStatusArea( (HDC)0, DRAW_TITLE|DRAW_LEDS );
// Draw buttons & call DrawStatusArea(DRAW_BACKGROUND | DRAW_LEDS | DRAW_DISK_STATUS)
DrawFrameWindow();
}

View File

@ -48,6 +48,7 @@
void GetViewportCXCY(int& nViewportCX, int& nViewportCY);
bool GetFullScreen32Bit(void);
void SetFullScreen32Bit(bool b32Bit);
void FrameUpdateApple2Type(void);
void FrameDrawDiskLEDS( HDC hdc );
void FrameDrawDiskStatus( HDC hdc );

View File

@ -804,159 +804,3 @@ bool HD_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version, co
return true;
}
//---
struct HDD_Unit
{
char szFilename[MAX_PATH];
BYTE error;
WORD memblock;
UINT diskblock;
WORD buf_ptr;
BOOL imageloaded;
BYTE buf[HD_BLOCK_SIZE];
UINT status_next;
UINT status_prev;
};
struct SS_CARD_HDD
{
SS_CARD_HDR Hdr;
HDD_Unit Unit[NUM_HARDDISKS];
BYTE CurrUnit;
BYTE Command;
};
void HD_GetSnapshot(const HANDLE hFile)
{
if (!HD_CardIsEnabled())
return;
SS_CARD_HDD CardHDD;
CardHDD.Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_HDD);
CardHDD.Hdr.UnitHdr.hdr.v2.Type = UT_Card;
CardHDD.Hdr.UnitHdr.hdr.v2.Version = 1;
CardHDD.Hdr.Slot = g_uSlot;
CardHDD.Hdr.Type = CT_GenericHDD;
CardHDD.CurrUnit = g_nHD_UnitNum;
CardHDD.Command = g_nHD_Command;
for (UINT i=0; i<NUM_HARDDISKS; i++)
{
strcpy(CardHDD.Unit[i].szFilename, g_HardDisk[i].fullname);
CardHDD.Unit[i].error = g_HardDisk[i].hd_error;
CardHDD.Unit[i].memblock = g_HardDisk[i].hd_memblock;
CardHDD.Unit[i].diskblock = g_HardDisk[i].hd_diskblock;
CardHDD.Unit[i].buf_ptr = g_HardDisk[i].hd_buf_ptr;
CardHDD.Unit[i].imageloaded = g_HardDisk[i].hd_imageloaded;
memcpy(CardHDD.Unit[i].buf, g_HardDisk[i].hd_buf, sizeof(CardHDD.Unit[i].buf));
CardHDD.Unit[i].status_next = g_HardDisk[i].hd_status_next;
CardHDD.Unit[i].status_prev = g_HardDisk[i].hd_status_prev;
}
//
DWORD dwBytesWritten;
BOOL bRes = WriteFile( hFile,
&CardHDD,
CardHDD.Hdr.UnitHdr.hdr.v2.Length,
&dwBytesWritten,
NULL);
if(!bRes || (dwBytesWritten != CardHDD.Hdr.UnitHdr.hdr.v2.Length))
{
//dwError = GetLastError();
throw std::string("Save error: HDD");
}
}
void HD_SetSnapshot(const HANDLE hFile, const std::string strSaveStatePath)
{
SS_CARD_HDD CardHDD;
DWORD dwBytesRead;
BOOL bRes = ReadFile( hFile,
&CardHDD,
sizeof(CardHDD),
&dwBytesRead,
NULL);
if (dwBytesRead != sizeof(CardHDD))
throw std::string("Card: file corrupt");
if (CardHDD.Hdr.Slot != 7) // fixme
throw std::string("Card: wrong slot");
if (CardHDD.Hdr.UnitHdr.hdr.v2.Version > 1)
throw std::string("Card: wrong version");
if (CardHDD.Hdr.UnitHdr.hdr.v2.Length != sizeof(SS_CARD_HDD))
throw std::string("Card: unit size mismatch");
g_nHD_UnitNum = CardHDD.CurrUnit;
g_nHD_Command = CardHDD.Command;
// Unplug all HDDs first in case HDD-2 is to be plugged in as HDD-1
for (UINT i=0; i<NUM_HARDDISKS; i++)
{
HD_Unplug(i);
ZeroMemory(&g_HardDisk[i], sizeof(HDD));
}
bool bResSelectImage = false;
for (UINT i=0; i<NUM_HARDDISKS; i++)
{
if (CardHDD.Unit[i].szFilename[0] == 0x00)
continue;
DWORD dwAttributes = GetFileAttributes(CardHDD.Unit[i].szFilename);
if (dwAttributes == INVALID_FILE_ATTRIBUTES)
{
// Get user to browse for file
bResSelectImage = HD_SelectImage(i, CardHDD.Unit[i].szFilename);
dwAttributes = GetFileAttributes(CardHDD.Unit[i].szFilename);
}
bool bImageError = (dwAttributes == INVALID_FILE_ATTRIBUTES);
if (!bImageError)
{
if (!HD_Insert(i, CardHDD.Unit[i].szFilename))
bImageError = true;
// HD_Insert() sets up:
// . imagename
// . fullname
// . hd_imageloaded
}
//
// strcpy(g_HardDisk[i].fullname, CardHDD.Unit[i].szFilename);
g_HardDisk[i].hd_error = CardHDD.Unit[i].error;
g_HardDisk[i].hd_memblock = CardHDD.Unit[i].memblock;
g_HardDisk[i].hd_diskblock = CardHDD.Unit[i].diskblock;
g_HardDisk[i].hd_buf_ptr = CardHDD.Unit[i].buf_ptr;
// g_HardDisk[i].hd_imageloaded = CardHDD.Unit[i].imageloaded;
memcpy(g_HardDisk[i].hd_buf, CardHDD.Unit[i].buf, sizeof(CardHDD.Unit[i].buf));
g_HardDisk[i].hd_status_next = (Disk_Status_e) CardHDD.Unit[i].status_next;
g_HardDisk[i].hd_status_prev = (Disk_Status_e) CardHDD.Unit[i].status_prev;
if (bImageError)
{
g_HardDisk[i].hd_imageloaded = FALSE;
}
}
if (!bResSelectImage)
RegSaveString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_HDV_START_DIR), 1, strSaveStatePath.c_str());
HD_SetEnabled(true);
FrameRefreshStatus(DRAW_LEDS);
}

View File

@ -47,5 +47,3 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
std::string HD_GetSnapshotCardName(void);
void HD_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
bool HD_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version, const std::string strSaveStatePath);
void HD_GetSnapshot(const HANDLE hFile);
void HD_SetSnapshot(const HANDLE hFile, const std::string strSaveStatePath);

View File

@ -891,21 +891,3 @@ void JoyLoadSnapshot(YamlLoadHelper& yamlLoadHelper)
yamlLoadHelper.PopMap();
}
//
void JoyGetSnapshot(unsigned __int64& rJoyCntrResetCycle, short* pJoystick0Trim, short* pJoystick1Trim)
{
rJoyCntrResetCycle = g_nJoyCntrResetCycle;
pJoystick0Trim[0] = JoyGetTrim(true);
pJoystick0Trim[1] = JoyGetTrim(false);
pJoystick1Trim[0] = 0; // TBD: not implemented yet
pJoystick1Trim[1] = 0; // TBD: not implemented yet
}
void JoySetSnapshot(const unsigned __int64 JoyCntrResetCycle, const short* pJoystick0Trim, const short* pJoystick1Trim)
{
g_nJoyCntrResetCycle = JoyCntrResetCycle;
JoySetTrim(pJoystick0Trim[0], true);
JoySetTrim(pJoystick0Trim[1], false);
}

View File

@ -27,8 +27,6 @@ void JoyportControl(const UINT uControl);
void JoySetSnapshot_v1(const unsigned __int64 JoyCntrResetCycle);
void JoySaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
void JoyLoadSnapshot(class YamlLoadHelper& yamlLoadHelper);
void JoyGetSnapshot(unsigned __int64& rJoyCntrResetCycle, short* pJoystick0Trim, short* pJoystick1Trim);
void JoySetSnapshot(const unsigned __int64 JoyCntrResetCycle, const short* pJoystick0Trim, const short* pJoystick1Trim);
BYTE __stdcall JoyReadButton(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
BYTE __stdcall JoyReadPosition(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);

View File

@ -531,15 +531,3 @@ void KeybLoadSnapshot(YamlLoadHelper& yamlLoadHelper)
yamlLoadHelper.PopMap();
}
//
void KeybGetSnapshot(BYTE& rLastKey)
{
rLastKey = g_nLastKey;
}
void KeybSetSnapshot(const BYTE LastKey)
{
g_nLastKey = LastKey;
}

View File

@ -17,8 +17,6 @@ void KeybToggleP8ACapsLock ();
void KeybSetSnapshot_v1(const BYTE LastKey);
void KeybSaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
void KeybLoadSnapshot(class YamlLoadHelper& yamlLoadHelper);
void KeybGetSnapshot(BYTE& rLastKey);
void KeybSetSnapshot(const BYTE LastKey);
BYTE __stdcall KeybReadData (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
BYTE __stdcall KeybReadFlag (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);

View File

@ -54,7 +54,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "..\resource\resource.h"
#include "Configuration\PropertySheet.h"
#include "Debugger\DebugDefs.h"
#include "SaveState_Structs_v2.h"
#include "YamlHelper.h"
// Memory Flag
@ -1882,160 +1881,3 @@ bool MemLoadSnapshotAux(YamlLoadHelper& yamlLoadHelper, UINT version)
return true;
}
//
void MemGetSnapshot(SS_BaseMemory_v2& Memory)
{
Memory.dwMemMode = memmode;
Memory.bLastWriteRam = lastwriteram;
Memory.IO_SELECT = IO_SELECT;
Memory.IO_SELECT_InternalROM = IO_SELECT_InternalROM;
Memory.ExpansionRomType = g_eExpansionRomType;
Memory.PeripheralRomSlot = g_uPeripheralRomSlot;
for(DWORD dwOffset = 0x0000; dwOffset < 0x10000; dwOffset+=0x100)
{
memcpy(Memory.MemMain+dwOffset, MemGetMainPtr((WORD)dwOffset), 0x100);
}
}
void MemSetSnapshot(const SS_BaseMemory_v2& Memory)
{
SetMemMode(Memory.dwMemMode);
lastwriteram = Memory.bLastWriteRam;
IO_SELECT = Memory.IO_SELECT;
IO_SELECT_InternalROM = Memory.IO_SELECT_InternalROM;
g_eExpansionRomType = (eExpansionRomType) Memory.ExpansionRomType;
g_uPeripheralRomSlot = Memory.PeripheralRomSlot;
memcpy(memmain, Memory.MemMain, nMemMainSize);
memset(memdirty, 0, 0x100);
//
modechanging = 0;
// NB. MemUpdatePaging(TRUE) called at end of Snapshot_LoadState_v2()
UpdatePaging(1); // Initialize=1 (Still needed, even with call to MemUpdatePaging() - why?)
}
//
// disable warning C4200: zero-sized array in struct/union
#pragma warning(disable: 4200)
struct SS_CARD_80COL_AUX_MEMORY
{
SS_CARD_HDR Hdr;
UINT NumAuxBanks; // [0,1..127] 0=no aux mem, 1=128K system, etc
UINT ActiveAuxBank; // [ 0..126] 0=memaux
BYTE MemAux[0];
};
void MemGetSnapshotAux(const HANDLE hFile)
{
if (IS_APPLE2)
{
return; // No Aux slot for AppleII
}
if (IS_APPLE2C)
{
_ASSERT(g_uMaxExPages == 1);
}
const UINT uSize = sizeof(SS_CARD_80COL_AUX_MEMORY) + g_uMaxExPages*(_6502_MEM_END+1);
SS_CARD_80COL_AUX_MEMORY* const pSS = (SS_CARD_80COL_AUX_MEMORY*) new BYTE [uSize];
pSS->Hdr.UnitHdr.hdr.v2.Length = uSize;
pSS->Hdr.UnitHdr.hdr.v2.Type = UT_Card;
pSS->Hdr.UnitHdr.hdr.v2.Version = 1;
pSS->Hdr.Slot = kSLOT_AUX;
pSS->Hdr.Type = g_uMaxExPages == 0 ? CT_80Col :
g_uMaxExPages == 1 ? CT_Extended80Col :
CT_RamWorksIII;
pSS->ActiveAuxBank = g_uActiveBank;
pSS->NumAuxBanks = g_uMaxExPages;
for(UINT uBank = 1; uBank <= g_uMaxExPages; uBank++)
{
memcpy(pSS->MemAux+(uBank-1)*(_6502_MEM_END+1), MemGetBankPtr(uBank), _6502_MEM_END+1);
}
//
DWORD dwBytesWritten;
BOOL bRes = WriteFile( hFile,
pSS,
pSS->Hdr.UnitHdr.hdr.v2.Length,
&dwBytesWritten,
NULL);
delete [] pSS;
if(!bRes || (dwBytesWritten != uSize))
{
//dwError = GetLastError();
throw std::string("Save error: 80COL_AUX_MEMORY card");
}
}
void MemSetSnapshotAux(const HANDLE hFile)
{
SS_CARD_80COL_AUX_MEMORY Card;
DWORD dwBytesRead;
BOOL bRes = ReadFile( hFile,
&Card,
sizeof(Card),
&dwBytesRead,
NULL);
if (dwBytesRead != sizeof(Card))
throw std::string("Card: file corrupt");
if (Card.Hdr.Slot != kSLOT_AUX)
throw std::string("Card: wrong slot");
if (Card.Hdr.UnitHdr.hdr.v2.Version > 1)
throw std::string("Card: wrong version");
if (Card.Hdr.UnitHdr.hdr.v2.Length < sizeof(SS_CARD_80COL_AUX_MEMORY))
throw std::string("Card: unit size mismatch");
if (Card.NumAuxBanks > kMaxExMemoryBanks)
throw std::string("Card: file corrupt");
if (Card.ActiveAuxBank >= Card.NumAuxBanks)
throw std::string("Card: file corrupt");
g_uActiveBank = Card.ActiveAuxBank;
g_uMaxExPages = Card.NumAuxBanks;
for(UINT uBank = 1; uBank <= g_uMaxExPages; uBank++)
{
LPBYTE pBank = MemGetBankPtr(uBank);
if (!pBank)
{
pBank = RWpages[uBank-1] = (LPBYTE) VirtualAlloc(NULL,_6502_MEM_END+1,MEM_COMMIT,PAGE_READWRITE);
if (!pBank)
throw std::string("Card: mem alloc failed");
}
bRes = ReadFile( hFile,
pBank,
_6502_MEM_END+1,
&dwBytesRead,
NULL);
if (dwBytesRead != _6502_MEM_END+1)
throw std::string("Card: file corrupt");
}
memaux = RWpages[g_uActiveBank];
// NB. MemUpdatePaging(TRUE) called at end of Snapshot_LoadState_v2()
}

View File

@ -60,10 +60,6 @@ void MemSaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
bool MemLoadSnapshot(class YamlLoadHelper& yamlLoadHelper);
void MemSaveSnapshotAux(class YamlSaveHelper& yamlSaveHelper);
bool MemLoadSnapshotAux(class YamlLoadHelper& yamlLoadHelper, UINT version);
void MemGetSnapshot(struct SS_BaseMemory_v2& Memory);
void MemSetSnapshot(const struct SS_BaseMemory_v2& Memory);
void MemGetSnapshotAux(const HANDLE hFile);
void MemSetSnapshotAux(const HANDLE hFile);
BYTE __stdcall IO_Null(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles);

View File

@ -2206,276 +2206,3 @@ bool Phasor_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version
return true;
}
//===========================================================================
struct Mockingboard_Unit
{
SY6522 RegsSY6522;
SSI263A RegsSSI263;
BYTE AYCurrentRegister;
bool bTimer1IrqPending;
bool bTimer2IrqPending;
bool bSpeechIrqPending;
// SS_AY8910 AY8910; // Internal state of AY8910
};
struct SS_CARD_MOCKINGBOARD
{
SS_CARD_HDR Hdr;
Mockingboard_Unit Unit[NUM_MB_UNITS];
};
void MB_GetSnapshot(const HANDLE hFile, const UINT uSlot)
{
SS_CARD_MOCKINGBOARD Card;
Card.Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_MOCKINGBOARD);
Card.Hdr.UnitHdr.hdr.v2.Type = UT_Card;
Card.Hdr.UnitHdr.hdr.v2.Version = 1;
Card.Hdr.Slot = uSlot; // fixme: object should be just 1 Mockingboard card & it will know its slot
Card.Hdr.Type = CT_MockingboardC;
const UINT nMbCardNum = uSlot - SLOT4;
Card.Hdr.UnitHdr.hdr.v2.Length += AY8910_GetSnapshot(NULL, nMbCardNum*2+0);
Card.Hdr.UnitHdr.hdr.v2.Length += AY8910_GetSnapshot(NULL, nMbCardNum*2+1);
UINT uTotalWriteSize = DoWriteFile(hFile, &Card, (UINT)&Card.Unit-(UINT)&Card);
//
UINT nDeviceNum = nMbCardNum*2;
SY6522_AY8910* pMB = &g_MB[nDeviceNum];
for(UINT i=0; i<NUM_MB_UNITS; i++)
{
memcpy(&Card.Unit[i].RegsSY6522, &pMB->sy6522, sizeof(SY6522));
memcpy(&Card.Unit[i].RegsSSI263, &pMB->SpeechChip, sizeof(SSI263A));
Card.Unit[i].AYCurrentRegister = pMB->nAYCurrentRegister;
Card.Unit[i].bTimer1IrqPending = false;
Card.Unit[i].bTimer2IrqPending = false;
Card.Unit[i].bSpeechIrqPending = false;
uTotalWriteSize += DoWriteFile(hFile, &Card.Unit[i], sizeof(Card.Unit[0]));
uTotalWriteSize += AY8910_GetSnapshot(hFile, nDeviceNum);
nDeviceNum++;
pMB++;
}
_ASSERT(uTotalWriteSize == Card.Hdr.UnitHdr.hdr.v2.Length);
if (uTotalWriteSize != Card.Hdr.UnitHdr.hdr.v2.Length)
throw std::string("Card: unit size mismatch");
}
void MB_SetSnapshot(const HANDLE hFile)
{
SS_CARD_MOCKINGBOARD Card;
UINT uTotalReadSize = DoReadFile(hFile, &Card, (UINT)&Card.Unit-(UINT)&Card);
if (Card.Hdr.Slot != 4 && Card.Hdr.Slot != 5) // fixme
throw std::string("Card: wrong slot");
if (Card.Hdr.UnitHdr.hdr.v2.Version > 1)
throw std::string("Card: wrong version");
if (Card.Hdr.UnitHdr.hdr.v2.Length <= sizeof(SS_CARD_MOCKINGBOARD))
throw std::string("Card: unit size mismatch");
AY8910UpdateSetCycles();
const UINT nMbCardNum = Card.Hdr.Slot - SLOT4;
UINT nDeviceNum = nMbCardNum*2;
SY6522_AY8910* pMB = &g_MB[nDeviceNum];
g_nSSI263Device = 0;
g_nCurrentActivePhoneme = -1;
for(UINT i=0; i<NUM_MB_UNITS; i++)
{
uTotalReadSize += DoReadFile(hFile, &Card.Unit[i], sizeof(Card.Unit[0]));
memcpy(&pMB->sy6522, &Card.Unit[i].RegsSY6522, sizeof(SY6522));
memcpy(&pMB->SpeechChip, &Card.Unit[i].RegsSSI263, sizeof(SSI263A));
pMB->nAYCurrentRegister = Card.Unit[i].AYCurrentRegister;
StartTimer(pMB); // Attempt to start timer
//
// Crude - currently only support a single speech chip
// FIX THIS:
// . Speech chip could be Votrax instead
// . Is this IRQ compatible with Phasor?
if(pMB->SpeechChip.DurationPhoneme)
{
g_nSSI263Device = nDeviceNum;
if((pMB->SpeechChip.CurrentMode != MODE_IRQ_DISABLED) && (pMB->sy6522.PCR == 0x0C) && (pMB->sy6522.IER & IxR_PERIPHERAL))
{
pMB->sy6522.IFR |= IxR_PERIPHERAL;
UpdateIFR(pMB);
pMB->SpeechChip.CurrentMode |= 1; // Set SSI263's D7 pin
}
}
uTotalReadSize += AY8910_SetSnapshot(hFile, nDeviceNum);
nDeviceNum++;
pMB++;
}
_ASSERT(uTotalReadSize == Card.Hdr.UnitHdr.hdr.v2.Length);
if (uTotalReadSize != Card.Hdr.UnitHdr.hdr.v2.Length)
throw std::string("Card: unit size mismatch");
AY8910_InitClock((int)CLK_6502);
// Setup in MB_InitializeIO() -> MB_SetSoundcardType()
g_SoundcardType = CT_Empty;
g_bPhasorEnable = false;
}
//===========================================================================
struct Phasor_Unit
{
SY6522 RegsSY6522;
SSI263A RegsSSI263;
BYTE AYCurrentRegister;
bool bTimer1IrqPending;
bool bTimer2IrqPending;
bool bSpeechIrqPending;
// SS_AY8910 AY8910[2]; // Internal state of AY8910
};
struct SS_CARD_PHASOR
{
SS_CARD_HDR Hdr;
UINT ClockScaleFactor;
UINT Mode;
Phasor_Unit Unit[NUM_PHASOR_UNITS];
};
void Phasor_GetSnapshot(const HANDLE hFile)
{
SS_CARD_PHASOR Card;
Card.Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_PHASOR);
Card.Hdr.UnitHdr.hdr.v2.Type = UT_Card;
Card.Hdr.UnitHdr.hdr.v2.Version = 1;
const UINT uSlot = 4; // fixme
Card.Hdr.Slot = uSlot; // fixme: object should just be Phasor card & it will know its slot
Card.Hdr.Type = CT_Phasor;
Card.ClockScaleFactor = g_PhasorClockScaleFactor;
Card.Mode = g_nPhasorMode;
for (UINT i=0; i<4; i++)
Card.Hdr.UnitHdr.hdr.v2.Length += AY8910_GetSnapshot(NULL, i);
UINT uTotalWriteSize = DoWriteFile(hFile, &Card, (UINT)&Card.Unit-(UINT)&Card);
//
UINT nDeviceNum = 0;
SY6522_AY8910* pMB = &g_MB[0]; // fixme: Phasor uses MB's slot4(2x6522), slot4(2xSSI263), but slot4+5(4xAY8910)
for(UINT i=0; i<NUM_PHASOR_UNITS; i++)
{
memcpy(&Card.Unit[i].RegsSY6522, &pMB->sy6522, sizeof(SY6522));
memcpy(&Card.Unit[i].RegsSSI263, &pMB->SpeechChip, sizeof(SSI263A));
Card.Unit[i].AYCurrentRegister = pMB->nAYCurrentRegister;
Card.Unit[i].bTimer1IrqPending = false;
Card.Unit[i].bTimer2IrqPending = false;
Card.Unit[i].bSpeechIrqPending = false;
uTotalWriteSize += DoWriteFile(hFile, &Card.Unit[i], sizeof(Card.Unit[0]));
uTotalWriteSize += AY8910_GetSnapshot(hFile, nDeviceNum+0);
uTotalWriteSize += AY8910_GetSnapshot(hFile, nDeviceNum+1);
nDeviceNum += 2;
pMB++;
}
_ASSERT(uTotalWriteSize == Card.Hdr.UnitHdr.hdr.v2.Length);
if (uTotalWriteSize != Card.Hdr.UnitHdr.hdr.v2.Length)
throw std::string("Card: unit size mismatch");
}
void Phasor_SetSnapshot(const HANDLE hFile)
{
SS_CARD_PHASOR Card;
UINT uTotalReadSize = DoReadFile(hFile, &Card, (UINT)&Card.Unit-(UINT)&Card);
if (Card.Hdr.Slot != 4) // fixme
throw std::string("Card: wrong slot");
if (Card.Hdr.UnitHdr.hdr.v2.Version > 1)
throw std::string("Card: wrong version");
if (Card.Hdr.UnitHdr.hdr.v2.Length <= sizeof(SS_CARD_PHASOR))
throw std::string("Card: unit size mismatch");
g_PhasorClockScaleFactor = Card.ClockScaleFactor;
g_nPhasorMode = Card.Mode;
AY8910UpdateSetCycles();
UINT nDeviceNum = 0;
SY6522_AY8910* pMB = &g_MB[0];
g_nSSI263Device = 0;
g_nCurrentActivePhoneme = -1;
for(UINT i=0; i<NUM_PHASOR_UNITS; i++)
{
uTotalReadSize += DoReadFile(hFile, &Card.Unit[i], sizeof(Card.Unit[0]));
memcpy(&pMB->sy6522, &Card.Unit[i].RegsSY6522, sizeof(SY6522));
memcpy(&pMB->SpeechChip, &Card.Unit[i].RegsSSI263, sizeof(SSI263A));
pMB->nAYCurrentRegister = Card.Unit[i].AYCurrentRegister;
StartTimer(pMB); // Attempt to start timer
//
// Crude - currently only support a single speech chip
// FIX THIS:
// . Speech chip could be Votrax instead
// . Is this IRQ compatible with Phasor?
if(pMB->SpeechChip.DurationPhoneme)
{
g_nSSI263Device = nDeviceNum;
if((pMB->SpeechChip.CurrentMode != MODE_IRQ_DISABLED) && (pMB->sy6522.PCR == 0x0C) && (pMB->sy6522.IER & IxR_PERIPHERAL))
{
pMB->sy6522.IFR |= IxR_PERIPHERAL;
UpdateIFR(pMB);
pMB->SpeechChip.CurrentMode |= 1; // Set SSI263's D7 pin
}
}
//
uTotalReadSize += AY8910_SetSnapshot(hFile, nDeviceNum+0);
uTotalReadSize += AY8910_SetSnapshot(hFile, nDeviceNum+1);
nDeviceNum += 2;
pMB++;
}
_ASSERT(uTotalReadSize == Card.Hdr.UnitHdr.hdr.v2.Length);
if (uTotalReadSize != Card.Hdr.UnitHdr.hdr.v2.Length)
throw std::string("Card: unit size mismatch");
AY8910_InitClock((int)(CLK_6502 * g_PhasorClockScaleFactor));
// Setup in MB_InitializeIO() -> MB_SetSoundcardType()
g_SoundcardType = CT_Empty;
g_bPhasorEnable = false;
}

View File

@ -28,11 +28,7 @@ int MB_SetSnapshot_v1(const struct SS_CARD_MOCKINGBOARD_v1* const pSS, const
std::string MB_GetSnapshotCardName(void);
void MB_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, const UINT uSlot);
bool MB_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version);
void MB_GetSnapshot(const HANDLE hFile, const UINT uSlot);
void MB_SetSnapshot(const HANDLE hFile);
std::string Phasor_GetSnapshotCardName(void);
void Phasor_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, const UINT uSlot);
bool Phasor_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version);
void Phasor_GetSnapshot(const HANDLE hFile);
void Phasor_SetSnapshot(const HANDLE hFile);

View File

@ -760,166 +760,6 @@ bool CMouseInterface::LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT sl
return true;
}
struct MouseCard_Unit
{
//6821
mc6821_t mc6821;
BYTE byIA;
BYTE byIB;
//MouseCard
int nDataLen;
BYTE byMode;
BYTE by6821B;
BYTE by6821A;
BYTE byBuff[8];
int nBuffPos;
BYTE byState;
int nX;
int nY;
BOOL bBtn0;
BOOL bBtn1;
bool bVBL;
//
int iX;
int iMinX;
int iMaxX;
int iY;
int iMinY;
int iMaxY;
BOOL bButtons[2];
//
bool bActive; // Mouse h/w is active within the Apple][ VM
bool bEnabled; // Windows' mouse events get passed to Apple]['s mouse h/w
};
struct SS_CARD_MOUSECARD
{
SS_CARD_HDR Hdr;
MouseCard_Unit Unit;
};
// Post:
// 0 = No mouse card
// >0 = Mouse card saved OK from slot n
// -1 = File error
int CMouseInterface::GetSnapshot(const HANDLE hFile)
{
if (!m_bActive)
return 0;
SS_CARD_MOUSECARD CardMouseCard;
CardMouseCard.Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_MOUSECARD);
CardMouseCard.Hdr.UnitHdr.hdr.v2.Type = UT_Card;
CardMouseCard.Hdr.UnitHdr.hdr.v2.Version = 1;
CardMouseCard.Hdr.Slot = m_uSlot;
CardMouseCard.Hdr.Type = CT_MouseInterface;
MouseCard_Unit& Unit = CardMouseCard.Unit;
m_6821.Get6821(Unit.mc6821, Unit.byIA, Unit.byIB);
Unit.nDataLen = m_nDataLen;
Unit.byMode = m_byMode;
Unit.by6821B = m_by6821B;
Unit.by6821A = m_by6821A;
memcpy(Unit.byBuff, m_byBuff, sizeof(Unit.byBuff));
Unit.nBuffPos = m_nBuffPos;
Unit.byState = m_byState;
Unit.nX = m_nX;
Unit.nY = m_nY;
Unit.bBtn0 = m_bBtn0;
Unit.bBtn1 = m_bBtn1;
Unit.bVBL = m_bVBL;
Unit.iX = m_iX;
Unit.iMinX = m_iMinX;
Unit.iMaxX = m_iMaxX;
Unit.iY = m_iY;
Unit.iMinY = m_iMinY;
Unit.iMaxY = m_iMaxY;
Unit.bButtons[0] = m_bButtons[0];
Unit.bButtons[1] = m_bButtons[1];
Unit.bActive = m_bActive;
Unit.bEnabled = m_bEnabled;
//
DWORD dwBytesWritten;
BOOL bRes = WriteFile( hFile,
&CardMouseCard,
CardMouseCard.Hdr.UnitHdr.hdr.v2.Length,
&dwBytesWritten,
NULL);
if(!bRes || (dwBytesWritten != CardMouseCard.Hdr.UnitHdr.hdr.v2.Length))
throw std::string("Save error: Mouse");
return m_uSlot;
}
void CMouseInterface::SetSnapshot(const HANDLE hFile)
{
SS_CARD_MOUSECARD CardMouseCard;
DWORD dwBytesRead;
BOOL bRes = ReadFile( hFile,
&CardMouseCard,
sizeof(CardMouseCard),
&dwBytesRead,
NULL);
if (dwBytesRead != sizeof(CardMouseCard))
throw std::string("Card: file corrupt");
if (CardMouseCard.Hdr.Slot != 4) // fixme
throw std::string("Card: wrong slot");
if (CardMouseCard.Hdr.UnitHdr.hdr.v2.Version > 1)
throw std::string("Card: wrong version");
if (CardMouseCard.Hdr.UnitHdr.hdr.v2.Length != sizeof(SS_CARD_MOUSECARD))
throw std::string("Card: unit size mismatch");
const MouseCard_Unit& Unit = CardMouseCard.Unit;
m_6821.Set6821(Unit.mc6821, Unit.byIA, Unit.byIB);
m_nDataLen = Unit.nDataLen;
m_byMode = Unit.byMode;
m_by6821B = Unit.by6821B;
m_by6821A = Unit.by6821A;
memcpy(m_byBuff, Unit.byBuff, sizeof(Unit.byBuff));
m_nBuffPos = Unit.nBuffPos;
m_byState = Unit.byState;
m_nX = Unit.nX;
m_nY = Unit.nY;
m_bBtn0 = Unit.bBtn0;
m_bBtn1 = Unit.bBtn1;
m_bVBL = Unit.bVBL;
m_iX = Unit.iX;
m_iMinX = Unit.iMinX;
m_iMaxX = Unit.iMaxX;
m_iY = Unit.iY;
m_iMinY = Unit.iMinY;
m_iMaxY = Unit.iMaxY;
m_bButtons[0] = Unit.bButtons[0];
m_bButtons[1] = Unit.bButtons[1];
m_bActive = Unit.bActive;
//m_bEnabled = Unit.bEnabled;
//m_uSlot = CardMouseCard.Hdr.Slot;
}
//=============================================================================
// DirectInput interface
//=============================================================================

View File

@ -40,8 +40,6 @@ public:
std::string GetSnapshotCardName(void);
void SaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
bool LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version);
int GetSnapshot(const HANDLE hFile);
void SetSnapshot(const HANDLE hFile);
protected:
void SetSlotRom();

View File

@ -322,106 +322,3 @@ bool Printer_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT
return true;
}
//---
struct PrinterCard_Unit
{
DWORD Inactivity;
UINT PrinterIdleLimit;
char PrintFilename[MAX_PATH];
BOOL IsFileOpen;
BOOL DumpToPrinter;
BOOL ConvertEncoding;
BOOL FilterUnprintable;
BOOL PrinterAppend;
BOOL EnableDumpToRealPrinter;
};
struct SS_CARD_PRINTER
{
SS_CARD_HDR Hdr;
PrinterCard_Unit Unit;
};
void Printer_GetSnapshot(const HANDLE hFile)
{
SS_CARD_PRINTER CardPrinter;
SS_CARD_PRINTER* const pSS = &CardPrinter;
pSS->Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_PRINTER);
pSS->Hdr.UnitHdr.hdr.v2.Type = UT_Card;
pSS->Hdr.UnitHdr.hdr.v2.Version = 1;
pSS->Hdr.Slot = g_uSlot;
pSS->Hdr.Type = CT_GenericPrinter;
CardPrinter.Unit.Inactivity = inactivity;
CardPrinter.Unit.PrinterIdleLimit = g_iPrinterIdleLimit;
memcpy(CardPrinter.Unit.PrintFilename, g_szPrintFilename, sizeof(CardPrinter.Unit.PrintFilename));
CardPrinter.Unit.IsFileOpen = (file != NULL);
CardPrinter.Unit.DumpToPrinter = g_bDumpToPrinter;
CardPrinter.Unit.ConvertEncoding = g_bConvertEncoding;
CardPrinter.Unit.FilterUnprintable = g_bFilterUnprintable;
CardPrinter.Unit.PrinterAppend = g_bPrinterAppend;
CardPrinter.Unit.EnableDumpToRealPrinter = g_bEnableDumpToRealPrinter;
//
DWORD dwBytesWritten;
BOOL bRes = WriteFile( hFile,
&CardPrinter,
CardPrinter.Hdr.UnitHdr.hdr.v2.Length,
&dwBytesWritten,
NULL);
if(!bRes || (dwBytesWritten != CardPrinter.Hdr.UnitHdr.hdr.v2.Length))
{
//dwError = GetLastError();
throw std::string("Save error: Printer Card");
}
}
void Printer_SetSnapshot(const HANDLE hFile)
{
SS_CARD_PRINTER CardPrinter;
DWORD dwBytesRead;
BOOL bRes = ReadFile( hFile,
&CardPrinter,
sizeof(CardPrinter),
&dwBytesRead,
NULL);
if (dwBytesRead != sizeof(CardPrinter))
throw std::string("Card: file corrupt");
if (CardPrinter.Hdr.Slot != 1) // fixme
throw std::string("Card: wrong slot");
if (CardPrinter.Hdr.UnitHdr.hdr.v2.Version > 1)
throw std::string("Card: wrong version");
if (CardPrinter.Hdr.UnitHdr.hdr.v2.Length != sizeof(SS_CARD_PRINTER))
throw std::string("Card: unit size mismatch");
ClosePrint(); // Close current print session (and close file handle)
inactivity = CardPrinter.Unit.Inactivity;
g_iPrinterIdleLimit = CardPrinter.Unit.PrinterIdleLimit;
memcpy(g_szPrintFilename, CardPrinter.Unit.PrintFilename, sizeof(g_szPrintFilename));
if (CardPrinter.Unit.IsFileOpen)
{
g_bPrinterAppend = true; // Re-open print-file in append mode
BOOL bRes = CheckPrint();
if (!bRes)
throw std::string("Printer Card: Unable to resume printing to file");
}
g_bDumpToPrinter = CardPrinter.Unit.DumpToPrinter == TRUE;
g_bConvertEncoding = CardPrinter.Unit.ConvertEncoding == TRUE;
g_bFilterUnprintable = CardPrinter.Unit.FilterUnprintable == TRUE;
g_bPrinterAppend = CardPrinter.Unit.PrinterAppend == TRUE;
g_bEnableDumpToRealPrinter = CardPrinter.Unit.EnableDumpToRealPrinter == TRUE;
}

View File

@ -12,8 +12,6 @@ unsigned int Printer_GetIdleLimit();
std::string Printer_GetSnapshotCardName(void);
void Printer_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
bool Printer_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version);
void Printer_GetSnapshot(const HANDLE hFile);
void Printer_SetSnapshot(const HANDLE hFile);
extern bool g_bDumpToPrinter;
extern bool g_bConvertEncoding;

View File

@ -29,7 +29,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "StdAfx.h"
#include "SaveState_Structs_v1.h"
#include "SaveState_Structs_v2.h"
#include "YamlHelper.h"
#include "AppleWin.h"
@ -63,6 +62,11 @@ static std::string g_strSaveStatePath;
static YamlHelper yamlHelper;
#define SS_FILE_VER 2
#define UNIT_APPLE2_VER 1
#define UNIT_SLOTS_VER 1
//-----------------------------------------------------------------------------
void Snapshot_SetFilename(std::string strPathname)
@ -225,276 +229,6 @@ static void Snapshot_LoadState_v1() // .aws v1.0.0.1, up to (and including) Appl
static HANDLE m_hFile = INVALID_HANDLE_VALUE;
static CConfigNeedingRestart m_ConfigNew;
static void Snapshot_LoadState_FileHdr(SS_FILE_HDR& Hdr)
{
try
{
m_hFile = CreateFile( g_strSaveStatePathname.c_str(),
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(m_hFile == INVALID_HANDLE_VALUE)
throw std::string("File not found: ") + g_strSaveStatePathname;
DWORD dwBytesRead;
BOOL bRes = ReadFile( m_hFile,
&Hdr,
sizeof(Hdr),
&dwBytesRead,
NULL);
if(!bRes || (dwBytesRead != sizeof(Hdr)))
throw std::string("File size mismatch");
if(Hdr.dwTag != AW_SS_TAG)
throw std::string("File corrupt");
}
catch(std::string szMessage)
{
MessageBox( g_hFrameWindow,
szMessage.c_str(),
TEXT("Load State"),
MB_ICONEXCLAMATION | MB_SETFOREGROUND);
if(m_hFile == INVALID_HANDLE_VALUE)
{
CloseHandle(m_hFile);
m_hFile = INVALID_HANDLE_VALUE;
}
}
}
static void LoadUnitApple2(DWORD Length, DWORD Version)
{
if (Version != UNIT_APPLE2_VER)
throw std::string("Apple2: Version mismatch");
if (Length != sizeof(SS_APPLE2_Unit_v2))
throw std::string("Apple2: Length mismatch");
if (SetFilePointer(m_hFile, -(LONG)sizeof(SS_UNIT_HDR), NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER)
throw std::string("Apple2: file corrupt");
SS_APPLE2_Unit_v2 Apple2Unit;
DWORD dwBytesRead;
BOOL bRes = ReadFile( m_hFile,
&Apple2Unit,
Length,
&dwBytesRead,
NULL);
if (dwBytesRead != Length)
throw std::string("Apple2: file corrupt");
g_Apple2Type = (eApple2Type) Apple2Unit.Apple2Type;
m_ConfigNew.m_Apple2Type = g_Apple2Type;
CpuSetSnapshot(Apple2Unit.CPU6502);
JoySetSnapshot(Apple2Unit.Joystick.JoyCntrResetCycle, &Apple2Unit.Joystick.Joystick0Trim[0], &Apple2Unit.Joystick.Joystick1Trim[0]);
KeybSetSnapshot(Apple2Unit.Keyboard.LastKey);
SpkrSetSnapshot(Apple2Unit.Speaker.SpkrLastCycle);
VideoSetSnapshot(Apple2Unit.Video);
MemSetSnapshot(Apple2Unit.Memory);
}
//===
static void LoadCardDisk2(void)
{
DiskSetSnapshot(m_hFile);
}
static void LoadCardMockingboardC(void)
{
MB_SetSnapshot(m_hFile);
}
static void LoadCardMouseInterface(void)
{
sg_Mouse.SetSnapshot(m_hFile);
}
static void LoadCardSSC(void)
{
sg_SSC.SetSnapshot(m_hFile);
}
static void LoadCardPrinter(void)
{
Printer_SetSnapshot(m_hFile);
}
static void LoadCardHDD(void)
{
HD_SetSnapshot(m_hFile, g_strSaveStatePath);
m_ConfigNew.m_bEnableHDD = true;
}
static void LoadCardPhasor(void)
{
Phasor_SetSnapshot(m_hFile);
}
static void LoadCardZ80(void)
{
Z80_SetSnapshot(m_hFile);
}
static void LoadCard80ColAuxMem(void)
{
MemSetSnapshotAux(m_hFile);
}
//===
static void LoadUnitCard(DWORD Length, DWORD Version)
{
SS_CARD_HDR Card;
if (Version != UNIT_APPLE2_VER)
throw std::string("Card: Version mismatch");
if (Length < sizeof(Card))
throw std::string("Card: file corrupt");
if (SetFilePointer(m_hFile, -(LONG)sizeof(Card.UnitHdr), NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER)
throw std::string("Card: file corrupt");
DWORD dwBytesRead;
BOOL bRes = ReadFile( m_hFile,
&Card,
sizeof(Card),
&dwBytesRead,
NULL);
if (dwBytesRead != sizeof(Card))
throw std::string("Card: file corrupt");
//currently cards are changed by restarting machine (ie. all slot empty) then adding cards (most of which are hardcoded to specific slots)
if (SetFilePointer(m_hFile, -(LONG)sizeof(SS_CARD_HDR), NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER)
throw std::string("Card: file corrupt");
bool bIsCardSupported = true;
switch(Card.Type)
{
case CT_Empty:
throw std::string("Card: todo");
break;
case CT_Disk2:
LoadCardDisk2();
break;
case CT_SSC:
LoadCardSSC();
break;
case CT_MockingboardC:
LoadCardMockingboardC();
break;
case CT_GenericPrinter:
LoadCardPrinter();
break;
case CT_GenericHDD:
LoadCardHDD();
break;
case CT_MouseInterface:
LoadCardMouseInterface();
break;
case CT_Z80:
LoadCardZ80();
break;
case CT_Phasor:
LoadCardPhasor();
break;
case CT_80Col:
case CT_Extended80Col:
case CT_RamWorksIII:
LoadCard80ColAuxMem();
break;
default:
//throw std::string("Card: unsupported");
bIsCardSupported = false;
if (SetFilePointer(m_hFile, Card.UnitHdr.hdr.v2.Length, NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER)
throw std::string("Card: failed to skip unsupported card");
}
if (bIsCardSupported)
{
if (Card.Slot <= 7)
m_ConfigNew.m_Slot[Card.Slot] = (SS_CARDTYPE) Card.Type;
else
m_ConfigNew.m_SlotAux = (SS_CARDTYPE) Card.Type;
}
}
// Todo:
// . Should this newly loaded config state be persisted to the Registry?
// - NB. it will get saved if the user opens the Config dialog + makes a change. Is this confusing to the user?
// Notes:
// . WindowScale - don't think this needs restoring (eg. like FullScreen)
static void LoadUnitConfig(DWORD Length, DWORD Version)
{
SS_APPLEWIN_CONFIG Config;
if (Version != UNIT_CONFIG_VER)
throw std::string("Config: Version mismatch");
if (Length != sizeof(Config))
throw std::string("Config: Length mismatch");
if (SetFilePointer(m_hFile, -(LONG)sizeof(Config.UnitHdr), NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER)
throw std::string("Config: file corrupt");
DWORD dwBytesRead;
BOOL bRes = ReadFile( m_hFile,
&Config,
Length,
&dwBytesRead,
NULL);
if (dwBytesRead != Length)
throw std::string("Config: file corrupt");
// Restore all config state
//Config.Cfg.AppleWinVersion // Nothing to do
g_eVideoType = Config.Cfg.VideoMode;
g_uHalfScanLines = Config.Cfg.IsHalfScanLines;
g_bConfirmReboot = Config.Cfg.IsConfirmReboot;
monochrome = Config.Cfg.MonochromeColor;
//Config.Cfg.WindowScale // NB. Just calling SetViewportScale() is no good. Use PostMessage() instead.
g_dwSpeed = Config.Cfg.CpuSpeed;
SetCurrentCLK6502();
JoySetJoyType(JN_JOYSTICK0, Config.Cfg.JoystickType[0]);
JoySetJoyType(JN_JOYSTICK1, Config.Cfg.JoystickType[1]);
sg_PropertySheet.SetJoystickCursorControl(Config.Cfg.IsAllowCursorsToBeRead);
sg_PropertySheet.SetAutofire(Config.Cfg.IsAutofire);
sg_PropertySheet.SetJoystickCenteringControl(Config.Cfg.IsKeyboardAutocentering);
//Config.Cfg.IsSwapButton0and1; // TBD: not implemented yet
sg_PropertySheet.SetScrollLockToggle(Config.Cfg.IsScrollLockToggle);
sg_PropertySheet.SetMouseShowCrosshair(Config.Cfg.IsMouseShowCrosshair);
sg_PropertySheet.SetMouseRestrictToWindow(Config.Cfg.IsMouseRestrictToWindow);
soundtype = Config.Cfg.SoundType;
SpkrSetVolume(Config.Cfg.SpeakerVolume, sg_PropertySheet.GetVolumeMax());
MB_SetVolume(Config.Cfg.MockingboardVolume, sg_PropertySheet.GetVolumeMax());
enhancedisk = Config.Cfg.IsEnhancedDiskSpeed;
g_bSaveStateOnExit = Config.Cfg.IsSaveStateOnExit ? true : false;
g_bPrinterAppend = Config.Cfg.IsAppendToFile ? true : false;
sg_PropertySheet.SetTheFreezesF8Rom(Config.Cfg.IsUsingFreezesF8Rom);
}
//---
static std::string GetSnapshotUnitApple2Name(void)
{
static const std::string name("Apple2");
@ -532,9 +266,9 @@ static eApple2Type ParseApple2Type(std::string type)
throw std::string("Load: Unknown Apple2 type");
}
static std::string GetApple2Type(void)
static std::string GetApple2TypeAsString(void)
{
switch (g_Apple2Type)
switch ( GetApple2Type() )
{
case A2TYPE_APPLE2: return SS_YAML_VALUE_APPLE2;
case A2TYPE_APPLE2PLUS: return SS_YAML_VALUE_APPLE2PLUS;
@ -584,9 +318,12 @@ static void ParseUnitApple2(YamlLoadHelper& yamlLoadHelper, UINT version)
throw std::string(SS_YAML_KEY_UNIT ": Apple2: Version mismatch");
std::string model = yamlLoadHelper.GetMapValueSTRING(SS_YAML_KEY_MODEL);
g_Apple2Type = ParseApple2Type(model);
SetApple2Type( ParseApple2Type(model) ); // NB. Sets default main CPU type
m_ConfigNew.m_Apple2Type = GetApple2Type();
CpuLoadSnapshot(yamlLoadHelper); // NB. Overrides default main CPU type
m_ConfigNew.m_CpuType = GetMainCpu();
CpuLoadSnapshot(yamlLoadHelper);
JoyLoadSnapshot(yamlLoadHelper);
KeybLoadSnapshot(yamlLoadHelper);
SpkrLoadSnapshot(yamlLoadHelper);
@ -706,10 +443,6 @@ static void ParseUnit(void)
{
ParseSlots(yamlLoadHelper, version);
}
else if (unit == SS_YAML_VALUE_UNIT_CONFIG)
{
//...
}
else
{
throw std::string(SS_YAML_KEY_UNIT ": Unknown type: " ) + unit;
@ -758,12 +491,9 @@ static void Snapshot_LoadState_v2(void)
sg_Mouse.Reset();
HD_SetEnabled(false);
while(1)
std::string scalar;
while(yamlHelper.GetScalar(scalar))
{
std::string scalar;
if (!yamlHelper.GetScalar(scalar))
break;
if (scalar == SS_YAML_KEY_UNIT)
ParseUnit();
else
@ -784,6 +514,11 @@ static void Snapshot_LoadState_v2(void)
MemInitializeIO();
MemUpdatePaging(TRUE);
// g_Apple2Type may've changed: so redraw frame (title, buttons, leds, etc)
SetCharsetType();
VideoReinitialize(); // g_CharsetType changed
FrameUpdateApple2Type();
}
catch(std::string szMessage)
{
@ -798,199 +533,24 @@ static void Snapshot_LoadState_v2(void)
yamlHelper.FinaliseParser();
}
static void Snapshot_LoadState_v2(DWORD dwVersion)
{
try
{
if (dwVersion != MAKE_VERSION(2,0,0,0))
throw std::string("Version mismatch");
CConfigNeedingRestart ConfigOld;
ConfigOld.m_Slot[1] = CT_GenericPrinter; // fixme
ConfigOld.m_Slot[2] = CT_SSC; // fixme
//ConfigOld.m_Slot[3] = CT_Uthernet; // todo
ConfigOld.m_Slot[6] = CT_Disk2; // fixme
ConfigOld.m_Slot[7] = ConfigOld.m_bEnableHDD ? CT_GenericHDD : CT_Empty; // fixme
//ConfigOld.m_SlotAux = ?; // fixme
for (UINT i=0; i<NUM_SLOTS; i++)
m_ConfigNew.m_Slot[i] = CT_Empty;
m_ConfigNew.m_SlotAux = CT_Empty;
m_ConfigNew.m_bEnableHDD = false;
//m_ConfigNew.m_bEnableTheFreezesF8Rom = ?; // todo: when support saving config
//m_ConfigNew.m_bEnhanceDisk = ?; // todo: when support saving config
MemReset();
PravetsReset();
DiskReset();
KeybReset();
VideoResetState();
MB_Reset();
#ifdef USE_SPEECH_API
g_Speech.Reset();
#endif
sg_Mouse.Uninitialize();
sg_Mouse.Reset();
HD_SetEnabled(false);
while(1)
{
SS_UNIT_HDR UnitHdr;
DWORD dwBytesRead;
BOOL bRes = ReadFile( m_hFile,
&UnitHdr,
sizeof(UnitHdr),
&dwBytesRead,
NULL);
if (dwBytesRead == 0)
break; // EOF (OK)
if(!bRes || (dwBytesRead != sizeof(UnitHdr)))
throw std::string("File size mismatch");
switch (UnitHdr.hdr.v2.Type)
{
case UT_Apple2:
LoadUnitApple2(UnitHdr.hdr.v2.Length, UnitHdr.hdr.v2.Version);
break;
case UT_Card:
LoadUnitCard(UnitHdr.hdr.v2.Length, UnitHdr.hdr.v2.Version);
break;
case UT_Config:
LoadUnitConfig(UnitHdr.hdr.v2.Length, UnitHdr.hdr.v2.Version);
break;
default:
// Log then skip unsupported unit type
break;
}
}
SetLoadedSaveStateFlag(true);
// NB. The following disparity should be resolved:
// . A change in h/w via the Configuration property sheets results in a the VM completely restarting (via WM_USER_RESTART)
// . A change in h/w via loading a save-state avoids this VM restart
// The latter is the desired approach (as the former needs a "power-on" / F2 to start things again)
sg_PropertySheet.ApplyNewConfig(m_ConfigNew, ConfigOld);
MemInitializeROM();
MemInitializeCustomF8ROM();
MemInitializeIO();
MemUpdatePaging(TRUE);
}
catch(std::string szMessage)
{
MessageBox( g_hFrameWindow,
szMessage.c_str(),
TEXT("Load State"),
MB_ICONEXCLAMATION | MB_SETFOREGROUND);
PostMessage(g_hFrameWindow, WM_USER_RESTART, 0, 0); // Power-cycle VM (undoing all the new state just loaded)
}
CloseHandle(m_hFile);
m_hFile = INVALID_HANDLE_VALUE;
}
void Snapshot_LoadState()
{
const std::string ext_yaml = (".yaml");
const size_t pos = g_strSaveStatePathname.size() - ext_yaml.size();
if (g_strSaveStatePathname.find(ext_yaml, pos) != std::string::npos) // find ".yaml" at end of pathname
const std::string ext_aws = (".aws");
const size_t pos = g_strSaveStatePathname.size() - ext_aws.size();
if (g_strSaveStatePathname.find(ext_aws, pos) != std::string::npos) // find ".aws" at end of pathname
{
Snapshot_LoadState_v2();
return;
}
//
SS_FILE_HDR Hdr;
Snapshot_LoadState_FileHdr(Hdr);
if (m_hFile == INVALID_HANDLE_VALUE)
return;
if(Hdr.dwVersion <= MAKE_VERSION(1,0,0,1))
{
CloseHandle(m_hFile);
m_hFile = INVALID_HANDLE_VALUE;
Snapshot_LoadState_v1();
return;
}
Snapshot_LoadState_v2(Hdr.dwVersion);
Snapshot_LoadState_v2();
}
//-----------------------------------------------------------------------------
// Todo:
// . "Uthernet Active" - save this in slot3 card's state?
// Notes:
// . Full Screen - don't think this needs save/restoring
static void SaveUnitConfig()
{
SS_APPLEWIN_CONFIG Config;
memset(&Config, 0, sizeof(Config));
Config.UnitHdr.hdr.v2.Length = sizeof(Config);
Config.UnitHdr.hdr.v2.Type = UT_Config;
Config.UnitHdr.hdr.v2.Version = UNIT_CONFIG_VER;
//
memcpy(Config.Cfg.AppleWinVersion, GetAppleWinVersion(), sizeof(Config.Cfg.AppleWinVersion));
Config.Cfg.VideoMode = g_eVideoType;
Config.Cfg.IsHalfScanLines = g_uHalfScanLines;
Config.Cfg.IsConfirmReboot = g_bConfirmReboot;
Config.Cfg.MonochromeColor = monochrome;
Config.Cfg.WindowScale = GetViewportScale();
Config.Cfg.CpuSpeed = g_dwSpeed;
Config.Cfg.JoystickType[0] = JoyGetJoyType(JN_JOYSTICK0);
Config.Cfg.JoystickType[1] = JoyGetJoyType(JN_JOYSTICK1);
Config.Cfg.IsAllowCursorsToBeRead = sg_PropertySheet.GetJoystickCursorControl();
Config.Cfg.IsAutofire = (sg_PropertySheet.GetAutofire(1)<<1) | sg_PropertySheet.GetAutofire(0);
Config.Cfg.IsKeyboardAutocentering = sg_PropertySheet.GetJoystickCenteringControl();
Config.Cfg.IsSwapButton0and1 = 0; // TBD: not implemented yet
Config.Cfg.IsScrollLockToggle = sg_PropertySheet.GetScrollLockToggle();
Config.Cfg.IsMouseShowCrosshair = sg_PropertySheet.GetMouseShowCrosshair();
Config.Cfg.IsMouseRestrictToWindow = sg_PropertySheet.GetMouseRestrictToWindow();
Config.Cfg.SoundType = soundtype;
Config.Cfg.SpeakerVolume = SpkrGetVolume();
Config.Cfg.MockingboardVolume = MB_GetVolume();
Config.Cfg.IsEnhancedDiskSpeed = enhancedisk;
Config.Cfg.IsSaveStateOnExit = g_bSaveStateOnExit;
Config.Cfg.IsAppendToFile = g_bPrinterAppend;
Config.Cfg.IsUsingFreezesF8Rom = sg_PropertySheet.GetTheFreezesF8Rom();
//
DWORD dwBytesWritten;
BOOL bRes = WriteFile( m_hFile,
&Config,
Config.UnitHdr.hdr.v2.Length,
&dwBytesWritten,
NULL);
if(!bRes || (dwBytesWritten != Config.UnitHdr.hdr.v2.Length))
{
//dwError = GetLastError();
throw std::string("Save error: Config");
}
}
// todo:
// . Uthernet card
#if 1
void Snapshot_SaveState(void)
{
try
@ -1003,7 +563,7 @@ void Snapshot_SaveState(void)
yamlSaveHelper.UnitHdr(GetSnapshotUnitApple2Name(), UNIT_APPLE2_VER);
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE);
yamlSaveHelper.Save("%s: %s\n", SS_YAML_KEY_MODEL, GetApple2Type().c_str());
yamlSaveHelper.Save("%s: %s\n", SS_YAML_KEY_MODEL, GetApple2TypeAsString().c_str());
CpuSaveSnapshot(yamlSaveHelper);
JoySaveSnapshot(yamlSaveHelper);
KeybSaveSnapshot(yamlSaveHelper);
@ -1054,116 +614,6 @@ void Snapshot_SaveState(void)
MB_ICONEXCLAMATION | MB_SETFOREGROUND);
}
}
#else
void Snapshot_SaveState()
{
try
{
m_hFile = CreateFile( g_strSaveStatePathname.c_str(),
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
DWORD dwError = GetLastError();
_ASSERT((dwError == 0) || (dwError == ERROR_ALREADY_EXISTS));
// todo: handle ERROR_ALREADY_EXISTS - ask if user wants to replace existing file
// - at this point any old file will have been truncated to zero
if(m_hFile == INVALID_HANDLE_VALUE)
{
//dwError = GetLastError();
throw std::string("Save error");
}
//
APPLEWIN_SNAPSHOT_v2 AppleSnapshot;
AppleSnapshot.Hdr.dwTag = AW_SS_TAG;
AppleSnapshot.Hdr.dwVersion = MAKE_VERSION(2,0,0,0);
AppleSnapshot.Hdr.dwChecksum = 0; // TO DO
SS_APPLE2_Unit_v2& Apple2Unit = AppleSnapshot.Apple2Unit;
//
// Apple2 unit
//
Apple2Unit.UnitHdr.hdr.v2.Length = sizeof(Apple2Unit);
Apple2Unit.UnitHdr.hdr.v2.Type = UT_Apple2;
Apple2Unit.UnitHdr.hdr.v2.Version = UNIT_APPLE2_VER;
Apple2Unit.Apple2Type = g_Apple2Type;
CpuGetSnapshot(Apple2Unit.CPU6502);
JoyGetSnapshot(Apple2Unit.Joystick.JoyCntrResetCycle, &Apple2Unit.Joystick.Joystick0Trim[0], &Apple2Unit.Joystick.Joystick1Trim[0]);
KeybGetSnapshot(Apple2Unit.Keyboard.LastKey);
SpkrGetSnapshot(Apple2Unit.Speaker.SpkrLastCycle);
VideoGetSnapshot(Apple2Unit.Video);
MemGetSnapshot(Apple2Unit.Memory);
DWORD dwBytesWritten;
BOOL bRes = WriteFile( m_hFile,
&AppleSnapshot,
sizeof(AppleSnapshot),
&dwBytesWritten,
NULL);
if(!bRes || (dwBytesWritten != sizeof(AppleSnapshot)))
{
//dwError = GetLastError();
throw std::string("Save error");
}
//
MemGetSnapshotAux(m_hFile);
Printer_GetSnapshot(m_hFile);
sg_SSC.GetSnapshot(m_hFile);
sg_Mouse.GetSnapshot(m_hFile);
if (g_Slot4 == CT_Z80)
Z80_GetSnapshot(m_hFile, 4);
if (g_Slot5 == CT_Z80)
Z80_GetSnapshot(m_hFile, 5);
if (g_Slot4 == CT_MockingboardC)
MB_GetSnapshot(m_hFile, 4);
if (g_Slot5 == CT_MockingboardC)
MB_GetSnapshot(m_hFile, 5);
if (g_Slot4 == CT_Phasor)
Phasor_GetSnapshot(m_hFile);
DiskGetSnapshot(m_hFile);
HD_GetSnapshot(m_hFile);
//
SaveUnitConfig();
}
catch(std::string szMessage)
{
MessageBox( g_hFrameWindow,
szMessage.c_str(),
TEXT("Save State"),
MB_ICONEXCLAMATION | MB_SETFOREGROUND);
}
CloseHandle(m_hFile);
m_hFile = INVALID_HANDLE_VALUE;
}
#endif
//-----------------------------------------------------------------------------

View File

@ -1,129 +0,0 @@
#pragma once
#include "SaveState_Structs_common.h"
// Structs used by save-state file v2
// *** DON'T CHANGE ANY STRUCT WITHOUT CONSIDERING BACKWARDS COMPATIBILITY WITH .AWS FORMAT ***
/////////////////////////////////////////////////////////////////////////////////
#define SS_FILE_VER 2
#define UNIT_APPLE2_VER 1
#define UNIT_SLOTS_VER 1
#define UNIT_CONFIG_VER 1
struct SS_CPU6502_v2
{
BYTE A;
BYTE X;
BYTE Y;
BYTE P;
BYTE S;
USHORT PC;
unsigned __int64 CumulativeCycles;
// IRQ = OR-sum of all interrupt sources
};
struct SS_IO_Joystick_v2
{
unsigned __int64 JoyCntrResetCycle;
short Joystick0Trim[2]; // [x,y]
short Joystick1Trim[2]; // [x,y]
};
struct SS_IO_Keyboard_v2
{
BYTE LastKey;
};
struct SS_IO_Speaker_v2
{
unsigned __int64 SpkrLastCycle;
};
struct SS_IO_Video_v2
{
UINT32 AltCharSet;
UINT32 VideoMode;
UINT32 CyclesThisVideoFrame;
};
struct SS_BaseMemory_v2
{
DWORD dwMemMode;
BOOL bLastWriteRam;
BYTE IO_SELECT;
BYTE IO_SELECT_InternalROM;
UINT ExpansionRomType;
UINT PeripheralRomSlot;
BYTE MemMain[nMemMainSize];
};
struct SS_APPLE2_Unit_v2
{
SS_UNIT_HDR UnitHdr;
UINT32 Apple2Type;
SS_CPU6502_v2 CPU6502;
SS_IO_Joystick_v2 Joystick;
SS_IO_Keyboard_v2 Keyboard;
SS_IO_Speaker_v2 Speaker;
SS_IO_Video_v2 Video;
SS_BaseMemory_v2 Memory;
};
/////////////////////////////////////////////////////////////////////////////////
#pragma pack(push,4) // push current alignment to stack & set alignment to 4
// - need so that 12-byte Hdr doesn't get padded to 16 bytes
// - NB. take care not to affect the old v2 structs
struct APPLEWIN_SNAPSHOT_v2
{
SS_FILE_HDR Hdr;
SS_APPLE2_Unit_v2 Apple2Unit;
// SS_CARD_EMPTY[8] Slots; // Slot 0..7 (0=language card for Apple][)
// SS_CARD_EMPTY AuxSlot; // Apple//e auxiliary slot (including optional RAMworks memory)
// SS_APPLEWIN_CONFIG AppleWinCfg;
};
#pragma pack(pop)
/////////////////////////////////////////////////////////////////////////////////
struct SS_AW_CFG
{
UINT16 AppleWinVersion[4]; // major,minor,fix,fix_minor
UINT32 VideoMode;
UINT32 IsHalfScanLines;
UINT32 IsConfirmReboot;
UINT32 MonochromeColor;
UINT32 WindowScale;
UINT32 CpuSpeed;
//
UINT32 JoystickType[2];
UINT32 IsAllowCursorsToBeRead;
UINT32 IsAutofire;
UINT32 IsKeyboardAutocentering;
UINT32 IsSwapButton0and1;
UINT32 IsScrollLockToggle;
UINT32 IsMouseShowCrosshair;
UINT32 IsMouseRestrictToWindow;
//
UINT32 SoundType;
UINT32 SpeakerVolume;
UINT32 MockingboardVolume;
//
UINT32 IsEnhancedDiskSpeed;
UINT32 IsSaveStateOnExit;
//
UINT32 IsAppendToFile;
UINT32 IsUsingFreezesF8Rom;
};
struct SS_APPLEWIN_CONFIG
{
SS_UNIT_HDR UnitHdr;
SS_AW_CFG Cfg;
};

View File

@ -1425,124 +1425,3 @@ bool CSuperSerialCard::LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT slot, U
return true;
}
//---
struct SSC_Unit
{
SSC_DIPSW DIPSWDefault;
SSC_DIPSW DIPSWCurrent;
DWORD uBaudRate;
BYTE uStopBits;
BYTE uByteSize;
BYTE uParity;
BYTE uControlByte;
BYTE uCommandByte;
DWORD dwCommInactivity; // If non-zero then COM port open
bool bTxIrqEnabled;
bool bRxIrqEnabled;
bool vbTxIrqPending;
bool vbRxIrqPending;
bool bWrittenTx;
char SerialPortName[8];
};
struct SS_CARD_SSC
{
SS_CARD_HDR Hdr;
SSC_Unit Unit;
};
void CSuperSerialCard::GetSnapshot(const HANDLE hFile)
{
SS_CARD_SSC CardSuperSerial;
CardSuperSerial.Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_SSC);
CardSuperSerial.Hdr.UnitHdr.hdr.v2.Type = UT_Card;
CardSuperSerial.Hdr.UnitHdr.hdr.v2.Version = 1;
CardSuperSerial.Hdr.Slot = m_uSlot;
CardSuperSerial.Hdr.Type = CT_SSC;
SSC_Unit& Unit = CardSuperSerial.Unit;
Unit.DIPSWDefault = m_DIPSWDefault;
Unit.DIPSWCurrent = m_DIPSWCurrent;
Unit.uBaudRate = m_uBaudRate;
Unit.uStopBits = m_uStopBits;
Unit.uByteSize = m_uByteSize;
Unit.uParity = m_uParity;
Unit.uControlByte = m_uControlByte;
Unit.uCommandByte = m_uCommandByte;
Unit.dwCommInactivity = m_dwCommInactivity;
Unit.bTxIrqEnabled = m_bTxIrqEnabled;
Unit.bRxIrqEnabled = m_bRxIrqEnabled;
Unit.vbTxIrqPending = m_vbTxIrqPending;
Unit.vbRxIrqPending = m_vbRxIrqPending;
Unit.bWrittenTx = m_bWrittenTx;
strncpy_s(Unit.SerialPortName, sizeof(Unit.SerialPortName), GetSerialPortName(), _TRUNCATE);
//
DWORD dwBytesWritten;
BOOL bRes = WriteFile( hFile,
&CardSuperSerial,
CardSuperSerial.Hdr.UnitHdr.hdr.v2.Length,
&dwBytesWritten,
NULL);
if(!bRes || (dwBytesWritten != CardSuperSerial.Hdr.UnitHdr.hdr.v2.Length))
throw std::string("Save error: SSC");
}
void CSuperSerialCard::SetSnapshot(const HANDLE hFile)
{
SS_CARD_SSC CardSuperSerial;
DWORD dwBytesRead;
BOOL bRes = ReadFile( hFile,
&CardSuperSerial,
sizeof(CardSuperSerial),
&dwBytesRead,
NULL);
if (dwBytesRead != sizeof(CardSuperSerial))
throw std::string("Card: file corrupt");
if (CardSuperSerial.Hdr.Slot != 2) // fixme
throw std::string("Card: wrong slot");
if (CardSuperSerial.Hdr.UnitHdr.hdr.v2.Version != 1)
throw std::string("Card: wrong version");
if (CardSuperSerial.Hdr.UnitHdr.hdr.v2.Length != sizeof(SS_CARD_SSC))
throw std::string("Card: unit size mismatch");
SSC_Unit& Unit = CardSuperSerial.Unit;
m_DIPSWDefault = Unit.DIPSWDefault;
m_DIPSWCurrent = Unit.DIPSWCurrent;
m_uBaudRate = Unit.uBaudRate;
m_uStopBits = Unit.uStopBits;
m_uByteSize = Unit.uByteSize;
m_uParity = Unit.uParity;
m_uControlByte = Unit.uControlByte;
m_uCommandByte = Unit.uCommandByte;
m_dwCommInactivity = Unit.dwCommInactivity;
m_bTxIrqEnabled = Unit.bTxIrqEnabled;
m_bRxIrqEnabled = Unit.bRxIrqEnabled;
m_vbTxIrqPending = Unit.vbTxIrqPending;
m_vbRxIrqPending = Unit.vbRxIrqPending;
m_bWrittenTx = Unit.bWrittenTx;
SetSerialPortName(Unit.SerialPortName);
}

View File

@ -37,8 +37,6 @@ public:
std::string GetSnapshotCardName(void);
void SaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
bool LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version);
void GetSnapshot(const HANDLE hFile);
void SetSnapshot(const HANDLE hFile);
char* GetSerialPortChoices();
DWORD GetSerialPort() { return m_dwSerialPortItem; } // Drop-down list item

View File

@ -1123,15 +1123,3 @@ void SpkrLoadSnapshot(YamlLoadHelper& yamlLoadHelper)
yamlLoadHelper.PopMap();
}
//
void SpkrGetSnapshot(unsigned __int64& rSpkrLastCycle)
{
rSpkrLastCycle = g_nSpkrLastCycle;
}
void SpkrSetSnapshot(const unsigned __int64 SpkrLastCycle)
{
g_nSpkrLastCycle = SpkrLastCycle;
}

View File

@ -29,7 +29,5 @@ void Spkr_DSUninit();
void SpkrSetSnapshot_v1(const unsigned __int64 SpkrLastCycle);
void SpkrSaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
void SpkrLoadSnapshot(class YamlLoadHelper& yamlLoadHelper);
void SpkrGetSnapshot(unsigned __int64& rSpkrLastCycle);
void SpkrSetSnapshot(const unsigned __int64 SpkrLastCycle);
BYTE __stdcall SpkrToggle (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);

View File

@ -39,7 +39,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "..\resource\resource.h"
#include "Configuration\PropertySheet.h"
#include "Debugger\Debugger_Color.h" // For NUM_DEBUG_COLORS
#include "SaveState_Structs_v2.h"
#include "YamlHelper.h"
#define HALF_PIXEL_SOLID 1
@ -2981,22 +2980,6 @@ void VideoLoadSnapshot(YamlLoadHelper& yamlLoadHelper)
yamlLoadHelper.PopMap();
}
//
void VideoGetSnapshot(SS_IO_Video_v2& Video)
{
Video.AltCharSet = !(g_nAltCharSetOffset == 0);
Video.VideoMode = g_uVideoMode;
Video.CyclesThisVideoFrame = g_dwCyclesThisFrame;
}
void VideoSetSnapshot(const SS_IO_Video_v2& Video)
{
g_nAltCharSetOffset = !Video.AltCharSet ? 0 : 256;
g_uVideoMode = Video.VideoMode;
g_dwCyclesThisFrame = Video.CyclesThisVideoFrame;
}
//===========================================================================
//
// References to Jim Sather's books are given as eg:

View File

@ -88,8 +88,6 @@ void VideoSetForceFullRedraw(void);
void VideoSetSnapshot_v1(const UINT AltCharSet, const UINT VideoMode);
void VideoSaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
void VideoLoadSnapshot(class YamlLoadHelper& yamlLoadHelper);
void VideoGetSnapshot(struct SS_IO_Video_v2& Video);
void VideoSetSnapshot(const struct SS_IO_Video_v2& Video);
void _Video_Dirty();
void _Video_RedrawScreen( VideoUpdateFuncPtr_t update, bool bMixed = false );

View File

@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "StdAfx.h"
#include "Log.h"
#include "YamlHelper.h"
int YamlHelper::InitParser(const char* pPathname)
@ -58,20 +59,6 @@ void YamlHelper::GetNextEvent(bool bInMap /*= false*/)
//printf("Parser error %d\n", m_parser.error);
throw std::string("Parser error");
}
if (m_newEvent.type == YAML_MAPPING_START_EVENT)
{
MapState state = {m_mapName, bInMap};
m_stackMapState.push(state);
}
else if (m_newEvent.type == YAML_MAPPING_END_EVENT)
{
MapState state = m_stackMapState.top();
m_lastMapName = m_mapName; // For GetMapRemainder()
m_mapName = state.name;
// ? = state.isInMap;
m_stackMapState.pop();
}
}
int YamlHelper::GetScalar(std::string& scalar)
@ -108,28 +95,6 @@ int YamlHelper::GetScalar(std::string& scalar)
return res;
}
void YamlHelper::GetListStartEvent(void)
{
GetNextEvent();
if (m_newEvent.type != YAML_SEQUENCE_START_EVENT)
{
//printf("Unexpected yaml event (%d)\n", m_newEvent.type);
throw std::string("Unexpected yaml event");
}
}
//void YamlHelper::GetListEndEvent(void)
//{
// GetNextEvent();
//
// if (m_newEvent.type != YAML_SEQUENCE_END_EVENT)
// {
// //printf("Unexpected yaml event (%d)\n", m_newEvent.type);
// throw std::string("Unexpected yaml event");
// }
//}
void YamlHelper::GetMapStartEvent(void)
{
GetNextEvent();
@ -141,32 +106,6 @@ void YamlHelper::GetMapStartEvent(void)
}
}
void YamlHelper::GetMapEndEvent(void)
{
GetNextEvent();
if (m_newEvent.type != YAML_MAPPING_END_EVENT)
{
//printf("Unexpected yaml event (%d)\n", m_newEvent.type);
throw std::string("Unexpected yaml event");
}
}
int YamlHelper::GetMapStartOrListEndEvent(void)
{
GetNextEvent();
if (m_newEvent.type != YAML_MAPPING_START_EVENT && m_newEvent.type != YAML_SEQUENCE_END_EVENT)
{
//printf("Unexpected yaml event (%d)\n", m_newEvent.type);
throw std::string("Unexpected yaml event");
}
return m_newEvent.type == YAML_MAPPING_START_EVENT ? 1 : 0;
}
//
int YamlHelper::ParseMap(MapYaml& mapYaml)
{
mapYaml.clear();
@ -260,21 +199,21 @@ bool YamlHelper::GetSubMap(MapYaml** mapYaml, const std::string key)
return true;
}
void YamlHelper::GetMapRemainder(MapYaml& mapYaml)
void YamlHelper::GetMapRemainder(std::string& mapName, MapYaml& mapYaml)
{
for (MapYaml::iterator iter = mapYaml.begin(); iter != mapYaml.end(); ++iter)
{
if (iter->second.subMap)
{
GetMapRemainder(*iter->second.subMap);
std::string subMapName(iter->first);
GetMapRemainder(subMapName, *iter->second.subMap);
delete iter->second.subMap;
}
else
{
const char* pKey = iter->first.c_str();
char szDbg[100];
sprintf(szDbg, "%s: Unknown key (%s)\n", m_lastMapName.c_str(), pKey);
OutputDebugString(szDbg);
LogOutput("%s: Unknown key (%s)\n", mapName.c_str(), pKey);
LogFileOutput("%s: Unknown key (%s)\n", mapName.c_str(), pKey);
}
}

View File

@ -6,14 +6,11 @@
#define SS_YAML_KEY_TAG "Tag"
#define SS_YAML_KEY_VERSION "Version"
#define SS_YAML_KEY_UNIT "Unit"
#define SS_YAML_KEY_UNIT_TYPE "Type"
#define SS_YAML_KEY_TYPE "Type"
#define SS_YAML_KEY_CARD "Card"
#define SS_YAML_KEY_STATE "State"
#define SS_YAML_VALUE_AWSS "AppleWin Save State"
#define SS_YAML_VALUE_UNIT_CARD "Card"
#define SS_YAML_VALUE_UNIT_CONFIG "Config"
struct MapValue;
typedef std::map<std::string, MapValue> MapYaml;
@ -44,21 +41,16 @@ public:
int InitParser(const char* pPathname);
void FinaliseParser(void);
void GetNextEvent(bool bInMap = false);
int GetScalar(std::string& scalar);
void GetListStartEvent(void);
// void GetListEndEvent(void);
void GetMapStartEvent(void);
void GetMapEndEvent(void);
int GetMapStartOrListEndEvent(void);
std::string GetMapName(void) { return m_mapName; }
private:
void GetNextEvent(bool bInMap = false);
int ParseMap(MapYaml& mapYaml);
std::string GetMapValue(MapYaml& mapYaml, const std::string key, bool& bFound);
void GetMapValueMemory(MapYaml& mapYaml, const LPBYTE pMemBase, const size_t kAddrSpaceSize);
bool GetSubMap(MapYaml** mapYaml, const std::string key);
void GetMapRemainder(MapYaml& mapYaml);
void GetMapRemainder(std::string& mapName, MapYaml& mapYaml);
void MakeAsciiToHexTable(void);
@ -70,19 +62,6 @@ private:
FILE* m_hFile;
char m_AsciiToHex[256];
//
std::string m_lastMapName;
std::string m_mapName;
struct MapState
{
std::string name;
bool isInMap;
};
std::stack< MapState > m_stackMapState;
MapYaml m_mapYaml;
};
@ -94,22 +73,33 @@ public:
YamlLoadHelper(YamlHelper& yamlHelper)
: m_yamlHelper(yamlHelper),
m_pMapYaml(&yamlHelper.m_mapYaml),
m_bIteratingOverMap(false)
m_bIteratingOverMap(false),
m_bDoGetMapRemainder(true),
m_topLevelMapName(yamlHelper.m_scalarName),
m_currentMapName(m_topLevelMapName)
{
if (!m_yamlHelper.ParseMap(yamlHelper.m_mapYaml))
throw std::string(m_yamlHelper.GetMapName() + ": Failed to parse map");
{
m_bDoGetMapRemainder = false;
throw std::string(m_currentMapName + ": Failed to parse map");
}
}
~YamlLoadHelper(void)
{
m_yamlHelper.GetMapRemainder(m_yamlHelper.m_mapYaml);
if (m_bDoGetMapRemainder)
m_yamlHelper.GetMapRemainder(m_topLevelMapName, m_yamlHelper.m_mapYaml);
}
INT GetMapValueINT(const std::string key)
{
bool bFound;
std::string value = m_yamlHelper.GetMapValue(*m_pMapYaml, key, bFound);
if (value == "") throw std::string(m_yamlHelper.GetMapName() + ": Missing: " + key);
if (value == "")
{
m_bDoGetMapRemainder = false;
throw std::string(m_currentMapName + ": Missing: " + key);
}
return strtol(value.c_str(), NULL, 0);
}
@ -117,7 +107,11 @@ public:
{
bool bFound;
std::string value = m_yamlHelper.GetMapValue(*m_pMapYaml, key, bFound);
if (value == "") throw std::string(m_yamlHelper.GetMapName() + ": Missing: " + key);
if (value == "")
{
m_bDoGetMapRemainder = false;
throw std::string(m_currentMapName + ": Missing: " + key);
}
return strtoul(value.c_str(), NULL, 0);
}
@ -125,7 +119,11 @@ public:
{
bool bFound;
std::string value = m_yamlHelper.GetMapValue(*m_pMapYaml, key, bFound);
if (value == "") throw std::string(m_yamlHelper.GetMapName() + ": Missing: " + key);
if (value == "")
{
m_bDoGetMapRemainder = false;
throw std::string(m_currentMapName + ": Missing: " + key);
}
return _strtoui64(value.c_str(), NULL, 0);
}
@ -149,7 +147,11 @@ public:
{
bool bFound;
std::string value = GetMapValueSTRING_NoThrow(key, bFound);
if (!bFound) throw std::string(m_yamlHelper.GetMapName() + ": Missing: " + key);
if (!bFound)
{
m_bDoGetMapRemainder = false;
throw std::string(m_currentMapName + ": Missing: " + key);
}
return value;
}
@ -160,10 +162,13 @@ public:
bool GetSubMap(const std::string key)
{
m_stackMap.push(m_pMapYaml);
YamlStackItem item = {m_pMapYaml, m_currentMapName};
m_stackMap.push(item);
bool res = m_yamlHelper.GetSubMap(&m_pMapYaml, key);
if (!res)
m_stackMap.pop();
else
m_currentMapName = key;
return res;
}
@ -172,8 +177,11 @@ public:
if (m_stackMap.empty())
return;
m_pMapYaml = m_stackMap.top();
YamlStackItem item = m_stackMap.top();
m_stackMap.pop();
m_pMapYaml = item.pMapYaml;
m_currentMapName = item.mapName;
}
std::string GetMapNextSlotNumber(void)
@ -198,7 +206,17 @@ public:
private:
YamlHelper& m_yamlHelper;
MapYaml* m_pMapYaml;
std::stack<MapYaml*> m_stackMap;
bool m_bDoGetMapRemainder;
struct YamlStackItem
{
MapYaml* pMapYaml;
std::string mapName;
};
std::stack<YamlStackItem> m_stackMap;
std::string m_topLevelMapName;
std::string m_currentMapName;
bool m_bIteratingOverMap;
MapYaml::iterator m_iter;
@ -209,6 +227,7 @@ private:
class YamlSaveHelper
{
friend class Indent; // Indent can access YamlSaveHelper's private members
public:
YamlSaveHelper(std::string pathname) :
m_hFile(NULL),

View File

@ -6339,7 +6339,7 @@ DWORD z80_mainloop(ULONG uTotalCycles, ULONG uExecutedCycles)
//cpu_int_status->num_dma_per_opcode = 0; // [AppleWin-TC] Not used
if (g_ActiveCPU != CPU_Z80) // [AppleWin-TC]
if (GetActiveCpu() != CPU_Z80) // [AppleWin-TC]
break;
//} while (!dma_request);
@ -6482,14 +6482,14 @@ void Z80_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, const UINT uSlot)
// NB. Not for 65C02 which is a static processor.
// . SoftCard controls the 6502's RDY line to periodically allow only 1 memory fetch by 6502 (ie. the opcode fetch)
//
// So save /g_ActiveCPU/ to SS_CARD_Z80 (so RDY is like IRQ & NMI signals, ie. saved struct of the producer's card)
// So save ActiveCPU to SS_CARD_Z80 (so RDY is like IRQ & NMI signals, ie. saved struct of the producer's card)
//
// NB. Save-state only occurs when message pump runs:
// . ie. at end of 1ms emulation burst
// Either 6502 or Z80 could be active.
//
yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_ACTIVE, g_ActiveCPU == CPU_Z80 ? 1 : 0);
yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_ACTIVE, GetActiveCpu() == CPU_Z80 ? 1 : 0);
yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGA, reg_a);
yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGB, reg_b);
@ -6563,185 +6563,7 @@ bool Z80_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT uSlot, UINT ver
export_registers();
if ( yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_ACTIVE) )
g_ActiveCPU = CPU_Z80; // Support MS SoftCard in multiple slots (only one Z80 can be active at any one time)
SetActiveCpu(CPU_Z80); // Support MS SoftCard in multiple slots (only one Z80 can be active at any one time)
return true;
}
//---
struct Z80_Unit
{
BYTE reg_a;
BYTE reg_b;
BYTE reg_c;
BYTE reg_d;
BYTE reg_e;
BYTE reg_f;
BYTE reg_h;
BYTE reg_l;
BYTE reg_ixh;
BYTE reg_ixl;
BYTE reg_iyh;
BYTE reg_iyl;
WORD reg_sp;
DWORD z80_reg_pc;
BYTE reg_i;
BYTE reg_r;
BYTE iff1;
BYTE iff2;
BYTE im_mode;
BYTE reg_a2;
BYTE reg_b2;
BYTE reg_c2;
BYTE reg_d2;
BYTE reg_e2;
BYTE reg_f2;
BYTE reg_h2;
BYTE reg_l2;
};
struct SS_CARD_Z80
{
SS_CARD_HDR Hdr;
Z80_Unit Unit;
UINT Active;
};
void Z80_GetSnapshot(const HANDLE hFile, const UINT uZ80Slot)
{
SS_CARD_Z80 Card;
SS_CARD_Z80* const pSS = &Card;
pSS->Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_Z80);
pSS->Hdr.UnitHdr.hdr.v2.Type = UT_Card;
pSS->Hdr.UnitHdr.hdr.v2.Version = 1;
pSS->Hdr.Slot = uZ80Slot; // fixme: object should know its slot
pSS->Hdr.Type = CT_Z80;
pSS->Unit.reg_a = reg_a;
pSS->Unit.reg_b = reg_b;
pSS->Unit.reg_c = reg_c;
pSS->Unit.reg_d = reg_d;
pSS->Unit.reg_e = reg_e;
pSS->Unit.reg_f = reg_f;
pSS->Unit.reg_h = reg_h;
pSS->Unit.reg_l = reg_l;
pSS->Unit.reg_ixh = reg_ixh;
pSS->Unit.reg_ixl = reg_ixl;
pSS->Unit.reg_iyh = reg_iyh;
pSS->Unit.reg_iyl = reg_iyl;
pSS->Unit.reg_sp = reg_sp;
pSS->Unit.z80_reg_pc = z80_reg_pc;
pSS->Unit.reg_i = reg_i;
pSS->Unit.reg_r = reg_r;
pSS->Unit.iff1 = iff1;
pSS->Unit.iff2 = iff2;
pSS->Unit.im_mode = im_mode;
pSS->Unit.reg_a2 = reg_a2;
pSS->Unit.reg_b2 = reg_b2;
pSS->Unit.reg_c2 = reg_c2;
pSS->Unit.reg_d2 = reg_d2;
pSS->Unit.reg_e2 = reg_e2;
pSS->Unit.reg_f2 = reg_f2;
pSS->Unit.reg_h2 = reg_h2;
pSS->Unit.reg_l2 = reg_l2;
// SoftCard SW & HW details: http://apple2info.net/images/f/f0/SC-SWHW.pdf
// . SoftCard uses the Apple II's DMA circuit to pause the 6502 (no CLK to 6502)
// . But: "In Apple II DMA, the 6502 CPU will die after approximately 15 clocks because it depends on the clock to refresh its internal registers."
// ref: Apple Tech Note: https://archive.org/stream/IIe_2523004_RDY_Line/IIe_2523004_RDY_Line_djvu.txt
// NB. Not for 65C02 which is a static processor.
// . SoftCard controls the 6502's RDY line to periodically allow only 1 memory fetch by 6502 (ie. the opcode fetch)
//
// So save /g_ActiveCPU/ to SS_CARD_Z80 (so RDY is like IRQ & NMI signals, ie. saved struct of the producer's card)
//
// NB. Save-state only occurs when message pump runs:
// . ie. at end of 1ms emulation burst
// Either 6502 or Z80 could be active.
//
pSS->Active = g_ActiveCPU == CPU_Z80 ? 1 : 0;
//
DWORD dwBytesWritten;
BOOL bRes = WriteFile( hFile,
&Card,
Card.Hdr.UnitHdr.hdr.v2.Length,
&dwBytesWritten,
NULL);
if(!bRes || (dwBytesWritten != Card.Hdr.UnitHdr.hdr.v2.Length))
{
//dwError = GetLastError();
throw std::string("Save error: Z80");
}
}
void Z80_SetSnapshot(const HANDLE hFile)
{
SS_CARD_Z80 Card;
DWORD dwBytesRead;
BOOL bRes = ReadFile( hFile,
&Card,
sizeof(Card),
&dwBytesRead,
NULL);
if (dwBytesRead != sizeof(Card))
throw std::string("Card: file corrupt");
if (Card.Hdr.Slot != 4 && Card.Hdr.Slot != 5) // fixme
throw std::string("Card: wrong slot");
if (Card.Hdr.UnitHdr.hdr.v2.Version > 1)
throw std::string("Card: wrong version");
if (Card.Hdr.UnitHdr.hdr.v2.Length != sizeof(SS_CARD_Z80))
throw std::string("Card: unit size mismatch");
SS_CARD_Z80* pSS = &Card;
reg_a = pSS->Unit.reg_a;
reg_b = pSS->Unit.reg_b;
reg_c = pSS->Unit.reg_c;
reg_d = pSS->Unit.reg_d;
reg_e = pSS->Unit.reg_e;
reg_f = pSS->Unit.reg_f;
reg_h = pSS->Unit.reg_h;
reg_l = pSS->Unit.reg_l;
reg_ixh = pSS->Unit.reg_ixh;
reg_ixl = pSS->Unit.reg_ixl;
reg_iyh = pSS->Unit.reg_iyh;
reg_iyl = pSS->Unit.reg_iyl;
reg_sp = pSS->Unit.reg_sp;
z80_reg_pc = pSS->Unit.z80_reg_pc;
reg_i = pSS->Unit.reg_i;
reg_r = pSS->Unit.reg_r;
iff1 = pSS->Unit.iff1;
iff2 = pSS->Unit.iff2;
im_mode = pSS->Unit.im_mode;
reg_a2 = pSS->Unit.reg_a2;
reg_b2 = pSS->Unit.reg_b2;
reg_c2 = pSS->Unit.reg_c2;
reg_d2 = pSS->Unit.reg_d2;
reg_e2 = pSS->Unit.reg_e2;
reg_f2 = pSS->Unit.reg_f2;
reg_h2 = pSS->Unit.reg_h2;
reg_l2 = pSS->Unit.reg_l2;
export_registers();
if (pSS->Active)
g_ActiveCPU = CPU_Z80; // Support MS SoftCard in multiple slots (only one Z80 can be active at any one time)
}

View File

@ -16,6 +16,7 @@
#include "StdAfx.h"
#include "AppleWin.h"
#include "CPU.h"
#include "Memory.h"
#include "z80emu.h"
@ -30,7 +31,7 @@ BYTE __stdcall CPMZ80_IONull(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULON
BYTE __stdcall CPMZ80_IOWrite(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft)
{
if ((uAddr & 0xFF00) == (0xC000 + (g_uCPMZ80Slot << 8)))
g_ActiveCPU = (g_ActiveCPU == CPU_6502) ? CPU_Z80 : CPU_6502;
SetActiveCpu( GetActiveCpu() == CPU_Z80 ? GetMainCpu() : CPU_Z80 );
return IO_Null(PC, uAddr, bWrite, uValue, nCyclesLeft);
}

View File

@ -19,5 +19,3 @@ void ConfigureSoftcard(LPBYTE pCxRomPeripheral, UINT uSlot);
std::string Z80_GetSnapshotCardName(void);
void Z80_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, const UINT uSlot);
bool Z80_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT uSlot, UINT version);
void Z80_GetSnapshot(const HANDLE hFile, const UINT uZ80Slot);
void Z80_SetSnapshot(const HANDLE hFile);

View File

@ -4,7 +4,6 @@
#include "../../source/CPU.h"
// From Applewin.cpp
eCPU g_ActiveCPU = CPU_6502;
enum AppMode_e g_nAppMode = MODE_RUNNING;
// From Memory.cpp
@ -38,6 +37,13 @@ regsrec regs;
static const int IRQ_CHECK_TIMEOUT = 128;
static signed int g_nIrqCheckTimeout = IRQ_CHECK_TIMEOUT;
static eCpuType g_ActiveCPU = CPU_65C02;
eCpuType GetActiveCpu(void)
{
return g_ActiveCPU;
}
static __forceinline int Fetch(BYTE& iOpcode, ULONG uExecutedCycles)
{
iOpcode = *(mem+regs.pc);