Save states support for new APU.

This commit is contained in:
Brandon Wright 2011-06-24 06:42:04 -05:00
parent 7c468e51c0
commit 39add9b47e
9 changed files with 178 additions and 23 deletions

View File

@ -194,6 +194,8 @@
namespace SNES namespace SNES
{ {
#include "dsp/blargg_endian.h"
CPU cpu; CPU cpu;
} }
@ -229,8 +231,6 @@ static void EightBitize (uint8 *, int);
static void DeStereo (uint8 *, int); static void DeStereo (uint8 *, int);
static void ReverseStereo (uint8 *, int); static void ReverseStereo (uint8 *, int);
static void UpdatePlaybackRate (void); static void UpdatePlaybackRate (void);
static void from_apu_to_state (uint8 **, void *, size_t);
static void to_apu_from_state (uint8 **, void *, size_t);
static void SPCSnapshotCallback (void); static void SPCSnapshotCallback (void);
static inline int S9xAPUGetClock (int32); static inline int S9xAPUGetClock (int32);
static inline int S9xAPUGetClockRemainder (int32); static inline int S9xAPUGetClockRemainder (int32);
@ -605,25 +605,30 @@ void S9xSoftResetAPU (void)
void S9xAPUSaveState (uint8 *block) void S9xAPUSaveState (uint8 *block)
{ {
// TODO: Save states uint8 *ptr = block;
/* uint8 *ptr = block;
spc_core->copy_state(&ptr, from_apu_to_state); SNES::smp.save_state (&ptr);
SNES::dsp.save_state (&ptr);
SET_LE32(ptr, spc::reference_time); SNES::set_le32(ptr, spc::reference_time);
ptr += sizeof(int32); ptr += sizeof(int32);
SET_LE32(ptr, spc::remainder); */ SNES::set_le32(ptr, spc::remainder);
ptr += sizeof(int32);
memcpy (ptr, SNES::cpu.registers, 4);
} }
void S9xAPULoadState (uint8 *block) void S9xAPULoadState (uint8 *block)
{ {
/* uint8 *ptr = block; uint8 *ptr = block;
S9xResetAPU(); S9xResetAPU();
spc_core->copy_state(&ptr, to_apu_from_state); SNES::smp.load_state (&ptr);
SNES::dsp.load_state (&ptr);
spc::reference_time = GET_LE32(ptr); spc::reference_time = SNES::get_le32(ptr);
ptr += sizeof(int32); ptr += sizeof(int32);
spc::remainder = GET_LE32(ptr); */ spc::remainder = SNES::get_le32(ptr);
ptr += sizeof(int32);
memcpy (SNES::cpu.registers, ptr, 4);
} }

View File

@ -183,7 +183,7 @@
typedef void (*apu_callback) (void *); typedef void (*apu_callback) (void *);
#define SPC_SAVE_STATE_BLOCK_SIZE (SNES_SPC::state_size + 8) #define SPC_SAVE_STATE_BLOCK_SIZE (1024 * 65)
bool8 S9xInitAPU (void); bool8 S9xInitAPU (void);
void S9xDeinitAPU (void); void S9xDeinitAPU (void);

View File

@ -7,16 +7,41 @@ DSP dsp;
#include "SPC_DSP.cpp" #include "SPC_DSP.cpp"
void DSP::power() { void DSP::power()
{
spc_dsp.init(smp.apuram); spc_dsp.init(smp.apuram);
spc_dsp.reset(); spc_dsp.reset();
} }
void DSP::reset() { void DSP::reset()
{
spc_dsp.soft_reset(); spc_dsp.soft_reset();
} }
DSP::DSP() { static void from_dsp_to_state (uint8 **buf, void *var, size_t size)
{
memcpy(*buf, var, size);
*buf += size;
}
static void to_dsp_from_state (uint8 **buf, void *var, size_t size)
{
memcpy(var, *buf, size);
*buf += size;
}
void DSP::save_state (uint8 **ptr)
{
spc_dsp.copy_state(ptr, from_dsp_to_state);
}
void DSP::load_state (uint8 **ptr)
{
spc_dsp.copy_state(ptr, to_dsp_from_state);
}
DSP::DSP()
{
} }
} }

View File

@ -10,6 +10,9 @@ public:
spc_dsp.write(addr, data); spc_dsp.write(addr, data);
} }
void save_state(uint8 **);
void load_state(uint8 **);
void power(); void power();
void reset(); void reset();

View File

@ -19,6 +19,9 @@ public:
#ifndef SNES9X #ifndef SNES9X
void serialize(serializer&); void serialize(serializer&);
#else
void load_state(uint8 **);
void save_state(uint8 **);
#endif #endif
SMP(); SMP();
~SMP(); ~SMP();

119
apu/bapu/smp/smp_state.cpp Normal file
View File

@ -0,0 +1,119 @@
#include "snes/snes.hpp"
namespace SNES {
#include "dsp/blargg_endian.h"
void SMP::save_state(uint8 **block) {
uint8 *ptr = *block;
memcpy(ptr, apuram, 64 * 1024);
ptr += 64 * 1024;
#undef INT32
#define INT32(i) set_le32(ptr, (i)); ptr += sizeof(int32)
INT32(clock);
INT32(opcode_number);
INT32(opcode_cycle);
INT32(regs.pc);
INT32(regs.sp);
INT32(regs.a);
INT32(regs.x);
INT32(regs.y);
INT32(regs.p.n);
INT32(regs.p.v);
INT32(regs.p.p);
INT32(regs.p.b);
INT32(regs.p.h);
INT32(regs.p.i);
INT32(regs.p.z);
INT32(regs.p.c);
INT32(status.iplrom_enable);
INT32(status.dsp_addr);
INT32(status.ram00f8);
INT32(status.ram00f9);
INT32(timer0.enable);
INT32(timer0.target);
INT32(timer0.stage1_ticks);
INT32(timer0.stage2_ticks);
INT32(timer0.stage3_ticks);
INT32(timer1.enable);
INT32(timer1.target);
INT32(timer1.stage1_ticks);
INT32(timer1.stage2_ticks);
INT32(timer1.stage3_ticks);
INT32(timer2.enable);
INT32(timer2.target);
INT32(timer2.stage1_ticks);
INT32(timer2.stage2_ticks);
INT32(timer2.stage3_ticks);
*block = ptr;
}
void SMP::load_state(uint8 **block) {
uint8 *ptr = *block;
memcpy(apuram, ptr, 64 * 1024);
ptr += 64 * 1024;
#undef INT32
#define INT32(i) i = get_le32(ptr); ptr += sizeof(int32)
INT32(clock);
INT32(opcode_number);
INT32(opcode_cycle);
INT32(regs.pc);
INT32(regs.sp);
INT32(regs.a);
INT32(regs.x);
INT32(regs.y);
INT32(regs.p.n);
INT32(regs.p.v);
INT32(regs.p.p);
INT32(regs.p.b);
INT32(regs.p.h);
INT32(regs.p.i);
INT32(regs.p.z);
INT32(regs.p.c);
INT32(status.iplrom_enable);
INT32(status.dsp_addr);
INT32(status.ram00f8);
INT32(status.ram00f9);
INT32(timer0.enable);
INT32(timer0.target);
INT32(timer0.stage1_ticks);
INT32(timer0.stage2_ticks);
INT32(timer0.stage3_ticks);
INT32(timer1.enable);
INT32(timer1.target);
INT32(timer1.stage1_ticks);
INT32(timer1.stage2_ticks);
INT32(timer1.stage3_ticks);
INT32(timer2.enable);
INT32(timer2.target);
INT32(timer2.stage1_ticks);
INT32(timer2.stage2_ticks);
INT32(timer2.stage3_ticks);
*block = ptr;
}
}

View File

@ -24,7 +24,7 @@ namespace SNES
struct Processor struct Processor
{ {
unsigned frequency; unsigned frequency;
int clock; int32 clock;
}; };
#include "smp/smp.hpp" #include "smp/smp.hpp"

View File

@ -124,9 +124,9 @@ snes9x_gtk_SOURCES += \
# Byuu's APU # Byuu's APU
snes9x_gtk_SOURCES += \ snes9x_gtk_SOURCES += \
../apu/bapu/dsp/dsp.cpp \ ../apu/bapu/dsp/dsp.cpp \
../apu/bapu/dsp/serialization.cpp \
../apu/bapu/dsp/SPC_DSP.cpp \ ../apu/bapu/dsp/SPC_DSP.cpp \
../apu/bapu/smp/smp.cpp ../apu/bapu/smp/smp.cpp \
../apu/bapu/smp/smp_state.cpp
# DSP # DSP
snes9x_gtk_SOURCES += \ snes9x_gtk_SOURCES += \

View File

@ -1269,7 +1269,7 @@ bool8 S9xUnfreezeGame (const char *filename)
void S9xFreezeToStream (STREAM stream) void S9xFreezeToStream (STREAM stream)
{ {
char buffer[1024]; char buffer[1024];
//uint8 *soundsnapshot = new uint8[SPC_SAVE_STATE_BLOCK_SIZE]; uint8 *soundsnapshot = new uint8[SPC_SAVE_STATE_BLOCK_SIZE];
S9xSetSoundMute(TRUE); S9xSetSoundMute(TRUE);
@ -1298,8 +1298,8 @@ void S9xFreezeToStream (STREAM stream)
FreezeBlock (stream, "FIL", Memory.FillRAM, 0x8000); FreezeBlock (stream, "FIL", Memory.FillRAM, 0x8000);
//S9xAPUSaveState(soundsnapshot); S9xAPUSaveState(soundsnapshot);
//FreezeBlock (stream, "SND", soundsnapshot, SPC_SAVE_STATE_BLOCK_SIZE); FreezeBlock (stream, "SND", soundsnapshot, SPC_SAVE_STATE_BLOCK_SIZE);
struct SControlSnapshot ctl_snap; struct SControlSnapshot ctl_snap;
S9xControlPreSaveState(&ctl_snap); S9xControlPreSaveState(&ctl_snap);
@ -1410,7 +1410,7 @@ void S9xFreezeToStream (STREAM stream)
S9xSetSoundMute(FALSE); S9xSetSoundMute(FALSE);
//delete [] soundsnapshot; delete [] soundsnapshot;
} }
int S9xUnfreezeFromStream (STREAM stream) int S9xUnfreezeFromStream (STREAM stream)
@ -1496,7 +1496,7 @@ int S9xUnfreezeFromStream (STREAM stream)
if (result != SUCCESS) if (result != SUCCESS)
break; break;
// result = UnfreezeBlockCopy (stream, "SND", &local_apu_sound, SPC_SAVE_STATE_BLOCK_SIZE); result = UnfreezeBlockCopy (stream, "SND", &local_apu_sound, SPC_SAVE_STATE_BLOCK_SIZE);
if (result != SUCCESS) if (result != SUCCESS)
break; break;