コード例 #1
0
ファイル: cpuexec.cpp プロジェクト: BASLQC/snes9xTYL
void
S9xDoHBlankProcessing ()
{
	START_PROFILE_FUNC (S9xDoHBlankProcessing);
	
#ifdef CPU_SHUTDOWN
  CPU.WaitCounter++;
#endif
  switch (CPU.WhichEvent)
    {
    case HBLANK_START_EVENT:
      if (IPPU.HDMA && CPU.V_Counter <= PPU.ScreenHeight)
	IPPU.HDMA = S9xDoHDMA (IPPU.HDMA);

      break;

    case HBLANK_END_EVENT:
      S9xSuperFXExec ();


      CPU.Cycles -= Settings.H_Max;
      (IAPUuncached->NextAPUTimerPos) -= (Settings.H_Max * 10000L);
      if ( (IAPUuncached->APUExecuting))
	(APUuncached->Cycles) -= Settings.H_Max;
      else
	(APUuncached->Cycles) = 0;

      CPU.NextEvent = -1;
      ICPU.Scanline++;

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

      if (PPU.VTimerEnabled && !PPU.HTimerEnabled &&
	  CPU.V_Counter == PPU.IRQVBeamPos)
	{
	  S9xSetIRQ (PPU_V_BEAM_IRQ_SOURCE);
	}

      if (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.
	  missing.dma_this_frame = 0;
	  IPPU.MaxBrightness = PPU.Brightness;
	  PPU.ForcedBlanking = (FillRAM[0x2100] >> 7) & 1;

	  FillRAM[0x4210] = 0x80;
	  if (FillRAM[0x4200] & 0x80)
	    {
	      CPU.NMIActive = TRUE;
	      CPU.Flags |= NMI_FLAG;
	      CPU.NMICycleCount = CPU.NMITriggerPoint;
	    }


	}

      if (CPU.V_Counter == PPU.ScreenHeight + 3)
	S9xUpdateJoypads ();

      if (CPU.V_Counter == FIRST_VISIBLE_LINE)
	{
	  FillRAM[0x4210] = 0;
	  CPU.Flags &= ~NMI_FLAG;
	  S9xStartScreenRefresh ();
	}
      if (CPU.V_Counter >= FIRST_VISIBLE_LINE &&
	  CPU.V_Counter < PPU.ScreenHeight + FIRST_VISIBLE_LINE)
	{
	  RenderLine (CPU.V_Counter - FIRST_VISIBLE_LINE);
	}

      break;
    case HTIMER_BEFORE_EVENT:
    case HTIMER_AFTER_EVENT:
      if (PPU.HTimerEnabled &&
	  (!PPU.VTimerEnabled || CPU.V_Counter == PPU.IRQVBeamPos))
	{
	  S9xSetIRQ (PPU_H_BEAM_IRQ_SOURCE);
	}
      break;
    }
コード例 #2
0
ファイル: cpuexec.cpp プロジェクト: Tchaly/snes9x-rpi
void S9xDoHBlankProcessing (struct SCPUState *cpu, struct SAPU *apu, struct SIAPU *iapu)
{
	struct SPPU *ppu = &PPU;
	struct InternalPPU *ippu = &IPPU;

#ifdef CPU_SHUTDOWN
    cpu->WaitCounter++;
#endif
    switch (cpu->WhichEvent)
    {
    case HBLANK_START_EVENT:
		if (ippu->HDMA && cpu->V_Counter <= ppu->ScreenHeight)
			ippu->HDMA = S9xDoHDMA (ippu, ppu, cpu);
	break;

    case HBLANK_END_EVENT:
#ifndef _ZAURUS
	S9xSuperFXExec ();
#endif
#ifndef STORM
#endif

	cpu->Cycles -= Settings.H_Max;
	if (iapu->APUExecuting)
	    apu->Cycles -= Settings.H_Max;
	else
	    apu->Cycles = 0;

	cpu->NextEvent = -1;
	ICPU.Scanline++;

	if (++cpu->V_Counter > (Settings.PAL ? SNES_MAX_PAL_VCOUNTER : SNES_MAX_NTSC_VCOUNTER))
	{
	    ppu->OAMAddr = ppu->SavedOAMAddr;
	    ppu->OAMFlip = 0;
	    cpu->V_Counter = 0;
	    cpu->NMIActive = FALSE;
	    ICPU.Frame++;
	    ppu->HVBeamCounterLatched = 0;
	    cpu->Flags |= SCAN_KEYS_FLAG;
	    S9xStartHDMA ();
	}

	if (ppu->VTimerEnabled && !ppu->HTimerEnabled &&
	    cpu->V_Counter == ppu->IRQVBeamPos)
	{
	    S9xSetIRQ (PPU_V_BEAM_IRQ_SOURCE, cpu);
	}

	if (cpu->V_Counter == ppu->ScreenHeight + FIRST_VISIBLE_LINE)
	{
	    // Start of V-blank
	    S9xEndScreenRefresh (ppu);
	    ppu->FirstSprite = 0;
	    ippu->HDMA = 0;
	    // Bits 7 and 6 of $4212 are computed when read in S9xGetPPU.
	    missing.dma_this_frame = 0;
	    ippu->MaxBrightness = ppu->Brightness;
	    ppu->ForcedBlanking = (Memory.FillRAM [0x2100] >> 7) & 1;

	    Memory.FillRAM[0x4210] = 0x80;
	    if (Memory.FillRAM[0x4200] & 0x80)
	    {
			cpu->NMIActive = TRUE;
			cpu->Flags |= NMI_FLAG;
			cpu->NMICycleCount = cpu->NMITriggerPoint;
	    }

#ifdef OLD_SNAPSHOT_CODE
	    if (cpu->Flags & SAVE_SNAPSHOT_FLAG)
	    {
			cpu->Flags &= ~SAVE_SNAPSHOT_FLAG;
			Registers.PC = cpu->PC - cpu->PCBase;
			S9xPackStatus ();
			S9xAPUPackStatus ();
			Snapshot (NULL);
	    }
#endif
        }

	if (cpu->V_Counter == ppu->ScreenHeight + 3)
	    S9xUpdateJoypads (&IPPU);

	if (cpu->V_Counter == FIRST_VISIBLE_LINE)
	{
	    Memory.FillRAM[0x4210] = 0;
	    cpu->Flags &= ~NMI_FLAG;
	    S9xStartScreenRefresh ();
	}
	if (cpu->V_Counter >= FIRST_VISIBLE_LINE &&
	    cpu->V_Counter < ppu->ScreenHeight + FIRST_VISIBLE_LINE)
	{
	    RenderLine (cpu->V_Counter - FIRST_VISIBLE_LINE, ppu);
	}
	// Use TimerErrorCounter to skip update of SPC700 timers once
	// every 128 updates. Needed because this section of code is called
	// once every emulated 63.5 microseconds, which coresponds to
	// 15.750KHz, but the SPC700 timers need to be updated at multiples
	// of 8KHz, hence the error correction.
//	IAPU.TimerErrorCounter++;
//	if (IAPU.TimerErrorCounter >= )
//	    IAPU.TimerErrorCounter = 0;
//	else
	{
	    if (apu->TimerEnabled [2])
	    {
			apu->Timer [2] += 4;
			while (apu->Timer [2] >= apu->TimerTarget [2])
			{
				iapu->RAM [0xff] = (iapu->RAM [0xff] + 1) & 0xf;
				apu->Timer [2] -= apu->TimerTarget [2];
#ifdef SPC700_SHUTDOWN		
				iapu->WaitCounter++;
				iapu->APUExecuting = TRUE;
#endif		
			}
	    }
	    if (cpu->V_Counter & 1)
	    {
			if (apu->TimerEnabled [0])
			{
				apu->Timer [0]++;
				if (apu->Timer [0] >= apu->TimerTarget [0])
				{
					iapu->RAM [0xfd] = (iapu->RAM [0xfd] + 1) & 0xf;
					apu->Timer [0] = 0;
#ifdef SPC700_SHUTDOWN		
					iapu->WaitCounter++;
					iapu->APUExecuting = TRUE;
#endif		    
			    }
			}
			if (apu->TimerEnabled [1])
			{
				apu->Timer [1]++;
				if (apu->Timer [1] >= apu->TimerTarget [1])
				{
					iapu->RAM [0xfe] = (iapu->RAM [0xfe] + 1) & 0xf;
					apu->Timer [1] = 0;
#ifdef SPC700_SHUTDOWN		
					iapu->WaitCounter++;
					iapu->APUExecuting = TRUE;
#endif		    
			    }
			}
	    }
	}
	break; //HBLANK_END_EVENT

    case HTIMER_BEFORE_EVENT:
    case HTIMER_AFTER_EVENT:
	if (ppu->HTimerEnabled &&
	    (!ppu->VTimerEnabled || cpu->V_Counter == ppu->IRQVBeamPos))
	{
	    S9xSetIRQ (PPU_H_BEAM_IRQ_SOURCE, cpu);
	}
	break;
    }
コード例 #3
0
void S9xDoHBlankProcessing ()
{
#ifdef CPU_SHUTDOWN
    CPU.WaitCounter++;
#endif
    switch (CPU.WhichEvent)
    {
    case HBLANK_START_EVENT:
		if (IPPU.HDMA && CPU.V_Counter <= PPU.ScreenHeight)
			IPPU.HDMA = S9xDoHDMA (IPPU.HDMA);
	break;

    case HBLANK_END_EVENT:
	S9xSuperFXExec ();

#ifndef STORM
	if (Settings.SoundSync)
	    S9xGenerateSound ();
#endif

	CPU.Cycles -= Settings.H_Max;
	if (IAPU.APUExecuting)
	    APU.Cycles -= Settings.H_Max;
	else
	    APU.Cycles = 0;

	CPU.NextEvent = -1;
	ICPU.Scanline++;

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

	if (PPU.VTimerEnabled && !PPU.HTimerEnabled &&
	    CPU.V_Counter == PPU.IRQVBeamPos)
	{
	    S9xSetIRQ (PPU_V_BEAM_IRQ_SOURCE);
	}

	if (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.
	    missing.dma_this_frame = 0;
	    IPPU.MaxBrightness = PPU.Brightness;
	    PPU.ForcedBlanking = (Memory.FillRAM [0x2100] >> 7) & 1;

	    Memory.FillRAM[0x4210] = 0x80;
	    if (Memory.FillRAM[0x4200] & 0x80)
	    {
			CPU.NMIActive = TRUE;
			CPU.Flags |= NMI_FLAG;
			CPU.NMICycleCount = CPU.NMITriggerPoint;
	    }

#ifdef OLD_SNAPSHOT_CODE
	    if (CPU.Flags & SAVE_SNAPSHOT_FLAG)
	    {
			CPU.Flags &= ~SAVE_SNAPSHOT_FLAG;
			Registers.PC = CPU.PC - CPU.PCBase;
			S9xPackStatus ();
			S9xAPUPackStatus ();
			Snapshot (NULL);
	    }
#endif
        }

	if (CPU.V_Counter == PPU.ScreenHeight + 3)
	    S9xUpdateJoypads ();

	if (CPU.V_Counter == FIRST_VISIBLE_LINE)
	{
	    Memory.FillRAM[0x4210] = 0;
	    CPU.Flags &= ~NMI_FLAG;
	    S9xStartScreenRefresh ();
	}
	if (CPU.V_Counter >= FIRST_VISIBLE_LINE &&
	    CPU.V_Counter < PPU.ScreenHeight + FIRST_VISIBLE_LINE)
	{
	    RenderLine (CPU.V_Counter - FIRST_VISIBLE_LINE);
	}
	// Use TimerErrorCounter to skip update of SPC700 timers once
	// every 128 updates. Needed because this section of code is called
	// once every emulated 63.5 microseconds, which coresponds to
	// 15.750KHz, but the SPC700 timers need to be updated at multiples
	// of 8KHz, hence the error correction.
//	IAPU.TimerErrorCounter++;
//	if (IAPU.TimerErrorCounter >= )
//	    IAPU.TimerErrorCounter = 0;
//	else
	{
	    if (APU.TimerEnabled [2])
	    {
			APU.Timer [2] += 4;
			while (APU.Timer [2] >= APU.TimerTarget [2])
			{
				IAPU.RAM [0xff] = (IAPU.RAM [0xff] + 1) & 0xf;
				APU.Timer [2] -= APU.TimerTarget [2];
#ifdef SPC700_SHUTDOWN		
				IAPU.WaitCounter++;
				IAPU.APUExecuting = TRUE;
#endif		
			}
	    }
	    if (CPU.V_Counter & 1)
	    {
			if (APU.TimerEnabled [0])
			{
				APU.Timer [0]++;
				if (APU.Timer [0] >= APU.TimerTarget [0])
				{
					IAPU.RAM [0xfd] = (IAPU.RAM [0xfd] + 1) & 0xf;
					APU.Timer [0] = 0;
#ifdef SPC700_SHUTDOWN		
					IAPU.WaitCounter++;
					IAPU.APUExecuting = TRUE;
#endif		    
			    }
			}
			if (APU.TimerEnabled [1])
			{
				APU.Timer [1]++;
				if (APU.Timer [1] >= APU.TimerTarget [1])
				{
					IAPU.RAM [0xfe] = (IAPU.RAM [0xfe] + 1) & 0xf;
					APU.Timer [1] = 0;
#ifdef SPC700_SHUTDOWN		
					IAPU.WaitCounter++;
					IAPU.APUExecuting = TRUE;
#endif		    
			    }
			}
	    }
	}
	break; //HBLANK_END_EVENT

    case HTIMER_BEFORE_EVENT:
    case HTIMER_AFTER_EVENT:
	if (PPU.HTimerEnabled &&
	    (!PPU.VTimerEnabled || CPU.V_Counter == PPU.IRQVBeamPos))
	{
	    S9xSetIRQ (PPU_H_BEAM_IRQ_SOURCE);
	}
	break;
    }