diff --git a/BizHawk.Emulation.Cores/Consoles/Sony/PSX/Octoshock.cs b/BizHawk.Emulation.Cores/Consoles/Sony/PSX/Octoshock.cs
index 185f9e8e7b..64583b7319 100644
--- a/BizHawk.Emulation.Cores/Consoles/Sony/PSX/Octoshock.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Sony/PSX/Octoshock.cs
@@ -21,7 +21,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
isPorted: true,
isReleased: false
)]
- public unsafe class Octoshock : IEmulator, IVideoProvider, ISyncSoundProvider, IMemoryDomains, ISaveRam, IDriveLight
+ public unsafe class Octoshock : IEmulator, IVideoProvider, ISyncSoundProvider, IMemoryDomains, ISaveRam, IStatable, IDriveLight
{
public string SystemId { get { return "PSX"; } }
@@ -213,7 +213,6 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
OctoshockDll.shock_Create(out psx, region, pFirmware);
SetMemoryDomains();
- StudySaveBufferSize();
//these should track values in octoshock gpu.cpp FillVideoParams
//if (discInfo.region == OctoshockDll.eRegion.EU)
@@ -248,6 +247,10 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
OctoshockDll.shock_MountEXE(psx, pExeBuffer, exe.Length);
}
OctoshockDll.shock_Peripheral_Connect(psx, 0x01, OctoshockDll.ePeripheralType.DualShock);
+
+ //do this after framebuffers and peripherals and whatever crap are setup. kind of lame, but thats how it is for now
+ StudySaveBufferSize();
+
OctoshockDll.shock_PowerOn(psx);
}
@@ -503,7 +506,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
var transaction = new OctoshockDll.ShockStateTransaction()
{
transaction = OctoshockDll.eShockStateTransaction.TextLoad,
- ff = s.GetFunctionPointersSave()
+ ff = s.GetFunctionPointersLoad()
};
int result = OctoshockDll.shock_StateTransaction(psx, ref transaction);
diff --git a/output/dll/octoshock.dll b/output/dll/octoshock.dll
index 20162735f3..85777f5953 100644
Binary files a/output/dll/octoshock.dll and b/output/dll/octoshock.dll differ
diff --git a/psx/octoshock/bizhawk/octoshock.vcxproj b/psx/octoshock/bizhawk/octoshock.vcxproj
index 7dacd099b4..e5bc0bd275 100644
--- a/psx/octoshock/bizhawk/octoshock.vcxproj
+++ b/psx/octoshock/bizhawk/octoshock.vcxproj
@@ -53,6 +53,7 @@
+
diff --git a/psx/octoshock/bizhawk/octoshock.vcxproj.filters b/psx/octoshock/bizhawk/octoshock.vcxproj.filters
index 61a5a98241..79b64800a8 100644
--- a/psx/octoshock/bizhawk/octoshock.vcxproj.filters
+++ b/psx/octoshock/bizhawk/octoshock.vcxproj.filters
@@ -226,6 +226,9 @@
emuware
+
+ cdrom
+
diff --git a/psx/octoshock/cdrom/SimpleFIFO.cpp b/psx/octoshock/cdrom/SimpleFIFO.cpp
index 5232837d15..f0a7f5fa14 100644
--- a/psx/octoshock/cdrom/SimpleFIFO.cpp
+++ b/psx/octoshock/cdrom/SimpleFIFO.cpp
@@ -1,6 +1,3 @@
#include "../mednafen.h"
#include "SimpleFIFO.h"
-
-
-
diff --git a/psx/octoshock/cdrom/SimpleFIFO.h b/psx/octoshock/cdrom/SimpleFIFO.h
index 5ec831d6b5..c705ec9bff 100644
--- a/psx/octoshock/cdrom/SimpleFIFO.h
+++ b/psx/octoshock/cdrom/SimpleFIFO.h
@@ -29,9 +29,10 @@ class SimpleFIFO
INLINE void SaveStatePostLoad(void)
{
- read_pos %= data.size();
- write_pos %= data.size();
- in_count %= (data.size() + 1);
+ //I think this is crap about file format (buffer size) change recovery. screw it.
+ //read_pos %= data.size();
+ //write_pos %= data.size();
+ //in_count %= (data.size() + 1);
}
#if 0
@@ -134,6 +135,20 @@ class SimpleFIFO
uint32 read_pos; // Read position
uint32 write_pos; // Write position
uint32 in_count; // Number of units in the FIFO
+
+ template void SyncState(EW::NewState *ns)
+ {
+ //I dont like this class...
+
+ PSS(&data[0], data.capacity());
+ NSS(read_pos);
+ NSS(write_pos);
+ NSS(in_count);
+
+
+ SaveStatePostLoad();
+ }
+
};
diff --git a/psx/octoshock/emuware/EW_state.cpp b/psx/octoshock/emuware/EW_state.cpp
index e16a68392b..21912a1134 100644
--- a/psx/octoshock/emuware/EW_state.cpp
+++ b/psx/octoshock/emuware/EW_state.cpp
@@ -1,6 +1,8 @@
#include "EW_state.h"
#include
#include
+#include
+#include
namespace EW {
@@ -56,13 +58,37 @@ void NewStateExternalFunctions::Load(void *ptr, size_t size, const char *name)
{
Load_(ptr, size, name);
}
-void NewStateExternalFunctions::EnterSection(const char *name)
+
+void NewStateExternalFunctions::EnterSection(const char *name, ...)
{
- EnterSection_(name);
+ //analysis: multiple passes to generate string not ideal, but there arent many sections.. so it should be OK. improvement would be special vararg overload
+ va_list ap;
+ va_start(ap,name);
+ char easybuf[32];
+ int size = vsnprintf(easybuf,0,name,ap);
+ char *ptr = easybuf;
+ if(size>31)
+ ptr = (char*)malloc(size+1);
+ vsprintf(ptr,name,ap);
+ EnterSection_(ptr);
+ if(ptr != easybuf)
+ free(ptr);
+ va_end(ap);
}
-void NewStateExternalFunctions::ExitSection(const char *name)
+void NewStateExternalFunctions::ExitSection(const char *name, ...)
{
- ExitSection_(name);
+ va_list ap;
+ va_start(ap,name);
+ char easybuf[32];
+ int size = vsnprintf(easybuf,0,name,ap);
+ char *ptr = easybuf;
+ if(size>31)
+ ptr = (char*)malloc(size+1);
+ vsprintf(ptr,name,ap);
+ ExitSection_(ptr);
+ if(ptr != easybuf)
+ free(ptr);
+ va_end(ap);
}
diff --git a/psx/octoshock/emuware/EW_state.h b/psx/octoshock/emuware/EW_state.h
index dfae22a4ab..acd3c1396a 100644
--- a/psx/octoshock/emuware/EW_state.h
+++ b/psx/octoshock/emuware/EW_state.h
@@ -12,8 +12,8 @@ namespace EW
public:
virtual void Save(const void *ptr, size_t size, const char *name) = 0;
virtual void Load(void *ptr, size_t size, const char *name) = 0;
- virtual void EnterSection(const char *name) { }
- virtual void ExitSection(const char *name) { }
+ virtual void EnterSection(const char *name, ...) { }
+ virtual void ExitSection(const char *name, ...) { }
};
class NewStateDummy : public NewState
@@ -62,8 +62,8 @@ namespace EW
NewStateExternalFunctions(const FPtrs *ff);
virtual void Save(const void *ptr, size_t size, const char *name);
virtual void Load(void *ptr, size_t size, const char *name);
- virtual void EnterSection(const char *name);
- virtual void ExitSection(const char *name);
+ virtual void EnterSection(const char *name, ...);
+ virtual void ExitSection(const char *name, ...);
};
// defines and explicitly instantiates
diff --git a/psx/octoshock/psx/cdc.cpp b/psx/octoshock/psx/cdc.cpp
index 6938182eeb..2b6f5800c8 100644
--- a/psx/octoshock/psx/cdc.cpp
+++ b/psx/octoshock/psx/cdc.cpp
@@ -215,99 +215,83 @@ void PS_CDC::Power(void)
lastts = 0;
}
-int PS_CDC::StateAction(StateMem *sm, int load, int data_only)
+SYNCFUNC(PS_CDC)
{
- SFORMAT StateRegs[] =
- {
- SFVAR(DiscChanged),
- SFVAR(DiscStartupDelay),
+ NSS(DiscChanged);
+ NSS(DiscStartupDelay);
- SFARRAY16(&AudioBuffer.Samples[0][0], sizeof(AudioBuffer.Samples) / sizeof(AudioBuffer.Samples[0][0])),
- SFVAR(AudioBuffer.Size),
- SFVAR(AudioBuffer.Freq),
- SFVAR(AudioBuffer.ReadPos),
+ NSS(AudioBuffer);
- SFARRAY(&Pending_DecodeVolume[0][0], 2 * 2),
- SFARRAY(&DecodeVolume[0][0], 2 * 2),
+ NSS(Pending_DecodeVolume);
+ NSS(DecodeVolume);
- SFARRAY16(&ADPCM_ResampBuf[0][0], sizeof(ADPCM_ResampBuf) / sizeof(ADPCM_ResampBuf[0][0])),
- SFVAR(ADPCM_ResampCurPhase),
- SFVAR(ADPCM_ResampCurPos),
+ NSS(ADPCM_ResampBuf);
+ NSS(ADPCM_ResampCurPhase);
+ NSS(ADPCM_ResampCurPos);
+
+ NSS(RegSelector);
+ NSS(ArgsBuf);
+ NSS(ArgsWP);
+ NSS(ArgsRP);
+
+ NSS(ArgsReceiveLatch);
+ NSS(ArgsReceiveBuf);
+ NSS(ArgsReceiveIn);
+
+ NSS(ResultsBuffer);
+ NSS(ResultsIn);
+ NSS(ResultsWP);
+ NSS(ResultsRP);
+
+ SSS(DMABuffer);
+
+ NSS(SB);
+ NSS(SB_In);
+
+ NSS(SectorPipe);
+ NSS(SectorPipe_Pos);
+ NSS(SectorPipe_In);
+
+ NSS(SubQBuf);
+ NSS(SubQBuf_Safe);
+
+ NSS(SubQChecksumOK);
+
+ NSS(HeaderBufValid);
+ NSS(HeaderBuf);
+
+ NSS(IRQBuffer);
+ NSS(IRQOutTestMask);
+ NSS(CDCReadyReceiveCounter);
+ NSS(FilterFile);
+ NSS(FilterChan);
- SFVAR(RegSelector),
- SFARRAY(ArgsBuf, 16),
- SFVAR(ArgsWP),
- SFVAR(ArgsRP),
+ NSS(PendingCommand);
+ NSS(PendingCommandPhase);
+ NSS(PendingCommandCounter);
- SFVAR(ArgsReceiveLatch),
- SFARRAY(ArgsReceiveBuf, 32),
- SFVAR(ArgsReceiveIn),
+ NSS(SPUCounter);
- SFARRAY(ResultsBuffer, 16),
- SFVAR(ResultsIn),
- SFVAR(ResultsWP),
- SFVAR(ResultsRP),
+ NSS(Mode);
+ NSS(DriveStatus);
+ NSS(StatusAfterSeek);
+ NSS(Forward);
+ NSS(Backward);
+ NSS(Muted);
- //
- //
- //
- SFARRAY(&DMABuffer.data[0], DMABuffer.data.size()),
- SFVAR(DMABuffer.read_pos),
- SFVAR(DMABuffer.write_pos),
- SFVAR(DMABuffer.in_count),
- //
- //
- //
+ NSS(PlayTrackMatch);
- SFARRAY(SB, sizeof(SB) / sizeof(SB[0])),
- SFVAR(SB_In),
+ NSS(PSRCounter);
- SFARRAY(&SectorPipe[0][0], sizeof(SectorPipe) / sizeof(SectorPipe[0][0])),
- SFVAR(SectorPipe_Pos),
- SFVAR(SectorPipe_In),
+ NSS(CurSector);
- SFARRAY(SubQBuf, sizeof(SubQBuf) / sizeof(SubQBuf[0])),
- SFARRAY(SubQBuf_Safe, sizeof(SubQBuf_Safe) / sizeof(SubQBuf_Safe[0])),
+ NSS(AsyncIRQPending);
+ NSS(AsyncResultsPending);
+ NSS(AsyncResultsPendingCount);
- SFVAR(SubQChecksumOK),
-
- SFVAR(HeaderBufValid),
- SFARRAY(HeaderBuf, sizeof(HeaderBuf) / sizeof(HeaderBuf[0])),
-
- SFVAR(IRQBuffer),
- SFVAR(IRQOutTestMask),
- SFVAR(CDCReadyReceiveCounter),
-
-
- SFVAR(FilterFile),
- SFVAR(FilterChan),
-
- SFVAR(PendingCommand),
- SFVAR(PendingCommandPhase),
- SFVAR(PendingCommandCounter),
-
- SFVAR(SPUCounter),
-
- SFVAR(Mode),
- SFVAR(DriveStatus),
- SFVAR(StatusAfterSeek),
- SFVAR(Forward),
- SFVAR(Backward),
- SFVAR(Muted),
-
- SFVAR(PlayTrackMatch),
-
- SFVAR(PSRCounter),
-
- SFVAR(CurSector),
-
- SFVAR(AsyncIRQPending),
- SFARRAY(AsyncResultsPending, sizeof(AsyncResultsPending) / sizeof(AsyncResultsPending[0])),
- SFVAR(AsyncResultsPendingCount),
-
- SFVAR(SeekTarget),
+ NSS(SeekTarget);
// FIXME: Save TOC stuff?
#if 0
@@ -316,27 +300,17 @@ int PS_CDC::StateAction(StateMem *sm, int load, int data_only)
uint8 DiscID[4];
#endif
- SFVAR(CommandLoc),
- SFVAR(CommandLoc_Dirty),
- SFARRAY16(&xa_previous[0][0], sizeof(xa_previous) / sizeof(xa_previous[0][0])),
+ NSS(CommandLoc);
+ NSS(CommandLoc_Dirty);
+ NSS(xa_previous);
- SFVAR(xa_cur_set),
- SFVAR(xa_cur_file),
- SFVAR(xa_cur_chan),
+ NSS(xa_cur_set);
+ NSS(xa_cur_file);
+ NSS(xa_cur_chan);
- SFVAR(ReportLastF),
+ NSS(ReportLastF);
- SFEND
- };
-
- int ret = MDFNSS_StateAction(sm, load, data_only, StateRegs, "CDC");
-
- if(load)
- {
- DMABuffer.SaveStatePostLoad();
- SectorPipe_Pos %= SectorPipe_Count;
- }
- return(ret);
+ //(%= crap about file format recovery in case SectorPipe_Pos changes)
}
void PS_CDC::ResetTS(void)
diff --git a/psx/octoshock/psx/cdc.h b/psx/octoshock/psx/cdc.h
index f2925aef93..5774547492 100644
--- a/psx/octoshock/psx/cdc.h
+++ b/psx/octoshock/psx/cdc.h
@@ -25,6 +25,8 @@ class PS_CDC
PS_CDC();
~PS_CDC();
+ templatevoid SyncState(EW::NewState *ns);
+
void SetDisc(bool tray_open, ShockDiscRef *disc, const char disc_id[4]);
void Power(void);
diff --git a/psx/octoshock/psx/cpu.cpp b/psx/octoshock/psx/cpu.cpp
index 42c53c909e..c9e4ac8953 100644
--- a/psx/octoshock/psx/cpu.cpp
+++ b/psx/octoshock/psx/cpu.cpp
@@ -951,4 +951,39 @@ void PS_CPU::CheckBreakpoints(void (*callback)(bool write, uint32_t address, uns
}
-}
+
+SYNCFUNC(PS_CPU)
+{
+ NSS(GPR);
+ NSS(LO);
+ NSS(HI);
+ NSS(BACKED_PC);
+ NSS(BACKED_new_PC);
+ NSS(BACKED_new_PC_mask);
+
+ NSS(IPCache);
+ NSS(Halted);
+
+ NSS(BACKED_LDWhich);
+ NSS(BACKED_LDValue);
+ NSS(LDAbsorb);
+
+ NSS(next_event_ts);
+ NSS(gte_ts_done);
+ NSS(muldiv_ts_done);
+
+ NSS(BIU);
+ NSS(ICache_Bulk);
+
+ NSS(CP0.Regs);
+
+ NSS(ReadAbsorb);
+ NSS(ReadAbsorbDummy);
+ NSS(ReadAbsorbWhich);
+ NSS(ReadFudge);
+
+ NSS(ScratchRAM.data8);
+
+} //SYNCFUNC(CPU)
+
+} //namespace MDFN_IEN_PSX
diff --git a/psx/octoshock/psx/cpu.h b/psx/octoshock/psx/cpu.h
index 7734001686..426a8d3c25 100644
--- a/psx/octoshock/psx/cpu.h
+++ b/psx/octoshock/psx/cpu.h
@@ -52,6 +52,8 @@ class PS_CPU
PS_CPU();
~PS_CPU();
+ templatevoid SyncState(EW::NewState *ns);
+
// FAST_MAP_* enums are in BYTES(8-bit), not in 32-bit units("words" in MIPS context), but the sizes
// will always be multiples of 4.
enum { FAST_MAP_SHIFT = 16 };
diff --git a/psx/octoshock/psx/dma.cpp b/psx/octoshock/psx/dma.cpp
index 270f84de93..09d162c5a2 100644
--- a/psx/octoshock/psx/dma.cpp
+++ b/psx/octoshock/psx/dma.cpp
@@ -777,44 +777,14 @@ uint32 DMA_Read(const pscpu_timestamp_t timestamp, uint32 A)
return(ret);
}
-
-int DMA_StateAction(StateMem *sm, int load, int data_only)
+void DMA_SyncState(bool isReader, EW::NewState *ns)
{
- SFORMAT StateRegs[] =
- {
- SFVAR(DMACycleCounter),
- SFVAR(DMAControl),
- SFVAR(DMAIntControl),
- SFVAR(DMAIntStatus),
- SFVAR(IRQOut),
-
-#define SFDMACH(n) SFVARN(DMACH[n].BaseAddr, #n "BaseAddr"), \
- SFVARN(DMACH[n].BlockControl, #n "BlockControl"), \
- SFVARN(DMACH[n].ChanControl, #n "ChanControl"), \
- SFVARN(DMACH[n].CurAddr, #n "CurAddr"), \
- SFVARN(DMACH[n].WordCounter, #n "WordCounter"), \
- SFVARN(DMACH[n].ClockCounter, #n "ClockCounter")
-
- SFDMACH(0),
- SFDMACH(1),
- SFDMACH(2),
- SFDMACH(3),
- SFDMACH(4),
- SFDMACH(5),
- SFDMACH(6),
-
-#undef SFDMACH
-
- SFEND
- };
- int ret = MDFNSS_StateAction(sm, load, data_only, StateRegs, "DMA");
-
- if(load)
- {
-
- }
-
- return(ret);
+ NSS(DMACycleCounter);
+ NSS(DMAControl);
+ NSS(DMAIntControl);
+ NSS(DMAIntStatus);
+ NSS(IRQOut);
+ NSS(DMACH);
}
diff --git a/psx/octoshock/psx/frontio.cpp b/psx/octoshock/psx/frontio.cpp
index 9e6666ecd4..8eaae1b0cb 100644
--- a/psx/octoshock/psx/frontio.cpp
+++ b/psx/octoshock/psx/frontio.cpp
@@ -141,9 +141,10 @@ FrontIO::FrontIO()
MCPorts[i] = new InputDevice();
}
- //always add one memory device for now
+ //always add one memory device for now
+ delete MCPorts[0];
MCPorts[0] = Device_Memcard_Create();
-}
+}
FrontIO::~FrontIO()
@@ -625,6 +626,68 @@ uint64 FrontIO::GetMemcardDirtyCount(unsigned int which)
return(MCPorts[which]->GetNVDirtyCount());
}
+//TODO - ok, savestating varying input devices. this is tricky.
+//its like... what happens when the hardware unfreezes with different input attached?
+//thats some kind of instantaneous change event which shouldnt/cant be properly emulated or likely even implemented
+//so in that respect it's very much like (if not identical to) CDs.
+//heres a discussion question. what are we doing here? savestating the CONSOLE or savestating the ENTIRE SYSTEM?
+//well, what's being emulated?
+//I dont know. lets save it for later.
+//You know, this is one reason mednafen had a distinction between ports and devices.
+//But I had to get rid of it, I just had to. At least they need to be organized into a pool differently somehow.
+
+//Anyway, think about this: We cant just savestate the entire system. The game will be depending on the input devices being in a certain state.
+//If theyre in any other state, literally, any other state, then the game will fail.
+//Therefore the entire system needs saving together and mismatches MUST NOT BE PERMITTED.
+
+SYNCFUNC(FrontIO)
+{
+ NSS(ClockDivider);
+
+ NSS(ReceivePending);
+ NSS(TransmitPending);
+
+ NSS(ReceiveInProgress);
+ NSS(TransmitInProgress);
+
+ NSS(ReceiveBufferAvail);
+
+ NSS(ReceiveBuffer);
+ NSS(TransmitBuffer);
+
+ NSS(ReceiveBitCounter);
+ NSS(TransmitBitCounter);
+
+ NSS(Mode);
+ NSS(Control);
+ NSS(Baudrate);
+
+ NSS(istatus);
+
+ // FIXME: Step mode save states.
+ NSS(irq10_pulse_ts);
+ NSS(dsr_pulse_delay);
+ NSS(dsr_active_until_ts);
+
+ //state actions for ports and such
+ for(int i=0;i<2;i++)
+ {
+ ns->EnterSection("PORT%d",i);
+ Ports[i]->SyncState(isReader,ns);
+ ns->ExitSection("PORT%d",i);
+ ns->EnterSection("MCPORT%d",i);
+ MCPorts[i]->SyncState(isReader,ns);
+ ns->ExitSection("MCPORT%d",i);
+ }
+
+ //more of this crap....
+ if(isReader)
+ {
+ IRQ_Assert(IRQ_SIO, istatus);
+ }
+
+}
+
int FrontIO::StateAction(StateMem* sm, int load, int data_only)
{
SFORMAT StateRegs[] =
diff --git a/psx/octoshock/psx/frontio.h b/psx/octoshock/psx/frontio.h
index cc7423a779..2f00b058c0 100644
--- a/psx/octoshock/psx/frontio.h
+++ b/psx/octoshock/psx/frontio.h
@@ -15,6 +15,8 @@ class InputDevice
virtual void Power(void);
virtual void UpdateInput(const void *data);
+
+ virtual void SyncState(bool isReader, EW::NewState *ns) {}
virtual int StateAction(StateMem* sm, int load, int data_only, const char* section_name);
virtual bool RequireNoFrameskip(void);
@@ -61,6 +63,8 @@ class FrontIO
FrontIO();
~FrontIO();
+ templatevoid SyncState(EW::NewState *ns);
+
void Power(void);
void Write(pscpu_timestamp_t timestamp, uint32 A, uint32 V);
uint32 Read(pscpu_timestamp_t timestamp, uint32 A);
diff --git a/psx/octoshock/psx/gpu.cpp b/psx/octoshock/psx/gpu.cpp
index f5d0eb68fb..85b4090f53 100644
--- a/psx/octoshock/psx/gpu.cpp
+++ b/psx/octoshock/psx/gpu.cpp
@@ -1573,119 +1573,105 @@ void PS_GPU::StartFrame(EmulateSpecStruct *espec_arg)
}
}
-int PS_GPU::StateAction(StateMem *sm, int load, int data_only)
+SYNCFUNC(PS_GPU)
{
- SFORMAT StateRegs[] =
- {
- SFARRAY16(&GPURAM[0][0], sizeof(GPURAM) / sizeof(GPURAM[0][0])),
+ NSS(GPURAM);
- SFVAR(DMAControl),
+ NSS(DMAControl);
- SFVAR(ClipX0),
- SFVAR(ClipY0),
- SFVAR(ClipX1),
- SFVAR(ClipY1),
+ NSS(ClipX0);
+ NSS(ClipY0);
+ NSS(ClipX1);
+ NSS(ClipY1);
- SFVAR(OffsX),
- SFVAR(OffsY),
+ NSS(OffsX);
+ NSS(OffsY);
- SFVAR(dtd),
- SFVAR(dfe),
+ NSS(dtd);
+ NSS(dfe);
- SFVAR(MaskSetOR),
- SFVAR(MaskEvalAND),
+ NSS(MaskSetOR);
+ NSS(MaskEvalAND);
- SFVAR(tww),
- SFVAR(twh),
- SFVAR(twx),
- SFVAR(twy),
+ NSS(tww);
+ NSS(twh);
+ NSS(twx);
+ NSS(twy);
- SFVAR(TexPageX),
- SFVAR(TexPageY),
+ NSS(TexPageX);
+ NSS(TexPageY);
- SFVAR(SpriteFlip),
+ NSS(SpriteFlip);
- SFVAR(abr),
- SFVAR(TexMode),
+ NSS(abr);
+ NSS(TexMode);
- SFARRAY32(&BlitterFIFO.data[0], BlitterFIFO.data.size()),
- SFVAR(BlitterFIFO.read_pos),
- SFVAR(BlitterFIFO.write_pos),
- SFVAR(BlitterFIFO.in_count),
+ SSS(BlitterFIFO);
- SFVAR(DataReadBuffer),
+ NSS(DataReadBuffer);
- SFVAR(IRQPending),
+ NSS(IRQPending);
- SFVAR(InCmd),
- SFVAR(InCmd_CC),
+ NSS(InCmd);
+ NSS(InCmd_CC);
-#define TVHELPER(n) SFVAR(n.x), SFVAR(n.y), SFVAR(n.u), SFVAR(n.v), SFVAR(n.r), SFVAR(n.g), SFVAR(n.b)
- TVHELPER(InQuad_F3Vertices[0]),
- TVHELPER(InQuad_F3Vertices[1]),
- TVHELPER(InQuad_F3Vertices[2]),
-#undef TVHELPER
- SFVAR(InQuad_clut),
+ NSS(InQuad_F3Vertices);
- SFVAR(InPLine_PrevPoint.x),
- SFVAR(InPLine_PrevPoint.y),
- SFVAR(InPLine_PrevPoint.r),
- SFVAR(InPLine_PrevPoint.g),
- SFVAR(InPLine_PrevPoint.b),
+ NSS(InQuad_clut);
- SFVAR(FBRW_X),
- SFVAR(FBRW_Y),
- SFVAR(FBRW_W),
- SFVAR(FBRW_H),
- SFVAR(FBRW_CurY),
- SFVAR(FBRW_CurX),
+ NSS(InPLine_PrevPoint);
- SFVAR(DisplayMode),
- SFVAR(DisplayOff),
- SFVAR(DisplayFB_XStart),
- SFVAR(DisplayFB_YStart),
+ NSS(FBRW_X);
+ NSS(FBRW_Y);
+ NSS(FBRW_W);
+ NSS(FBRW_H);
+ NSS(FBRW_CurY);
+ NSS(FBRW_CurX);
- SFVAR(HorizStart),
- SFVAR(HorizEnd),
+ NSS(DisplayMode);
+ NSS(DisplayOff);
+ NSS(DisplayFB_XStart);
+ NSS(DisplayFB_YStart);
- SFVAR(VertStart),
- SFVAR(VertEnd),
+ NSS(HorizStart);
+ NSS(HorizEnd);
- SFVAR(DisplayFB_CurYOffset),
- SFVAR(DisplayFB_CurLineYReadout),
+ NSS(VertStart);
+ NSS(VertEnd);
- SFVAR(InVBlank),
+ NSS(DisplayFB_CurYOffset);
+ NSS(DisplayFB_CurLineYReadout);
- SFVAR(LinesPerField),
- SFVAR(scanline),
- SFVAR(field),
- SFVAR(field_ram_readout),
- SFVAR(PhaseChange),
+ NSS(InVBlank);
- SFVAR(DotClockCounter),
+ NSS(LinesPerField);
+ NSS(scanline);
+ NSS(field);
+ NSS(field_ram_readout);
+ NSS(PhaseChange);
- SFVAR(GPUClockCounter),
- SFVAR(LineClockCounter),
- SFVAR(LinePhase),
+ NSS(DotClockCounter);
- SFVAR(DrawTimeAvail),
+ NSS(GPUClockCounter);
+ NSS(LineClockCounter);
+ NSS(LinePhase);
- SFEND
- };
- int ret = MDFNSS_StateAction(sm, load, data_only, StateRegs, "GPU");
+ NSS(DrawTimeAvail);
- if(load)
- {
- RecalcTexWindowLUT();
- BlitterFIFO.SaveStatePostLoad();
+ if(isReader)
+ {
+ //cached luts; safe not to sync
+ RecalcTexWindowLUT();
- HorizStart &= 0xFFF;
- HorizEnd &= 0xFFF;
+ //what the hell is this? I dont like it at all.
+ HorizStart &= 0xFFF;
+ HorizEnd &= 0xFFF;
- IRQ_Assert(IRQ_GPU, IRQPending);
- }
+ //this is kind of typical stuff, BUT: a cursory inspection reveals nothing. the IRQ and CPU modules should be handling it OK
+ //LOOK HERE FOR BUGS
+ IRQ_Assert(IRQ_GPU, IRQPending);
+ }
- return(ret);
}
}
diff --git a/psx/octoshock/psx/gpu.h b/psx/octoshock/psx/gpu.h
index c14f5783b5..2109318ccd 100644
--- a/psx/octoshock/psx/gpu.h
+++ b/psx/octoshock/psx/gpu.h
@@ -42,6 +42,8 @@ class PS_GPU
PS_GPU(bool pal_clock_and_tv, int sls, int sle) MDFN_COLD;
~PS_GPU() MDFN_COLD;
+ templatevoid SyncState(EW::NewState *ns);
+
void FillVideoParams(MDFNGI* gi) MDFN_COLD;
void Power(void) MDFN_COLD;
diff --git a/psx/octoshock/psx/gte.cpp b/psx/octoshock/psx/gte.cpp
index e83b907de7..32c800ae98 100644
--- a/psx/octoshock/psx/gte.cpp
+++ b/psx/octoshock/psx/gte.cpp
@@ -233,63 +233,11 @@ void GTE_Power(void)
Reg23 = 0;
}
-// TODO: Don't save redundant state, regarding CR cache variables
int GTE_StateAction(StateMem *sm, int load, int data_only)
{
- SFORMAT StateRegs[] =
- {
- SFARRAY32(CR, 32),
- SFVAR(FLAGS),
- SFARRAY16(&Matrices.Raw16[0][0], 4 * 10),
+return 1;
- SFARRAY32(&CRVectors.All[0][0], 4 * 4),
-
- SFVAR(OFX),
- SFVAR(OFY),
- SFVAR(H),
- SFVAR(DQA),
- SFVAR(DQB),
-
- SFVAR(ZSF3),
- SFVAR(ZSF4),
- SFARRAY16(&Vectors[0][0], 3 * 4),
-
- SFARRAY(RGB.Raw8, 4),
- SFVAR(OTZ),
- SFARRAY16(IR, 4),
-
- SFVAR(XY_FIFO[0].X),
- SFVAR(XY_FIFO[0].Y),
- SFVAR(XY_FIFO[1].X),
- SFVAR(XY_FIFO[1].Y),
- SFVAR(XY_FIFO[2].X),
- SFVAR(XY_FIFO[2].Y),
- SFVAR(XY_FIFO[3].X),
- SFVAR(XY_FIFO[3].Y),
-
- SFARRAY16(Z_FIFO, 4),
-
- SFARRAY(RGB_FIFO[0].Raw8, 4),
- SFARRAY(RGB_FIFO[1].Raw8, 4),
- SFARRAY(RGB_FIFO[2].Raw8, 4),
-
- SFARRAY32(MAC, 4),
-
- SFVAR(LZCS),
- SFVAR(LZCR),
- SFVAR(Reg23),
-
- SFEND
- };
- int ret = MDFNSS_StateAction(sm, load, data_only, StateRegs, "GTE");
-
- if(load)
- {
-
- }
-
- return(ret);
}
@@ -1731,6 +1679,43 @@ int32 GTE_Instruction(uint32 instr)
return(ret - 1);
}
+void GTE_SyncState(bool isReader, EW::NewState *ns)
+{
+ NSS(CR);
+ NSS(FLAGS);
+
+ NSS(Matrices);
+
+ NSS(CRVectors);
+
+ NSS(OFX);
+ NSS(OFY);
+ NSS(H);
+ NSS(DQA);
+ NSS(DQB);
+
+ NSS(ZSF3);
+ NSS(ZSF4);
+ NSS(Vectors);
+
+ NSS(RGB);
+ NSS(OTZ);
+ NSS(IR);
+
+ NSS(XY_FIFO);
+
+ NSS(Z_FIFO);
+
+ NSS(RGB_FIFO);
+
+ NSS(MAC);
+
+ NSS(LZCS);
+ NSS(LZCR);
+ NSS(Reg23);
+}
+
#ifndef PSXDEV_GTE_TESTING
}
#endif
+
diff --git a/psx/octoshock/psx/input/dualshock.cpp b/psx/octoshock/psx/input/dualshock.cpp
index f1847e9587..38509c94a8 100644
--- a/psx/octoshock/psx/input/dualshock.cpp
+++ b/psx/octoshock/psx/input/dualshock.cpp
@@ -60,7 +60,7 @@ class InputDevice_DualShock : public InputDevice
virtual ~InputDevice_DualShock();
virtual void Power(void);
- virtual int StateAction(StateMem* sm, int load, int data_only, const char* section_name);
+ virtual void SyncState(bool isReader, EW::NewState *ns);
virtual void Update(const pscpu_timestamp_t timestamp);
virtual void ResetTS(void);
@@ -232,56 +232,40 @@ void InputDevice_DualShock::Power(void)
prev_ana_button_state = false;
}
-int InputDevice_DualShock::StateAction(StateMem* sm, int load, int data_only, const char* section_name)
-{
- SFORMAT StateRegs[] =
+ void InputDevice_DualShock::SyncState(bool isReader, EW::NewState *ns)
{
- SFVAR(cur_ana_button_state),
- SFVAR(prev_ana_button_state),
- SFVAR(combo_anatoggle_counter),
+ NSS(cur_ana_button_state);
+ NSS(prev_ana_button_state);
+ NSS(combo_anatoggle_counter);
- SFVAR(da_rumble_compat),
+ NSS(da_rumble_compat);
- SFVAR(analog_mode),
- SFVAR(analog_mode_locked),
+ NSS(analog_mode);
+ NSS(analog_mode_locked);
- SFVAR(mad_munchkins),
- SFARRAY(rumble_magic, sizeof(rumble_magic)),
+ NSS(mad_munchkins);
+ NSS(rumble_magic);
- SFARRAY(rumble_param, sizeof(rumble_param)),
+ NSS(rumble_param);
- SFVAR(dtr),
+ NSS(dtr);
- SFARRAY(buttons, sizeof(buttons)),
- SFARRAY(&axes[0][0], sizeof(axes)),
+ NSS(buttons);
+ NSS(axes);
- SFVAR(command_phase),
- SFVAR(bitpos),
- SFVAR(receive_buffer),
+ NSS(command_phase);
+ NSS(bitpos);
+ NSS(receive_buffer);
- SFVAR(command),
+ NSS(command);
- SFARRAY(transmit_buffer, sizeof(transmit_buffer)),
- SFVAR(transmit_pos),
- SFVAR(transmit_count),
+ NSS(transmit_buffer);
+ NSS(transmit_pos);
+ NSS(transmit_count);
- SFEND
- };
- int ret = MDFNSS_StateAction(sm, load, data_only, StateRegs, section_name);
-
- if(load)
- {
- if((transmit_pos + transmit_count) > sizeof(transmit_buffer))
- {
- transmit_pos = 0;
- transmit_count = 0;
- }
+ //THERES MORE BUFFER SIZE SANITY CHECKS HERE. DONT LIKE THAT STUFF
}
- return(ret);
-}
-
-
void InputDevice_DualShock::UpdateInput(const void *data)
{
uint8 *d8 = (uint8 *)data;
diff --git a/psx/octoshock/psx/input/memcard.cpp b/psx/octoshock/psx/input/memcard.cpp
index db872a7bec..e201e6dfdf 100644
--- a/psx/octoshock/psx/input/memcard.cpp
+++ b/psx/octoshock/psx/input/memcard.cpp
@@ -41,7 +41,7 @@ class InputDevice_Memcard : public InputDevice
virtual void Power(void);
virtual int StateAction(StateMem* sm, int load, int data_only, const char* section_name);
-
+ virtual void SyncState(bool isReader, EW::NewState *ns);
//
//
//
@@ -162,6 +162,38 @@ void InputDevice_Memcard::Power(void)
presence_new = true;
}
+void InputDevice_Memcard::SyncState(bool isReader, EW::NewState *ns)
+{
+ NSS(presence_new);
+
+ NSS(rw_buffer);
+ NSS(write_xor);
+
+ NSS(dtr);
+ NSS(command_phase);
+ NSS(bitpos);
+ NSS(receive_buffer);
+
+ NSS(command);
+ NSS(addr);
+ NSS(calced_xor);
+
+ NSS(transmit_buffer);
+ NSS(transmit_count);
+
+ NSS(data_used);
+
+ //(now there was logic to avoid savestating cards that had never been used. only needed if we have a pool of cards)
+ //(also it called Format() but I dont see how that makes sense at all and anyway I'm ignoring it)
+
+ //now for the BIG QUESTION, regarding clobber's lament.
+ //we need to dump the contents of the card along with the register state. its necessary for safety.
+ //HOWEVER - we clear the dirty flag. that way, a user wont accidentally `clobber` his savestates when loading a state.
+ //instead, the state will only be dirtied when the game actually modifies the contents
+ NSS(card_data);
+ dirty_count = 0;
+}
+
int InputDevice_Memcard::StateAction(StateMem* sm, int load, int data_only, const char* section_name)
{
// Don't save dirty_count.
diff --git a/psx/octoshock/psx/irq.cpp b/psx/octoshock/psx/irq.cpp
index 20a36c7a13..61182b075d 100644
--- a/psx/octoshock/psx/irq.cpp
+++ b/psx/octoshock/psx/irq.cpp
@@ -58,6 +58,19 @@ int IRQ_StateAction(StateMem *sm, int load, int data_only)
}
+void IRQ_SyncState(bool isReader, EW::NewState *ns)
+{
+ NSS(Asserted);
+ NSS(Mask);
+ NSS(Status);
+
+ //as usual, not sure why this is necessary
+ if(isReader)
+ {
+ Recalc();
+ }
+}
+
void IRQ_Assert(int which, bool status)
{
uint32 old_Asserted = Asserted;
diff --git a/psx/octoshock/psx/mdec.cpp b/psx/octoshock/psx/mdec.cpp
index 3e3f366027..00218548f0 100644
--- a/psx/octoshock/psx/mdec.cpp
+++ b/psx/octoshock/psx/mdec.cpp
@@ -164,64 +164,50 @@ void MDEC_Power(void)
RAMOffsetWWS = 0;
}
-int MDEC_StateAction(StateMem *sm, int load, int data_only)
+template void MDEC_SyncState(EW::NewState *ns)
{
- SFORMAT StateRegs[] =
- {
- SFVAR(ClockCounter),
- SFVAR(MDRPhase),
+ NSS(ClockCounter);
+ NSS(MDRPhase);
-#define SFFIFO32(fifoobj) SFARRAY32(&fifoobj.data[0], fifoobj.data.size()), \
- SFVAR(fifoobj.read_pos), \
- SFVAR(fifoobj.write_pos), \
- SFVAR(fifoobj.in_count)
+ SSS(InFIFO);
+ SSS(OutFIFO);
- SFFIFO32(InFIFO),
- SFFIFO32(OutFIFO),
-#undef SFFIFO
+ NSS(block_y);
+ NSS(block_cb);
+ NSS(block_cr);
- SFARRAY(&block_y[0][0], sizeof(block_y) / sizeof(block_y[0][0])),
- SFARRAY(&block_cb[0][0], sizeof(block_cb) / sizeof(block_cb[0][0])),
- SFARRAY(&block_cr[0][0], sizeof(block_cr) / sizeof(block_cr[0][0])),
+ NSS(Control);
+ NSS(Command);
+ NSS(InCommand);
- SFVAR(Control),
- SFVAR(Command),
- SFVAR(InCommand),
+ NSS(QMatrix);
+ NSS(QMIndex);
- SFARRAY(&QMatrix[0][0], sizeof(QMatrix) / sizeof(QMatrix[0][0])),
- SFVAR(QMIndex),
+ NSS(IDCTMatrix);
+ NSS(IDCTMIndex);
- SFARRAY16(&IDCTMatrix[0], sizeof(IDCTMatrix) / sizeof(IDCTMatrix[0])),
- SFVAR(IDCTMIndex),
+ NSS(QScale);
- SFVAR(QScale),
+ NSS(Coeff);
+ NSS(CoeffIndex);
+ NSS(DecodeWB);
- SFARRAY16(&Coeff[0], sizeof(Coeff) / sizeof(Coeff[0])),
- SFVAR(CoeffIndex),
- SFVAR(DecodeWB),
+ NSS(PixelBuffer);
+ NSS(PixelBufferReadOffset);
+ NSS(PixelBufferCount32);
- SFARRAY32(&PixelBuffer.pix32[0], sizeof(PixelBuffer.pix32) / sizeof(PixelBuffer.pix32[0])),
- SFVAR(PixelBufferReadOffset),
- SFVAR(PixelBufferCount32),
+ NSS(InCounter);
- SFVAR(InCounter),
+ NSS(RAMOffsetY);
+ NSS(RAMOffsetCounter);
+ NSS(RAMOffsetWWS);
- SFVAR(RAMOffsetY),
- SFVAR(RAMOffsetCounter),
- SFVAR(RAMOffsetWWS),
+}
- SFEND
- };
-
- int ret = MDFNSS_StateAction(sm, load, data_only, StateRegs, "MDEC");
-
- if(load)
- {
- InFIFO.SaveStatePostLoad();
- OutFIFO.SaveStatePostLoad();
- }
-
- return(ret);
+void MDEC_SyncState(bool isReader, EW::NewState *ns)
+{
+ if(isReader) MDEC_SyncState(ns);
+ else MDEC_SyncState(ns);
}
static INLINE int8 Mask9ClampS8(int32 v)
diff --git a/psx/octoshock/psx/psx.cpp b/psx/octoshock/psx/psx.cpp
index e73f4e5989..a77c3e7681 100644
--- a/psx/octoshock/psx/psx.cpp
+++ b/psx/octoshock/psx/psx.cpp
@@ -1116,6 +1116,7 @@ struct {
case eShockMemcardTransaction_Write:
FIO->MCPorts[portnum]->WriteNV((uint8*)transaction->buffer128k,0,128*1024);
+ FIO->MCPorts[portnum]->ResetNVDirtyCount();
return SHOCK_OK;
case eShockMemcardTransaction_Read:
@@ -1825,62 +1826,6 @@ static void CloseGame(void)
Cleanup();
}
-static int StateAction(StateMem *sm, int load, int data_only)
-{
-
- //SFORMAT StateRegs[] =
- //{
- // NSS(CD_TrayOpen);
- // PSS(MainRAM.data8, 2*1024*1024);
- // NSS(SysControl.Regs, 9);
-
- // //SFVAR(PSX_PRNG.lcgo),
- // //SFVAR(PSX_PRNG.x),
- // //SFVAR(PSX_PRNG.y),
- // //SFVAR(PSX_PRNG.z),
- // //SFVAR(PSX_PRNG.c),
-
- // SFEND
- //};
-
- //int ret = MDFNSS_StateAction(sm, load, data_only, StateRegs, "MAIN");
-
- //// Call SetDisc() BEFORE we load CDC state, since SetDisc() has emulation side effects. We might want to clean this up in the future.
- //if(load)
- //{
- // if(CD_SelectedDisc >= (int)cdifs->size())
- // CD_SelectedDisc = -1;
-
- ////DAW????????????
- //// CDC->SetDisc(CD_TrayOpen, (CD_SelectedDisc >= 0 && !CD_TrayOpen) ? (*cdifs)[CD_SelectedDisc] : NULL,
- ////(CD_SelectedDisc >= 0 && !CD_TrayOpen) ? cdifs_scex_ids[CD_SelectedDisc] : NULL);
- //}
-
- //// TODO: Remember to increment dirty count in memory card state loading routine.
-
- //ret &= CPU->StateAction(sm, load, data_only);
- //ret &= DMA_StateAction(sm, load, data_only);
- //ret &= TIMER_StateAction(sm, load, data_only);
- //ret &= SIO_StateAction(sm, load, data_only);
-
- //ret &= CDC->StateAction(sm, load, data_only);
- //ret &= MDEC_StateAction(sm, load, data_only);
- //ret &= GPU->StateAction(sm, load, data_only);
- //ret &= SPU->StateAction(sm, load, data_only);
-
- //ret &= FIO->StateAction(sm, load, data_only);
-
- //ret &= IRQ_StateAction(sm, load, data_only); // Do it last.
-
- //if(load)
- //{
- // ForceEventUpdates(0); // FIXME to work with debugger step mode.
- //}
-
- //return(ret);
- return 0;
-}
-
static void CDInsertEject(void)
{
CD_TrayOpen = !CD_TrayOpen;
@@ -1922,6 +1867,10 @@ EW_EXPORT s32 shock_SetDisc(void* psx, ShockDiscRef* disc)
s32 ret = shock_AnalyzeDisc(disc,&info);
if(ret != SHOCK_OK) return ret;
+ //heres a comment from some old savestating code. something to keep in mind (maybe or maybe not a surprise depending on your point of view)
+ //"Call SetDisc() BEFORE we load CDC state, since SetDisc() has emulation side effects. We might want to clean this up in the future."
+ //I'm not really sure I like how SetDisc works, so I'm glad this was brought to our attention
+
s_CurrDiscInfo = info;
s_CurrDisc = disc;
CDC->SetDisc(true,s_CurrDisc,s_CurrDiscInfo.id);
@@ -2419,62 +2368,79 @@ public:
templatevoid SyncState(EW::NewState *ns);
} s_PSX;
-//--OLD SAVESTATE--
- //SFORMAT StateRegs[] =
- //{
- // NSS(CD_TrayOpen);
- // PSS(MainRAM.data8, 2*1024*1024);
- // NSS(SysControl.Regs, 9);
-
- // //SFVAR(PSX_PRNG.lcgo),
- // //SFVAR(PSX_PRNG.x),
- // //SFVAR(PSX_PRNG.y),
- // //SFVAR(PSX_PRNG.z),
- // //SFVAR(PSX_PRNG.c),
-
- // SFEND
- //};
-
- //int ret = MDFNSS_StateAction(sm, load, data_only, StateRegs, "MAIN");
-
- //// Call SetDisc() BEFORE we load CDC state, since SetDisc() has emulation side effects. We might want to clean this up in the future.
- //if(load)
- //{
- // if(CD_SelectedDisc >= (int)cdifs->size())
- // CD_SelectedDisc = -1;
-
- ////DAW????????????
- //// CDC->SetDisc(CD_TrayOpen, (CD_SelectedDisc >= 0 && !CD_TrayOpen) ? (*cdifs)[CD_SelectedDisc] : NULL,
- ////(CD_SelectedDisc >= 0 && !CD_TrayOpen) ? cdifs_scex_ids[CD_SelectedDisc] : NULL);
- //}
-
- //// TODO: Remember to increment dirty count in memory card state loading routine.
-
- //ret &= CPU->StateAction(sm, load, data_only);
- //ret &= DMA_StateAction(sm, load, data_only);
- //ret &= TIMER_StateAction(sm, load, data_only);
- //ret &= SIO_StateAction(sm, load, data_only);
-
- //ret &= CDC->StateAction(sm, load, data_only);
- //ret &= MDEC_StateAction(sm, load, data_only);
- //ret &= GPU->StateAction(sm, load, data_only);
- //ret &= SPU->StateAction(sm, load, data_only);
-
- //ret &= FIO->StateAction(sm, load, data_only);
-
- //ret &= IRQ_StateAction(sm, load, data_only); // Do it last.
-
- //if(load)
- //{
- // ForceEventUpdates(0); // FIXME to work with debugger step mode.
- //}
-
+namespace MDFN_IEN_PSX {
+void DMA_SyncState(bool isReader, EW::NewState *ns);
+void GTE_SyncState(bool isReader, EW::NewState *ns);
+void TIMER_SyncState(bool isReader, EW::NewState *ns);
+void SIO_SyncState(bool isReader, EW::NewState *ns);
+void MDEC_SyncState(bool isReader, EW::NewState *ns);
+void IRQ_SyncState(bool isReader, EW::NewState *ns);
+}
SYNCFUNC(PSX)
{
NSS(CD_TrayOpen);
PSS(MainRAM.data8, 2*1024*1024);
- NSS(SysControl.Regs); //9 regs.. does the array work?
+ NSS(SysControl.Regs);
+ NSS(PSX_PRNG.lcgo);
+ NSS(PSX_PRNG.x);
+ NSS(PSX_PRNG.y);
+ NSS(PSX_PRNG.z);
+ NSS(PSX_PRNG.c);
+
+ //note: mednafen used to save the current disc index. that's kind of nice, I guess, if you accept that responsibility in the core.
+ //but we're not doing things that way.
+ //I think instead maybe we should generate a hash of the inserted disc and save that, and then check if theres a mismatch between the disc at the time of the savestate and the current disc
+ //but we'll do that in the frontend for now
+
+ //old:
+ // "TODO: Remember to increment dirty count in memory card state loading routine."
+ //not sure what this means or whether I like it
+
+ //I've kept the ordering of these sections the same, in case its important for some unknown reason.. for now.
+
+ TSS(CPU);
+
+ ns->EnterSection("GTE");
+ GTE_SyncState(isReader,ns);
+ ns->ExitSection("GTE");
+
+ ns->EnterSection("DMA");
+ DMA_SyncState(isReader,ns);
+ ns->ExitSection("DMA");
+
+ ns->EnterSection("TIMER");
+ TIMER_SyncState(isReader,ns);
+ ns->ExitSection("TIMER");
+
+ ns->EnterSection("SIO");
+ SIO_SyncState(isReader,ns);
+ ns->ExitSection("SIO");
+
+ TSS(CDC);
+
+ ns->EnterSection("MDEC");
+ MDEC_SyncState(isReader,ns);
+ ns->ExitSection("MDEC");
+
+ TSS(GPU); //did some special logic for the CPU, ordering may matter, but probably not
+
+ TSS(SPU);
+ TSS(FIO); //TODO - DUALSHOCK, MC
+
+
+ //"Do it last." the comments say. And all this other nonsense about IRQs in the other state syncing functions. weird.....
+ //ret &= IRQ_StateAction(sm, load, data_only); //
+
+ ns->EnterSection("IRQ");
+ IRQ_SyncState(isReader,ns);
+ ns->ExitSection("IRQ");
+
+ //zero: this is probably OK
+ if(isReader)
+ {
+ ForceEventUpdates(0); // FIXME to work with debugger step mode.
+ }
}
EW_EXPORT s32 shock_StateTransaction(void *psx, ShockStateTransaction* transaction)
@@ -2518,5 +2484,8 @@ EW_EXPORT s32 shock_StateTransaction(void *psx, ShockStateTransaction* transacti
return SHOCK_OK;
}
return SHOCK_ERROR;
+
+ default:
+ return SHOCK_ERROR;
}
}
\ No newline at end of file
diff --git a/psx/octoshock/psx/psx.h b/psx/octoshock/psx/psx.h
index 45ec5d53dc..4757d3c2a5 100644
--- a/psx/octoshock/psx/psx.h
+++ b/psx/octoshock/psx/psx.h
@@ -316,6 +316,9 @@ EW_EXPORT s32 shock_SetDisc(void* psx, ShockDiscRef* disc);
EW_EXPORT s32 shock_CloseTray(void* psx);
//Steps emulation by the specified interval
+//TODO - think about something. After loadstating, the device input state is probably nonsense.
+//Normally we'd set the input before frame advancing. But every frontend might not do that, and we might not be stepping by one frame.
+//What to do about this?
EW_EXPORT s32 shock_Step(void* psx, eShockStep step);
//Fetches the framebuffer. Can retrieve parameters (set the job ptr to NULL) or fill the provided job ptr with the framebuffer (make sure its big enough).
diff --git a/psx/octoshock/psx/sio.cpp b/psx/octoshock/psx/sio.cpp
index a2b02c0937..5470432603 100644
--- a/psx/octoshock/psx/sio.cpp
+++ b/psx/octoshock/psx/sio.cpp
@@ -103,26 +103,14 @@ void SIO_Write(pscpu_timestamp_t timestamp, uint32 A, uint32 V)
}
}
-int SIO_StateAction(StateMem *sm, int load, int data_only)
+
+void SIO_SyncState(bool isReader, EW::NewState *ns)
{
- SFORMAT StateRegs[] =
- {
- SFVAR(Status),
- SFVAR(Mode),
- SFVAR(Control),
- SFVAR(BaudRate),
- SFVAR(DataBuffer),
-
- SFEND
- };
- int ret = MDFNSS_StateAction(sm, load, data_only, StateRegs, "SIO");
-
- if(load)
- {
-
- }
-
- return(ret);
+ NSS(Status);
+ NSS(Mode);
+ NSS(Control);
+ NSS(BaudRate);
+ NSS(DataBuffer);
}
}
diff --git a/psx/octoshock/psx/spu.cpp b/psx/octoshock/psx/spu.cpp
index 4caad3b07a..0c774e4c2f 100644
--- a/psx/octoshock/psx/spu.cpp
+++ b/psx/octoshock/psx/spu.cpp
@@ -1160,147 +1160,61 @@ int32 PS_SPU::EndFrame(int16 *SoundBuf)
}
}
-int PS_SPU::StateAction(StateMem *sm, int load, int data_only)
+SYNCFUNC(PS_SPU)
{
- SFORMAT StateRegs[] =
- {
-#define SFSWEEP(r) SFVAR((r).Control), \
- SFVAR((r).Current), \
- SFVAR((r).Divider)
+ NSS(Voices);
-#define SFVOICE(n) SFARRAY16(&Voices[n].DecodeBuffer[0], sizeof(Voices[n].DecodeBuffer) / sizeof(Voices[n].DecodeBuffer[0])), \
- SFVAR(Voices[n].DecodeM2), \
- SFVAR(Voices[n].DecodeM1), \
- SFVAR(Voices[n].DecodePlayDelay), \
- SFVAR(Voices[n].DecodeWritePos), \
- SFVAR(Voices[n].DecodeReadPos), \
- SFVAR(Voices[n].DecodeAvail), \
- SFVAR(Voices[n].DecodeShift), \
- SFVAR(Voices[n].DecodeWeight), \
- SFVAR(Voices[n].DecodeFlags), \
- SFVAR(Voices[n].IgnoreSampLA), \
- \
- SFSWEEP(Voices[n].Sweep[0]), \
- SFSWEEP(Voices[n].Sweep[1]), \
- \
- SFVAR(Voices[n].Pitch), \
- SFVAR(Voices[n].CurPhase), \
- \
- SFVAR(Voices[n].StartAddr), \
- SFVAR(Voices[n].CurAddr), \
- SFVAR(Voices[n].ADSRControl), \
- SFVAR(Voices[n].LoopAddr), \
- SFVAR(Voices[n].PreLRSample), \
- \
- SFVAR(Voices[n].ADSR.EnvLevel), \
- SFVAR(Voices[n].ADSR.Divider), \
- SFVAR(Voices[n].ADSR.Phase), \
- \
- SFVAR(Voices[n].ADSR.AttackExp), \
- SFVAR(Voices[n].ADSR.SustainExp), \
- SFVAR(Voices[n].ADSR.SustainDec), \
- SFVAR(Voices[n].ADSR.ReleaseExp), \
- \
- SFVAR(Voices[n].ADSR.AttackRate), \
- SFVAR(Voices[n].ADSR.DecayRate), \
- SFVAR(Voices[n].ADSR.SustainRate), \
- SFVAR(Voices[n].ADSR.ReleaseRate), \
- \
- SFVAR(Voices[n].ADSR.SustainLevel)
+ NSS(NoiseCounter);
+ NSS(LFSR);
- SFVOICE(0),
- SFVOICE(1),
- SFVOICE(2),
- SFVOICE(3),
- SFVOICE(4),
- SFVOICE(5),
- SFVOICE(6),
- SFVOICE(7),
- SFVOICE(8),
- SFVOICE(9),
- SFVOICE(10),
- SFVOICE(11),
- SFVOICE(12),
- SFVOICE(13),
- SFVOICE(14),
- SFVOICE(15),
- SFVOICE(16),
- SFVOICE(17),
- SFVOICE(18),
- SFVOICE(19),
- SFVOICE(20),
- SFVOICE(21),
- SFVOICE(22),
- SFVOICE(23),
-#undef SFVOICE
+ NSS(FM_Mode);
+ NSS(Noise_Mode);
+ NSS(Reverb_Mode);
- SFVAR(NoiseCounter),
- SFVAR(LFSR),
+ NSS(ReverbWA);
- SFVAR(FM_Mode),
- SFVAR(Noise_Mode),
- SFVAR(Reverb_Mode),
+ NSS(GlobalSweep);
- SFVAR(ReverbWA),
+ NSS(ReverbVol);
- SFSWEEP(GlobalSweep[0]),
- SFSWEEP(GlobalSweep[1]),
-
- SFARRAY32(ReverbVol, sizeof(ReverbVol) / sizeof(ReverbVol[0])),
-
- SFARRAY32(CDVol, sizeof(CDVol) / sizeof(CDVol[0])),
- SFARRAY32(ExternVol, sizeof(ExternVol) / sizeof(ExternVol[0])),
+ NSS(CDVol);
+ NSS(ExternVol);
- SFVAR(IRQAddr),
+ NSS(IRQAddr);
- SFVAR(RWAddr),
+ NSS(RWAddr);
- SFVAR(SPUControl),
+ NSS(SPUControl);
- SFVAR(VoiceOn),
- SFVAR(VoiceOff),
+ NSS(VoiceOn);
+ NSS(VoiceOff);
- SFVAR(BlockEnd),
+ NSS(BlockEnd);
- SFVAR(CWA),
+ NSS(CWA);
- SFARRAY16(Regs, sizeof(Regs) / sizeof(Regs[0])),
- SFARRAY16(AuxRegs, sizeof(AuxRegs) / sizeof(AuxRegs[0])),
+ NSS(Regs);
+ NSS(AuxRegs);
- SFARRAY16(&RDSB[0][0], sizeof(RDSB) / sizeof(RDSB[0][0])),
- SFVAR(RDSB_WP),
+ NSS(RDSB);
+ NSS(RDSB_WP);
- SFARRAY16(&RUSB[0][0], sizeof(RUSB) / sizeof(RUSB[0][0])),
- SFVAR(RUSB_WP),
+ NSS(RUSB);
+ NSS(RUSB_WP);
- SFVAR(ReverbCur),
- SFVAR(IRQAsserted),
+ NSS(ReverbCur);
+ NSS(IRQAsserted);
- SFVAR(clock_divider),
+ NSS(clock_divider);
- SFARRAY16(SPURAM, 524288 / sizeof(uint16)),
- SFEND
- };
-#undef SFSWEEP
- int ret = 1;
+ NSS(SPURAM);
- ret &= MDFNSS_StateAction(sm, load, data_only, StateRegs, "SPU");
-
- if(load)
- {
- for(unsigned i = 0; i < 24; i++)
- {
- Voices[i].DecodeReadPos &= 0x1F;
- Voices[i].DecodeWritePos &= 0x1F;
- }
-
- RDSB_WP &= 0x3F;
- RUSB_WP &= 0x3F;
-
- IRQ_Assert(IRQ_SPU, IRQAsserted);
- }
-
- return(ret);
+ //if(isReader)
+ //{
+ //there was more weird crap here about controlling the range of variables. just sanity checks, I guess? to prevent crashes? no thanks, id rather have crashes alert me to nondeterminisms.
+ //and another thing like this, which I think makes no sense. I really need to test these.
+ IRQ_Assert(IRQ_SPU, IRQAsserted);
+ //}
}
uint16 PS_SPU::PeekSPURAM(uint32 address)
diff --git a/psx/octoshock/psx/spu.h b/psx/octoshock/psx/spu.h
index 85ae819e2f..813233b5ef 100644
--- a/psx/octoshock/psx/spu.h
+++ b/psx/octoshock/psx/spu.h
@@ -99,6 +99,8 @@ class PS_SPU
PS_SPU();
~PS_SPU();
+ templatevoid SyncState(EW::NewState *ns);
+
int StateAction(StateMem *sm, int load, int data_only);
void Power(void);
diff --git a/psx/octoshock/psx/timer.cpp b/psx/octoshock/psx/timer.cpp
index 8cb918e19c..a00fd859dc 100644
--- a/psx/octoshock/psx/timer.cpp
+++ b/psx/octoshock/psx/timer.cpp
@@ -446,34 +446,11 @@ void TIMER_Power(void)
memset(Timers, 0, sizeof(Timers));
}
-int TIMER_StateAction(StateMem *sm, int load, int data_only)
+void TIMER_SyncState(bool isReader, EW::NewState *ns)
{
- SFORMAT StateRegs[] =
- {
-#define SFTIMER(n) SFVARN(Timers[n].Mode, #n "Mode"), \
- SFVARN(Timers[n].Counter, #n "Counter"), \
- SFVARN(Timers[n].Target, #n "Target"), \
- SFVARN(Timers[n].Div8Counter, #n "Div8Counter"), \
- SFVARN(Timers[n].IRQDone, #n "IRQDone"), \
- SFVARN(Timers[n].DoZeCounting, #n "DoZeCounting")
- SFTIMER(0),
- SFTIMER(1),
- SFTIMER(2),
-#undef SFTIMER
-
- SFVAR(vblank),
- SFVAR(hretrace),
-
- SFEND
- };
- int ret = MDFNSS_StateAction(sm, load, data_only, StateRegs, "TIMER");
-
- if(load)
- {
-
- }
-
- return(ret);
+ NSS(Timers);
+ NSS(vblank);
+ NSS(hretrace);
}
uint32 TIMER_GetRegister(unsigned int which, char *special, const uint32 special_len)