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
{
#include "dsp/blargg_endian.h"
CPU cpu;
}
@ -229,8 +231,6 @@ static void EightBitize (uint8 *, int);
static void DeStereo (uint8 *, int);
static void ReverseStereo (uint8 *, int);
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 inline int S9xAPUGetClock (int32);
static inline int S9xAPUGetClockRemainder (int32);
@ -605,25 +605,30 @@ void S9xSoftResetAPU (void)
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);
SET_LE32(ptr, spc::remainder); */
SNES::set_le32(ptr, spc::remainder);
ptr += sizeof(int32);
memcpy (ptr, SNES::cpu.registers, 4);
}
void S9xAPULoadState (uint8 *block)
{
/* uint8 *ptr = block;
uint8 *ptr = block;
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);
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 *);
#define SPC_SAVE_STATE_BLOCK_SIZE (SNES_SPC::state_size + 8)
#define SPC_SAVE_STATE_BLOCK_SIZE (1024 * 65)
bool8 S9xInitAPU (void);
void S9xDeinitAPU (void);

View File

@ -7,16 +7,41 @@ DSP dsp;
#include "SPC_DSP.cpp"
void DSP::power() {
void DSP::power()
{
spc_dsp.init(smp.apuram);
spc_dsp.reset();
}
void DSP::reset() {
void DSP::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);
}
void save_state(uint8 **);
void load_state(uint8 **);
void power();
void reset();

View File

@ -19,6 +19,9 @@ public:
#ifndef SNES9X
void serialize(serializer&);
#else
void load_state(uint8 **);
void save_state(uint8 **);
#endif
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
{
unsigned frequency;
int clock;
int32 clock;
};
#include "smp/smp.hpp"

View File

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

View File

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