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

📄 ppu.cpp

📁 著名SFC模拟器Snes9x的源代码。
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		    PPU.OAMAddr = 0;			    }	    PPU.OAMReadFlip ^= 1;#ifdef DEBUGGER	    missing.oam_read = 1;#endif	    return (byte);	case 0x2139:	    // Read vram low byte#ifdef DEBUGGER	    missing.vram_read = 1;#endif	    if (IPPU.FirstVRAMRead)		byte = Memory.VRAM[PPU.VMA.Address << 1];	    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;	    }	    break;	case 0x213A:	    // Read vram high byte#ifdef DEBUGGER	    missing.vram_read = 1;#endif	    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;	    }	    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 (byte);	    	case 0x213C:	    // Horizontal counter value 0-339#ifdef DEBUGGER	    missing.h_counter_read = 1;#endif	    if (PPU.HBeamFlip)		byte = PPU.HBeamPosLatched >> 8;	    else		byte = (uint8)PPU.HBeamPosLatched;	    PPU.HBeamFlip ^= 1;	    break;	case 0x213D:	    // Vertical counter value 0-262#ifdef DEBUGGER	    missing.v_counter_read = 1;#endif	    if (PPU.VBeamFlip)		byte = PPU.VBeamPosLatched >> 8;	    else		byte = (uint8)PPU.VBeamPosLatched;	    PPU.VBeamFlip ^= 1;	    break;	case 0x213E:	    // PPU time and range over flags	    return (0);	case 0x213F:	    // NTSC/PAL and which field flags	    PPU.VBeamFlip = PPU.HBeamFlip = 0;	    return ((Settings.PAL ? 0x10 : 0) | (Memory.FillRAM[0x213f] & 0xc0));	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			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 (Memory.FillRAM [Address]);	case 0x2190:	    return (1);	}    }    else    {	if (Settings.SA1)	    return (S9xGetSA1 (Address));	if (Address <= 0x2fff || Address >= 0x3000 + 768)	{	    switch (Address)	    {	    case 0x21c2:	        return (0x20);	    case 0x21c3:	        return (0);	    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		// XXX:	        return (0); //Memory.FillRAM[Address]);	    }	}		if (!Settings.SuperFX)	    return (0x30);#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    }    return (byte);}/**********************************************************************************************//* S9xSetCPU()                                                                                   *//* This function sets a CPU/DMA Register to a specific byte                                   *//**********************************************************************************************/void S9xSetCPU (uint8 byte, uint16 Address){    int d;        if (Address < 0x4200)    {#ifdef VAR_CYCLES	CPU.Cycles += ONE_CYCLE;#endif	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 (!PPU.VTimerEnabled)	    {#ifdef DEBUGGER		missing.virq = 1;		missing.virq_pos = PPU.IRQVBeamPos;#endif		PPU.VTimerEnabled = TRUE;		if (PPU.HTimerEnabled)		    S9xUpdateHTimer ();		else		if (PPU.IRQVBeamPos == CPU.V_Counter)		    S9xSetIRQ (PPU_V_BEAM_IRQ_SOURCE);	    }	}	else	    PPU.VTimerEnabled = FALSE;	if (byte & 0x10)	{	    if (!PPU.HTimerEnabled)	    {#ifdef DEBUGGER		missing.hirq = 1;		missing.hirq_pos = PPU.IRQHBeamPos;#endif		PPU.HTimerEnabled = TRUE;		S9xUpdateHTimer ();	    }	}	else	{	    // No need to check for HTimer being disabled as the scanline	    // event trigger code won't trigger an H-IRQ unless its enabled.	    PPU.HTimerEnabled = FALSE;	    PPU.HTimerPosition = Settings.H_Max + 1;	}	if (CPU.IRQCycleCount == 0)	    CLEAR_IRQ_SOURCE (PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE);	if ((byte & 0x80) && 	    !(Memory.FillRAM [0x4200] & 0x80) &&	    CPU.V_Counter >= PPU.ScreenHeight + FIRST_VISIBLE_LINE &&	    CPU.V_Counter <= PPU.ScreenHeight + 15 &&	    !CPU.NMIActive)	{	    CPU.Flags |= NMI_FLAG;	    CPU.NMIActive = TRUE;	    CPU.NMICycleCount = CPU.NMITriggerPoint;	}	break;    case 0x4201:	// I/O port output     case 0x4202:	// Multiplier (for multply)	break;    case 0x4203:	{	    // Multiplicand	    uint32 res = Memory.FillRAM[0x4202] * byte;	    Memory.FillRAM[0x4216] = (uint8) res;	    Memory.FillRAM[0x4217] = (uint8) (res >> 8);	    break;	}    case 0x4204:    case 0x4205:	// Low and high muliplier (for divide)	break;    case 0x4206:	{	    // Divisor	    uint16 a = Memory.FillRAM[0x4204] + (Memory.FillRAM[0x4205] << 8);	    uint16 div = byte ? a / byte : 0xffff;	    uint16 rem = byte ? a % byte : a;	    Memory.FillRAM[0x4214] = (uint8)div;	    Memory.FillRAM[0x4215] = div >> 8;	    Memory.FillRAM[0x4216] = (uint8)rem;	    Memory.FillRAM[0x4217] = rem >> 8;	    break;	}    case 0x4207:	d = PPU.IRQHBeamPos;	PPU.IRQHBeamPos = (PPU.IRQHBeamPos & 0xFF00) | byte;	if (PPU.HTimerEnabled && PPU.IRQHBeamPos != d)	    S9xUpdateHTimer ();	break;    case 0x4208:	d = PPU.IRQHBeamPos;	PPU.IRQHBeamPos = (PPU.IRQHBeamPos & 0xFF) | ((byte & 1) << 8);	if (PPU.HTimerEnabled && PPU.IRQHBeamPos != d)	    S9xUpdateHTimer ();	break;    case 0x4209:	d = PPU.IRQVBeamPos;	PPU.IRQVBeamPos = (PPU.IRQVBeamPos & 0xFF00) | byte;#ifdef DEBUGGER	missing.virq_pos = PPU.IRQVBeamPos;#endif	if (PPU.VTimerEnabled && PPU.IRQVBeamPos != d)	{	    if (PPU.HTimerEnabled)		S9xUpdateHTimer ();	    else	    {		if (PPU.IRQVBeamPos == CPU.V_Counter)		    S9xSetIRQ (PPU_V_BEAM_IRQ_SOURCE);	    }	}	break;    case 0x420A:	d = PPU.IRQVBeamPos;	PPU.IRQVBeamPos = (PPU.IRQVBeamPos & 0xFF) | ((byte & 1) << 8);#ifdef DEBUGGER	missing.virq_pos = PPU.IRQVBeamPos;#endif	if (PPU.VTimerEnabled && PPU.IRQVBeamPos != d)	{	    if (PPU.HTimerEnabled)		S9xUpdateHTimer ();	    else	    {		if (PPU.IRQVBeamPos == CPU.V_Counter)		    S9xSetIRQ (PPU_V_BEAM_IRQ_SOURCE);	    }	}	break;    case 0x420B:#ifdef DEBUGGER	missing.dma_this_frame = byte;	missing.dma_channels = byte;#endif	if ((byte & 0x01) != 0)	    S9xDoDMA (0);	if ((byte & 0x02) != 0)	    S9xDoDMA (1);	if ((byte & 0x04) != 0)	    S9xDoDMA (2);	if ((byte & 0x08) != 0)	    S9xDoDMA (3);	if ((byte & 0x10) != 0)	    S9xDoDMA (4);	if ((byte & 0x20) != 0)	    S9xDoDMA (5);	if ((byte & 0x40) != 0)	    S9xDoDMA (6);	if ((byte & 0x80) != 0)	    S9xDoDMA (7);	break;    case 0x420C:#ifdef DEBUGGER	missing.hdma_this_frame |= byte;	missing.hdma_channels |= byte; #endif	if (Settings.DisableHDMA)	    byte = 0;	Memory.FillRAM[0x420c] = byte;	IPPU.HDMA = byte;	break;    case 0x420d:	// Cycle speed 0 - 2.68Mhz, 1 - 3.58Mhz (banks 0x80 +)	if ((byte & 1) != (Memory.FillRAM [0x420d] & 1))	{	    if (byte & 1)	    {		CPU.FastROMSpeed = 6;#ifdef DEBUGGER		missing.fast_rom = 1;#endif	    }	    else		CPU.FastROMSpeed = 8;	    Memory.FixROMSpeed ();	}	/* FALL */    case 0x420e:    case 0x420f:	// --->>> Unknown	break;    case 0x4210:	// NMI ocurred flag (reset on read or write)	Memory.FillRAM[0x4210] = 0;	return;    case 0x4211:	// IRQ ocurred flag (reset on read or write)	CLEAR_IRQ_SOURCE (PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE);	break;    case 0x4212:	// v-blank, h-blank and joypad being scanned flags (read-only)    case 0x4213:	// I/O Port (read-only)    case 0x4214:    case 0x4215:	// Quotent of divide (read-only)    case 0x4216:    case 0x4217:	// Multiply product (read-only)	return;    case 0x4218:    case 0x4219:    case 0x421a:    case 0x421b:    case 0x421c:    case 0x421d:

⌨️ 快捷键说明

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