From a66f10d9e405e3545100c27f11dc3c2d06d0b475 Mon Sep 17 00:00:00 2001 From: OV2 Date: Fri, 20 Jan 2012 04:24:36 +0100 Subject: [PATCH] Convert old savestates for new smp --- apu/apu.cpp | 112 ++++++++++++ apu/apu.h | 1 + port.h | 10 +- snapshot.cpp | 8 +- snapshot.h | 4 +- win32/snes9xw.vcproj | 402 ++++++------------------------------------- 6 files changed, 179 insertions(+), 358 deletions(-) diff --git a/apu/apu.cpp b/apu/apu.cpp index 237f3939..bc9f616a 100644 --- a/apu/apu.cpp +++ b/apu/apu.cpp @@ -637,6 +637,118 @@ void S9xAPULoadState (uint8 *block) memcpy (SNES::cpu.registers, ptr, 4); } +static void to_var_from_buf (uint8 **buf, void *var, size_t size) +{ + memcpy(var, *buf, size); + *buf += size; +} + +#undef IF_0_THEN_256 +#define IF_0_THEN_256( n ) ((uint8_t) ((n) - 1) + 1) +void S9xAPULoadBlarggState(uint8 *oldblock) +{ + uint8 *ptr = oldblock; + + SNES::SPC_State_Copier copier(&ptr,to_var_from_buf); + + copier.copy(SNES::smp.apuram,0x10000); // RAM + + uint8_t regs_in [0x10]; + uint8_t regs [0x10]; + uint16_t pc, spc_time, dsp_time; + uint8_t a,x,y,psw,sp; + + copier.copy(regs,0x10); // REGS + copier.copy(regs_in,0x10); // REGS_IN + + // CPU Regs + pc = copier.copy_int( 0, sizeof(uint16_t) ); + a = copier.copy_int( 0, sizeof(uint8_t) ); + x = copier.copy_int( 0, sizeof(uint8_t) ); + y = copier.copy_int( 0, sizeof(uint8_t) ); + psw = copier.copy_int( 0, sizeof(uint8_t) ); + sp = copier.copy_int( 0, sizeof(uint8_t) ); + copier.extra(); + + // times + spc_time = copier.copy_int( 0, sizeof(uint16_t) ); + dsp_time = copier.copy_int( 0, sizeof(uint16_t) ); + + int cur_time = S9xAPUGetClock(CPU.Cycles); + + // spc_time is absolute, dsp_time is relative + // smp.clock is relative, dsp.clock relative but counting upwards + SNES::smp.clock = spc_time - cur_time; + SNES::dsp.clock = -1 * dsp_time; + + // DSP + SNES::dsp.load_state(&ptr); + + // Timers + uint16_t next_time[3]; + uint8_t divider[3], counter[3]; + for ( int i = 0; i < 3; i++ ) + { + next_time[i] = copier.copy_int( 0, sizeof(uint16_t) ); + divider[i] = copier.copy_int( 0, sizeof(uint8_t) ); + counter[i] = copier.copy_int( 0, sizeof(uint8_t) ); + copier.extra(); + } + // construct timers out of available parts from blargg smp + SNES::smp.timer0.enable = regs[1] >> 0 & 1; // regs[1] = CONTROL + SNES::smp.timer0.target = IF_0_THEN_256(regs[10]); // regs[10+i] = TiTARGET + // blargg counts time, get ticks through timer frequency + // (assume tempo = 256) + SNES::smp.timer0.stage1_ticks = 128 - (next_time[0] - cur_time) / 128; + SNES::smp.timer0.stage2_ticks = divider[0]; + SNES::smp.timer0.stage3_ticks = counter[0]; + + SNES::smp.timer1.enable = regs[1] >> 1 & 1; + SNES::smp.timer1.target = IF_0_THEN_256(regs[11]); + SNES::smp.timer1.stage1_ticks = 128 - (next_time[1] - cur_time) / 128; + SNES::smp.timer1.stage2_ticks = divider[0]; + SNES::smp.timer1.stage3_ticks = counter[0]; + + SNES::smp.timer2.enable = regs[1] >> 2 & 1; + SNES::smp.timer2.target = IF_0_THEN_256(regs[12]); + SNES::smp.timer2.stage1_ticks = 16 - (next_time[2] - cur_time) / 16; + SNES::smp.timer2.stage2_ticks = divider[0]; + SNES::smp.timer2.stage3_ticks = counter[0]; + + copier.extra(); + + SNES::smp.opcode_number = 0; + SNES::smp.opcode_cycle = 0; + + SNES::smp.regs.pc = pc; + SNES::smp.regs.sp = sp; + SNES::smp.regs.a = a; + SNES::smp.regs.x = x; + SNES::smp.regs.y = y; + + // blargg's psw has same layout as byuu's flags + SNES::smp.regs.p = psw; + + // blargg doesn't explicitly store iplrom_enable + SNES::smp.status.iplrom_enable = regs[1] & 0x80; + + SNES::smp.status.dsp_addr = regs[2]; + + SNES::smp.status.ram00f8 = regs_in[8]; + SNES::smp.status.ram00f9 = regs_in[9]; + + // default to 0 - we are on an opcode boundary, shouldn't matter + SNES::smp.rd=SNES::smp.wr=SNES::smp.dp=SNES::smp.sp=SNES::smp.ya=SNES::smp.bit=0; + + spc::reference_time = SNES::get_le32(ptr); + ptr += sizeof(int32); + spc::remainder = SNES::get_le32(ptr); + ptr += sizeof(int32); + + // blargg stores CPUIx in regs_in + memcpy (SNES::cpu.registers, regs_in + 4, 4); +} + bool8 S9xSPCDump (const char *filename) { FILE *fs; diff --git a/apu/apu.h b/apu/apu.h index 44b183a8..61575dae 100644 --- a/apu/apu.h +++ b/apu/apu.h @@ -198,6 +198,7 @@ void S9xAPUSetReferenceTime (int32); void S9xAPUTimingSetSpeedup (int); void S9xAPUAllowTimeOverflow (bool); void S9xAPULoadState (uint8 *); +void S9xAPULoadBlarggState(uint8 *oldblock); void S9xAPUSaveState (uint8 *); void S9xDumpSPCSnapshot (void); bool8 S9xSPCDump (const char *); diff --git a/port.h b/port.h index 0e8192e5..bd43353c 100644 --- a/port.h +++ b/port.h @@ -248,10 +248,16 @@ typedef signed int int32; #endif typedef unsigned int uint32; #endif -typedef unsigned char uint8_t; -typedef signed char int8_t; typedef signed __int64 int64; typedef unsigned __int64 uint64; +typedef int8 int8_t; +typedef uint8 uint8_t; +typedef int16 int16_t; +typedef uint16 uint16_t; +typedef int32 int32_t; +typedef uint32 uint32_t; +typedef int64 int64_t; +typedef uint64 uint64_t; typedef int socklen_t; #else // __WIN32__ typedef signed char int8; diff --git a/snapshot.cpp b/snapshot.cpp index e6cd879a..8c9a434e 100644 --- a/snapshot.cpp +++ b/snapshot.cpp @@ -1626,7 +1626,11 @@ int S9xUnfreezeFromStream (STREAM stream) memcpy(Memory.FillRAM, local_fillram, 0x8000); - S9xAPULoadState(local_apu_sound); + if(version < SNAPSHOT_VERSION_BAPU) { + printf("Using Blargg APU snapshot loading (snapshot version %d, current is %d)\n...", version, SNAPSHOT_VERSION); + S9xAPULoadBlarggState(local_apu_sound); + } else + S9xAPULoadState(local_apu_sound); struct SControlSnapshot ctl_snap; UnfreezeStructFromCopy(&ctl_snap, SnapControls, COUNT(SnapControls), local_control_data, version); @@ -1678,7 +1682,7 @@ int S9xUnfreezeFromStream (STREAM stream) if (local_bsx_data) UnfreezeStructFromCopy(&BSX, SnapBSX, COUNT(SnapBSX), local_bsx_data, version); - if (version < SNAPSHOT_VERSION) + if (version < SNAPSHOT_VERSION_IRQ) { printf("Converting old snapshot version %d to %d\n...", version, SNAPSHOT_VERSION); diff --git a/snapshot.h b/snapshot.h index 1cb4bd8c..a522abae 100644 --- a/snapshot.h +++ b/snapshot.h @@ -180,7 +180,9 @@ #define _SNAPSHOT_H_ #define SNAPSHOT_MAGIC "#!s9xsnp" -#define SNAPSHOT_VERSION 7 +#define SNAPSHOT_VERSION_IRQ 7 +#define SNAPSHOT_VERSION_BAPU 8 +#define SNAPSHOT_VERSION 8 #define SUCCESS 1 #define WRONG_FORMAT (-1) diff --git a/win32/snes9xw.vcproj b/win32/snes9xw.vcproj index 4b5bda35..06e38e15 100644 --- a/win32/snes9xw.vcproj +++ b/win32/snes9xw.vcproj @@ -158,7 +158,7 @@ FavorSizeOrSpeed="1" OmitFramePointers="true" WholeProgramOptimization="true" - AdditionalIncludeDirectories="$(ProjectDir),$(ProjectDir)..\,$(ProjectDir)..\..\,$(ProjectDir)..\..\zLib,$(ProjectDir)..\unzip,$(ProjectDir)..\..\FMOD\api\inc,$(ProjectDir)..\..\libPNG\src,$(ProjectDir)..\snes9x" + AdditionalIncludeDirectories="$(ProjectDir),$(ProjectDir)..\,$(ProjectDir)..\..\,$(ProjectDir)..\..\zLib,$(ProjectDir)..\unzip,$(ProjectDir)..\..\FMOD\api\inc,$(ProjectDir)..\..\libPNG\src,$(ProjectDir)..\apu\bapu" PreprocessorDefinitions="NDEBUG;HAVE_LIBPNG;JMA_SUPPORT;ZLIB;UNZIP_SUPPORT;__WIN32__;FMODEX_SUPPORT;NETPLAY_SUPPORT" StringPooling="true" RuntimeLibrary="0" @@ -255,7 +255,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - + - - - + - - - - + + + + + + + + + + - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +