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

📄 ppu.cpp

📁 SFC游戏模拟器 snes9x 1.43 的原代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
					return;				}	}	Memory.FillRAM[Address] = Byte;}/******************************************************************************//* S9xGetPPU()                                                                *//* This function retrieves a PPU Register                                     *//******************************************************************************/uint8 S9xGetPPU (uint16 Address){ 	uint8 byte = OpenBus;	if(Address<0x2100)//not a real PPU reg		return OpenBus; //treat as unmapped memory returning last byte on the bus    if (Address <= 0x2190)    { 	switch (Address)  	{  	case 0x2100:  	case 0x2101:  	case 0x2102:    case 0x2103:  #ifdef DEBUGGER  	    missing.oam_address_read = 1;  #endif			return OpenBus;	case 0x2104:	case 0x2105:	case 0x2106:		return PPU.OpenBus1;	case 0x2107:		return OpenBus;	case 0x2108:	case 0x2109:	case 0x210a:		return PPU.OpenBus1;	case 0x210b:	case 0x210c:	case 0x210d:	case 0x210e:	case 0x210f:	case 0x2110:	case 0x2111:	case 0x2112:	case 0x2113:			missing.bg_offset_read = 1;			return OpenBus;	case 0x2114:#ifdef DEBUGGER	    missing.bg_offset_read = 1;#endif	case 0x2115:	case 0x2116:			return PPU.OpenBus1;	case 0x2117:			return OpenBus;	case 0x2118:	case 0x2119:	case 0x211a:			return PPU.OpenBus1;	case 0x211b:	case 0x211c:	case 0x211d:	case 0x211e:	case 0x211f:	case 0x2120:#ifdef DEBUGGER	    missing.matrix_read = 1;#endif			return OpenBus;	case 0x2121:	case 0x2122:	case 0x2123:			return OpenBus;	case 0x2124:	case 0x2125:	case 0x2126:			return PPU.OpenBus1;	case 0x2127:			return OpenBus;	case 0x2128:	case 0x2129:	case 0x212a:			return PPU.OpenBus1;	case 0x212b:	case 0x212c:	case 0x212d:	case 0x212e:	case 0x212f:	case 0x2130:	case 0x2131:	case 0x2132:	case 0x2133:			return OpenBus;	case 0x2134:	case 0x2135:	case 0x2136:	    // 16bit x 8bit multiply read result.	    if (PPU.Need16x8Mulitply)	    {		int32 r = (int32) PPU.MatrixA * (int32) (PPU.MatrixB >> 8);		Memory.FillRAM[0x2134] = (uint8) r;		Memory.FillRAM[0x2135] = (uint8)(r >> 8);		Memory.FillRAM[0x2136] = (uint8)(r >> 16);		PPU.Need16x8Mulitply = FALSE;	    }#ifdef DEBUGGER	    missing.matrix_multiply = 1;#endif		return (PPU.OpenBus1 = Memory.FillRAM[Address]);	case 0x2137:		S9xLatchCounters(0);		return OpenBus;	case 0x2138:		// Read OAM (sprite) control data		if(PPU.OAMAddr&0x100){			if (!(PPU.OAMFlip&1))			{				byte = PPU.OAMData [(PPU.OAMAddr&0x10f) << 1];			}			else			{				byte = PPU.OAMData [((PPU.OAMAddr&0x10f) << 1) + 1];				PPU.OAMAddr=(PPU.OAMAddr+1)&0x1ff;				if (PPU.OAMPriorityRotation && PPU.FirstSprite != (PPU.OAMAddr >> 1))				{					PPU.FirstSprite = (PPU.OAMAddr&0xFE) >> 1;					IPPU.OBJChanged = TRUE;#ifdef DEBUGGER					missing.sprite_priority_rotation = 1;#endif				}			}		} else {			if (!(PPU.OAMFlip&1))			{				byte = PPU.OAMData [PPU.OAMAddr << 1];			}			else			{				byte = PPU.OAMData [(PPU.OAMAddr << 1) + 1];				++PPU.OAMAddr;				if (PPU.OAMPriorityRotation && PPU.FirstSprite != (PPU.OAMAddr >> 1))				{					PPU.FirstSprite = (PPU.OAMAddr&0xFE) >> 1;					IPPU.OBJChanged = TRUE;#ifdef DEBUGGER					missing.sprite_priority_rotation = 1;#endif				}			}		}		PPU.OAMFlip ^= 1;#ifdef DEBUGGER	    missing.oam_read = 1;#endif		return (PPU.OpenBus1 = byte);	case 0x2139:		// Read vram low byte#ifdef DEBUGGER		missing.vram_read = 1;#endif#ifdef CORRECT_VRAM_READS		byte = IPPU.VRAMReadBuffer & 0xff;		if (!PPU.VMA.High)		{			if (PPU.VMA.FullGraphicCount)			{				uint32 addr = PPU.VMA.Address;				uint32 rem = addr & PPU.VMA.Mask1;				uint32 address = (addr & ~PPU.VMA.Mask1) +					(rem >> PPU.VMA.Shift) +					((rem & (PPU.VMA.FullGraphicCount - 1)) << 3);				IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM+((address << 1) & 0xFFFF));			} else				IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM+((PPU.VMA.Address << 1) & 0xffff));			PPU.VMA.Address += PPU.VMA.Increment;		}#else		if (IPPU.FirstVRAMRead)			byte = Memory.VRAM[(PPU.VMA.Address << 1)&0xFFFF];		else			if (PPU.VMA.FullGraphicCount)			{				uint32 addr = PPU.VMA.Address - 1;				uint32 rem = addr & PPU.VMA.Mask1;				uint32 address = (addr & ~PPU.VMA.Mask1) +					(rem >> PPU.VMA.Shift) +					((rem & (PPU.VMA.FullGraphicCount - 1)) << 3);				byte = Memory.VRAM [((address << 1) - 2) & 0xFFFF];			}			else				byte = Memory.VRAM[((PPU.VMA.Address << 1) - 2) & 0xffff];						if (!PPU.VMA.High)			{				PPU.VMA.Address += PPU.VMA.Increment;				IPPU.FirstVRAMRead = FALSE;			}#endif			PPU.OpenBus1 = byte;			break;	case 0x213A:		// Read vram high byte#ifdef DEBUGGER		missing.vram_read = 1;#endif#ifdef CORRECT_VRAM_READS		byte = (IPPU.VRAMReadBuffer>>8) & 0xff;		if (PPU.VMA.High)		{			if (PPU.VMA.FullGraphicCount)			{				uint32 addr = PPU.VMA.Address;				uint32 rem = addr & PPU.VMA.Mask1;				uint32 address = (addr & ~PPU.VMA.Mask1) +					(rem >> PPU.VMA.Shift) +					((rem & (PPU.VMA.FullGraphicCount - 1)) << 3);				IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM+((address << 1) & 0xFFFF));			} else				IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM+((PPU.VMA.Address << 1) & 0xffff));			PPU.VMA.Address += PPU.VMA.Increment;		}#else		if (IPPU.FirstVRAMRead)			byte = Memory.VRAM[((PPU.VMA.Address << 1) + 1) & 0xffff];		else			if (PPU.VMA.FullGraphicCount)			{				uint32 addr = PPU.VMA.Address - 1;				uint32 rem = addr & PPU.VMA.Mask1;				uint32 address = (addr & ~PPU.VMA.Mask1) +					(rem >> PPU.VMA.Shift) +					((rem & (PPU.VMA.FullGraphicCount - 1)) << 3);				byte = Memory.VRAM [((address << 1) - 1) & 0xFFFF];			}			else				byte = Memory.VRAM[((PPU.VMA.Address << 1) - 1) & 0xFFFF];			if (PPU.VMA.High)			{				PPU.VMA.Address += PPU.VMA.Increment;				IPPU.FirstVRAMRead = FALSE;			}#endif			PPU.OpenBus1 = byte;			break;	case 0x213B:	    // Read palette data#ifdef DEBUGGER	    missing.cgram_read = 1;#endif	    if (PPU.CGFLIPRead)		byte = PPU.CGDATA [PPU.CGADD++] >> 8;	    else		byte = PPU.CGDATA [PPU.CGADD] & 0xff;	    PPU.CGFLIPRead ^= 1;	    return (PPU.OpenBus2 = byte);	    	case 0x213C:	    // Horizontal counter value 0-339#ifdef DEBUGGER	    missing.h_counter_read = 1;#endif	    if (PPU.HBeamFlip)		byte = (PPU.OpenBus2 & 0xfe) | ((PPU.HBeamPosLatched >> 8) & 0x01);	    else		byte = (uint8)PPU.HBeamPosLatched;            PPU.OpenBus2 = byte;	    PPU.HBeamFlip ^= 1;	    break;	case 0x213D:	    // Vertical counter value 0-262#ifdef DEBUGGER	    missing.v_counter_read = 1;#endif	    if (PPU.VBeamFlip)                byte = (PPU.OpenBus2 & 0xfe) | ((PPU.VBeamPosLatched >> 8) & 0x01);	    else                byte = (uint8)PPU.VBeamPosLatched;            PPU.OpenBus2 = byte;	    PPU.VBeamFlip ^= 1;	    break;	case 0x213E:	    // PPU time and range over flags	    FLUSH_REDRAW ();	    //so far, 5c77 version is always 1.		return (PPU.OpenBus1 = (Model->_5C77 | PPU.RangeTimeOver));	case 0x213F:	    // NTSC/PAL and which field flags	    PPU.VBeamFlip = PPU.HBeamFlip = 0;            //neviksti found a 2 and a 3 here. SNEeSe uses a 3.            //XXX: field flags not emulated	    return ((Settings.PAL ? 0x10 : 0) | (Memory.FillRAM[0x213f] & 0xc0)| Model->_5C78) | (~PPU.OpenBus2 & 0x20);	case 0x2140: case 0x2141: case 0x2142: case 0x2143:	case 0x2144: case 0x2145: case 0x2146: case 0x2147:	case 0x2148: case 0x2149: case 0x214a: case 0x214b:	case 0x214c: case 0x214d: case 0x214e: case 0x214f:	case 0x2150: case 0x2151: case 0x2152: case 0x2153:	case 0x2154: case 0x2155: case 0x2156: case 0x2157:	case 0x2158: case 0x2159: case 0x215a: case 0x215b:	case 0x215c: case 0x215d: case 0x215e: case 0x215f:	case 0x2160: case 0x2161: case 0x2162: case 0x2163:	case 0x2164: case 0x2165: case 0x2166: case 0x2167:	case 0x2168: case 0x2169: case 0x216a: case 0x216b:	case 0x216c: case 0x216d: case 0x216e: case 0x216f:	case 0x2170: case 0x2171: case 0x2172: case 0x2173:	case 0x2174: case 0x2175: case 0x2176: case 0x2177:	case 0x2178: case 0x2179: case 0x217a: case 0x217b:	case 0x217c: case 0x217d: case 0x217e: case 0x217f:#ifdef SPCTOOL	    return ((uint8) _SPCOutP [Address & 3]);#else    //	CPU.Flags |= DEBUG_MODE_FLAG;#ifdef SPC700_SHUTDOWN		    IAPU.APUExecuting = Settings.APUEnabled;	    IAPU.WaitCounter++;#endif	    if (Settings.APUEnabled)	    {#ifdef CPU_SHUTDOWN//		CPU.WaitAddress = CPU.PCAtOpcodeStart;#endif			if (SNESGameFixes.APU_OutPorts_ReturnValueFix &&		    Address >= 0x2140 && Address <= 0x2143 && !CPU.V_Counter)		{                    return (uint8)((Address & 1) ? ((rand() & 0xff00) >> 8) : 				   (rand() & 0xff));		}		return (APU.OutPorts [Address & 3]);	    }	    switch (Settings.SoundSkipMethod)	    {	    case 0:	    case 1:		CPU.BranchSkip = TRUE;		break;	    case 2:		break;	    case 3:		CPU.BranchSkip = TRUE;		break;	    }	    if ((Address & 3) < 2)	    {		int r = rand ();		if (r & 2)		{		    if (r & 4)			return ((Address & 3) == 1 ? 0xaa : 0xbb);		    else			return ((r >> 3) & 0xff);		}	    }	    else	    {		int r = rand ();		if (r & 2)		    return ((r >> 3) & 0xff);	    }	    return (Memory.FillRAM[Address]);#endif // SPCTOOL	case 0x2180:	    // Read WRAM#ifdef DEBUGGER	    missing.wram_read = 1;#endif	    byte = Memory.RAM [PPU.WRAM++];	    PPU.WRAM &= 0x1FFFF;	    break;	case 0x2181:	case 0x2182:	case 0x2183:			return OpenBus;		  default:			return OpenBus;	}    }    else    {	if (Settings.SA1)	    return (S9xGetSA1 (Address));	if (Address <= 0x2fff || Address >= 0x3000 + 768)	{	    switch (Address)	    {	    case 0x21c2:			if(Model->_5C77 ==2)		        return (0x20);			//	fprintf(stderr, "Read from $21c2!\n");				return OpenBus;	    case 0x21c3:				if(Model->_5C77 ==2)			        return (0);			//	fprintf(stderr, "Read from $21c3!\n");				return OpenBus;	    case 0x2800:		// For Dai Kaijyu Monogatari II		if (Settings.SRTC)		    return (S9xGetSRTC (Address));		/*FALL*/			    	    default:#ifdef DEBUGGER	        missing.unknownppu_read = Address;	        if (Settings.TraceUnknownRegisters)		{		    sprintf (String, "Unknown register read: $%04X\n", Address);		    S9xMessage (S9X_TRACE, S9X_PPU_TRACE, String);		}#endif				return OpenBus;	    }	}		if (!Settings.SuperFX)			return OpenBus;#ifdef ZSNES_FX	if (Address < 0x3040)	    byte = S9xSuperFXReadReg (Address);	else	    byte = Memory.FillRAM [Address];#ifdef CPU_SHUTDOWN	if (Address == 0x3030)	    CPU.WaitAddress = CPU.PCAtOpcodeStart;#endif		if (Address == 0x3031)	    CLEAR_IRQ_SOURCE (GSU_IRQ_SOURCE);#else	byte = Memory.FillRAM [Address];//if (Address != 0x3030 && Address != 0x3031)//printf ("%04x\n", Address);#ifdef CPU_SHUTDOWN	if (Address == 0x3030)	{	    CPU.WaitAddress = CPU.PCAtOpcodeStart;	}	else#endif	if (Address == 0x3031)	{	    CLEAR_IRQ_SOURCE (GSU_IRQ_SOURCE);	    Memory.FillRAM [0x3031] = byte & 0x7f;	}	return (byte);#endif    }//    fprintf(stderr, "%03d: %02x from %04x\n", CPU.V_Counter, byte, Address);    return (byte);}/******************************************************************************//* S9xSetCPU()                                                                *//* This function sets a CPU/DMA Register to a specific byte                   *//******************************************************************************/void S9xSetCPU (uint8 byte, uint16 Address){	int d;//	fprintf(stderr, "%03d: %02x to %04x\n", CPU.V_Counter, byte, Address);	if (Address < 0x4200)	{		CPU.Cycles += ONE_CYCLE;		switch (Address)		{		  case 0x4016:			// S9xReset reading of old-style joypads			if ((byte & 1) && !(Memory.FillRAM [Address] & 1))			{				PPU.Joypad1ButtonReadPos = 0;				PPU.Joypad2ButtonReadPos = 0;				PPU.Joypad3ButtonReadPos = 0;			}			break;		  case 0x4017:			break;		  default:#ifdef DEBUGGER			missing.unknowncpu_write = Address;			if (Settings.TraceUnknownRegisters)			{				sprintf (String, "Unknown register register write: $%02X->$%04X\n",						 byte, Address);				S9xMessage (S9X_TRACE, S9X_PPU_TRACE, String);			}#endif			break;		}	}	else		switch (Address)		{		  case 0x4200:			// NMI, V & H IRQ and joypad reading enable flags			if (byte & 0x20)			{				//if(!SNESGameFixes.umiharakawaseFix && PPU.IRQVBeamPos==262) fprintf(stderr, "PPU.IRQVBeamPos = %d, CPU.V_Counter = %d\n", PPU.IRQVBeamPos, CPU.V_Counter);				if (!PPU.VTimerEnabled)				{

⌨️ 快捷键说明

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