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 S9xAPUSetByte(uint8 val, uint32 Address) { Address &= 0xffff; if (Address <= 0xff && Address >= 0xf0) { if (Address == 0xf3) S9xSetAPUDSP(val); else if (Address >= 0xf4 && Address <= 0xf7) APU.OutPorts [Address - 0xf4] = val; else if (Address == 0xf1) S9xSetAPUControl(val); else if (Address < 0xfd) { IAPU.RAM [Address] = val; if (Address >= 0xfa) { if (val == 0) APU.TimerTarget [Address - 0xfa] = 0x100; else APU.TimerTarget [Address - 0xfa] = val; } } } else { #if 0 if (Address >= 0x2500 && Address <= 0x2504) printf("%06d %04x <- %02x\n", ICPU.Scanline, Address, val); if (Address == 0x26c6) { extern FILE *apu_trace; extern FILE *trace; APU.Flags |= TRACE_FLAG; CPU.Flags |= TRACE_FLAG; if (apu_trace == NULL) apu_trace = fopen("aputrace.log", "wb"); if (trace == NULL) trace = fopen("trace.log", "wb"); printf("TRACING SWITCHED ON\n"); } #endif if (Address < 0xffc0) IAPU.RAM [Address] = val; else { APU.ExtraRAM [Address - 0xffc0] = val; if (!APU.ShowROM) IAPU.RAM [Address] = val; } } }
void S9xAPUSetByteZ(uint8 val, uint8 Address) { if (Address >= 0xf0 && IAPU.DirectPage == IAPU.RAM) { if (Address == 0xf3) S9xSetAPUDSP(val); else if (Address >= 0xf4 && Address <= 0xf7) APU.OutPorts [Address - 0xf4] = val; else if (Address == 0xf1) S9xSetAPUControl(val); else if (Address < 0xfd) { IAPU.RAM [Address] = val; if (Address >= 0xfa) { if (val == 0) APU.TimerTarget [Address - 0xfa] = 0x100; else APU.TimerTarget [Address - 0xfa] = val; } } } else IAPU.DirectPage [Address] = val; }
/* 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 }