MSXHawk: working savestates
This commit is contained in:
parent
5b4b85d2b2
commit
59a22415d2
|
@ -63,6 +63,26 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
|
|||
|
||||
#endregion
|
||||
|
||||
#region State Save / Load
|
||||
|
||||
/// <summary>
|
||||
/// Save State
|
||||
/// </summary>
|
||||
/// <param name="core">opaque state pointer</param>
|
||||
/// <param name="saver">save buffer</param>
|
||||
[DllImport("MSXHAWK.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void MSX_save_state(IntPtr core, byte[] saver);
|
||||
|
||||
/// <summary>
|
||||
/// Load State
|
||||
/// </summary>
|
||||
/// <param name="core">opaque state pointer</param>
|
||||
/// <param name="loader">load buffer</param>
|
||||
[DllImport("MSXHAWK.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void MSX_load_state(IntPtr core, byte[] loader);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Memory Domain Functions
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.IO;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
@ -40,14 +41,6 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
|
|||
|
||||
private void SyncState(Serializer ser)
|
||||
{
|
||||
byte[] core = null;
|
||||
if (ser.IsWriter)
|
||||
{
|
||||
using var ms = new MemoryStream();
|
||||
ms.Close();
|
||||
core = ms.ToArray();
|
||||
}
|
||||
|
||||
ser.BeginSection("MSX");
|
||||
|
||||
if (SaveRAM != null)
|
||||
|
@ -65,7 +58,15 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
|
|||
|
||||
if (ser.IsReader)
|
||||
{
|
||||
SyncAllByteArrayDomains();
|
||||
ser.Sync(nameof(MSX_core), ref MSX_core, false);
|
||||
LibMSX.MSX_load_state(MSX_Pntr, MSX_core);
|
||||
Console.WriteLine("here1");
|
||||
}
|
||||
else
|
||||
{
|
||||
LibMSX.MSX_save_state(MSX_Pntr, MSX_core);
|
||||
ser.Sync(nameof(MSX_core), ref MSX_core, false);
|
||||
Console.WriteLine("here2");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,6 +60,7 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
|
|||
}
|
||||
|
||||
IntPtr MSX_Pntr { get; set; } = IntPtr.Zero;
|
||||
byte[] MSX_core = new byte[0x20000];
|
||||
|
||||
// Constants
|
||||
private const int BankSize = 16384;
|
||||
|
|
|
@ -108,6 +108,26 @@ namespace MSXHawk
|
|||
return psg.sampleclock;
|
||||
}
|
||||
|
||||
#pragma region State Save / Load
|
||||
|
||||
void SaveState(uint8_t* saver)
|
||||
{
|
||||
saver = vdp.SaveState(saver);
|
||||
saver = cpu.SaveState(saver);
|
||||
saver = psg.SaveState(saver);
|
||||
saver = MemMap.SaveState(saver);
|
||||
}
|
||||
|
||||
void LoadState(uint8_t* loader)
|
||||
{
|
||||
loader = vdp.LoadState(loader);
|
||||
loader = cpu.LoadState(loader);
|
||||
loader = psg.LoadState(loader);
|
||||
loader = MemMap.LoadState(loader);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Memory Domain Functions
|
||||
|
||||
uint8_t GetSysBus(uint32_t addr)
|
||||
|
|
|
@ -48,6 +48,20 @@ MSXHAWK_EXPORT uint32_t MSX_get_audio(MSXCore* p, uint32_t* dest_L, uint32_t* de
|
|||
return p->GetAudio(dest_L, dest_R, n_samp_L, n_samp_R);
|
||||
}
|
||||
|
||||
#pragma region State Save / Load
|
||||
|
||||
// save state
|
||||
MSXHAWK_EXPORT void MSX_save_state(MSXCore* p, uint8_t* saver)
|
||||
{
|
||||
p->SaveState(saver);
|
||||
}
|
||||
|
||||
// load state
|
||||
MSXHAWK_EXPORT void MSX_load_state(MSXCore* p, uint8_t* loader)
|
||||
{
|
||||
p->LoadState(loader);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Memory Domain Functions
|
||||
|
|
|
@ -155,9 +155,4 @@ namespace MSXHawk
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -14,26 +14,22 @@ namespace MSXHawk
|
|||
class MemoryManager
|
||||
{
|
||||
public:
|
||||
MemoryManager()
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
VDP* vdp_pntr;
|
||||
SN76489sms* psg_pntr;
|
||||
Z80A* cpu_pntr;
|
||||
|
||||
uint8_t* rom;
|
||||
|
||||
// initialized by core loading, not savestated
|
||||
uint32_t rom_size;
|
||||
uint32_t rom_mapper;
|
||||
uint8_t ram[0x2000];
|
||||
|
||||
// State
|
||||
bool PortDEEnabled = false;
|
||||
bool lagged;
|
||||
bool start_pressed;
|
||||
|
||||
uint8_t controller_byte_1, controller_byte_2;
|
||||
|
||||
uint8_t Port01 = 0xFF;
|
||||
uint8_t Port02 = 0xFF;
|
||||
uint8_t Port03 = 0x00;
|
||||
|
@ -41,11 +37,27 @@ namespace MSXHawk
|
|||
uint8_t Port05 = 0x00;
|
||||
uint8_t Port3E = 0xAF;
|
||||
uint8_t Port3F = 0xFF;
|
||||
uint8_t PortDE = 0x00;
|
||||
|
||||
uint8_t PortDE = 0x00;
|
||||
uint8_t reg_FFFC, reg_FFFD, reg_FFFE, reg_FFFF;
|
||||
uint8_t ram[0x2000];
|
||||
uint8_t cart_ram[0x8000];
|
||||
|
||||
uint8_t reg_FFFC, reg_FFFD, reg_FFFE, reg_FFFF;
|
||||
MemoryManager()
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
uint8_t HardwareRead(uint32_t value);
|
||||
|
||||
void HardwareWrite(uint32_t addr, uint8_t value);
|
||||
|
||||
void remap_ROM_0();
|
||||
|
||||
void remap_ROM_1();
|
||||
|
||||
void remap_ROM_2();
|
||||
|
||||
void remap_RAM();
|
||||
|
||||
void Load_ROM(uint8_t* ext_rom, uint32_t ext_rom_size, uint32_t ext_rom_mapper)
|
||||
{
|
||||
|
@ -64,18 +76,6 @@ namespace MSXHawk
|
|||
remap_RAM();
|
||||
}
|
||||
|
||||
uint8_t HardwareRead(uint32_t value);
|
||||
|
||||
void HardwareWrite(uint32_t addr, uint8_t value);
|
||||
|
||||
void remap_ROM_0();
|
||||
|
||||
void remap_ROM_1();
|
||||
|
||||
void remap_ROM_2();
|
||||
|
||||
void remap_RAM();
|
||||
|
||||
void MemoryWrite(uint32_t addr, uint8_t value)
|
||||
{
|
||||
switch (addr)
|
||||
|
@ -146,5 +146,68 @@ namespace MSXHawk
|
|||
|
||||
return value;
|
||||
}
|
||||
|
||||
#pragma region State Save / Load
|
||||
|
||||
uint8_t* SaveState(uint8_t* saver)
|
||||
{
|
||||
*saver = (uint8_t)(PortDEEnabled ? 1 : 0); saver++;
|
||||
*saver = (uint8_t)(lagged ? 1 : 0); saver++;
|
||||
*saver = (uint8_t)(start_pressed ? 1 : 0); saver++;
|
||||
|
||||
*saver = controller_byte_1; saver++;
|
||||
*saver = controller_byte_2; saver++;
|
||||
*saver = Port01; saver++;
|
||||
*saver = Port02; saver++;
|
||||
*saver = Port03; saver++;
|
||||
*saver = Port04; saver++;
|
||||
*saver = Port05; saver++;
|
||||
*saver = Port3E; saver++;
|
||||
*saver = Port3F; saver++;
|
||||
*saver = PortDE; saver++;
|
||||
*saver = reg_FFFC; saver++;
|
||||
*saver = reg_FFFD; saver++;
|
||||
*saver = reg_FFFE; saver++;
|
||||
*saver = reg_FFFF; saver++;
|
||||
|
||||
std::memcpy(saver, &ram, 0x2000); saver += 0x2000;
|
||||
std::memcpy(saver, &cart_ram, 0x8000); saver += 0x8000;
|
||||
|
||||
return saver;
|
||||
}
|
||||
|
||||
uint8_t* LoadState(uint8_t* loader)
|
||||
{
|
||||
PortDEEnabled = *loader == 1; loader++;
|
||||
lagged = *loader == 1; loader++;
|
||||
start_pressed = *loader == 1; loader++;
|
||||
|
||||
controller_byte_1 = *loader; loader++;
|
||||
controller_byte_2 = *loader; loader++;
|
||||
Port01 = *loader; loader++;
|
||||
Port02 = *loader; loader++;
|
||||
Port03 = *loader; loader++;
|
||||
Port04 = *loader; loader++;
|
||||
Port05 = *loader; loader++;
|
||||
Port3E = *loader; loader++;
|
||||
Port3F = *loader; loader++;
|
||||
PortDE = *loader; loader++;
|
||||
reg_FFFC = *loader; loader++;
|
||||
reg_FFFD = *loader; loader++;
|
||||
reg_FFFE = *loader; loader++;
|
||||
reg_FFFF = *loader; loader++;
|
||||
|
||||
std::memcpy(&ram, loader, 0x2000); loader += 0x2000;
|
||||
std::memcpy(&cart_ram, loader, 0x2000); loader += 0x2000;
|
||||
|
||||
remap_ROM_0();
|
||||
remap_ROM_1();
|
||||
remap_ROM_2();
|
||||
remap_RAM();
|
||||
|
||||
return loader;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
};
|
||||
}
|
|
@ -239,7 +239,7 @@ namespace MSXHawk
|
|||
|
||||
#pragma region State Save / Load
|
||||
|
||||
void SaveState(uint8_t* saver)
|
||||
uint8_t* SaveState(uint8_t* saver)
|
||||
{
|
||||
*saver = (uint8_t)(vol_tone ? 1 : 0); saver++;
|
||||
*saver = (uint8_t)(noise_type ? 1 : 0); saver++;
|
||||
|
@ -292,10 +292,12 @@ namespace MSXHawk
|
|||
*saver = (uint8_t)((old_sample_L >> 16) & 0xFF); saver++; *saver = (uint8_t)((old_sample_L >> 24) & 0xFF); saver++;
|
||||
|
||||
*saver = (uint8_t)(old_sample_R & 0xFF); saver++; *saver = (uint8_t)((old_sample_R >> 8) & 0xFF); saver++;
|
||||
*saver = (uint8_t)((old_sample_R >> 16) & 0xFF); saver++; *saver = (uint8_t)((old_sample_R >> 24) & 0xFF); saver++;
|
||||
*saver = (uint8_t)((old_sample_R >> 16) & 0xFF); saver++; *saver = (uint8_t)((old_sample_R >> 24) & 0xFF); saver++;
|
||||
|
||||
return saver;
|
||||
}
|
||||
|
||||
void LoadState(uint8_t* loader)
|
||||
uint8_t* LoadState(uint8_t* loader)
|
||||
{
|
||||
vol_tone = *loader == 1; loader++;
|
||||
noise_type = *loader == 1; loader++;
|
||||
|
@ -349,6 +351,8 @@ namespace MSXHawk
|
|||
|
||||
old_sample_R = *loader; loader++; old_sample_R |= (*loader << 8); loader++;
|
||||
old_sample_R |= (*loader << 16); loader++; old_sample_R |= (*loader << 24); loader++;
|
||||
|
||||
return loader;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
|
|
@ -1201,7 +1201,7 @@ namespace MSXHawk
|
|||
|
||||
#pragma region State Save / Load
|
||||
|
||||
void SaveState(uint8_t* saver)
|
||||
uint8_t* SaveState(uint8_t* saver)
|
||||
{
|
||||
*saver = (uint8_t)(VdpWaitingForLatchInt ? 1 : 0); saver++;
|
||||
*saver = (uint8_t)(VIntPending ? 1 : 0); saver++;
|
||||
|
@ -1249,9 +1249,11 @@ namespace MSXHawk
|
|||
|
||||
*saver = (uint8_t)(ScanLine & 0xFF); saver++; *saver = (uint8_t)((ScanLine >> 8) & 0xFF); saver++;
|
||||
*saver = (uint8_t)((ScanLine >> 16) & 0xFF); saver++; *saver = (uint8_t)((ScanLine >> 24) & 0xFF); saver++;
|
||||
|
||||
return saver;
|
||||
}
|
||||
|
||||
void LoadState(uint8_t* loader)
|
||||
uint8_t* LoadState(uint8_t* loader)
|
||||
{
|
||||
VdpWaitingForLatchInt = *loader == 1; loader++;
|
||||
VIntPending = *loader == 1; loader++;
|
||||
|
@ -1300,11 +1302,11 @@ namespace MSXHawk
|
|||
ScanLine = *loader; loader++; ScanLine |= (*loader << 8); loader++;
|
||||
ScanLine |= (*loader << 16); loader++; ScanLine |= (*loader << 24); loader++;
|
||||
|
||||
for (uint32_t i = 0; i < 16; i++)
|
||||
WriteRegister(i, Registers[i]);
|
||||
for (uint16_t i = 0; i < 0x4000; i++)
|
||||
UpdatePatternBuffer(i, VRAM[i]);
|
||||
for (uint32_t i = 0; i < 16; i++) { WriteRegister(i, Registers[i]); }
|
||||
for (uint16_t i = 0; i < 0x4000; i++) { UpdatePatternBuffer(i, VRAM[i]); }
|
||||
UpdatePrecomputedPalette();
|
||||
|
||||
return loader;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
|
|
@ -70,7 +70,7 @@ namespace MSXHawk
|
|||
uint32_t BUSRQ[19] = {}; // fixed size - do not change at runtime
|
||||
uint32_t MEMRQ[19] = {}; // fixed size - do not change at runtime
|
||||
|
||||
long TotalExecutedCycles;
|
||||
uint64_t TotalExecutedCycles;
|
||||
|
||||
// non-state variables
|
||||
uint32_t Ztemp1, Ztemp2, Ztemp3, Ztemp4;
|
||||
|
@ -962,46 +962,6 @@ namespace MSXHawk
|
|||
cur_instr[33] = d33; cur_instr[34] = d34; cur_instr[35] = d35;
|
||||
cur_instr[36] = d36; cur_instr[37] = d37;
|
||||
}
|
||||
/*
|
||||
// State Save/Load
|
||||
void SyncState(Serializer ser)
|
||||
{
|
||||
ser.BeginSection(nameof(Z80A));
|
||||
ser.Sync(nameof(Regs), ref Regs, false);
|
||||
ser.Sync("NMI", ref nonMaskableInterrupt);
|
||||
ser.Sync("NMIPending", ref nonMaskableInterruptPending);
|
||||
ser.Sync("IM", ref interruptMode);
|
||||
ser.Sync("IFF1", ref iff1);
|
||||
ser.Sync("IFF2", ref iff2);
|
||||
ser.Sync("Halted", ref halted);
|
||||
ser.Sync(nameof(I_skip), ref I_skip);
|
||||
ser.Sync("ExecutedCycles", ref TotalExecutedCycles);
|
||||
ser.Sync(nameof(EI_pending), ref EI_pending);
|
||||
|
||||
ser.Sync(nameof(instr_pntr), ref instr_pntr);
|
||||
ser.Sync(nameof(bus_pntr), ref bus_pntr);
|
||||
ser.Sync(nameof(mem_pntr), ref mem_pntr);
|
||||
ser.Sync(nameof(irq_pntr), ref irq_pntr);
|
||||
ser.Sync(nameof(cur_instr), ref cur_instr, false);
|
||||
ser.Sync(nameof(BUSRQ), ref BUSRQ, false);
|
||||
ser.Sync(nameof(IRQS), ref IRQS);
|
||||
ser.Sync(nameof(MEMRQ), ref MEMRQ, false);
|
||||
ser.Sync(nameof(opcode), ref opcode);
|
||||
ser.Sync(nameof(FlagI), ref FlagI);
|
||||
ser.Sync(nameof(FlagW), ref FlagW);
|
||||
|
||||
ser.Sync(nameof(NO_prefix), ref NO_prefix);
|
||||
ser.Sync(nameof(CB_prefix), ref CB_prefix);
|
||||
ser.Sync(nameof(IX_prefix), ref IX_prefix);
|
||||
ser.Sync(nameof(IY_prefix), ref IY_prefix);
|
||||
ser.Sync(nameof(IXCB_prefix), ref IXCB_prefix);
|
||||
ser.Sync(nameof(IYCB_prefix), ref IYCB_prefix);
|
||||
ser.Sync(nameof(EXTD_prefix), ref EXTD_prefix);
|
||||
ser.Sync(nameof(PRE_SRC), ref PRE_SRC);
|
||||
|
||||
ser.EndSection();
|
||||
}
|
||||
*/
|
||||
|
||||
void InitTableParity()
|
||||
{
|
||||
|
@ -4553,7 +4513,7 @@ namespace MSXHawk
|
|||
reg_state.append(val_char_1, 4);
|
||||
|
||||
reg_state.append(" Cy:");
|
||||
reg_state.append(val_char_1, sprintf_s(val_char_1, 32, "%16u", TotalExecutedCycles));
|
||||
reg_state.append(val_char_1, sprintf_s(val_char_1, 32, "%16u", (unsigned int)TotalExecutedCycles));
|
||||
reg_state.append(" ");
|
||||
|
||||
reg_state.append(FlagCget() ? "C" : "c");
|
||||
|
@ -5168,7 +5128,7 @@ namespace MSXHawk
|
|||
|
||||
#pragma region State Save / Load
|
||||
|
||||
void SaveState(uint8_t* saver)
|
||||
uint8_t* SaveState(uint8_t* saver)
|
||||
{
|
||||
*saver = (uint8_t)(NO_prefix ? 1 : 0); saver++;
|
||||
*saver = (uint8_t)(CB_prefix ? 1 : 0); saver++;
|
||||
|
@ -5229,9 +5189,16 @@ namespace MSXHawk
|
|||
*saver = (uint8_t)(MEMRQ[i] & 0xFF); saver++; *saver = (uint8_t)((MEMRQ[i] >> 8) & 0xFF); saver++;
|
||||
*saver = (uint8_t)((MEMRQ[i] >> 16) & 0xFF); saver++; *saver = (uint8_t)((MEMRQ[i] >> 24) & 0xFF); saver++;
|
||||
}
|
||||
|
||||
*saver = (uint8_t)(TotalExecutedCycles & 0xFF); saver++; *saver = (uint8_t)((TotalExecutedCycles >> 8) & 0xFF); saver++;
|
||||
*saver = (uint8_t)((TotalExecutedCycles >> 16) & 0xFF); saver++; *saver = (uint8_t)((TotalExecutedCycles >> 24) & 0xFF); saver++;
|
||||
*saver = (uint8_t)((TotalExecutedCycles >> 16) & 0x32); saver++; *saver = (uint8_t)((TotalExecutedCycles >> 40) & 0xFF); saver++;
|
||||
*saver = (uint8_t)((TotalExecutedCycles >> 16) & 0x48); saver++; *saver = (uint8_t)((TotalExecutedCycles >> 56) & 0xFF); saver++;
|
||||
|
||||
return saver;
|
||||
}
|
||||
|
||||
void LoadState(uint8_t* loader)
|
||||
uint8_t* LoadState(uint8_t* loader)
|
||||
{
|
||||
NO_prefix = *loader == 1; loader++;
|
||||
CB_prefix = *loader == 1; loader++;
|
||||
|
@ -5292,6 +5259,13 @@ namespace MSXHawk
|
|||
MEMRQ[i] = *loader; loader++; MEMRQ[i] |= (*loader << 8); loader++;
|
||||
MEMRQ[i] |= (*loader << 16); loader++; MEMRQ[i] |= (*loader << 24); loader++;
|
||||
}
|
||||
|
||||
TotalExecutedCycles = *loader; loader++; TotalExecutedCycles |= (*loader << 8); loader++;
|
||||
TotalExecutedCycles |= (*loader << 16); loader++; TotalExecutedCycles |= (*loader << 24); loader++;
|
||||
TotalExecutedCycles |= ((uint64_t)*loader << 32); loader++; TotalExecutedCycles |= ((uint64_t)*loader << 40); loader++;
|
||||
TotalExecutedCycles |= ((uint64_t)*loader << 48); loader++; TotalExecutedCycles |= ((uint64_t)*loader << 56); loader++;
|
||||
|
||||
return loader;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
|
Loading…
Reference in New Issue