⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ppu.h

📁 著名SFC模拟器Snes9x的源代码。
💻 H
字号:
/* * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. * * (c) Copyright 1996 - 2001 Gary Henderson (gary@daniver.demon.co.uk) and *                           Jerremy Koot (jkoot@snes9x.com) * * Super FX C emulator code  * (c) Copyright 1997 - 1999 Ivar (Ivar@snes9x.com) and *                           Gary Henderson. * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. * * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. * C4 C code (c) Copyright 2001 Gary Henderson (gary@daniver.demon.co.uk). * * DOS port code contains the works of other authors. See headers in * individual files. * * Snes9x homepage: www.snes9x.com * * Permission to use, copy, modify and distribute Snes9x in both binary and * source form, for non-commercial purposes, is hereby granted without fee, * providing that this license information and copyright notice appear with * all copies and any derived work. * * This software is provided 'as-is', without any express or implied * warranty. In no event shall the authors be held liable for any damages * arising from the use of this software. * * Snes9x is freeware for PERSONAL USE only. Commercial users should * seek permission of the copyright holders first. Commercial use includes * charging money for Snes9x or software derived from Snes9x. * * The copyright holders request that bug fixes and improvements to the code * should be forwarded to them so everyone can benefit from the modifications * in future versions. * * Super NES and Super Nintendo Entertainment System are trademarks of * Nintendo Co., Limited and its subsidiary companies. */#ifndef _PPU_H_#define _PPU_H_#define FIRST_VISIBLE_LINE 1extern uint8 GetBank;extern uint16 SignExtend [2];#define TILE_2BIT 0#define TILE_4BIT 1#define TILE_8BIT 2#define MAX_2BIT_TILES 4096#define MAX_4BIT_TILES 2048#define MAX_8BIT_TILES 1024#define PPU_H_BEAM_IRQ_SOURCE	(1 << 0)#define PPU_V_BEAM_IRQ_SOURCE	(1 << 1)#define GSU_IRQ_SOURCE		(1 << 2)#define SA1_IRQ_SOURCE		(1 << 7)#define SA1_DMA_IRQ_SOURCE	(1 << 5)struct ClipData {    uint32  Count [6];    uint32  Left [6][6];    uint32  Right [6][6];};struct InternalPPU {    bool8  ColorsChanged;    uint8  HDMA;    bool8  HDMAStarted;    uint8  MaxBrightness;    bool8  LatchedBlanking;    bool8  OBJChanged;    bool8  RenderThisFrame;    bool8  DirectColourMapsNeedRebuild;    uint32 FrameCount;    uint32 RenderedFramesCount;    uint32 DisplayedRenderedFrameCount;    uint32 SkippedFrames;    uint32 FrameSkip;    uint8  *TileCache [3];    uint8  *TileCached [3];    bool8  FirstVRAMRead;    bool8  LatchedInterlace;    bool8  DoubleWidthPixels;    int    RenderedScreenHeight;    int    RenderedScreenWidth;    uint32 Red [256];    uint32 Green [256];    uint32 Blue [256];    uint8  *XB;    uint16 ScreenColors [256];    int	   PreviousLine;    int	   CurrentLine;    int	   Controller;    uint32 Joypads[5];    uint32 SuperScope;    uint32 Mouse[2];    int    PrevMouseX[2];    int    PrevMouseY[2];    struct ClipData Clip [2];};struct SOBJ{    short  HPos;    uint16 VPos;    uint16 Name;    uint8  VFlip;    uint8  HFlip;    uint8  Priority;    uint8  Palette;    uint8  Size;};struct SPPU {    uint8  BGMode;    uint8  BG3Priority;    uint8  Brightness;    struct {	bool8 High;	uint8 Increment;	uint16 Address;	uint16 Mask1;	uint16 FullGraphicCount;	uint16 Shift;    } VMA;    struct {	uint16 SCBase;	uint16 VOffset;	uint16 HOffset;	uint8 BGSize;	uint16 NameBase;	uint16 SCSize;    } BG [4];    bool8  CGFLIP;    uint16 CGDATA [256];     uint8  FirstSprite;    uint8  LastSprite;    struct SOBJ OBJ [128];    uint8  OAMPriorityRotation;    uint16 OAMAddr;    uint8  OAMFlip;    uint16 OAMTileAddress;    uint16 IRQVBeamPos;    uint16 IRQHBeamPos;    uint16 VBeamPosLatched;    uint16 HBeamPosLatched;    uint8  HBeamFlip;    uint8  VBeamFlip;    uint8  HVBeamCounterLatched;    short  MatrixA;    short  MatrixB;    short  MatrixC;    short  MatrixD;    short  CentreX;    short  CentreY;    uint8  Joypad1ButtonReadPos;    uint8  Joypad2ButtonReadPos;    uint8  CGADD;    uint8  FixedColourRed;    uint8  FixedColourGreen;    uint8  FixedColourBlue;    uint16 SavedOAMAddr;    uint16 ScreenHeight;    uint32 WRAM;    uint8  BG_Forced;    bool8  ForcedBlanking;    bool8  OBJThroughMain;    bool8  OBJThroughSub;    uint8  OBJSizeSelect;    uint16 OBJNameBase;    bool8  OBJAddition;    uint8  OAMReadFlip;    uint8  OAMData [512 + 32];    bool8  VTimerEnabled;    bool8  HTimerEnabled;    short  HTimerPosition;    uint8  Mosaic;    bool8  BGMosaic [4];    bool8  Mode7HFlip;    bool8  Mode7VFlip;    uint8  Mode7Repeat;    uint8  Window1Left;    uint8  Window1Right;    uint8  Window2Left;    uint8  Window2Right;    uint8  ClipCounts [6];    uint8  ClipWindowOverlapLogic [6];    uint8  ClipWindow1Enable [6];    uint8  ClipWindow2Enable [6];    bool8  ClipWindow1Inside [6];    bool8  ClipWindow2Inside [6];    bool8  RecomputeClipWindows;    uint8  CGFLIPRead;    uint16 OBJNameSelect;    bool8  Need16x8Mulitply;    uint8  Joypad3ButtonReadPos;    uint8  MouseSpeed[2];};#define CLIP_OR 0#define CLIP_AND 1#define CLIP_XOR 2#define CLIP_XNOR 3struct SDMA {    bool8  TransferDirection;    bool8  AAddressFixed;    bool8  AAddressDecrement;    uint8  TransferMode;    uint8  ABank;    uint16 AAddress;    uint16 Address;    uint8  BAddress;    // General DMA only:    uint16 TransferBytes;    // H-DMA only:    bool8  HDMAIndirectAddressing;    uint16 IndirectAddress;    uint8  IndirectBank;    uint8  Repeat;    uint8  LineCount;    uint8  FirstLine;};START_EXTERN_Cvoid S9xUpdateScreen ();void S9xResetPPU ();void S9xFixColourBrightness ();void S9xUpdateJoypads ();void S9xProcessMouse(int which1);void S9xSuperFXExec ();void S9xSetPPU (uint8 Byte, uint16 Address);uint8 S9xGetPPU (uint16 Address);void S9xSetCPU (uint8 Byte, uint16 Address);uint8 S9xGetCPU (uint16 Address);void S9xInitC4 ();void S9xSetC4 (uint8 Byte, uint16 Address);uint8 S9xGetC4 (uint16 Address);void S9xSetC4RAM (uint8 Byte, uint16 Address);uint8 S9xGetC4RAM (uint16 Address);extern struct SPPU PPU;extern struct SDMA DMA [8];extern struct InternalPPU IPPU;END_EXTERN_C#include "gfx.h"#include "memmap.h"STATIC inline uint8 REGISTER_4212(){    GetBank = 0;    if (CPU.V_Counter >= PPU.ScreenHeight + FIRST_VISIBLE_LINE &&	CPU.V_Counter < PPU.ScreenHeight + FIRST_VISIBLE_LINE + 3)	GetBank = 1;    GetBank |= CPU.Cycles >= Settings.HBlankStart ? 0x40 : 0;    if (CPU.V_Counter >= PPU.ScreenHeight + FIRST_VISIBLE_LINE)	GetBank |= 0x80; /* XXX: 0x80 or 0xc0 ? */    return (GetBank);}STATIC inline void FLUSH_REDRAW (){    if (IPPU.PreviousLine != IPPU.CurrentLine)	S9xUpdateScreen ();}STATIC inline void REGISTER_2104 (uint8 byte){    if (PPU.OAMAddr >= 0x110)	return;	    int addr = (PPU.OAMAddr << 1) + (PPU.OAMFlip & 1);        if (byte != PPU.OAMData [addr])    {	FLUSH_REDRAW ();	PPU.OAMData [addr] = byte;	IPPU.OBJChanged = TRUE;	if (addr & 0x200)	{	    // X position high bit, and sprite size (x4)	    struct SOBJ *pObj = &PPU.OBJ [(addr & 0x1f) * 4];	    pObj->HPos = (pObj->HPos & 0xFF) | SignExtend[(byte >> 0) & 1];	    pObj++->Size = byte & 2;	    pObj->HPos = (pObj->HPos & 0xFF) | SignExtend[(byte >> 2) & 1];	    pObj++->Size = byte & 8;	    pObj->HPos = (pObj->HPos & 0xFF) | SignExtend[(byte >> 4) & 1];	    pObj++->Size = byte & 32;	    pObj->HPos = (pObj->HPos & 0xFF) | SignExtend[(byte >> 6) & 1];	    pObj->Size = byte & 128;	}	else	{	    if (addr & 1)	    {		if (addr & 2)		{		    addr = PPU.OAMAddr >> 1;		    // Tile within group, priority, h and v flip.		    PPU.OBJ[addr].Name &= 0xFF;		    PPU.OBJ[addr].Name |= ((uint16) (byte & 1)) << 8;		    PPU.OBJ[addr].Palette = (byte >> 1) & 7;		    PPU.OBJ[addr].Priority = (byte >> 4) & 3;		    PPU.OBJ[addr].HFlip = (byte >> 6) & 1;		    PPU.OBJ[addr].VFlip = (byte >> 7) & 1;		}		else		{		    // Sprite Y position		    PPU.OBJ[PPU.OAMAddr >> 1].VPos = byte;		}	    }	    else	    {		if (addr & 2)		{		    // Tile group		    		    PPU.OBJ[addr = PPU.OAMAddr >> 1].Name &= 0x100;		    PPU.OBJ[addr].Name |= byte;		}		else		{		    // X position (low)		    PPU.OBJ[addr = PPU.OAMAddr >> 1].HPos &= 0xFF00;		    PPU.OBJ[addr].HPos |= byte;		}	    }	}    }    PPU.OAMFlip ^= 1;    if (!(PPU.OAMFlip & 1))	PPU.OAMAddr++;    Memory.FillRAM [0x2104] = byte;}STATIC inline void REGISTER_2118 (uint8 Byte){    uint32 address;    if (PPU.VMA.FullGraphicCount)    {	uint32 rem = PPU.VMA.Address & PPU.VMA.Mask1;	address = (((PPU.VMA.Address & ~PPU.VMA.Mask1) +			 (rem >> PPU.VMA.Shift) +			 ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3)) << 1) & 0xffff;	Memory.VRAM [address] = Byte;    }    else    {	Memory.VRAM[address = (PPU.VMA.Address << 1) & 0xFFFF] = Byte;    }    IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE;    IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE;    IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE;    if (!PPU.VMA.High)    {#ifdef DEBUGGER	if (Settings.TraceVRAM && !CPU.InDMA)	{	    printf ("VRAM write byte: $%04X (%d,%d)\n", PPU.VMA.Address,		    Memory.FillRAM[0x2115] & 3,		    (Memory.FillRAM [0x2115] & 0x0c) >> 2);	}#endif		PPU.VMA.Address += PPU.VMA.Increment;    }//    Memory.FillRAM [0x2118] = Byte;}STATIC inline void REGISTER_2118_tile (uint8 Byte){    uint32 address;    uint32 rem = PPU.VMA.Address & PPU.VMA.Mask1;    address = (((PPU.VMA.Address & ~PPU.VMA.Mask1) +		 (rem >> PPU.VMA.Shift) +		 ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3)) << 1) & 0xffff;    Memory.VRAM [address] = Byte;    IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE;    IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE;    IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE;    if (!PPU.VMA.High)	PPU.VMA.Address += PPU.VMA.Increment;//    Memory.FillRAM [0x2118] = Byte;}STATIC inline void REGISTER_2118_linear (uint8 Byte){    uint32 address;    Memory.VRAM[address = (PPU.VMA.Address << 1) & 0xFFFF] = Byte;    IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE;    IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE;    IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE;    if (!PPU.VMA.High)	PPU.VMA.Address += PPU.VMA.Increment;//    Memory.FillRAM [0x2118] = Byte;}STATIC inline void REGISTER_2119 (uint8 Byte){    uint32 address;    if (PPU.VMA.FullGraphicCount)    {	uint32 rem = PPU.VMA.Address & PPU.VMA.Mask1;	address = ((((PPU.VMA.Address & ~PPU.VMA.Mask1) +		    (rem >> PPU.VMA.Shift) +		    ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3)) << 1) + 1) & 0xFFFF;	Memory.VRAM [address] = Byte;    }    else    {	Memory.VRAM[address = ((PPU.VMA.Address << 1) + 1) & 0xFFFF] = Byte;    }    IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE;    IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE;    IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE;    if (PPU.VMA.High)    {#ifdef DEBUGGER	if (Settings.TraceVRAM && !CPU.InDMA)	{	    printf ("VRAM write word: $%04X (%d,%d)\n", PPU.VMA.Address,		    Memory.FillRAM[0x2115] & 3,		    (Memory.FillRAM [0x2115] & 0x0c) >> 2);	}#endif		PPU.VMA.Address += PPU.VMA.Increment;    }//    Memory.FillRAM [0x2119] = Byte;}STATIC inline void REGISTER_2119_tile (uint8 Byte){    uint32 rem = PPU.VMA.Address & PPU.VMA.Mask1;    uint32 address = ((((PPU.VMA.Address & ~PPU.VMA.Mask1) +		    (rem >> PPU.VMA.Shift) +		    ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3)) << 1) + 1) & 0xFFFF;    Memory.VRAM [address] = Byte;    IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE;    IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE;    IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE;    if (PPU.VMA.High)	PPU.VMA.Address += PPU.VMA.Increment;//    Memory.FillRAM [0x2119] = Byte;}STATIC inline void REGISTER_2119_linear (uint8 Byte){    uint32 address;    Memory.VRAM[address = ((PPU.VMA.Address << 1) + 1) & 0xFFFF] = Byte;    IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE;    IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE;    IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE;    if (PPU.VMA.High)	PPU.VMA.Address += PPU.VMA.Increment;//    Memory.FillRAM [0x2119] = Byte;}STATIC inline void REGISTER_2122(uint8 Byte){    // CG-RAM (palette) write    if (PPU.CGFLIP)    {	if ((Byte & 0x7f) != (PPU.CGDATA[PPU.CGADD] >> 8))	{	    if (Settings.SixteenBit)		FLUSH_REDRAW ();	    PPU.CGDATA[PPU.CGADD] &= 0x00FF;	    PPU.CGDATA[PPU.CGADD] |= (Byte & 0x7f) << 8;	    IPPU.ColorsChanged = TRUE;	    if (Settings.SixteenBit)	    {		IPPU.Blue [PPU.CGADD] = IPPU.XB [(Byte >> 2) & 0x1f];		IPPU.Green [PPU.CGADD] = IPPU.XB [(PPU.CGDATA[PPU.CGADD] >> 5) & 0x1f];		IPPU.ScreenColors [PPU.CGADD] = (uint16) BUILD_PIXEL (IPPU.Red [PPU.CGADD],							     IPPU.Green [PPU.CGADD],							     IPPU.Blue [PPU.CGADD]);	    }	}	PPU.CGADD++;    }    else    {	if (Byte != (uint8) (PPU.CGDATA[PPU.CGADD] & 0xff))	{	    if (Settings.SixteenBit)		FLUSH_REDRAW ();	    PPU.CGDATA[PPU.CGADD] &= 0x7F00;	    PPU.CGDATA[PPU.CGADD] |= Byte;	    IPPU.ColorsChanged = TRUE;	    if (Settings.SixteenBit)	    {		IPPU.Red [PPU.CGADD] = IPPU.XB [Byte & 0x1f];		IPPU.Green [PPU.CGADD] = IPPU.XB [(PPU.CGDATA[PPU.CGADD] >> 5) & 0x1f];		IPPU.ScreenColors [PPU.CGADD] = (uint16) BUILD_PIXEL (IPPU.Red [PPU.CGADD],							     IPPU.Green [PPU.CGADD],							     IPPU.Blue [PPU.CGADD]);	    }	}    }    PPU.CGFLIP ^= 1;//    Memory.FillRAM [0x2122] = Byte;}STATIC inline void REGISTER_2180(uint8 Byte){    Memory.RAM[PPU.WRAM++] = Byte;    PPU.WRAM &= 0x1FFFF;    Memory.FillRAM [0x2180] = Byte;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -