From 37ad1ebd632291caaa21abf4450e74cc9dacd8c6 Mon Sep 17 00:00:00 2001 From: tomcw Date: Sun, 14 Feb 2016 16:01:30 +0000 Subject: [PATCH] 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 --- ApplewinExpress9.00.vcproj | 4 - source/AY8910.cpp | 169 ------ source/AY8910.h | 2 - source/Applewin.cpp | 65 +- source/Applewin.h | 6 +- source/CPU.cpp | 100 ++-- source/CPU.h | 11 +- source/CPU/cpu6502.h | 2 +- source/CPU/cpu65C02.h | 2 +- source/CPU/cpu65d02.h | 2 +- source/Common.h | 1 + source/Configuration/Config.h | 7 +- source/Configuration/PageConfig.cpp | 1 + source/Configuration/PropertySheetHelper.cpp | 52 +- source/Configuration/PropertySheetHelper.h | 1 + source/Disk.cpp | 209 +------ source/Disk.h | 2 - source/Frame.cpp | 26 +- source/Frame.h | 1 + source/Harddisk.cpp | 156 ----- source/Harddisk.h | 2 - source/Joystick.cpp | 18 - source/Joystick.h | 2 - source/Keyboard.cpp | 12 - source/Keyboard.h | 2 - source/Memory.cpp | 158 ----- source/Memory.h | 4 - source/Mockingboard.cpp | 273 --------- source/Mockingboard.h | 4 - source/MouseInterface.cpp | 160 ----- source/MouseInterface.h | 2 - source/ParallelPrinter.cpp | 103 ---- source/ParallelPrinter.h | 2 - source/SaveState.cpp | 598 +------------------ source/SaveState_Structs_v2.h | 129 ---- source/SerialComms.cpp | 121 ---- source/SerialComms.h | 2 - source/Speaker.cpp | 12 - source/Speaker.h | 2 - source/Video.cpp | 17 - source/Video.h | 2 - source/YamlHelper.cpp | 73 +-- source/YamlHelper.h | 85 ++- source/Z80VICE/z80.cpp | 186 +----- source/z80emu.cpp | 3 +- source/z80emu.h | 2 - test/TestCPU6502/TestCPU6502.cpp | 8 +- 47 files changed, 302 insertions(+), 2499 deletions(-) delete mode 100644 source/SaveState_Structs_v2.h diff --git a/ApplewinExpress9.00.vcproj b/ApplewinExpress9.00.vcproj index b710ac63..0e4d70b8 100644 --- a/ApplewinExpress9.00.vcproj +++ b/ApplewinExpress9.00.vcproj @@ -782,10 +782,6 @@ RelativePath=".\source\SaveState_Structs_v1.h" > - - diff --git a/source/AY8910.cpp b/source/AY8910.cpp index 4305aa9b..b40f26b0 100644 --- a/source/AY8910.cpp +++ b/source/AY8910.cpp @@ -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); -} diff --git a/source/AY8910.h b/source/AY8910.h index f33e0630..ea2596e6 100644 --- a/source/AY8910.h +++ b/source/AY8910.h @@ -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 diff --git a/source/Applewin.cpp b/source/Applewin.cpp index 59e2284c..b8608c33 100644 --- a/source/Applewin.cpp +++ b/source/Applewin.cpp @@ -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; diff --git a/source/Applewin.h b/source/Applewin.h index a8313335..cb15246e 100644 --- a/source/Applewin.h +++ b/source/Applewin.h @@ -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; diff --git a/source/CPU.cpp b/source/CPU.cpp index f693f053..e12e28a3 100644 --- a/source/CPU.cpp +++ b/source/CPU.cpp @@ -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; -} diff --git a/source/CPU.h b/source/CPU.h index 38c46917..5086e9e1 100644 --- a/source/CPU.h +++ b/source/CPU.h @@ -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); diff --git a/source/CPU/cpu6502.h b/source/CPU/cpu6502.h index 1815e941..3b58dd91 100644 --- a/source/CPU/cpu6502.h +++ b/source/CPU/cpu6502.h @@ -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) } diff --git a/source/CPU/cpu65C02.h b/source/CPU/cpu65C02.h index 2cafc375..5d649b05 100644 --- a/source/CPU/cpu65C02.h +++ b/source/CPU/cpu65C02.h @@ -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) } diff --git a/source/CPU/cpu65d02.h b/source/CPU/cpu65d02.h index 0e01abdf..f036c139 100644 --- a/source/CPU/cpu65d02.h +++ b/source/CPU/cpu65d02.h @@ -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) } diff --git a/source/Common.h b/source/Common.h index b2f9ee22..19be87e0 100644 --- a/source/Common.h +++ b/source/Common.h @@ -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" diff --git a/source/Configuration/Config.h b/source/Configuration/Config.h index 2724bf69..36be83af 100644 --- a/source/Configuration/Config.h +++ b/source/Configuration/Config.h @@ -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; diff --git a/source/Configuration/PageConfig.cpp b/source/Configuration/PageConfig.cpp index 78ba4116..944420d6 100644 --- a/source/Configuration/PageConfig.cpp +++ b/source/Configuration/PageConfig.cpp @@ -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; diff --git a/source/Configuration/PropertySheetHelper.cpp b/source/Configuration/PropertySheetHelper.cpp index 5f684fc0..a6ec332a 100644 --- a/source/Configuration/PropertySheetHelper.cpp +++ b/source/Configuration/PropertySheetHelper.cpp @@ -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); diff --git a/source/Configuration/PropertySheetHelper.h b/source/Configuration/PropertySheetHelper.h index 52d08420..5fd83fd4 100644 --- a/source/Configuration/PropertySheetHelper.h +++ b/source/Configuration/PropertySheetHelper.h @@ -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); diff --git a/source/Disk.cpp b/source/Disk.cpp index a6070338..5ec21ba4 100644 --- a/source/Disk.cpp +++ b/source/Disk.cpp @@ -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 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 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; iUnit[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; iUnit[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); -} diff --git a/source/Disk.h b/source/Disk.h index 1bcbd786..f759bf2f 100644 --- a/source/Disk.h +++ b/source/Disk.h @@ -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); diff --git a/source/Frame.cpp b/source/Frame.cpp index 2089d264..d4d9a49d 100644 --- a/source/Frame.cpp +++ b/source/Frame.cpp @@ -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(); +} diff --git a/source/Frame.h b/source/Frame.h index 322820b7..e9149f78 100644 --- a/source/Frame.h +++ b/source/Frame.h @@ -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 ); diff --git a/source/Harddisk.cpp b/source/Harddisk.cpp index 7c69f96e..a4c70f2a 100644 --- a/source/Harddisk.cpp +++ b/source/Harddisk.cpp @@ -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 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; iHdr.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() -} diff --git a/source/Memory.h b/source/Memory.h index 8e5ca745..3a104755 100644 --- a/source/Memory.h +++ b/source/Memory.h @@ -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); diff --git a/source/Mockingboard.cpp b/source/Mockingboard.cpp index 1f79bf35..c52d69b9 100644 --- a/source/Mockingboard.cpp +++ b/source/Mockingboard.cpp @@ -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; isy6522, 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; isy6522, &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; isy6522, 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; isy6522, &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; -} diff --git a/source/Mockingboard.h b/source/Mockingboard.h index 487463c2..901a9e41 100644 --- a/source/Mockingboard.h +++ b/source/Mockingboard.h @@ -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); diff --git a/source/MouseInterface.cpp b/source/MouseInterface.cpp index 9a8f3921..d6bee8ed 100644 --- a/source/MouseInterface.cpp +++ b/source/MouseInterface.cpp @@ -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 //============================================================================= diff --git a/source/MouseInterface.h b/source/MouseInterface.h index 54570ede..edb62ca8 100644 --- a/source/MouseInterface.h +++ b/source/MouseInterface.h @@ -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(); diff --git a/source/ParallelPrinter.cpp b/source/ParallelPrinter.cpp index 85bbed2d..79df8242 100644 --- a/source/ParallelPrinter.cpp +++ b/source/ParallelPrinter.cpp @@ -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; -} diff --git a/source/ParallelPrinter.h b/source/ParallelPrinter.h index 87216bc0..d2b96bdb 100644 --- a/source/ParallelPrinter.h +++ b/source/ParallelPrinter.h @@ -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; diff --git a/source/SaveState.cpp b/source/SaveState.cpp index 2aab70f4..2dd77a3b 100644 --- a/source/SaveState.cpp +++ b/source/SaveState.cpp @@ -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; isecond.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); } } diff --git a/source/YamlHelper.h b/source/YamlHelper.h index 6fe2e935..cc45ff0a 100644 --- a/source/YamlHelper.h +++ b/source/YamlHelper.h @@ -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 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 m_stackMap; + bool m_bDoGetMapRemainder; + + struct YamlStackItem + { + MapYaml* pMapYaml; + std::string mapName; + }; + std::stack 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), diff --git a/source/Z80VICE/z80.cpp b/source/Z80VICE/z80.cpp index 21c7c885..3b43dc89 100644 --- a/source/Z80VICE/z80.cpp +++ b/source/Z80VICE/z80.cpp @@ -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) -} diff --git a/source/z80emu.cpp b/source/z80emu.cpp index 932711e3..01542099 100644 --- a/source/z80emu.cpp +++ b/source/z80emu.cpp @@ -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); } diff --git a/source/z80emu.h b/source/z80emu.h index 49fced1f..3b256f0a 100644 --- a/source/z80emu.h +++ b/source/z80emu.h @@ -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); diff --git a/test/TestCPU6502/TestCPU6502.cpp b/test/TestCPU6502/TestCPU6502.cpp index 30147f82..30088ceb 100644 --- a/test/TestCPU6502/TestCPU6502.cpp +++ b/test/TestCPU6502/TestCPU6502.cpp @@ -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);