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)