mirror of
https://github.com/libretro/snes9x.git
synced 2026-10-17 15:25:43 +00:00
Stream existed to let the savestate and patch code work over either a
file or a buffer. Nothing needs the file half any more: savestates go
through S9xFreezeGameMem / S9xUnfreezeGameMem, and patches now arrive as
buffers whether they came from a loose file, a zip entry or an .msu1
pack member. What was left was three subclasses, a virtual dispatch per
byte in places, and a macro block in snes9x.h that had to be hidden
behind __cplusplus so the C sources could include the header at all.
bytestream.h replaces it: a struct with buf/size/pos and inline
read/write/seek/tell. A NULL buffer counts bytes without storing them,
which is the S9xFreezeSize sizing pass that nulStream used to do. Reads
past the end come up short and seeks are clamped, so a malformed
savestate or patch cannot walk off the buffer.
Removed with it:
- stream.cpp and stream.h, and the STREAM macro family in snes9x.h,
which means snes9x.h no longer needs its __cplusplus guard.
- S9xFreezeGame and S9xUnfreezeGame, the file-backed savestate entry
points, along with S9xOpenSnapshotFile and S9xCloseSnapshotFile.
- S9xResetSaveTimer and the oops-snapshot machinery it drove, whose
only purpose was writing a .oops file through those entry points,
and S9xMessageFromResult, which reported their failures.
- the WDM debug opcode that wrote a .wdm snapshot. It was inside
#ifdef DEBUGGER, which this tree does not build, and it was the only
other S9xFreezeGame caller.
- conffile.cpp and conffile.h. Nothing constructs a ConfigFile; the
single reference outside the file was an empty S9xParsePortConfig
stub in the port, implementing a declaration nobody calls.
- ReadStreamUntilEOF, which existed because Stream had no size(). The
UPS and BPS readers wanted the whole patch in memory and now just
address the cursor's buffer directly, so a patch is no longer copied
a second time to be read.
Verified: Killer Instinct is unchanged on four input scripts - same
audio hash, same sample count, same video. Savestates round-trip
(preemptive-frames replay 0/240 mismatches, save/restore audio
deterministic), IPS and BPS patches apply from a loose file and from
both stored and deflated zips, ROMs load from loose files and zips, and
the MSU-1, input and peripheral suites all pass.
178 lines
3.7 KiB
C++
178 lines
3.7 KiB
C++
/*****************************************************************************\
|
|
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
|
This file is licensed under the Snes9x License.
|
|
For further information, consult the LICENSE file in the root directory.
|
|
\*****************************************************************************/
|
|
|
|
#include "snes9x.h"
|
|
#include "memmap.h"
|
|
#include "dma.h"
|
|
#include "apu/apu.h"
|
|
#include "fxemu.h"
|
|
#include "sdd1.h"
|
|
#include "srtc.h"
|
|
#include "snapshot.h"
|
|
#include "cheats.h"
|
|
#ifdef DEBUGGER
|
|
#include "debug.h"
|
|
#endif
|
|
|
|
static void S9xResetCPU (void);
|
|
static void S9xSoftResetCPU (void);
|
|
|
|
|
|
static void S9xResetCPU (void)
|
|
{
|
|
S9xSoftResetCPU();
|
|
Registers.SL = 0xff;
|
|
Registers.P.W = 0;
|
|
Registers.A.W = 0;
|
|
Registers.X.W = 0;
|
|
Registers.Y.W = 0;
|
|
SetFlags(MemoryFlag | IndexFlag | IRQ | Emulation);
|
|
ClearFlags(Decimal);
|
|
}
|
|
|
|
static void S9xSoftResetCPU (void)
|
|
{
|
|
CPU.Cycles = 182; // Or 188. This is the cycle count just after the jump to the Reset Vector.
|
|
CPU.PrevCycles = CPU.Cycles;
|
|
CPU.V_Counter = 0;
|
|
CPU.Flags = CPU.Flags & (DEBUG_MODE_FLAG | TRACE_FLAG);
|
|
CPU.PCBase = NULL;
|
|
CPU.NMIPending = FALSE;
|
|
CPU.IRQLine = FALSE;
|
|
CPU.IRQTransition = FALSE;
|
|
CPU.IRQExternal = FALSE;
|
|
CPU.MemSpeed = SLOW_ONE_CYCLE;
|
|
CPU.MemSpeedx2 = SLOW_ONE_CYCLE * 2;
|
|
CPU.FastROMSpeed = SLOW_ONE_CYCLE;
|
|
CPU.InDMA = FALSE;
|
|
CPU.InHDMA = FALSE;
|
|
CPU.InDMAorHDMA = FALSE;
|
|
CPU.InWRAMDMAorHDMA = FALSE;
|
|
CPU.HDMARanInDMA = 0;
|
|
CPU.CurrentDMAorHDMAChannel = -1;
|
|
CPU.WhichEvent = HC_RENDER_EVENT;
|
|
CPU.NextEvent = Timings.RenderPos;
|
|
CPU.WaitingForInterrupt = FALSE;
|
|
CPU.AutoSaveTimer = 0;
|
|
CPU.SRAMModified = FALSE;
|
|
|
|
Registers.PBPC = 0;
|
|
Registers.PB = 0;
|
|
Registers.PCw = S9xGetWord(0xfffc);
|
|
OpenBus = Registers.PCh;
|
|
Registers.D.W = 0;
|
|
Registers.DB = 0;
|
|
Registers.SH = 1;
|
|
Registers.SL -= 3;
|
|
Registers.XH = 0;
|
|
Registers.YH = 0;
|
|
|
|
ICPU.ShiftedPB = 0;
|
|
ICPU.ShiftedDB = 0;
|
|
SetFlags(MemoryFlag | IndexFlag | IRQ | Emulation);
|
|
ClearFlags(Decimal);
|
|
|
|
Timings.H_Max = Timings.H_Max_Master;
|
|
Timings.V_Max = Timings.V_Max_Master;
|
|
Timings.NMITriggerPos = 0xffff;
|
|
Timings.NextIRQTimer = 0x0fffffff;
|
|
Timings.IRQFlagChanging = IRQ_NONE;
|
|
|
|
if (Model->_5A22 == 2)
|
|
Timings.WRAMRefreshPos = SNES_WRAM_REFRESH_HC_v2;
|
|
else
|
|
Timings.WRAMRefreshPos = SNES_WRAM_REFRESH_HC_v1;
|
|
|
|
S9xSetPCBase(Registers.PBPC);
|
|
|
|
ICPU.S9xOpcodes = S9xOpcodesE1;
|
|
ICPU.S9xOpLengths = S9xOpLengthsM1X1;
|
|
|
|
S9xUnpackStatus();
|
|
}
|
|
|
|
void S9xReset (void)
|
|
{
|
|
|
|
memset(Memory.RAM, 0x55, sizeof(Memory.RAM));
|
|
memset(Memory.VRAM, 0x00, sizeof(Memory.VRAM));
|
|
memset(Memory.FillRAM, 0, 0x8000);
|
|
|
|
S9xResetBSX();
|
|
S9xResetCPU();
|
|
S9xResetPPU();
|
|
S9xResetDMA();
|
|
S9xResetAPU();
|
|
S9xResetMSU1();
|
|
|
|
if (Settings.DSP)
|
|
S9xResetDSP();
|
|
if (Settings.SuperFX)
|
|
S9xResetSuperFX();
|
|
if (Settings.SA1)
|
|
S9xSA1Init();
|
|
if (Settings.SDD1)
|
|
S9xResetSDD1();
|
|
if (Settings.SPC7110)
|
|
S9xResetSPC7110();
|
|
if (Settings.C4)
|
|
S9xInitC4();
|
|
if (Settings.OBC1)
|
|
S9xResetOBC1();
|
|
if (Settings.SRTC)
|
|
S9xResetSRTC();
|
|
if (Settings.MSU1)
|
|
S9xMSU1Init();
|
|
|
|
S9xInitCheatData();
|
|
}
|
|
|
|
void S9xSoftReset (void)
|
|
{
|
|
|
|
memset(Memory.FillRAM, 0, 0x8000);
|
|
|
|
if (Settings.BS)
|
|
S9xResetBSX();
|
|
|
|
S9xSoftResetCPU();
|
|
S9xSoftResetPPU();
|
|
S9xResetDMA();
|
|
S9xSoftResetAPU();
|
|
S9xResetMSU1();
|
|
|
|
if (Settings.DSP)
|
|
S9xResetDSP();
|
|
if (Settings.SuperFX)
|
|
S9xResetSuperFX();
|
|
if (Settings.SA1)
|
|
S9xSA1Init();
|
|
if (Settings.SDD1)
|
|
S9xResetSDD1();
|
|
if (Settings.SPC7110)
|
|
S9xResetSPC7110();
|
|
if (Settings.C4)
|
|
S9xInitC4();
|
|
if (Settings.OBC1)
|
|
S9xResetOBC1();
|
|
if (Settings.SRTC)
|
|
S9xResetSRTC();
|
|
if (Settings.MSU1)
|
|
S9xMSU1Init();
|
|
|
|
S9xInitCheatData();
|
|
}
|
|
|
|
extern "C" void S9xSuperFXIRQHook (void)
|
|
{
|
|
CPU.IRQExternal = TRUE;
|
|
}
|
|
|
|
extern "C" void S9xSuperFXIRQClearHook (void)
|
|
{
|
|
CPU.IRQExternal = FALSE;
|
|
}
|