static void SPCPlayDefrost(void) { uint16 savedswitch; short i; savedswitch = so.stereo_switch; S9xResetAPU(); S9xSetSoundMute(true); memcpy(&APU, StoredAPU, sizeof(SAPU)); memcpy(&APURegisters, StoredAPURegisters, sizeof(SAPURegisters)); memcpy(&SoundData, StoredSoundData, sizeof(SSoundData)); memcpy(IAPU.RAM, StoredIAPURAM, 0x10000); if (!mbxFinished) { for (i = 0; i < 4; i++) APU.OutPorts[i] = IAPU.RAM[0xf4 + i]; for (i = 0; i < 3; i++) { if (IAPU.RAM[0xfa + i] == 0) APU.TimerTarget[i] = 0x100; else APU.TimerTarget[i] = IAPU.RAM[0xfa + i]; } S9xSetAPUControl(IAPU.RAM[0xf1] & 0xcf); // Don't reset I/O ports } S9xSetSoundMute(false); IAPU.PC = IAPU.RAM + APURegisters.PC; S9xAPUUnpackStatus(); if (APUCheckDirectPage()) IAPU.DirectPage = IAPU.RAM + 0x100; else IAPU.DirectPage = IAPU.RAM; IAPU.APUExecuting = true; IAPU.NextAPUTimerPos = oldNextAPUTimerPos; IAPU.APUTimerCounter = oldAPUTimerCounter; CPU.Cycles = oldCPUCycles; S9xFixSoundAfterSnapshotLoad(SNAPSHOT_VERSION); so.stereo_switch = savedswitch; }
void SnesEmu::sl() { if (emsl.save) { S9xSRTCPreSaveState(); } else { S9xReset(); } snesCpuSl(); snesMemSl(); snesPpuSl(); snesDmaSl(); snesSoundSl(); snesSpuSl(); if (!emsl.save) { S9xFixSoundAfterSnapshotLoad(); S9xSetPCBase(ICPU.ShiftedPB + Registers.PC); S9xReschedule(); S9xSRTCPostLoadState(); if (Settings.SDD1) S9xSDD1PostLoadState(); S9xSetSoundMute(FALSE); } }
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); }
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); }
/* Restore SPC state ---------------------------------------------------------------- */ static void RestoreSPC() { int i; APURegisters.PC = BackupAPURegisters.PC; APURegisters.YA.B.A = BackupAPURegisters.YA.B.A; APURegisters.X = BackupAPURegisters.X; APURegisters.YA.B.Y = BackupAPURegisters.YA.B.Y; APURegisters.P = BackupAPURegisters.P; APURegisters.S = BackupAPURegisters.S; memcpy (IAPU.RAM, BackupAPURAM, 65536); memcpy (APU.ExtraRAM, BackupAPUExtraRAM, 64); memcpy (APU.DSP, BackupDSPRAM, 128); for (i = 0; i < 4; i ++) { APU.OutPorts[i] = IAPU.RAM[0xf4 + i]; } IAPU.TimerErrorCounter = 0; for (i = 0; i < 3; i ++) { if (IAPU.RAM[0xfa + i] == 0) APU.TimerTarget[i] = 0x100; else APU.TimerTarget[i] = IAPU.RAM[0xfa + i]; } S9xSetAPUControl (IAPU.RAM[0xf1]); /* from snaporig.cpp (ReadOrigSnapshot) */ 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; S9xFixSoundAfterSnapshotLoad (); S9xSetFrequencyModulationEnable (APU.DSP[APU_PMON]); S9xSetMasterVolume (APU.DSP[APU_MVOL_LEFT], APU.DSP[APU_MVOL_RIGHT]); S9xSetEchoVolume (APU.DSP[APU_EVOL_LEFT], APU.DSP[APU_EVOL_RIGHT]); uint8 mask = 1; int type; for (i = 0; i < 8; i++, mask <<= 1) { // unused // Channel *ch = &SoundData.channels[i]; S9xFixEnvelope (i, APU.DSP[APU_GAIN + (i << 4)], APU.DSP[APU_ADSR1 + (i << 4)], APU.DSP[APU_ADSR2 + (i << 4)]); S9xSetSoundVolume (i, APU.DSP[APU_VOL_LEFT + (i << 4)], APU.DSP[APU_VOL_RIGHT + (i << 4)]); S9xSetSoundFrequency (i, ((APU.DSP[APU_P_LOW + (i << 4)] + (APU.DSP[APU_P_HIGH + (i << 4)] << 8)) & FREQUENCY_MASK) * 8); if (APU.DSP [APU_NON] & mask) type = SOUND_NOISE; else type = SOUND_SAMPLE; S9xSetSoundType (i, type); if ((APU.DSP[APU_KON] & mask) != 0) { APU.KeyedChannels |= mask; S9xPlaySample (i); } } #if 0 unsigned char temp=IAPU.RAM[0xf2]; for(i=0;i<128;i++){ IAPU.RAM[0xf2]=i; S9xSetAPUDSP(APU.DSP[i]); } IAPU.RAM[0xf2]=temp; #endif }