📄 ppu.cpp
字号:
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));#else IPPU.FirstVRAMRead = TRUE;#endif break; case 0x2118: // VRAM write data (low)#ifndef CORRECT_VRAM_READS IPPU.FirstVRAMRead = TRUE;#endif REGISTER_2118(Byte); break; case 0x2119: // VRAM write data (high)#ifndef CORRECT_VRAM_READS IPPU.FirstVRAMRead = TRUE;#endif REGISTER_2119(Byte); break; case 0x211a: // Mode 7 outside rotation area display mode and flipping if (Byte != Memory.FillRAM [0x211a]) { FLUSH_REDRAW (); PPU.Mode7Repeat = Byte >> 6; if (PPU.Mode7Repeat == 1) PPU.Mode7Repeat = 0; PPU.Mode7VFlip = (Byte & 2) >> 1; PPU.Mode7HFlip = Byte & 1; } break; case 0x211b: // Mode 7 matrix A (low & high) PPU.MatrixA = ((PPU.MatrixA >> 8) & 0xff) | (Byte << 8); PPU.Need16x8Mulitply = TRUE; break; case 0x211c: // Mode 7 matrix B (low & high) PPU.MatrixB = ((PPU.MatrixB >> 8) & 0xff) | (Byte << 8); PPU.Need16x8Mulitply = TRUE; break; case 0x211d: // Mode 7 matrix C (low & high) PPU.MatrixC = ((PPU.MatrixC >> 8) & 0xff) | (Byte << 8); break; case 0x211e: // Mode 7 matrix D (low & high) PPU.MatrixD = ((PPU.MatrixD >> 8) & 0xff) | (Byte << 8); break; case 0x211f: // Mode 7 centre of rotation X (low & high) PPU.CentreX = ((PPU.CentreX >> 8) & 0xff) | (Byte << 8); break; case 0x2120: // Mode 7 centre of rotation Y (low & high) PPU.CentreY = ((PPU.CentreY >> 8) & 0xff) | (Byte << 8); break; case 0x2121: // CG-RAM address PPU.CGFLIP = 0; PPU.CGFLIPRead = 0; PPU.CGADD = Byte; break; case 0x2122: REGISTER_2122(Byte); break; case 0x2123: // Window 1 and 2 enable for backgrounds 1 and 2 if (Byte != Memory.FillRAM [0x2123]) { FLUSH_REDRAW (); PPU.ClipWindow1Enable [0] = !!(Byte & 0x02); PPU.ClipWindow1Enable [1] = !!(Byte & 0x20); PPU.ClipWindow2Enable [0] = !!(Byte & 0x08); PPU.ClipWindow2Enable [1] = !!(Byte & 0x80); PPU.ClipWindow1Inside [0] = !(Byte & 0x01); PPU.ClipWindow1Inside [1] = !(Byte & 0x10); PPU.ClipWindow2Inside [0] = !(Byte & 0x04); PPU.ClipWindow2Inside [1] = !(Byte & 0x40); PPU.RecomputeClipWindows = TRUE;#ifdef DEBUGGER if (Byte & 0x80) missing.window2[1] = 1; if (Byte & 0x20) missing.window1[1] = 1; if (Byte & 0x08) missing.window2[0] = 1; if (Byte & 0x02) missing.window1[0] = 1;#endif } break; case 0x2124: // Window 1 and 2 enable for backgrounds 3 and 4 if (Byte != Memory.FillRAM [0x2124]) { FLUSH_REDRAW (); PPU.ClipWindow1Enable [2] = !!(Byte & 0x02); PPU.ClipWindow1Enable [3] = !!(Byte & 0x20); PPU.ClipWindow2Enable [2] = !!(Byte & 0x08); PPU.ClipWindow2Enable [3] = !!(Byte & 0x80); PPU.ClipWindow1Inside [2] = !(Byte & 0x01); PPU.ClipWindow1Inside [3] = !(Byte & 0x10); PPU.ClipWindow2Inside [2] = !(Byte & 0x04); PPU.ClipWindow2Inside [3] = !(Byte & 0x40); PPU.RecomputeClipWindows = TRUE;#ifdef DEBUGGER if (Byte & 0x80) missing.window2[3] = 1; if (Byte & 0x20) missing.window1[3] = 1; if (Byte & 0x08) missing.window2[2] = 1; if (Byte & 0x02) missing.window1[2] = 1;#endif } 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; if(IPPU.DoubleHeightPixels) IPPU.RenderedScreenHeight = PPU.ScreenHeight << 1; else IPPU.RenderedScreenHeight = PPU.ScreenHeight;#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 //if((Byte & 1)&&(PPU.BGMode==5||PPU.BGMode==6)) //IPPU.Interlace=1; if((Memory.FillRAM [0x2133] ^ Byte)&3) { FLUSH_REDRAW (); if((Memory.FillRAM [0x2133] ^ Byte)&2) IPPU.OBJChanged = TRUE; if(PPU.BGMode==5||PPU.BGMode==6) IPPU.Interlace = Byte&1; IPPU.InterlaceSprites=0; // IPPU.InterlaceSprites = (Byte&2)>>1; } } 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; fx_dirtySCBR(); break; case 0x3039: Memory.FillRAM [Address] = Byte; break; case 0x303a: Memory.FillRAM [Address] = Byte; break; case 0x303b: break; case 0x303c: Memory.FillRAM [Address] = Byte; fx_updateRamBank(Byte); 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -