📄 ppu.cpp
字号:
} break; case 0x2125: // Window 1 and 2 enable for objects and colour window if (Byte != Memory.FillRAM [0x2125]) { FLUSH_REDRAW (); PPU.ClipWindow1Enable [4] = !!(Byte & 0x02); PPU.ClipWindow1Enable [5] = !!(Byte & 0x20); PPU.ClipWindow2Enable [4] = !!(Byte & 0x08); PPU.ClipWindow2Enable [5] = !!(Byte & 0x80); PPU.ClipWindow1Inside [4] = !(Byte & 0x01); PPU.ClipWindow1Inside [5] = !(Byte & 0x10); PPU.ClipWindow2Inside [4] = !(Byte & 0x04); PPU.ClipWindow2Inside [5] = !(Byte & 0x40); PPU.RecomputeClipWindows = TRUE;#ifdef DEBUGGER if (Byte & 0x80) missing.window2[5] = 1; if (Byte & 0x20) missing.window1[5] = 1; if (Byte & 0x08) missing.window2[4] = 1; if (Byte & 0x02) missing.window1[4] = 1;#endif } break; case 0x2126: // Window 1 left position if (Byte != Memory.FillRAM [0x2126]) { FLUSH_REDRAW (); PPU.Window1Left = Byte; PPU.RecomputeClipWindows = TRUE; } break; case 0x2127: // Window 1 right position if (Byte != Memory.FillRAM [0x2127]) { FLUSH_REDRAW (); PPU.Window1Right = Byte; PPU.RecomputeClipWindows = TRUE; } break; case 0x2128: // Window 2 left position if (Byte != Memory.FillRAM [0x2128]) { FLUSH_REDRAW (); PPU.Window2Left = Byte; PPU.RecomputeClipWindows = TRUE; } break; case 0x2129: // Window 2 right position if (Byte != Memory.FillRAM [0x2129]) { FLUSH_REDRAW (); PPU.Window2Right = Byte; PPU.RecomputeClipWindows = TRUE; } break; case 0x212a: // Windows 1 & 2 overlap logic for backgrounds 1 - 4 if (Byte != Memory.FillRAM [0x212a]) { FLUSH_REDRAW (); PPU.ClipWindowOverlapLogic [0] = (Byte & 0x03); PPU.ClipWindowOverlapLogic [1] = (Byte & 0x0c) >> 2; PPU.ClipWindowOverlapLogic [2] = (Byte & 0x30) >> 4; PPU.ClipWindowOverlapLogic [3] = (Byte & 0xc0) >> 6; PPU.RecomputeClipWindows = TRUE; } break; case 0x212b: // Windows 1 & 2 overlap logic for objects and colour window if (Byte != Memory.FillRAM [0x212b]) { FLUSH_REDRAW (); PPU.ClipWindowOverlapLogic [4] = Byte & 0x03; PPU.ClipWindowOverlapLogic [5] = (Byte & 0x0c) >> 2; PPU.RecomputeClipWindows = TRUE; } break; case 0x212c: // Main screen designation (backgrounds 1 - 4 and objects) if (Byte != Memory.FillRAM [0x212c]) { FLUSH_REDRAW (); PPU.RecomputeClipWindows = TRUE; Memory.FillRAM [Address] = Byte; return; } break; case 0x212d: // Sub-screen designation (backgrounds 1 - 4 and objects) if (Byte != Memory.FillRAM [0x212d]) { FLUSH_REDRAW ();#ifdef DEBUGGER if (Byte & 0x1f) missing.subscreen = 1;#endif PPU.RecomputeClipWindows = TRUE; Memory.FillRAM [Address] = Byte; return; } break; case 0x212e: // Window mask designation for main screen ? if (Byte != Memory.FillRAM [0x212e]) { FLUSH_REDRAW (); PPU.RecomputeClipWindows = TRUE; } break; case 0x212f: // Window mask designation for sub-screen ? if (Byte != Memory.FillRAM [0x212f]) { FLUSH_REDRAW (); PPU.RecomputeClipWindows = TRUE; } break; case 0x2130: // Fixed colour addition or screen addition if (Byte != Memory.FillRAM [0x2130]) { FLUSH_REDRAW (); PPU.RecomputeClipWindows = TRUE;#ifdef DEBUGGER if ((Byte & 1) && (PPU.BGMode == 3 || PPU.BGMode == 4 || PPU.BGMode == 7)) missing.direct = 1;#endif } break; case 0x2131: // Colour addition or subtraction select if (Byte != Memory.FillRAM[0x2131]) { FLUSH_REDRAW (); // Backgrounds 1 - 4, objects and backdrop colour add/sub enable#ifdef DEBUGGER if (Byte & 0x80) { // Subtract if (Memory.FillRAM[0x2130] & 0x02) missing.subscreen_sub = 1; else missing.fixed_colour_sub = 1; } else { // Addition if (Memory.FillRAM[0x2130] & 0x02) missing.subscreen_add = 1; else missing.fixed_colour_add = 1; }#endif Memory.FillRAM[0x2131] = Byte; } break; case 0x2132: if (Byte != Memory.FillRAM [0x2132]) { FLUSH_REDRAW (); // Colour data for fixed colour addition/subtraction if (Byte & 0x80) PPU.FixedColourBlue = Byte & 0x1f; if (Byte & 0x40) PPU.FixedColourGreen = Byte & 0x1f; if (Byte & 0x20) PPU.FixedColourRed = Byte & 0x1f; } break; case 0x2133: // Screen settings if (Byte != Memory.FillRAM [0x2133]) {#ifdef DEBUGGER if (Byte & 0x40) missing.mode7_bgmode = 1; if (Byte & 0x08) missing.pseudo_512 = 1;#endif if (Byte & 0x04) { PPU.ScreenHeight = SNES_HEIGHT_EXTENDED;#ifdef DEBUGGER missing.lines_239 = 1;#endif } else PPU.ScreenHeight = SNES_HEIGHT;#ifdef DEBUGGER if (Byte & 0x02) missing.sprite_double_height = 1; if (Byte & 1) missing.interlace = 1;#endif } break; case 0x2134: case 0x2135: case 0x2136: // Matrix 16bit x 8bit multiply result (read-only) return; case 0x2137: // Software latch for horizontal and vertical timers (read-only) return; case 0x2138: // OAM read data (read-only) return; case 0x2139: case 0x213a: // VRAM read data (read-only) return; case 0x213b: // CG-RAM read data (read-only) return; case 0x213c: case 0x213d: // Horizontal and vertical (low/high) read counter (read-only) return; case 0x213e: // PPU status (time over and range over) return; case 0x213f: // NTSC/PAL select and field (read-only) return; 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 _SPCInPB (Address & 3, Byte);#else // CPU.Flags |= DEBUG_MODE_FLAG; Memory.FillRAM [Address] = Byte; IAPU.RAM [(Address & 3) + 0xf4] = Byte;#ifdef SPC700_SHUTDOWN IAPU.APUExecuting = Settings.APUEnabled; IAPU.WaitCounter++;#endif#endif // SPCTOOL break; case 0x2180: REGISTER_2180(Byte); break; case 0x2181: PPU.WRAM &= 0x1FF00; PPU.WRAM |= Byte; break; case 0x2182: PPU.WRAM &= 0x100FF; PPU.WRAM |= Byte << 8; break; case 0x2183: PPU.WRAM &= 0x0FFFF; PPU.WRAM |= Byte << 16; PPU.WRAM &= 0x1FFFF; break; } } else { if (Settings.SA1) { if (Address >= 0x2200 && Address <0x23ff) S9xSetSA1 (Byte, Address); else Memory.FillRAM [Address] = Byte; return; } else // Dai Kaijyu Monogatari II if (Address == 0x2801 && Settings.SRTC) S9xSetSRTC (Byte, Address); else if (Address < 0x3000 || Address >= 0x3000 + 768) {#ifdef DEBUGGER missing.unknownppu_write = Address; if (Settings.TraceUnknownRegisters) { sprintf (String, "Unknown register write: $%02X->$%04X\n", Byte, Address); S9xMessage (S9X_TRACE, S9X_PPU_TRACE, String); }#endif } else { if (!Settings.SuperFX) return; #ifdef ZSNES_FX Memory.FillRAM [Address] = Byte; if (Address < 0x3040) S9xSuperFXWriteReg (Byte, Address); #else switch (Address) { case 0x3030: if ((Memory.FillRAM [0x3030] ^ Byte) & FLG_G) { Memory.FillRAM [Address] = Byte; // Go flag has been changed if (Byte & FLG_G) S9xSuperFXExec (); else FxFlushCache (); } else Memory.FillRAM [Address] = Byte; break; case 0x3031: Memory.FillRAM [Address] = Byte; break; case 0x3033: Memory.FillRAM [Address] = Byte; break; case 0x3034: Memory.FillRAM [Address] = Byte & 0x7f; break; case 0x3036: Memory.FillRAM [Address] = Byte & 0x7f; break; case 0x3037: Memory.FillRAM [Address] = Byte; break; case 0x3038: Memory.FillRAM [Address] = Byte; break; case 0x3039: Memory.FillRAM [Address] = Byte; break; case 0x303a: Memory.FillRAM [Address] = Byte; break; case 0x303b: break; case 0x303f: Memory.FillRAM [Address] = Byte; break; case 0x301f: Memory.FillRAM [Address] = Byte; Memory.FillRAM [0x3000 + GSU_SFR] |= FLG_G; S9xSuperFXExec (); return; default: Memory.FillRAM[Address] = Byte; if (Address >= 0x3100) { FxCacheWriteAccess (Address); } break; } #endif return; } } Memory.FillRAM[Address] = Byte;}/**********************************************************************************************//* S9xGetPPU() *//* This function retrieves a PPU Register *//**********************************************************************************************/uint8 S9xGetPPU (uint16 Address){ uint8 byte = 0; if (Address <= 0x2190) { switch (Address) { case 0x2100: case 0x2101: return (Memory.FillRAM[Address]); case 0x2102:#ifdef DEBUGGER missing.oam_address_read = 1;#endif return (uint8)(PPU.OAMAddr); case 0x2103: return (((PPU.OAMAddr >> 8) & 1) | (PPU.OAMPriorityRotation << 7)); case 0x2104: case 0x2105: case 0x2106: case 0x2107: case 0x2108: case 0x2109: case 0x210a: case 0x210b: case 0x210c: return (Memory.FillRAM[Address]); case 0x210d: case 0x210e: case 0x210f: case 0x2110: case 0x2111: case 0x2112: case 0x2113: case 0x2114:#ifdef DEBUGGER missing.bg_offset_read = 1;#endif return (Memory.FillRAM[Address]); case 0x2115: return (Memory.FillRAM[Address]); case 0x2116: return (uint8)(PPU.VMA.Address); case 0x2117: return (PPU.VMA.Address >> 8); case 0x2118: case 0x2119: case 0x211a: return (Memory.FillRAM[Address]); case 0x211b: case 0x211c: case 0x211d: case 0x211e: case 0x211f: case 0x2120:#ifdef DEBUGGER missing.matrix_read = 1;#endif return (Memory.FillRAM[Address]); case 0x2121: return (PPU.CGADD); case 0x2122: case 0x2123: case 0x2124: case 0x2125: case 0x2126: case 0x2127: case 0x2128: case 0x2129: case 0x212a: case 0x212b: case 0x212c: case 0x212d: case 0x212e: case 0x212f: case 0x2130: case 0x2131: case 0x2132: case 0x2133: return (Memory.FillRAM[Address]); 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 (Memory.FillRAM[Address]); case 0x2137: // Latch h and v counters#ifdef DEBUGGER missing.h_v_latch = 1;#endif#if 0#ifdef CPU_SHUTDOWN CPU.WaitAddress = CPU.PCAtOpcodeStart;#endif#endif PPU.HVBeamCounterLatched = 1; PPU.VBeamPosLatched = (uint16) CPU.V_Counter; PPU.HBeamPosLatched = (uint16) ((CPU.Cycles * SNES_HCOUNTER_MAX) / Settings.H_Max); // Causes screen flicker for Yoshi's Island //CLEAR_IRQ_SOURCE (PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE); return (0); case 0x2138: // Read OAM (sprite) control data if (!PPU.OAMReadFlip) { byte = PPU.OAMData [PPU.OAMAddr << 1]; } else { byte = PPU.OAMData [(PPU.OAMAddr << 1) + 1]; if (++PPU.OAMAddr >= 0x110)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -