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

View File

@ -210,7 +210,7 @@ static LPBYTE g_pMemMainLanguageCard = NULL;
static DWORD memmode = LanguageCardUnit::kMemModeInitialState;
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
#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)
{
int data = 0;
if (g_NoSlotClock.Read(address, data))
if (g_NoSlotClock->Read(address, data))
return (BYTE) data;
}
else
{
g_NoSlotClock.Write(address);
g_NoSlotClock->Write(address);
return 0;
}
}
@ -1949,7 +1949,8 @@ void MemReset()
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.
// . 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.
@ -2452,3 +2473,17 @@ bool MemLoadSnapshotAux(YamlLoadHelper& yamlLoadHelper, UINT unitVersion)
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);
LPVOID MemGetSlotParameters (UINT uSlot);
bool MemGetAnnunciator(UINT annunciator);
bool MemHasNoSlotClock(void);
void MemInsertNoSlotClock(void);
void MemRemoveNoSlotClock(void);
std::string MemGetSnapshotUnitAuxSlotName(void);
void MemSaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
bool MemLoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT unitVersion);
void MemSaveSnapshotAux(class YamlSaveHelper& yamlSaveHelper);
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);

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 "NoSlotClock.h"
#include "YamlHelper.h"
CNoSlotClock::CNoSlotClock()
:
@ -166,6 +167,45 @@ void CNoSlotClock::PopulateClockRegister()
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()
{
Reset();

View File

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

View File

@ -71,10 +71,13 @@ static YamlHelper yamlHelper;
// v3: Extended: memory (added 'AnnunciatorN')
// v4: Extended: video (added 'Video Refresh Rate')
// 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_MISC_VER 1
//-----------------------------------------------------------------------------
void Snapshot_SetFilename(const std::string & strPathname)
@ -134,6 +137,12 @@ static std::string GetSnapshotUnitSlotsName(void)
return name;
}
static std::string GetSnapshotUnitMiscName(void)
{
static const std::string name("Miscellaneous");
return name;
}
#define SS_YAML_KEY_MODEL "Model"
#define SS_YAML_VALUE_APPLE2 "Apple]["
@ -353,6 +362,9 @@ static void ParseUnit(void)
if (unit == GetSnapshotUnitApple2Name())
{
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())
{
@ -362,6 +374,11 @@ static void ParseUnit(void)
{
ParseSlots(yamlLoadHelper, unitVersion);
}
else if (unit == GetSnapshotUnitMiscName())
{
// NB. could extend for other misc devices - see how ParseSlots() calls GetMapNextSlotNumber()
NoSlotClockLoadSnapshot(yamlLoadHelper);
}
else
{
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_bEnableTheFreezesF8Rom = ?; // todo: when support saving config
MemReset(); // Also calls CpuInitialize(), CNoSlotClock.Reset()
MemReset(); // Also calls CpuInitialize()
PravetsReset();
if (g_CardMgr.IsSSCInstalled())
@ -570,6 +587,15 @@ void Snapshot_SaveState(void)
if (g_CardMgr.QuerySlot(SLOT7) == CT_GenericHDD)
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)
{