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.NMILine = FALSE; CPU.IRQLine = FALSE; CPU.IRQTransition = FALSE; CPU.IRQLastState = FALSE; CPU.IRQExternal = FALSE; CPU.IRQPending = Timings.IRQPendCount; 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.InterlaceField = FALSE; Timings.H_Max = Timings.H_Max_Master; Timings.V_Max = Timings.V_Max_Master; Timings.NMITriggerPos = 0xffff; 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 S9xResetCPU () { CPUPack.Registers.PB = 0; CPUPack.Registers.PC = S9xGetWord (0xFFFC); CPUPack.Registers.D.W = 0; CPUPack.Registers.DB = 0; CPUPack.Registers.SH = 1; CPUPack.Registers.SL = 0xFF; CPUPack.Registers.XH = 0; CPUPack.Registers.YH = 0; CPUPack.Registers.P.W = 0; CPUPack.ICPU.ShiftedPB = 0; CPUPack.ICPU.ShiftedDB = 0; SetFlags (MemoryFlag | IndexFlag | IRQ | Emulation); ClearFlags (Decimal); CPUPack.CPU.Flags = CPUPack.CPU.Flags & (DEBUG_MODE_FLAG | TRACE_FLAG); CPUPack.CPU.BranchSkip = FALSE; CPUPack.CPU.NMIActive = FALSE; CPUPack.CPU.IRQActive = FALSE; CPUPack.CPU.WaitingForInterrupt = FALSE; CPUPack.CPU.InDMA = FALSE; CPUPack.CPU.WhichEvent = HBLANK_START_EVENT; S9x_Current_HBlank_Event=S9xDoHBlankProcessing_HBLANK_START_EVENT; CPUPack.CPU.PC = NULL; CPUPack.CPU.PCBase = NULL; CPUPack.CPU.PCAtOpcodeStart = NULL; CPUPack.CPU.WaitAddress = NULL; CPUPack.CPU.WaitCounter = 0; CPUPack.CPU.Cycles = 0; old_cpu_cycles=0; cpu_glob_cycles=0; CPUPack.CPU.NextEvent = Settings.HBlankStart; CPUPack.CPU.V_Counter = 0; CPUPack.CPU.MemSpeed = SLOW_ONE_CYCLE; CPUPack.CPU.MemSpeedx2 = SLOW_ONE_CYCLE * 2; CPUPack.CPU.FastROMSpeed = SLOW_ONE_CYCLE; CPUPack.CPU.AutoSaveTimer = 0; CPUPack.CPU.SRAMModified = FALSE; // CPUPack.CPU.NMITriggerPoint = 4; // Set when ROM image loaded CPUPack.CPU.BRKTriggered = FALSE; //CPUPack.CPU.TriedInterleavedMode2 = FALSE; // Reset when ROM image loaded CPUPack.CPU.NMICycleCount = 0; CPUPack.CPU.IRQCycleCount = 0; S9xSetPCBase (CPUPack.Registers.PC); #ifndef VAR_CYCLES CPUPack.ICPU.Speed = S9xE1M1X1; #endif CPUPack.ICPU.S9xOpcodes = S9xOpcodesM1X1; CPUPack.ICPU.CPUExecuting = TRUE; S9xUnpackStatus(); }
void S9xResetCPU() { ICPU.Registers.PB = 0; ICPU.Registers.PC = S9xGetWord(0xFFFC); ICPU.Registers.D.W = 0; ICPU.Registers.DB = 0; ICPU.Registers.SH = 1; ICPU.Registers.SL = 0xFF; ICPU.Registers.XH = 0; ICPU.Registers.YH = 0; ICPU.Registers.P.W = 0; ICPU.ShiftedPB = 0; ICPU.ShiftedDB = 0; SetFlags(MemoryFlag | IndexFlag | IRQ | Emulation); ClearFlags(Decimal); CPU.Flags = CPU.Flags & (DEBUG_MODE_FLAG | TRACE_FLAG); CPU.BranchSkip = false; CPU.NMIActive = false; CPU.IRQActive = false; CPU.WaitingForInterrupt = false; CPU.InDMA = false; CPU.WhichEvent = HBLANK_START_EVENT; CPU.PC = NULL; CPU.PCBase = NULL; CPU.PCAtOpcodeStart = NULL; CPU.WaitAddress = NULL; CPU.WaitCounter = 0; CPU.Cycles = 0; CPU.NextEvent = Settings.HBlankStart; CPU.V_Counter = 0; CPU.MemSpeed = SLOW_ONE_CYCLE; CPU.MemSpeedx2 = SLOW_ONE_CYCLE * 2; CPU.FastROMSpeed = SLOW_ONE_CYCLE; CPU.AutoSaveTimer = 0; CPU.SRAMModified = false; // CPU.NMITriggerPoint = 4; // Set when ROM image loaded CPU.BRKTriggered = false; //CPU.TriedInterleavedMode2 = false; // Reset when ROM image loaded CPU.NMICycleCount = 0; CPU.IRQCycleCount = 0; S9xSetPCBase(ICPU.Registers.PC); ICPU.S9xOpcodes = S9xOpcodesE1; ICPU.CPUExecuting = true; S9xUnpackStatus(); }
static int ReadOrigSnapshot (STREAM snap) { char buffer [_MAX_PATH]; char rom_filename [_MAX_PATH]; int result; int i; int j; int version; int len = strlen (ORIG_SNAPSHOT_MAGIC) + 1 + 4 + 1; if (READ_STREAM (buffer, len, snap) != len) return (WRONG_FORMAT); if (strncmp (buffer, ORIG_SNAPSHOT_MAGIC, strlen (ORIG_SNAPSHOT_MAGIC)) != 0) return (WRONG_FORMAT); if ((version = atoi (&buffer [strlen (SNAPSHOT_MAGIC) + 1])) > ORIG_SNAPSHOT_VERSION) return (WRONG_VERSION); if ((result = ReadBlock ("NAM:", rom_filename, _MAX_PATH, snap)) != SUCCESS) return (result); if ((result = ReadBlock ("HiR:", buffer, 0x41, snap)) != SUCCESS) return (result); if (strcasecmp (rom_filename, Memory.ROMFilename) != 0 && strcasecmp (S9xBasename (rom_filename), S9xBasename (Memory.ROMFilename)) != 0) { S9xMessage (S9X_WARNING, S9X_FREEZE_ROM_NAME, "Current loaded ROM image doesn't match that required by freeze-game file."); } S9xReset (); S9xSetSoundMute (TRUE); if ((result = ReadBlock ("CPU:", &OrigCPU, sizeof (OrigCPU), snap)) != SUCCESS) return (result); OrigCPU.FastROMSpeed = OrigCPU.FastROMSpeed_old; Memory.FixROMSpeed (); if (version == 3) { OrigCPU.Cycles = OrigCPU.Cycles_old; OrigCPU.NextEvent = OrigCPU.NextEvent_old; OrigCPU.V_Counter = OrigCPU.V_Counter_old; OrigCPU.MemSpeed = OrigCPU.MemSpeed_old; OrigCPU.MemSpeedx2 = OrigCPU.MemSpeedx2_old; OrigCPU.FastROMSpeed = OrigCPU.FastROMSpeed_old; } CPU.Flags = OrigCPU.Flags; CPU.BranchSkip = OrigCPU.BranchSkip; CPU.NMIActive = OrigCPU.NMIActive; CPU.IRQActive = OrigCPU.IRQActive; CPU.WaitingForInterrupt = OrigCPU.WaitingForInterrupt; CPU.WhichEvent = OrigCPU.WhichEvent; CPU.Cycles = OrigCPU.Cycles; CPU.NextEvent = OrigCPU.NextEvent; CPU.V_Counter = OrigCPU.V_Counter; CPU.MemSpeed = OrigCPU.MemSpeed; CPU.MemSpeedx2 = OrigCPU.MemSpeedx2; CPU.FastROMSpeed = OrigCPU.FastROMSpeed; if ((result = ReadBlock ("REG:", &OrigRegisters, sizeof (OrigRegisters), snap)) != SUCCESS) return (result); Registers = *(struct SRegisters *) &OrigRegisters; if ((result = ReadBlock ("PPU:", &OrigPPU, sizeof (OrigPPU), snap)) != SUCCESS) return (result); if (version == 2) { OrigPPU.OBJNameSelect = OrigPPU.OBJNameSelect_old << 13; OrigPPU.OBJNameBase <<= 1; OrigPPU.OBJNameSelect <<= 13; } PPU.BGMode = OrigPPU.BGMode; PPU.BG3Priority = OrigPPU.BG3Priority; PPU.Brightness = OrigPPU.Brightness; PPU.VMA.High = OrigPPU.VMA.High; PPU.VMA.Increment = OrigPPU.VMA.Increment; PPU.VMA.Address = OrigPPU.VMA.Address; PPU.VMA.Mask1 = OrigPPU.VMA.Mask1; PPU.VMA.FullGraphicCount = OrigPPU.VMA.FullGraphicCount; PPU.VMA.Shift = OrigPPU.VMA.Shift; for (i = 0; i < 4; i++) { PPU.BG[i].SCBase = OrigPPU.BG[i].SCBase; PPU.BG[i].VOffset = OrigPPU.BG[i].VOffset; PPU.BG[i].HOffset = OrigPPU.BG[i].HOffset; PPU.BG[i].BGSize = OrigPPU.BG[i].BGSize; PPU.BG[i].NameBase = OrigPPU.BG[i].NameBase; PPU.BG[i].SCSize = OrigPPU.BG[i].SCSize; } PPU.CGFLIP = OrigPPU.CGFLIP; for (i = 0; i < 256; i++) PPU.CGDATA [i] = OrigPPU.CGDATA [i]; PPU.FirstSprite = OrigPPU.FirstSprite; for (i = 0; i < 128; i++) { PPU.OBJ[i].HPos = OrigPPU.OBJ [i].HPos; PPU.OBJ[i].VPos = OrigPPU.OBJ [i].VPos; PPU.OBJ[i].Name = OrigPPU.OBJ [i].Name; PPU.OBJ[i].VFlip = OrigPPU.OBJ [i].VFlip; PPU.OBJ[i].HFlip = OrigPPU.OBJ [i].HFlip; PPU.OBJ[i].Priority = OrigPPU.OBJ [i].Priority; PPU.OBJ[i].Palette = OrigPPU.OBJ [i].Palette; PPU.OBJ[i].Size = OrigPPU.OBJ [i].Size; } PPU.OAMPriorityRotation = OrigPPU.OAMPriorityRotation; PPU.OAMAddr = OrigPPU.OAMAddr; PPU.OAMFlip = OrigPPU.OAMFlip; PPU.OAMTileAddress = OrigPPU.OAMTileAddress; PPU.IRQVBeamPos = OrigPPU.IRQVBeamPos; PPU.IRQHBeamPos = OrigPPU.IRQHBeamPos; PPU.VBeamPosLatched = OrigPPU.VBeamPosLatched; PPU.HBeamPosLatched = OrigPPU.HBeamPosLatched; PPU.HBeamFlip = OrigPPU.HBeamFlip; PPU.VBeamFlip = OrigPPU.VBeamFlip; PPU.HVBeamCounterLatched = OrigPPU.HVBeamCounterLatched; PPU.MatrixA = OrigPPU.MatrixA; PPU.MatrixB = OrigPPU.MatrixB; PPU.MatrixC = OrigPPU.MatrixC; PPU.MatrixD = OrigPPU.MatrixD; PPU.CentreX = OrigPPU.CentreX; PPU.CentreY = OrigPPU.CentreY; PPU.Joypad1ButtonReadPos = OrigPPU.Joypad1ButtonReadPos; PPU.Joypad2ButtonReadPos = OrigPPU.Joypad2ButtonReadPos; PPU.Joypad3ButtonReadPos = OrigPPU.Joypad3ButtonReadPos; PPU.CGADD = OrigPPU.CGADD; PPU.FixedColourRed = OrigPPU.FixedColourRed; PPU.FixedColourGreen = OrigPPU.FixedColourGreen; PPU.FixedColourBlue = OrigPPU.FixedColourBlue; PPU.SavedOAMAddr = OrigPPU.SavedOAMAddr; PPU.ScreenHeight = OrigPPU.ScreenHeight; PPU.WRAM = OrigPPU.WRAM; PPU.ForcedBlanking = OrigPPU.ForcedBlanking; PPU.OBJNameSelect = OrigPPU.OBJNameSelect; PPU.OBJSizeSelect = OrigPPU.OBJSizeSelect; PPU.OBJNameBase = OrigPPU.OBJNameBase; PPU.OAMReadFlip = OrigPPU.OAMReadFlip; memmove (PPU.OAMData, OrigPPU.OAMData, sizeof (PPU.OAMData)); PPU.VTimerEnabled = OrigPPU.VTimerEnabled; PPU.HTimerEnabled = OrigPPU.HTimerEnabled; PPU.HTimerPosition = OrigPPU.HTimerPosition; PPU.Mosaic = OrigPPU.Mosaic; memmove (PPU.BGMosaic, OrigPPU.BGMosaic, sizeof (PPU.BGMosaic)); PPU.Mode7HFlip = OrigPPU.Mode7HFlip; PPU.Mode7VFlip = OrigPPU.Mode7VFlip; PPU.Mode7Repeat = OrigPPU.Mode7Repeat; PPU.Window1Left = OrigPPU.Window1Left; PPU.Window1Right = OrigPPU.Window1Right; PPU.Window2Left = OrigPPU.Window2Left; PPU.Window2Right = OrigPPU.Window2Right; for (i = 0; i < 6; i++) { PPU.ClipWindowOverlapLogic [i] = OrigPPU.ClipWindowOverlapLogic [i]; PPU.ClipWindow1Enable [i] = OrigPPU.ClipWindow1Enable [i]; PPU.ClipWindow2Enable [i] = OrigPPU.ClipWindow2Enable [i]; PPU.ClipWindow1Inside [i] = OrigPPU.ClipWindow1Inside [i]; PPU.ClipWindow2Inside [i] = OrigPPU.ClipWindow2Inside [i]; } PPU.CGFLIPRead = OrigPPU.CGFLIPRead; PPU.Need16x8Mulitply = OrigPPU.Need16x8Mulitply; IPPU.ColorsChanged = TRUE; IPPU.OBJChanged = TRUE; S9xFixColourBrightness (); IPPU.RenderThisFrame = FALSE; if ((result = ReadBlock ("DMA:", OrigDMA, sizeof (OrigDMA), snap)) != SUCCESS) return (result); for (i = 0; i < 8; i++) { DMA[i].TransferDirection = OrigDMA[i].TransferDirection; DMA[i].AAddressFixed = OrigDMA[i].AAddressFixed; DMA[i].AAddressDecrement = OrigDMA[i].AAddressDecrement; DMA[i].TransferMode = OrigDMA[i].TransferMode; DMA[i].ABank = OrigDMA[i].ABank; DMA[i].AAddress = OrigDMA[i].AAddress; DMA[i].Address = OrigDMA[i].Address; DMA[i].BAddress = OrigDMA[i].BAddress; DMA[i].TransferBytes = OrigDMA[i].TransferBytes; DMA[i].HDMAIndirectAddressing = OrigDMA[i].HDMAIndirectAddressing; DMA[i].IndirectAddress = OrigDMA[i].IndirectAddress; DMA[i].IndirectBank = OrigDMA[i].IndirectBank; DMA[i].Repeat = OrigDMA[i].Repeat; DMA[i].LineCount = OrigDMA[i].LineCount; DMA[i].FirstLine = OrigDMA[i].FirstLine; } if ((result = ReadBlock ("VRA:", Memory.VRAM, 0x10000, snap)) != SUCCESS) return (result); if ((result = ReadBlock ("RAM:", Memory.RAM, 0x20000, snap)) != SUCCESS) return (result); if ((result = ReadBlock ("SRA:", Memory.SRAM, 0x10000, snap)) != SUCCESS) return (result); if ((result = ReadBlock ("FIL:", Memory.FillRAM, 0x8000, snap)) != SUCCESS) return (result); if (ReadBlock ("APU:", &OrigAPU, sizeof (OrigAPU), snap) == SUCCESS) { APU = *(struct SAPU *) &OrigAPU; if ((result = ReadBlock ("ARE:", &OrigAPURegisters, sizeof (OrigAPURegisters), snap)) != SUCCESS) return (result); APURegisters = *(struct SAPURegisters *) &OrigAPURegisters; if ((result = ReadBlock ("ARA:", IAPU.RAM, 0x10000, snap)) != SUCCESS) return (result); if ((result = ReadBlock ("SOU:", &OrigSoundData, sizeof (SOrigSoundData), snap)) != SUCCESS) return (result); SoundData.master_volume_left = OrigSoundData.master_volume_left; SoundData.master_volume_right = OrigSoundData.master_volume_right; SoundData.echo_volume_left = OrigSoundData.echo_volume_left; SoundData.echo_volume_right = OrigSoundData.echo_volume_right; SoundData.echo_enable = OrigSoundData.echo_enable; SoundData.echo_feedback = OrigSoundData.echo_feedback; SoundData.echo_ptr = OrigSoundData.echo_ptr; SoundData.echo_buffer_size = OrigSoundData.echo_buffer_size; SoundData.echo_write_enabled = OrigSoundData.echo_write_enabled; SoundData.echo_channel_enable = OrigSoundData.echo_channel_enable; SoundData.pitch_mod = OrigSoundData.pitch_mod; for (i = 0; i < 3; i++) SoundData.dummy [i] = OrigSoundData.dummy [i]; for (i = 0; i < NUM_CHANNELS; i++) { SoundData.channels [i].state = OrigSoundData.channels [i].state; SoundData.channels [i].type = OrigSoundData.channels [i].type; SoundData.channels [i].volume_left = OrigSoundData.channels [i].volume_left; SoundData.channels [i].volume_right = OrigSoundData.channels [i].volume_right; SoundData.channels [i].hertz = OrigSoundData.channels [i].frequency; SoundData.channels [i].count = OrigSoundData.channels [i].count; SoundData.channels [i].loop = OrigSoundData.channels [i].loop; SoundData.channels [i].envx = OrigSoundData.channels [i].envx; SoundData.channels [i].left_vol_level = OrigSoundData.channels [i].left_vol_level; SoundData.channels [i].right_vol_level = OrigSoundData.channels [i].right_vol_level; SoundData.channels [i].envx_target = OrigSoundData.channels [i].envx_target; SoundData.channels [i].env_error = OrigSoundData.channels [i].env_error; SoundData.channels [i].erate = OrigSoundData.channels [i].erate; SoundData.channels [i].direction = OrigSoundData.channels [i].direction; SoundData.channels [i].attack_rate = OrigSoundData.channels [i].attack_rate; SoundData.channels [i].decay_rate = OrigSoundData.channels [i].decay_rate; SoundData.channels [i].sustain_rate = OrigSoundData.channels [i].sustain_rate; SoundData.channels [i].release_rate = OrigSoundData.channels [i].release_rate; SoundData.channels [i].sustain_level = OrigSoundData.channels [i].sustain_level; SoundData.channels [i].sample = OrigSoundData.channels [i].sample; for (j = 0; j < 16; j++) SoundData.channels [i].decoded [j] = OrigSoundData.channels [i].decoded [j]; for (j = 0; j < 2; j++) SoundData.channels [i].previous [j] = OrigSoundData.channels [i].previous [j]; SoundData.channels [i].sample_number = OrigSoundData.channels [i].sample_number; SoundData.channels [i].last_block = OrigSoundData.channels [i].last_block; SoundData.channels [i].needs_decode = OrigSoundData.channels [i].needs_decode; SoundData.channels [i].block_pointer = OrigSoundData.channels [i].block_pointer; SoundData.channels [i].sample_pointer = OrigSoundData.channels [i].sample_pointer; SoundData.channels [i].mode = OrigSoundData.channels [i].mode; } S9xSetSoundMute (FALSE); IAPU.PC = IAPU.RAM + APURegisters.PC; S9xAPUUnpackStatus (); if (APUCheckDirectPage ()) IAPU.DirectPage = IAPU.RAM + 0x100; else IAPU.DirectPage = IAPU.RAM; Settings.APUEnabled = TRUE; IAPU.APUExecuting = TRUE; } else { Settings.APUEnabled = FALSE; IAPU.APUExecuting = FALSE; S9xSetSoundMute (TRUE); } S9xFixSoundAfterSnapshotLoad (1); ICPU.ShiftedPB = Registers.PB << 16; ICPU.ShiftedDB = Registers.DB << 16; S9xSetPCBase (ICPU.ShiftedPB + Registers.PC); S9xUnpackStatus (); S9xFixCycles (); S9xReschedule (); return (SUCCESS); }
static int Unfreeze() { // notaz: overflowing the damn Symbian stack again char buffer [16]; char rom_filename [512]; int result; int version; unsigned int len = strlen(SNAPSHOT_MAGIC) + 1 + 4 + 1; if (statef_read(buffer, len) != (int)len) return (WRONG_FORMAT); if (strncmp(buffer, SNAPSHOT_MAGIC, strlen(SNAPSHOT_MAGIC)) != 0) return (WRONG_FORMAT); if ((version = atoi(&buffer [strlen(SNAPSHOT_MAGIC) + 1])) > SNAPSHOT_VERSION) return (WRONG_VERSION); if ((result = UnfreezeBlock("NAM", (uint8*) rom_filename, 512)) != SUCCESS) return (result); if (strcasecmp(rom_filename, Memory.ROMFilename) != 0 && strcasecmp(S9xBasename(rom_filename), S9xBasename(Memory.ROMFilename)) != 0) { S9xMessage(S9X_WARNING, S9X_FREEZE_ROM_NAME, "Current loaded ROM image doesn't match that required by freeze-game file."); } uint32 old_flags = CPU.Flags; #ifdef USE_SA1 uint32 sa1_old_flags = SA1.Flags; #endif S9xReset(); S9xSetSoundMute(TRUE); if ((result = UnfreezeStruct("CPU", &CPU, SnapCPU, COUNT(SnapCPU))) != SUCCESS) return (result); FixROMSpeed(); CPU.Flags |= old_flags & (DEBUG_MODE_FLAG | TRACE_FLAG | SINGLE_STEP_FLAG | FRAME_ADVANCE_FLAG); if ((result = UnfreezeStruct("REG", &Registers, SnapRegisters, COUNT(SnapRegisters))) != SUCCESS) return (result); if ((result = UnfreezeStruct("PPU", &PPU, SnapPPU, COUNT(SnapPPU))) != SUCCESS) return (result); IPPU.ColorsChanged = TRUE; IPPU.OBJChanged = TRUE; CPU.InDMA = FALSE; // Restore colors from PPU unsigned int i; for (i = 0; i < 256; i++) { IPPU.Red[i] = PPU.CGDATA[i] & 0x1f; IPPU.Green[i] = (PPU.CGDATA[i] >> 5) & 0x1f; IPPU.Blue[i] = (PPU.CGDATA[i] >> 10) & 0x1f; } S9xFixColourBrightness(); IPPU.RenderThisFrame = FALSE; if ((result = UnfreezeStruct("DMA", DMA, SnapDMA, COUNT(SnapDMA))) != SUCCESS) return (result); if ((result = UnfreezeBlock("VRA", Memory.VRAM, 0x10000)) != SUCCESS) return (result); if ((result = UnfreezeBlock("RAM", Memory.RAM, 0x20000)) != SUCCESS) return (result); if ((result = UnfreezeBlock("SRA", SRAM, 0x20000)) != SUCCESS) return (result); if ((result = UnfreezeBlock("FIL", Memory.FillRAM, 0x8000)) != SUCCESS) return (result); // Restore graphics shadow registers GFX.r212c_s = Memory.FillRAM[0x212c]; GFX.r212d_s = Memory.FillRAM[0x212d]; GFX.r212e_s = Memory.FillRAM[0x212e]; GFX.r212f_s = Memory.FillRAM[0x212f]; GFX.r2130_s = Memory.FillRAM[0x2130]; GFX.r2131_s = Memory.FillRAM[0x2131]; if (UnfreezeStruct("APU", &APU, SnapAPU, COUNT(SnapAPU)) == SUCCESS) { SAPURegisters spcregs; if ((result = UnfreezeStruct("ARE", &spcregs, SnapAPURegisters, COUNT(SnapAPURegisters))) != SUCCESS) return (result); // reload all SPC700 regs from savestate compatible struct IAPU.P = spcregs.P; IAPU.YA.W = spcregs.YA.W; IAPU.X = spcregs.X; IAPU.S = spcregs.S; IAPU.PC = IAPU.RAM + spcregs.PC; if ((result = UnfreezeBlock("ARA", IAPU.RAM, 0x10000)) != SUCCESS) return (result); if ((result = UnfreezeStruct("SOU", &SoundData, SnapSoundData, COUNT(SnapSoundData))) != SUCCESS) return (result); // notaz: just to be sure int u; for (u = 0; u < 8; u++) { SoundData.channels[u].env_ind_attack &= 0xf; SoundData.channels[u].env_ind_decay &= 0x7; SoundData.channels[u].env_ind_sustain &= 0x1f; } S9xSetSoundMute(FALSE); S9xAPUUnpackStatus(); if (APUCheckDirectPage()) IAPU.DirectPage = IAPU.RAM + 0x100; else IAPU.DirectPage = IAPU.RAM; Settings.APUEnabled = TRUE; /*IAPU.APUExecuting*/CPU.APU_APUExecuting = TRUE; } else { Settings.APUEnabled = FALSE; /*IAPU.APUExecuting*/CPU.APU_APUExecuting = FALSE; S9xSetSoundMute(TRUE); } #ifdef USE_SA1 if ((result = UnfreezeStruct("SA1", &SA1, SnapSA1, COUNT(SnapSA1))) == SUCCESS) { if ((result = UnfreezeStruct("SAR", &SA1Registers, SnapSA1Registers, COUNT(SnapSA1Registers))) != SUCCESS) return (result); S9xFixSA1AfterSnapshotLoad(); SA1.Flags |= sa1_old_flags & (TRACE_FLAG); } #endif S9xFixSoundAfterSnapshotLoad(); ICPU.ShiftedPB = Registers.PB << 16; ICPU.ShiftedDB = Registers.DB << 16; S9xSetPCBase(ICPU.ShiftedPB + Registers.PC); #ifndef ASMCPU S9xUnpackStatus(); // not needed S9xFixCycles(); // also not needed? #endif S9xReschedule(); S9xSRTCPostLoadState(); if (Settings.SDD1) S9xSDD1PostLoadState(); return (SUCCESS); }