Esempio n. 1
0
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:", 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 + IAPU.PC;
      S9xAPUUnpackStatus();
      if (APUCheckDirectPage())
         IAPU.DirectPage = IAPU.RAM + 0x100;
      else
         IAPU.DirectPage = IAPU.RAM;
      Settings.APUEnabled = TRUE;
      CPU.APU_APUExecuting = TRUE;
   }
   else
   {
      Settings.APUEnabled = FALSE;
      CPU.APU_APUExecuting = FALSE;
      S9xSetSoundMute(TRUE);
   }
   S9xFixSoundAfterSnapshotLoad();
   ICPU.ShiftedPB = Registers.PB << 16;
   ICPU.ShiftedDB = Registers.DB << 16;
   S9xSetPCBase(ICPU.ShiftedPB + Registers.PC, &CPU);
   S9xUnpackStatus();
   S9xFixCycles(&Registers, &ICPU);
   S9xReschedule();

   return (SUCCESS);
}
Esempio n. 2
0
/* 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) {
        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
}