NoSlotClock:

. added to save-state (v6) via a new unit type 'Miscellaneous'
. added cmd line switch '-no-nsc' to configure AppleII without an NSC
This commit is contained in:
tomcw 2020-06-10 20:56:00 +01:00
parent f491bb19cd
commit c9ef6ecee1
6 changed files with 126 additions and 7 deletions

View File

@ -1318,6 +1318,7 @@ struct CmdLine
bSlot0LanguageCard = false; bSlot0LanguageCard = false;
bSlot7EmptyOnExit = false; bSlot7EmptyOnExit = false;
bSwapButtons0and1 = false; bSwapButtons0and1 = false;
bRemoveNoSlotClock = false;
bestWidth = 0; bestWidth = 0;
bestHeight = 0; bestHeight = 0;
szImageName_harddisk[HARDDISK_1] = NULL; szImageName_harddisk[HARDDISK_1] = NULL;
@ -1350,6 +1351,7 @@ struct CmdLine
bool bSlotEmpty[NUM_SLOTS]; bool bSlotEmpty[NUM_SLOTS];
bool bSlot7EmptyOnExit; bool bSlot7EmptyOnExit;
bool bSwapButtons0and1; bool bSwapButtons0and1;
bool bRemoveNoSlotClock;
SS_CARDTYPE slotInsert[NUM_SLOTS]; SS_CARDTYPE slotInsert[NUM_SLOTS];
UINT bestWidth; UINT bestWidth;
UINT bestHeight; UINT bestHeight;
@ -1802,6 +1804,10 @@ static bool ProcessCmdLine(LPSTR lpCmdLine)
lpNextArg = GetNextArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg);
g_cmdLine.strCurrentDir = lpCmdLine; g_cmdLine.strCurrentDir = lpCmdLine;
} }
else if (strcmp(lpCmdLine, "-no-nsc") == 0)
{
g_cmdLine.bRemoveNoSlotClock = true;
}
else // unsupported else // unsupported
{ {
LogFileOutput("Unsupported arg: %s\n", lpCmdLine); LogFileOutput("Unsupported arg: %s\n", lpCmdLine);
@ -2036,6 +2042,9 @@ static void RepeatInitialization(void)
if (!g_cmdLine.strCurrentDir.empty()) if (!g_cmdLine.strCurrentDir.empty())
SetCurrentImageDir(g_cmdLine.strCurrentDir); SetCurrentImageDir(g_cmdLine.strCurrentDir);
if (g_cmdLine.bRemoveNoSlotClock)
MemRemoveNoSlotClock();
MemInitialize(); MemInitialize();
LogFileOutput("Main: MemInitialize()\n"); LogFileOutput("Main: MemInitialize()\n");

View File

@ -210,7 +210,7 @@ static LPBYTE g_pMemMainLanguageCard = NULL;
static DWORD memmode = LanguageCardUnit::kMemModeInitialState; static DWORD memmode = LanguageCardUnit::kMemModeInitialState;
static BOOL modechanging = 0; // An Optimisation: means delay calling UpdatePaging() for 1 instruction static BOOL modechanging = 0; // An Optimisation: means delay calling UpdatePaging() for 1 instruction
static CNoSlotClock g_NoSlotClock; static CNoSlotClock* g_NoSlotClock = new CNoSlotClock;
static LanguageCardUnit* g_pLanguageCard = NULL; // For all Apple II, //e and above static LanguageCardUnit* g_pLanguageCard = NULL; // For all Apple II, //e and above
#ifdef RAMWORKS #ifdef RAMWORKS
@ -832,17 +832,17 @@ static BYTE __stdcall IO_Cxxx(WORD programcounter, WORD address, BYTE write, BYT
} }
} }
if (IsPotentialNoSlotClockAccess(address)) if (g_NoSlotClock && IsPotentialNoSlotClockAccess(address))
{ {
if (!write) if (!write)
{ {
int data = 0; int data = 0;
if (g_NoSlotClock.Read(address, data)) if (g_NoSlotClock->Read(address, data))
return (BYTE) data; return (BYTE) data;
} }
else else
{ {
g_NoSlotClock.Write(address); g_NoSlotClock->Write(address);
return 0; return 0;
} }
} }
@ -1949,7 +1949,8 @@ void MemReset()
z80_reset(); // NB. Also called above in CpuInitialize() z80_reset(); // NB. Also called above in CpuInitialize()
g_NoSlotClock.Reset(); // NB. Power-cycle, but not RESET signal if (g_NoSlotClock)
g_NoSlotClock->Reset(); // NB. Power-cycle, but not RESET signal
} }
//=========================================================================== //===========================================================================
@ -2136,6 +2137,26 @@ bool MemGetAnnunciator(UINT annunciator)
//=========================================================================== //===========================================================================
bool MemHasNoSlotClock(void)
{
return g_NoSlotClock != NULL;
}
void MemInsertNoSlotClock(void)
{
if (!MemHasNoSlotClock())
g_NoSlotClock = new CNoSlotClock;
g_NoSlotClock->Reset();
}
void MemRemoveNoSlotClock(void)
{
delete g_NoSlotClock;
g_NoSlotClock = NULL;
}
//===========================================================================
// NB. Don't need to save 'modechanging', as this is just an optimisation to save calling UpdatePaging() twice. // NB. Don't need to save 'modechanging', as this is just an optimisation to save calling UpdatePaging() twice.
// . If we were to save the state when 'modechanging' is set, then on restoring the state, the 6502 code will immediately update the read memory mode. // . If we were to save the state when 'modechanging' is set, then on restoring the state, the 6502 code will immediately update the read memory mode.
// . This will work correctly. // . This will work correctly.
@ -2452,3 +2473,17 @@ bool MemLoadSnapshotAux(YamlLoadHelper& yamlLoadHelper, UINT unitVersion)
return true; return true;
} }
void NoSlotClockSaveSnapshot(YamlSaveHelper& yamlSaveHelper)
{
if (g_NoSlotClock)
g_NoSlotClock->SaveSnapshot(yamlSaveHelper);
}
void NoSlotClockLoadSnapshot(YamlLoadHelper& yamlLoadHelper)
{
if (!g_NoSlotClock)
g_NoSlotClock = new CNoSlotClock;
g_NoSlotClock->LoadSnapshot(yamlLoadHelper);
}

View File

@ -82,11 +82,16 @@ void MemResetPaging ();
void MemUpdatePaging(BOOL initialize); void MemUpdatePaging(BOOL initialize);
LPVOID MemGetSlotParameters (UINT uSlot); LPVOID MemGetSlotParameters (UINT uSlot);
bool MemGetAnnunciator(UINT annunciator); bool MemGetAnnunciator(UINT annunciator);
bool MemHasNoSlotClock(void);
void MemInsertNoSlotClock(void);
void MemRemoveNoSlotClock(void);
std::string MemGetSnapshotUnitAuxSlotName(void); std::string MemGetSnapshotUnitAuxSlotName(void);
void MemSaveSnapshot(class YamlSaveHelper& yamlSaveHelper); void MemSaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
bool MemLoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT unitVersion); bool MemLoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT unitVersion);
void MemSaveSnapshotAux(class YamlSaveHelper& yamlSaveHelper); void MemSaveSnapshotAux(class YamlSaveHelper& yamlSaveHelper);
bool MemLoadSnapshotAux(class YamlLoadHelper& yamlLoadHelper, UINT unitVersion); bool MemLoadSnapshotAux(class YamlLoadHelper& yamlLoadHelper, UINT unitVersion);
void NoSlotClockSaveSnapshot(YamlSaveHelper& yamlSaveHelper);
void NoSlotClockLoadSnapshot(YamlLoadHelper& yamlLoadHelper);
BYTE __stdcall IO_Null(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles); BYTE __stdcall IO_Null(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles);

View File

@ -41,6 +41,7 @@ All the other drivers and utilities available to me don't define the DOW mapping
#include "StdAfx.h" #include "StdAfx.h"
#include "NoSlotClock.h" #include "NoSlotClock.h"
#include "YamlHelper.h"
CNoSlotClock::CNoSlotClock() CNoSlotClock::CNoSlotClock()
: :
@ -166,6 +167,45 @@ void CNoSlotClock::PopulateClockRegister()
m_ClockRegister.WriteNibble(year / 10); m_ClockRegister.WriteNibble(year / 10);
} }
#define SS_YAML_KEY_CLOCK_REGISTER_ENABLED "Clock Register Enabled"
#define SS_YAML_KEY_WRITE_ENABLED "Write Enabled"
#define SS_YAML_KEY_CLOCK_REGISTER_MASK "Clock Register Mask"
#define SS_YAML_KEY_CLOCK_REGISTER "Clock Register"
#define SS_YAML_KEY_COMPARISON_REGISTER_MASK "Comparison Register Mask"
#define SS_YAML_KEY_COMPARISON_REGISTER "Comparison Register"
std::string CNoSlotClock::GetSnapshotStructName(void)
{
static const std::string name("No Slot Clock");
return name;
}
void CNoSlotClock::SaveSnapshot(YamlSaveHelper& yamlSaveHelper)
{
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", GetSnapshotStructName().c_str());
yamlSaveHelper.SaveBool(SS_YAML_KEY_CLOCK_REGISTER_ENABLED, m_bClockRegisterEnabled);
yamlSaveHelper.SaveBool(SS_YAML_KEY_WRITE_ENABLED, m_bWriteEnabled);
yamlSaveHelper.SaveHexUint64(SS_YAML_KEY_CLOCK_REGISTER_MASK, m_ClockRegister.m_Mask);
yamlSaveHelper.SaveHexUint64(SS_YAML_KEY_CLOCK_REGISTER, m_ClockRegister.m_Register);
yamlSaveHelper.SaveHexUint64(SS_YAML_KEY_COMPARISON_REGISTER_MASK, m_ComparisonRegister.m_Mask);
yamlSaveHelper.SaveHexUint64(SS_YAML_KEY_COMPARISON_REGISTER, m_ComparisonRegister.m_Register);
}
void CNoSlotClock::LoadSnapshot(YamlLoadHelper& yamlLoadHelper)
{
if (!yamlLoadHelper.GetSubMap(GetSnapshotStructName()))
return;
m_bClockRegisterEnabled = yamlLoadHelper.LoadBool(SS_YAML_KEY_CLOCK_REGISTER_ENABLED);
m_bWriteEnabled = yamlLoadHelper.LoadBool(SS_YAML_KEY_WRITE_ENABLED);
m_ClockRegister.m_Mask = yamlLoadHelper.LoadUint64(SS_YAML_KEY_CLOCK_REGISTER_MASK);
m_ClockRegister.m_Register = yamlLoadHelper.LoadUint64(SS_YAML_KEY_CLOCK_REGISTER);
m_ComparisonRegister.m_Mask = yamlLoadHelper.LoadUint64(SS_YAML_KEY_COMPARISON_REGISTER_MASK);
m_ComparisonRegister.m_Register = yamlLoadHelper.LoadUint64(SS_YAML_KEY_COMPARISON_REGISTER);
yamlLoadHelper.PopMap();
}
CNoSlotClock::RingRegister64::RingRegister64() CNoSlotClock::RingRegister64::RingRegister64()
{ {
Reset(); Reset();

View File

@ -57,6 +57,9 @@ public:
bool ClockRead(int& data); bool ClockRead(int& data);
void ClockWrite(int address); void ClockWrite(int address);
void SaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
void LoadSnapshot(class YamlLoadHelper& yamlLoadHelper);
bool m_bClockRegisterEnabled; bool m_bClockRegisterEnabled;
bool m_bWriteEnabled; bool m_bWriteEnabled;
RingRegister64 m_ClockRegister; RingRegister64 m_ClockRegister;
@ -64,6 +67,7 @@ public:
private: private:
void PopulateClockRegister(); void PopulateClockRegister();
std::string GetSnapshotStructName(void);
static const UINT64 kClockInitSequence = 0x5CA33AC55CA33AC5; static const UINT64 kClockInitSequence = 0x5CA33AC55CA33AC5;
}; };

View File

@ -71,10 +71,13 @@ static YamlHelper yamlHelper;
// v3: Extended: memory (added 'AnnunciatorN') // v3: Extended: memory (added 'AnnunciatorN')
// v4: Extended: video (added 'Video Refresh Rate') // v4: Extended: video (added 'Video Refresh Rate')
// v5: Extended: cpu (added 'Defer IRQ By 1 Opcode') // v5: Extended: cpu (added 'Defer IRQ By 1 Opcode')
#define UNIT_APPLE2_VER 5 // v6: Added 'Unit Miscellaneous' for NoSlotClock(NSC)
#define UNIT_APPLE2_VER 6
#define UNIT_SLOTS_VER 1 #define UNIT_SLOTS_VER 1
#define UNIT_MISC_VER 1
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Snapshot_SetFilename(const std::string & strPathname) void Snapshot_SetFilename(const std::string & strPathname)
@ -134,6 +137,12 @@ static std::string GetSnapshotUnitSlotsName(void)
return name; return name;
} }
static std::string GetSnapshotUnitMiscName(void)
{
static const std::string name("Miscellaneous");
return name;
}
#define SS_YAML_KEY_MODEL "Model" #define SS_YAML_KEY_MODEL "Model"
#define SS_YAML_VALUE_APPLE2 "Apple][" #define SS_YAML_VALUE_APPLE2 "Apple]["
@ -353,6 +362,9 @@ static void ParseUnit(void)
if (unit == GetSnapshotUnitApple2Name()) if (unit == GetSnapshotUnitApple2Name())
{ {
ParseUnitApple2(yamlLoadHelper, unitVersion); ParseUnitApple2(yamlLoadHelper, unitVersion);
if (unitVersion < 6) MemInsertNoSlotClock(); // NSC always inserted
else MemRemoveNoSlotClock(); // NSC only add if there's a misc unit
} }
else if (unit == MemGetSnapshotUnitAuxSlotName()) else if (unit == MemGetSnapshotUnitAuxSlotName())
{ {
@ -362,6 +374,11 @@ static void ParseUnit(void)
{ {
ParseSlots(yamlLoadHelper, unitVersion); ParseSlots(yamlLoadHelper, unitVersion);
} }
else if (unit == GetSnapshotUnitMiscName())
{
// NB. could extend for other misc devices - see how ParseSlots() calls GetMapNextSlotNumber()
NoSlotClockLoadSnapshot(yamlLoadHelper);
}
else else
{ {
throw std::string(SS_YAML_KEY_UNIT ": Unknown type: " ) + unit; throw std::string(SS_YAML_KEY_UNIT ": Unknown type: " ) + unit;
@ -400,7 +417,7 @@ static void Snapshot_LoadState_v2(void)
m_ConfigNew.m_bEnableHDD = false; m_ConfigNew.m_bEnableHDD = false;
//m_ConfigNew.m_bEnableTheFreezesF8Rom = ?; // todo: when support saving config //m_ConfigNew.m_bEnableTheFreezesF8Rom = ?; // todo: when support saving config
MemReset(); // Also calls CpuInitialize(), CNoSlotClock.Reset() MemReset(); // Also calls CpuInitialize()
PravetsReset(); PravetsReset();
if (g_CardMgr.IsSSCInstalled()) if (g_CardMgr.IsSSCInstalled())
@ -570,6 +587,15 @@ void Snapshot_SaveState(void)
if (g_CardMgr.QuerySlot(SLOT7) == CT_GenericHDD) if (g_CardMgr.QuerySlot(SLOT7) == CT_GenericHDD)
HD_SaveSnapshot(yamlSaveHelper); HD_SaveSnapshot(yamlSaveHelper);
} }
// Miscellaneous
if (MemHasNoSlotClock())
{
yamlSaveHelper.UnitHdr(GetSnapshotUnitMiscName(), UNIT_MISC_VER);
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE);
NoSlotClockSaveSnapshot(yamlSaveHelper);
}
} }
catch(std::string szMessage) catch(std::string szMessage)
{ {