aboutsummaryrefslogtreecommitdiff
path: root/source/ppu.cpp
diff options
context:
space:
mode:
authorNebuleon Fumika2012-12-18 22:53:49 -0500
committerNebuleon Fumika2012-12-18 22:53:49 -0500
commite708c127fa51beab567a9ce0e3ab53b58c997773 (patch)
tree647a8d7aa072ed1cb46ecfe800d4db85a155780d /source/ppu.cpp
parent286bfd58050a13e2e0e30bb35a7a1d189ec7edd1 (diff)
downloadsnes9x2005-e708c127fa51beab567a9ce0e3ab53b58c997773.tar.gz
snes9x2005-e708c127fa51beab567a9ce0e3ab53b58c997773.tar.bz2
snes9x2005-e708c127fa51beab567a9ce0e3ab53b58c997773.zip
Un-inline a bunch of stuff.
With the MIPS instruction cache, this means that two consecutive SNES CPU instructions using e.g. the same addressing style or the same opcode have a chance that the second one will use the first one's code and that it will be cached.
Diffstat (limited to 'source/ppu.cpp')
-rw-r--r--source/ppu.cpp285
1 files changed, 284 insertions, 1 deletions
diff --git a/source/ppu.cpp b/source/ppu.cpp
index fc0bd51..389bdd2 100644
--- a/source/ppu.cpp
+++ b/source/ppu.cpp
@@ -117,7 +117,7 @@ uint8 in_bit=0;
extern uint8 *HDMAMemPointers [8];
-static inline void S9xLatchCounters (bool force)
+void S9xLatchCounters (bool force)
{
if(!force && !(Memory.FillRAM[0x4213] & 0x80)) return;
@@ -3297,3 +3297,286 @@ printf ("%06x: %d\n", t, FxEmulate (2000000));
}
#endif
+// Register reads and writes...
+
+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);
+}
+
+void FLUSH_REDRAW ()
+{
+ if (IPPU.PreviousLine != IPPU.CurrentLine)
+ S9xUpdateScreen ();
+}
+
+void REGISTER_2104 (uint8 byte)
+{
+ if (PPU.OAMAddr & 0x100)
+ {
+ int addr = ((PPU.OAMAddr & 0x10f) << 1) + (PPU.OAMFlip & 1);
+ if (byte != PPU.OAMData [addr]){
+ FLUSH_REDRAW ();
+ PPU.OAMData [addr] = byte;
+ IPPU.OBJChanged = TRUE;
+
+ // 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;
+ }
+ PPU.OAMFlip ^= 1;
+ if(!(PPU.OAMFlip & 1)){
+ ++PPU.OAMAddr;
+ PPU.OAMAddr &= 0x1ff;
+ if (PPU.OAMPriorityRotation && PPU.FirstSprite != (PPU.OAMAddr >> 1))
+ {
+ PPU.FirstSprite = (PPU.OAMAddr&0xFE) >> 1;
+ IPPU.OBJChanged = TRUE;
+ }
+ } else {
+ if (PPU.OAMPriorityRotation && (PPU.OAMAddr&1)) IPPU.OBJChanged = TRUE;
+ }
+ } else if(!(PPU.OAMFlip & 1)){
+ PPU.OAMWriteRegister &= 0xff00;
+ PPU.OAMWriteRegister |= byte;
+ PPU.OAMFlip |= 1;
+ if (PPU.OAMPriorityRotation && (PPU.OAMAddr&1)) IPPU.OBJChanged = TRUE;
+ } else {
+ PPU.OAMWriteRegister &= 0x00ff;
+ uint8 lowbyte = (uint8)(PPU.OAMWriteRegister);
+ uint8 highbyte = byte;
+ PPU.OAMWriteRegister |= byte << 8;
+
+ int addr = (PPU.OAMAddr << 1);
+
+ if (lowbyte != PPU.OAMData [addr] ||
+ highbyte != PPU.OAMData [addr+1])
+ {
+ FLUSH_REDRAW ();
+ PPU.OAMData [addr] = lowbyte;
+ PPU.OAMData [addr+1] = highbyte;
+ IPPU.OBJChanged = TRUE;
+ if (addr & 2)
+ {
+ // Tile
+ PPU.OBJ[addr = PPU.OAMAddr >> 1].Name = PPU.OAMWriteRegister & 0x1ff;
+
+ // priority, h and v flip.
+ PPU.OBJ[addr].Palette = (highbyte >> 1) & 7;
+ PPU.OBJ[addr].Priority = (highbyte >> 4) & 3;
+ PPU.OBJ[addr].HFlip = (highbyte >> 6) & 1;
+ PPU.OBJ[addr].VFlip = (highbyte >> 7) & 1;
+ }
+ else
+ {
+ // X position (low)
+ PPU.OBJ[addr = PPU.OAMAddr >> 1].HPos &= 0xFF00;
+ PPU.OBJ[addr].HPos |= lowbyte;
+
+ // Sprite Y position
+ PPU.OBJ[addr].VPos = highbyte;
+ }
+ }
+ PPU.OAMFlip &= ~1;
+ ++PPU.OAMAddr;
+ if (PPU.OAMPriorityRotation && PPU.FirstSprite != (PPU.OAMAddr >> 1))
+ {
+ PPU.FirstSprite = (PPU.OAMAddr&0xFE) >> 1;
+ IPPU.OBJChanged = TRUE;
+ }
+ }
+
+ Memory.FillRAM [0x2104] = byte;
+}
+
+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;
+}
+
+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;
+}
+
+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;
+}
+
+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;
+}
+
+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;
+}
+
+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;
+}
+
+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;
+}
+
+void REGISTER_2180(uint8 Byte)
+{
+ Memory.RAM[PPU.WRAM++] = Byte;
+ PPU.WRAM &= 0x1FFFF;
+ Memory.FillRAM [0x2180] = Byte;
+}