示例#1
0
void
S9xDoHBlankProcessing_HBLANK_START_EVENT ()
{
	//START_PROFILE_FUNC (S9xDoHBlankProcessing);
#ifdef CPU_SHUTDOWN
  CPUPack.CPU.WaitCounter++;
#endif

  if (IPPU.HDMA && CPUPack.CPU.V_Counter <= PPU.ScreenHeight) IPPU.HDMA = S9xDoHDMA (IPPU.HDMA);
  S9xReschedule ();
  //FINISH_PROFILE_FUNC (S9xDoHBlankProcessing); 
}
示例#2
0
int os9x_load(const char *ext) {	
	FILE *savefile;
	const char *save_filename;
	os9x_externstate_mode=0;
	
	save_filename=S9xGetSaveFilename (ext);	
	savefile=fopen(save_filename,"rb");
  if (savefile) {
  	fclose(savefile);
		S9xUnfreezeGame(save_filename);
//		S9xInitUpdate();
		S9xReschedule ();
		return 1;
	} 
	return 0;
}
示例#3
0
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);
	}
}
示例#4
0
void
S9xDoHBlankProcessing_HBLANK_END_EVENT () {
	//START_PROFILE_FUNC (S9xDoHBlankProcessing);			
#ifdef CPU_SHUTDOWN
  CPUPack.CPU.WaitCounter++;
#endif
  if (Settings.SuperFX) S9xSuperFXExec ();
  	  

	cpu_glob_cycles += CPUPack.CPU.Cycles-old_cpu_cycles;		
	CPUPack.CPU.Cycles -= Settings.H_Max;	
	old_cpu_cycles=CPUPack.CPU.Cycles;
	
#ifdef FAST_IAPU_APUEXECUTING_CHECK
	if (IAPU_APUExecuting_Main==false || APUExecuting_Main_Counter==0)
		IAPU_APUExecuting_Main = IAPU_APUExecuting;
	if (IAPU_APUExecuting_Main){
		apu_glob_cycles_Main=cpu_glob_cycles;
		if (cpu_glob_cycles>=0x00700000) {
			APU_EXECUTE2();
		}
	}
	else {
  		apu_glob_cycles=apu_glob_cycles_Main=0;
  		Uncache_APU_Cycles = 0;
	}
	if (APUExecuting_Main_Counter==0){
		FLUSH_APU();
	}
#else
  //(IAPUuncached.NextAPUTimerPos) -= (Settings.H_Max * 10000L);      
  if (  (IAPU_APUExecuting_Main)) {
  	//(APUPack.APU.Cycles) -= Settings.H_Max;
		apu_glob_cycles=cpu_glob_cycles;
#ifdef ME_SOUND		
		if (cpu_glob_cycles>=0x00700000) {		
			APU_EXECUTE2 ();
		}
#else
//		if (cpu_glob_cycles>=0x00000000) {		
//			APU_EXECUTE2 ();
//		}
#endif		
  }
  else {
  	//(APUPack.APU.Cycles) = 0;
  	apu_glob_cycles=0;
  	Uncache_APU_Cycles = 0;
  }
#endif
  
       
  CPUPack.CPU.NextEvent = -1;
// not use
//  CPUPack.ICPU.Scanline++;

  if (++CPUPack.CPU.V_Counter > (Settings.PAL ? SNES_MAX_PAL_VCOUNTER : SNES_MAX_NTSC_VCOUNTER)) {
  	//PPU.OAMAddr = PPU.SavedOAMAddr;
    //PPU.OAMFlip = 0;            
    CPUPack.CPU.V_Counter = 0;
    ROM_GLOBAL[0x213F]^=0x80;
    CPUPack.CPU.NMIActive = FALSE;
    //CPUPack.ICPU.Frame++;
    PPU.HVBeamCounterLatched = 0;
    CPUPack.CPU.Flags |= SCAN_KEYS_FLAG;
    S9xStartHDMA ();
  }

  if (PPU.VTimerEnabled && !PPU.HTimerEnabled && CPUPack.CPU.V_Counter == PPU.IRQVBeamPos) S9xSetIRQ (PPU_V_BEAM_IRQ_SOURCE);
#if (1)
//  pEvent->apu_event1[pEvent->apu_event1_cpt2 & 0xFFFF]=(os9x_apu_ratio != 256) ? cpu_glob_cycles * os9x_apu_ratio / 256: cpu_glob_cycles;
//  pEvent->apu_event1_cpt2++;
  uint32 EventVal = (os9x_apu_ratio != 256) ? cpu_glob_cycles * os9x_apu_ratio / 256: cpu_glob_cycles;
  if (CPUPack.CPU.V_Counter & 1) {
    EventVal |= 0x80000000;
  }
#ifdef ME_SOUND
  int pos=apu_event1_cpt2_main++;
  apu_event1[pos & APU_EVENT_MASK] = EventVal;
  apu_event1_cpt2=apu_event1_cpt2_main;
#else
  int pos=apu_event1_cpt2;
  apu_event1[pos & APU_EVENT_MASK] = EventVal;
  apu_event1_cpt2=pos+1;
#endif

  //APU_EXECUTE2 ();
    
  /*if ((APUPack.APU.TimerEnabled) [2]) {
		(APUPack.APU.Timer) [2] += 4;
		while ((APUPack.APU.Timer) [2] >= (APUPack.APU.TimerTarget) [2]) {
		  (IAPUuncached.RAM) [0xff] = ((IAPUuncached.RAM) [0xff] + 1) & 0xf;
		  (APUPack.APU.Timer) [2] -= (APUPack.APU.TimerTarget) [2];
#ifdef SPC700_SHUTDOWN
		  (IAPUuncached.WaitCounter)++;
		  (IAPU_APUExecuting)= TRUE;
#endif		
		}
	}*/
#else
	if (CPUPack.CPU.V_Counter & 1) {		
		apu_event2[(apu_event2_cpt2)&0xFFFF]=cpu_glob_cycles * os9x_apu_ratio / 256;  
  	(apu_event2_cpt2)++;
		/*if ((APUPack.APU.TimerEnabled) [0]) {
		  (APUPack.APU.Timer) [0]++;
		  if ((APUPack.APU.Timer) [0] >= (APUPack.APU.TimerTarget) [0]) {
				(IAPUuncached.RAM) [0xfd] = ((IAPUuncached.RAM) [0xfd] + 1) & 0xf;
				(APUPack.APU.Timer) [0] = 0;
#ifdef SPC700_SHUTDOWN		
				(IAPUuncached.WaitCounter)++;
				(IAPU_APUExecuting)= TRUE;
#endif		    
		  }
		}
		if ((APUPack.APU.TimerEnabled) [1]) {
		  (APUPack.APU.Timer) [1]++;
		  if ((APUPack.APU.Timer) [1] >= (APUPack.APU.TimerTarget) [1]) {
				(IAPUuncached.RAM) [0xfe] = ((IAPUuncached.RAM) [0xfe] + 1) & 0xf;
				(APUPack.APU.Timer) [1] = 0;
#ifdef SPC700_SHUTDOWN		
				(IAPUuncached.WaitCounter)++;
				(IAPU_APUExecuting) = TRUE;
#endif		    
		  }
		}*/		
	}	  
#endif
  if (CPUPack.CPU.V_Counter == FIRST_VISIBLE_LINE)
    {
      ROM_GLOBAL[0x4210] = 0;
      CPUPack.CPU.Flags &= ~NMI_FLAG;
      S9xStartScreenRefresh ();
    }
  if (CPUPack.CPU.V_Counter >= FIRST_VISIBLE_LINE &&
      CPUPack.CPU.V_Counter < PPU.ScreenHeight + FIRST_VISIBLE_LINE)
    {
      RenderLine (CPUPack.CPU.V_Counter - FIRST_VISIBLE_LINE);
      S9xReschedule ();                  
  		//FINISH_PROFILE_FUNC (S9xDoHBlankProcessing); 
  		return;
    }

  if (CPUPack.CPU.V_Counter == PPU.ScreenHeight + FIRST_VISIBLE_LINE)
    {
      // Start of V-blank
      S9xEndScreenRefresh ();
      //PPU.FirstSprite = 0;
      IPPU.HDMA = 0;
      // Bits 7 and 6 of $4212 are computed when read in S9xGetPPU.
#ifdef DEBUGGER
	  missing.dma_this_frame = 0;
#endif
	  IPPU.MaxBrightness = PPU.Brightness;
      PPU.ForcedBlanking = (ROM_GLOBAL[0x2100] >> 7) & 1;
      
      if(!PPU.ForcedBlanking){
				PPU.OAMAddr = PPU.SavedOAMAddr;			
				uint8 tmp = 0;
				if(PPU.OAMPriorityRotation)
					tmp = (PPU.OAMAddr&0xFE)>>1;
				if((PPU.OAMFlip&1) || PPU.FirstSprite!=tmp){
					PPU.FirstSprite=tmp;
					IPPU.OBJChanged=TRUE;
				}			
				PPU.OAMFlip = 0;
			}
示例#5
0
void S9xDoHEventProcessing (void)
{
#ifdef DEBUGGER
	static char	eventname[7][32] =
	{
		"",
		"HC_HBLANK_START_EVENT",
		"HC_HDMA_START_EVENT  ",
		"HC_HCOUNTER_MAX_EVENT",
		"HC_HDMA_INIT_EVENT   ",
		"HC_RENDER_EVENT      ",
		"HC_WRAM_REFRESH_EVENT"
	};
#endif

#ifdef DEBUGGER
	if (Settings.TraceHCEvent)
		S9xTraceFormattedMessage("--- HC event processing  (%s)  expected HC:%04d  executed HC:%04d",
			eventname[CPU.WhichEvent], CPU.NextEvent, CPU.Cycles);
#endif

	switch (CPU.WhichEvent)
	{
		case HC_HBLANK_START_EVENT:
			S9xReschedule();
			break;

		case HC_HDMA_START_EVENT:
			S9xReschedule();

			if (PPU.HDMA && CPU.V_Counter <= PPU.ScreenHeight)
			{
			#ifdef DEBUGGER
				S9xTraceFormattedMessage("*** HDMA Transfer HC:%04d, Channel:%02x", CPU.Cycles, PPU.HDMA);
			#endif
				PPU.HDMA = S9xDoHDMA(PPU.HDMA);
			}

			break;

		case HC_HCOUNTER_MAX_EVENT:
			if (Settings.SuperFX)
			{
				if (!SuperFX.oneLineDone)
					S9xSuperFXExec();
				SuperFX.oneLineDone = FALSE;
			}

			S9xAPUEndScanline();
			CPU.Cycles -= Timings.H_Max;
			CPU.PrevCycles -= Timings.H_Max;
			S9xAPUSetReferenceTime(CPU.Cycles);

			if ((Timings.NMITriggerPos != 0xffff) && (Timings.NMITriggerPos >= Timings.H_Max))
				Timings.NMITriggerPos -= Timings.H_Max;

			CPU.V_Counter++;
			if (CPU.V_Counter >= Timings.V_Max)	// V ranges from 0 to Timings.V_Max - 1
			{
				CPU.V_Counter = 0;
				Timings.InterlaceField ^= 1;

				// From byuu:
				// [NTSC]
				// interlace mode has 525 scanlines: 263 on the even frame, and 262 on the odd.
				// non-interlace mode has 524 scanlines: 262 scanlines on both even and odd frames.
				// [PAL] <PAL info is unverified on hardware>
				// interlace mode has 625 scanlines: 313 on the even frame, and 312 on the odd.
				// non-interlace mode has 624 scanlines: 312 scanlines on both even and odd frames.
				if (IPPU.Interlace && !Timings.InterlaceField)
					Timings.V_Max = Timings.V_Max_Master + 1;	// 263 (NTSC), 313?(PAL)
				else
					Timings.V_Max = Timings.V_Max_Master;		// 262 (NTSC), 312?(PAL)

				Memory.FillRAM[0x213F] ^= 0x80;
				PPU.RangeTimeOver = 0;

				// FIXME: reading $4210 will wait 2 cycles, then perform reading, then wait 4 more cycles.
				Memory.FillRAM[0x4210] = Model->_5A22;
				CPU.NMILine = FALSE;
				Timings.NMITriggerPos = 0xffff;

				ICPU.Frame++;
				PPU.HVBeamCounterLatched = 0;
				CPU.Flags |= SCAN_KEYS_FLAG;
			}

			// From byuu:
			// In non-interlace mode, there are 341 dots per scanline, and 262 scanlines per frame.
			// On odd frames, scanline 240 is one dot short.
			// In interlace mode, there are always 341 dots per scanline. Even frames have 263 scanlines,
			// and odd frames have 262 scanlines.
			// Interlace mode scanline 240 on odd frames is not missing a dot.
			if (CPU.V_Counter == 240 && !IPPU.Interlace && Timings.InterlaceField)	// V=240
				Timings.H_Max = Timings.H_Max_Master - ONE_DOT_CYCLE;	// HC=1360
			else
				Timings.H_Max = Timings.H_Max_Master;					// HC=1364

			if (Model->_5A22 == 2)
			{
				if (CPU.V_Counter != 240 || IPPU.Interlace || !Timings.InterlaceField)	// V=240
				{
					if (Timings.WRAMRefreshPos == SNES_WRAM_REFRESH_HC_v2 - ONE_DOT_CYCLE)	// HC=534
						Timings.WRAMRefreshPos = SNES_WRAM_REFRESH_HC_v2;					// HC=538
					else
						Timings.WRAMRefreshPos = SNES_WRAM_REFRESH_HC_v2 - ONE_DOT_CYCLE;	// HC=534
				}
			}
			else
				Timings.WRAMRefreshPos = SNES_WRAM_REFRESH_HC_v1;

			if (CPU.V_Counter == PPU.ScreenHeight + FIRST_VISIBLE_LINE)	// VBlank starts from V=225(240).
			{
				S9xEndScreenRefresh();
				PPU.HDMA = 0;
				// Bits 7 and 6 of $4212 are computed when read in S9xGetPPU.
			#ifdef DEBUGGER
				missing.dma_this_frame = 0;
			#endif
				IPPU.MaxBrightness = PPU.Brightness;
				PPU.ForcedBlanking = (Memory.FillRAM[0x2100] >> 7) & 1;

				if (!PPU.ForcedBlanking)
				{
					PPU.OAMAddr = PPU.SavedOAMAddr;

					uint8	tmp = 0;

					if (PPU.OAMPriorityRotation)
						tmp = (PPU.OAMAddr & 0xFE) >> 1;
					if ((PPU.OAMFlip & 1) || PPU.FirstSprite != tmp)
					{
						PPU.FirstSprite = tmp;
						IPPU.OBJChanged = TRUE;
					}

					PPU.OAMFlip = 0;
				}

				// FIXME: writing to $4210 will wait 6 cycles.
				Memory.FillRAM[0x4210] = 0x80 | Model->_5A22;
				if (Memory.FillRAM[0x4200] & 0x80)
				{
					// FIXME: triggered at HC=6, checked just before the final CPU cycle,
					// then, when to call S9xOpcode_NMI()?
					CPU.NMILine = TRUE;
					Timings.NMITriggerPos = 6 + 6;
				}

			}
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);
}
示例#7
0
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);
}
示例#8
0
void S9xDoHEventProcessing (void)
{
	uint8 tmp;

	switch (CPU.WhichEvent)
	{
		case HC_HBLANK_START_EVENT:
			if (PPU.HTimerPosition == Timings.HBlankStart)
				S9xCheckMissingHTimerPosition();
			S9xReschedule();
			break;

		case HC_HDMA_START_EVENT:
			if (PPU.HTimerPosition == Timings.HDMAStart)
				S9xCheckMissingHTimerPosition();
			S9xReschedule();

			if (PPU.HDMA && CPU.V_Counter <= PPU.ScreenHeight)
				PPU.HDMA = S9xDoHDMA(PPU.HDMA);

			break;

		case HC_HCOUNTER_MAX_EVENT:
			if (Settings.SuperFX && !SuperFX.oneLineDone && CHECK_EXEC_SUPERFX())
				S9xSuperFXExec();
			SuperFX.oneLineDone = FALSE; // do this even without SFX

			S9xAPUExecute();
			CPU.Cycles -= Timings.H_Max;
			S9xAPUSetReferenceTime(CPU.Cycles);

			if ((Timings.NMITriggerPos != 0xffff) && (Timings.NMITriggerPos >= Timings.H_Max))
				Timings.NMITriggerPos -= Timings.H_Max;

			CPU.V_Counter++;
			if (CPU.V_Counter >= Timings.V_Max)	/* V ranges from 0 to Timings.V_Max - 1 */
			{
				CPU.V_Counter = 0;
				Timings.InterlaceField ^= 1;

				/* From byuu:
				   [NTSC]
				   interlace mode has 525 scanlines: 263 on 
				   the even frame, and 262 on the odd.

				   non-interlace mode has 524 scanlines: 
				   262 scanlines on both even and odd frames.
				   
				   [PAL] <PAL info is unverified on hardware>
				   interlace mode has 625 scanlines: 313 on 
				   the even frame, and 312 on the odd.
				   
				   non-interlace mode has 624 scanlines: 
				   312 scanlines on both even and odd frames. */

				Timings.V_Max = Timings.V_Max_Master;	/* 262 (NTSC), 312?(PAL) */

				if (IPPU.Interlace && !Timings.InterlaceField)
					Timings.V_Max += 1;	/* 263 (NTSC), 313?(PAL) */

				Memory.FillRAM[0x213F] ^= 0x80;
				PPU.RangeTimeOver = 0;

				/* FIXME: reading $4210 will wait 2 cycles, 
				then perform reading, then wait 4 more cycles. */

				Memory.FillRAM[0x4210] = MAX_5A22_VERSION;
				CPU.Flags &= ~NMI_FLAG;
				Timings.NMITriggerPos = 0xffff;

				ICPU.Frame++;
				PPU.HVBeamCounterLatched = 0;
				CPU.Flags |= SCAN_KEYS_FLAG;
			}

			/* From byuu:
			   In non-interlace mode, there are 341 dots 
			   per scanline, and 262 scanlines per frame.
			   
			   On odd frames, scanline 240 is one dot short.
			   In interlace mode, there are always 341 dots 
			   per scanline. Even frames have 263 scanlines,
			   and odd frames have 262 scanlines.
			   
			   Interlace mode scanline 240 on odd frames is 
			   not missing a dot. */

			Timings.H_Max = Timings.H_Max_Master;					/* HC=1364 */

			if (CPU.V_Counter == 240 && !IPPU.Interlace && Timings.InterlaceField)	/* V=240 */
				Timings.H_Max -= ONE_DOT_CYCLE;					/* HC=1360 */

			if (CPU.V_Counter != 240 || IPPU.Interlace || !Timings.InterlaceField)	/* V=240 */
			{
				if (Timings.WRAMRefreshPos == SNES_WRAM_REFRESH_HC_v2_MIN_ONE_DOT_CYCLE) /* HC=534 */
					Timings.WRAMRefreshPos = SNES_WRAM_REFRESH_HC_v2; /* HC=538 */
				else
					Timings.WRAMRefreshPos = SNES_WRAM_REFRESH_HC_v2_MIN_ONE_DOT_CYCLE; /* HC=534 */
			}

			if (PPU.HTimerPosition == 0)
				S9xCheckMissingHTimerPosition();

			if (CPU.V_Counter == PPU.ScreenHeight + FIRST_VISIBLE_LINE) /* VBlank starts from V=225(240). */
			{
				S9xEndScreenRefresh();
				PPU.HDMA = 0;
				/* Bits 7 and 6 of $4212 are computed when read in S9xGetPPU. */
				PPU.ForcedBlanking = (Memory.FillRAM[0x2100] >> 7) & 1;

				if (!PPU.ForcedBlanking)
				{
					PPU.OAMAddr = PPU.SavedOAMAddr;

					tmp = 0;

					if (PPU.OAMPriorityRotation)
						tmp = (PPU.OAMAddr & 0xFE) >> 1;
					if ((PPU.OAMFlip & 1) || PPU.FirstSprite != tmp)
					{
						PPU.FirstSprite = tmp;
						IPPU.OBJChanged = TRUE;
					}

					PPU.OAMFlip = 0;
				}

				/* FIXME: writing to $4210 will wait 6 cycles. */
				Memory.FillRAM[0x4210] = 0x80 | MAX_5A22_VERSION;
				if (Memory.FillRAM[0x4200] & 0x80)
				{
					/* FIXME: triggered at HC=6, checked just 
					before the final CPU cycle, then, when to 
					call S9xOpcode_NMI()? */
					CPU.Flags |= NMI_FLAG;
					Timings.NMITriggerPos = 6 + 6;
				}

			}