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:
parent
2f6e86c0fa
commit
37ad1ebd63
47 changed files with 302 additions and 2499 deletions
|
@ -782,10 +782,6 @@
|
|||
RelativePath=".\source\SaveState_Structs_v1.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\source\SaveState_Structs_v2.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\source\SSI263Phonemes.h"
|
||||
>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
100
source/CPU.cpp
100
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;
|
||||
}
|
||||
|
|
11
source/CPU.h
11
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);
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
209
source/Disk.cpp
209
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<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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
//=============================================================================
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue