CPU save-state: added 'Defer IRQ By 1 Opcode' (v5) and comments for why the other state doesn't need saving

This commit is contained in:
tomcw 2019-11-18 15:08:59 +00:00
parent b82de931a1
commit 7d38b1ba38
5 changed files with 27 additions and 14 deletions

View File

@ -143,6 +143,8 @@ 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 bool g_irqDefer1Opcode = false;
//
static eCpuType g_MainCPU = CPU_65C02;
@ -403,8 +405,8 @@ static __forceinline void NMI(ULONG& uExecutedCycles, BOOL& flagc, BOOL& flagn,
#endif
}
// NB. No need to save to save-state, as IRQ() follows CheckInterruptSources(), and IRQ() always sets it to false.
static bool g_irqOnLastOpcodeCycle = false;
static bool g_irqDefer1Opcode = false;
static __forceinline void IRQ(ULONG& uExecutedCycles, BOOL& flagc, BOOL& flagn, BOOL& flagv, BOOL& flagz)
{
@ -681,6 +683,8 @@ void CpuReset()
regs.bJammed = 0;
g_irqDefer1Opcode = false;
SetActiveCpu( GetMainCpu() );
z80_reset();
}
@ -694,7 +698,8 @@ void CpuReset()
#define SS_YAML_KEY_REGP "P"
#define SS_YAML_KEY_REGS "S"
#define SS_YAML_KEY_REGPC "PC"
#define SS_YAML_KEY_CUMULATIVECYCLES "Cumulative Cycles"
#define SS_YAML_KEY_CUMULATIVE_CYCLES "Cumulative Cycles"
#define SS_YAML_KEY_IRQ_DEFER_1_OPCODE "Defer IRQ By 1 Opcode"
#define SS_YAML_VALUE_6502 "6502"
#define SS_YAML_VALUE_65C02 "65C02"
@ -717,10 +722,11 @@ void CpuSaveSnapshot(YamlSaveHelper& yamlSaveHelper)
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGP, regs.ps);
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGS, (BYTE) regs.sp);
yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_REGPC, regs.pc);
yamlSaveHelper.SaveHexUint64(SS_YAML_KEY_CUMULATIVECYCLES, g_nCumulativeCycles);
yamlSaveHelper.SaveHexUint64(SS_YAML_KEY_CUMULATIVE_CYCLES, g_nCumulativeCycles);
yamlSaveHelper.SaveBool(SS_YAML_KEY_IRQ_DEFER_1_OPCODE, g_irqDefer1Opcode);
}
void CpuLoadSnapshot(YamlLoadHelper& yamlLoadHelper)
void CpuLoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT version)
{
if (!yamlLoadHelper.GetSubMap(CpuGetSnapshotStructName()))
return;
@ -741,7 +747,10 @@ void CpuLoadSnapshot(YamlLoadHelper& yamlLoadHelper)
CpuIrqReset();
CpuNmiReset();
g_nCumulativeCycles = yamlLoadHelper.LoadUint64(SS_YAML_KEY_CUMULATIVECYCLES);
g_nCumulativeCycles = yamlLoadHelper.LoadUint64(SS_YAML_KEY_CUMULATIVE_CYCLES);
if (version >= 5)
g_irqDefer1Opcode = yamlLoadHelper.LoadBool(SS_YAML_KEY_IRQ_DEFER_1_OPCODE);
yamlLoadHelper.PopMap();
}

View File

@ -29,7 +29,7 @@ void CpuNmiAssert(eIRQSRC Device);
void CpuNmiDeassert(eIRQSRC Device);
void CpuReset ();
void CpuSaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
void CpuLoadSnapshot(class YamlLoadHelper& yamlLoadHelper);
void CpuLoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT version);
BYTE CpuRead(USHORT addr, ULONG uExecutedCycles);
void CpuWrite(USHORT addr, BYTE a, ULONG uExecutedCycles);

View File

@ -129,8 +129,10 @@ struct SY6522_AY8910
SSI263A SpeechChip;
MockingboardUnitState_e state; // Where a unit is a 6522+AY8910 pair
MockingboardUnitState_e stateB; // Phasor: 6522 & 2nd AY8910
bool bLoadT1C;
bool bLoadT2C;
// NB. No need to save to save-state, as it will be done immediately after opcode completes in MB_UpdateCycles()
bool bLoadT1C; // Load T1C with T1L after opcode completes
bool bLoadT2C; // Load T2C with T2L after opcode completes
};
@ -1814,9 +1816,10 @@ static bool CheckTimerUnderflowAndIrq(USHORT& timerCounter, int& timerIrqDelay,
_ASSERT(timerIrqDelay == 1);
timerIrqDelay = 0;
timerIrq = true;
// don't re-underflow if TIMER = 0x0000 (so just return)
// if LATCH is very small then could underflow for every opcode...
}
else if (oldTimer >= 0 && timer < 0) // Underflow occurs for 0x0000 -> 0xFFFF
if (oldTimer >= 0 && timer < 0) // Underflow occurs for 0x0000 -> 0xFFFF
{
if (pTimerUnderflow)
*pTimerUnderflow = true; // Just for Willy Byte!

View File

@ -116,7 +116,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
static int g_nHiresPage = 1;
static int g_nTextPage = 1;
static bool g_bDelayVideoMode = false;
static bool g_bDelayVideoMode = false; // NB. No need to save to save-state, as it will be done immediately after opcode completes in NTSC_VideoUpdateCycles()
static uint32_t g_uNewVideoModeFlags = 0;
// Understanding the Apple II, Timing Generation and the Video Scanner, Pg 3-11

View File

@ -68,7 +68,8 @@ static YamlHelper yamlHelper;
// v2: Extended: keyboard (added 'Key Waiting'), memory (LC mem type for II/II+, inverted MF_INTCXROM bit)
// v3: Extended: memory (added 'AnnunciatorN')
// v4: Extended: video (added 'Video Refresh Rate')
#define UNIT_APPLE2_VER 4
// v5: Extended: cpu (added 'Defer IRQ By 1 Opcode')
#define UNIT_APPLE2_VER 5
#define UNIT_SLOTS_VER 1
@ -214,7 +215,7 @@ static void ParseUnitApple2(YamlLoadHelper& yamlLoadHelper, UINT version)
SetApple2Type( ParseApple2Type(model) ); // NB. Sets default main CPU type
m_ConfigNew.m_Apple2Type = GetApple2Type();
CpuLoadSnapshot(yamlLoadHelper); // NB. Overrides default main CPU type
CpuLoadSnapshot(yamlLoadHelper, version); // NB. Overrides default main CPU type
m_ConfigNew.m_CpuType = GetMainCpu();
JoyLoadSnapshot(yamlLoadHelper);
@ -390,7 +391,7 @@ static void Snapshot_LoadState_v2(void)
m_ConfigNew.m_bEnableHDD = false;
//m_ConfigNew.m_bEnableTheFreezesF8Rom = ?; // todo: when support saving config
MemReset();
MemReset(); // Also calls CpuInitialize()
PravetsReset();
sg_Disk2Card.Reset();
HD_Reset();