summaryrefslogtreecommitdiff
path: root/src/ppu.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ppu.c')
-rw-r--r--src/ppu.c2464
1 files changed, 1227 insertions, 1237 deletions
diff --git a/src/ppu.c b/src/ppu.c
index 3f7a1c6..cdd8048 100644
--- a/src/ppu.c
+++ b/src/ppu.c
@@ -4,7 +4,7 @@
* (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and
* Jerremy Koot (jkoot@snes9x.com)
*
- * Super FX C emulator code
+ * Super FX C emulator code
* (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and
* Gary Henderson.
* Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_.
@@ -59,71 +59,69 @@
extern FxInit_s SuperFX;
extern FxRegs_s GSU;
#else
-EXTERN_C void S9xSuperFXWriteReg (uint8, uint32);
-EXTERN_C uint8 S9xSuperFXReadReg (uint32);
+EXTERN_C void S9xSuperFXWriteReg(uint8, uint32);
+EXTERN_C uint8 S9xSuperFXReadReg(uint32);
#endif
-extern uint8 *HDMAMemPointers [8];
+extern uint8* HDMAMemPointers [8];
-void S9xUpdateHTimer ()
+void S9xUpdateHTimer()
{
- if (PPU.HTimerEnabled)
- {
+ if (PPU.HTimerEnabled)
+ {
#ifdef DEBUGGER
- missing.hirq_pos = PPU.IRQHBeamPos;
+ missing.hirq_pos = PPU.IRQHBeamPos;
#endif
- PPU.HTimerPosition = PPU.IRQHBeamPos * Settings.H_Max / SNES_HCOUNTER_MAX;
- if (PPU.HTimerPosition == Settings.H_Max ||
- PPU.HTimerPosition == Settings.HBlankStart)
- {
- PPU.HTimerPosition--;
- }
-
- if (!PPU.VTimerEnabled || CPU.V_Counter == PPU.IRQVBeamPos)
- {
- if (PPU.HTimerPosition < CPU.Cycles)
- {
- // Missed the IRQ on this line already
- if (CPU.WhichEvent == HBLANK_END_EVENT ||
- CPU.WhichEvent == HTIMER_AFTER_EVENT)
- {
- CPU.WhichEvent = HBLANK_END_EVENT;
- CPU.NextEvent = Settings.H_Max;
- }
- else
- {
- CPU.WhichEvent = HBLANK_START_EVENT;
- CPU.NextEvent = Settings.HBlankStart;
- }
- }
- else
- {
- if (CPU.WhichEvent == HTIMER_BEFORE_EVENT ||
- CPU.WhichEvent == HBLANK_START_EVENT)
- {
- if (PPU.HTimerPosition > Settings.HBlankStart)
- {
- // HTimer was to trigger before h-blank start,
- // now triggers after start of h-blank
- CPU.NextEvent = Settings.HBlankStart;
- CPU.WhichEvent = HBLANK_START_EVENT;
- }
- else
- {
- CPU.NextEvent = PPU.HTimerPosition;
- CPU.WhichEvent = HTIMER_BEFORE_EVENT;
- }
- }
- else
- {
- CPU.WhichEvent = HTIMER_AFTER_EVENT;
- CPU.NextEvent = PPU.HTimerPosition;
- }
- }
- }
- }
+ PPU.HTimerPosition = PPU.IRQHBeamPos * Settings.H_Max / SNES_HCOUNTER_MAX;
+ if (PPU.HTimerPosition == Settings.H_Max ||
+ PPU.HTimerPosition == Settings.HBlankStart)
+ PPU.HTimerPosition--;
+
+ if (!PPU.VTimerEnabled || CPU.V_Counter == PPU.IRQVBeamPos)
+ {
+ if (PPU.HTimerPosition < CPU.Cycles)
+ {
+ // Missed the IRQ on this line already
+ if (CPU.WhichEvent == HBLANK_END_EVENT ||
+ CPU.WhichEvent == HTIMER_AFTER_EVENT)
+ {
+ CPU.WhichEvent = HBLANK_END_EVENT;
+ CPU.NextEvent = Settings.H_Max;
+ }
+ else
+ {
+ CPU.WhichEvent = HBLANK_START_EVENT;
+ CPU.NextEvent = Settings.HBlankStart;
+ }
+ }
+ else
+ {
+ if (CPU.WhichEvent == HTIMER_BEFORE_EVENT ||
+ CPU.WhichEvent == HBLANK_START_EVENT)
+ {
+ if (PPU.HTimerPosition > Settings.HBlankStart)
+ {
+ // HTimer was to trigger before h-blank start,
+ // now triggers after start of h-blank
+ CPU.NextEvent = Settings.HBlankStart;
+ CPU.WhichEvent = HBLANK_START_EVENT;
+ }
+ else
+ {
+ CPU.NextEvent = PPU.HTimerPosition;
+ CPU.WhichEvent = HTIMER_BEFORE_EVENT;
+ }
+ }
+ else
+ {
+ CPU.WhichEvent = HTIMER_AFTER_EVENT;
+ CPU.NextEvent = PPU.HTimerPosition;
+ }
+ }
+ }
+ }
}
-void S9xFixColourBrightness ()
+void S9xFixColourBrightness()
{
IPPU.XB = mul_brightness [PPU.Brightness];
if (Settings.SixteenBit)
@@ -134,7 +132,7 @@ void S9xFixColourBrightness ()
//IPPU.Red [i] = IPPU.XB [PPU.CGDATA [i] & 0x1f];
//IPPU.Green [i] = IPPU.XB [(PPU.CGDATA [i] >> 5) & 0x1f];
//IPPU.Blue [i] = IPPU.XB [(PPU.CGDATA [i] >> 10) & 0x1f];
- IPPU.ScreenColors [i] = BUILD_PIXEL (IPPU.XB[IPPU.Red [i]], IPPU.XB[IPPU.Green [i]], IPPU.XB[IPPU.Blue [i]]);
+ IPPU.ScreenColors [i] = BUILD_PIXEL(IPPU.XB[IPPU.Red [i]], IPPU.XB[IPPU.Green [i]], IPPU.XB[IPPU.Blue [i]]);
}
}
}
@@ -157,474 +155,472 @@ void S9xFixColourBrightness ()
/**********************************************************************************************/
void S9xSetCPU(uint8 byte, uint16 Address)
{
- int d;
+ int d;
- if (Address < 0x4200)
- {
+ if (Address < 0x4200)
+ {
#ifdef VAR_CYCLES
- CPU.Cycles += ONE_CYCLE;
+ 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 :
+ 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);
- }
+ 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)
- {
+ 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;
+ 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)
- {
+ 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;
+ 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;
- }
+ 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;
+ }
#ifndef RC_OPTIMIZED
- if (!Settings.DaffyDuck)
- 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 + (SNESGameFixes.alienVSpredetorFix ? 25 : 15)
- && //jyam 15->25 alien vs predetor
- // Panic Bomberman clears the NMI pending flag @ scanline 230 before enabling
- // NMIs again. The NMI routine crashes the CPU if it is called without the NMI
- // pending flag being set...
- (Memory.FillRAM[0x4210] & 0x80) && !CPU.NMIActive)
- {
- CPU.Flags |= NMI_FLAG;
- CPU.NMIActive = TRUE;
- CPU.NMICycleCount = CPU.NMITriggerPoint;
- }
+ if (!Settings.DaffyDuck)
+ 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 + (SNESGameFixes.alienVSpredetorFix ? 25 : 15)
+ && //jyam 15->25 alien vs predetor
+ // Panic Bomberman clears the NMI pending flag @ scanline 230 before enabling
+ // NMIs again. The NMI routine crashes the CPU if it is called without the NMI
+ // pending flag being set...
+ (Memory.FillRAM[0x4210] & 0x80) && !CPU.NMIActive)
+ {
+ CPU.Flags |= NMI_FLAG;
+ CPU.NMIActive = TRUE;
+ CPU.NMICycleCount = CPU.NMITriggerPoint;
+ }
#endif
- 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;
+ 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;
+ 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);
+ 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;
+ 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 :
+ 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;
+ 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 :
+ 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;
+ 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 = ONE_CYCLE;
+ //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 = ONE_CYCLE;
#ifdef DEBUGGER
- missing.fast_rom = 1;
+ missing.fast_rom = 1;
#endif
- }
- else
- CPU.FastROMSpeed = SLOW_ONE_CYCLE;
-
- 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 :
- case 0x421e :
- case 0x421f :
- // Joypad values (read-only)
- return;
-
- case 0x4300 :
- case 0x4310 :
- case 0x4320 :
- case 0x4330 :
- case 0x4340 :
- case 0x4350 :
- case 0x4360 :
- case 0x4370 :
- d = (Address >> 4) & 0x7;
- DMA[d].TransferDirection = (byte & 128) != 0 ? 1 : 0;
- DMA[d].HDMAIndirectAddressing = (byte & 64) != 0 ? 1 : 0;
- DMA[d].AAddressDecrement = (byte & 16) != 0 ? 1 : 0;
- DMA[d].AAddressFixed = (byte & 8) != 0 ? 1 : 0;
- DMA[d].TransferMode = (byte & 7);
- break;
-
- case 0x4301 :
- case 0x4311 :
- case 0x4321 :
- case 0x4331 :
- case 0x4341 :
- case 0x4351 :
- case 0x4361 :
- case 0x4371 :
- DMA[((Address >> 4) & 0x7)].BAddress = byte;
- break;
-
- case 0x4302 :
- case 0x4312 :
- case 0x4322 :
- case 0x4332 :
- case 0x4342 :
- case 0x4352 :
- case 0x4362 :
- case 0x4372 :
- d = (Address >> 4) & 0x7;
- DMA[d].AAddress &= 0xFF00;
- DMA[d].AAddress |= byte;
- break;
-
- case 0x4303 :
- case 0x4313 :
- case 0x4323 :
- case 0x4333 :
- case 0x4343 :
- case 0x4353 :
- case 0x4363 :
- case 0x4373 :
- d = (Address >> 4) & 0x7;
- DMA[d].AAddress &= 0xFF;
- DMA[d].AAddress |= byte << 8;
- break;
-
- case 0x4304 :
- case 0x4314 :
- case 0x4324 :
- case 0x4334 :
- case 0x4344 :
- case 0x4354 :
- case 0x4364 :
- case 0x4374 :
- DMA[((Address >> 4) & 0x7)].ABank = byte;
- HDMAMemPointers[((Address >> 4) & 0x7)]=NULL;
- break;
-
- case 0x4305 :
- case 0x4315 :
- case 0x4325 :
- case 0x4335 :
- case 0x4345 :
- case 0x4355 :
- case 0x4365 :
- case 0x4375 :
- d = (Address >> 4) & 0x7;
- DMA[d].TransferBytes &= 0xFF00;
- DMA[d].TransferBytes |= byte;
- DMA[d].IndirectAddress &= 0xff00;
- DMA[d].IndirectAddress |= byte;
- HDMAMemPointers[d]=NULL;
- break;
-
- case 0x4306 :
- case 0x4316 :
- case 0x4326 :
- case 0x4336 :
- case 0x4346 :
- case 0x4356 :
- case 0x4366 :
- case 0x4376 :
- d = (Address >> 4) & 0x7;
- DMA[d].TransferBytes &= 0xFF;
- DMA[d].TransferBytes |= byte << 8;
- DMA[d].IndirectAddress &= 0xff;
- DMA[d].IndirectAddress |= byte << 8;
- HDMAMemPointers[d]=NULL;
- break;
-
- case 0x4307 :
- case 0x4317 :
- case 0x4327 :
- case 0x4337 :
- case 0x4347 :
- case 0x4357 :
- case 0x4367 :
- case 0x4377 :
- DMA[d = ((Address >> 4) & 0x7)].IndirectBank = byte;
- HDMAMemPointers[d]=NULL;
- break;
-
- case 0x4308 :
- case 0x4318 :
- case 0x4328 :
- case 0x4338 :
- case 0x4348 :
- case 0x4358 :
- case 0x4368 :
- case 0x4378 :
- d = (Address >> 4) & 7;
- DMA[d].Address &= 0xff00;
- DMA[d].Address |= byte;
- HDMAMemPointers[d] = NULL;
- break;
-
- case 0x4309 :
- case 0x4319 :
- case 0x4329 :
- case 0x4339 :
- case 0x4349 :
- case 0x4359 :
- case 0x4369 :
- case 0x4379 :
- d = (Address >> 4) & 0x7;
- DMA[d].Address &= 0xff;
- DMA[d].Address |= byte << 8;
- HDMAMemPointers[d] = NULL;
- break;
-
- case 0x430A :
- case 0x431A :
- case 0x432A :
- case 0x433A :
- case 0x434A :
- case 0x435A :
- case 0x436A :
- case 0x437A :
- d = (Address >> 4) & 0x7;
- DMA[d].LineCount = byte & 0x7f;
- DMA[d].Repeat = !(byte & 0x80);
- break;
-
- case 0x430F:
- case 0x431F:
- case 0x432F:
- case 0x433F:
- case 0x434F:
- case 0x435F:
- case 0x436F:
- case 0x437F:
- Address &= ~4; // Convert 43xF to 43xB
- /* fall through */
- case 0x430B:
- case 0x431B:
- case 0x432B:
- case 0x433B:
- case 0x434B:
- case 0x435B:
- case 0x436B:
- case 0x437B:
-
- // Unknown, but they seem to be RAM-ish
- break;
- case 0x4800 :
- case 0x4801 :
- case 0x4802 :
- case 0x4803 :
- //printf ("%02x->%04x\n", byte, Address);
- break;
-
- case 0x4804 :
- case 0x4805 :
- case 0x4806 :
- case 0x4807 :
- //printf ("%02x->%04x\n", byte, Address);
-
- S9xSetSDD1MemoryMap(Address - 0x4804, byte & 7);
- break;
- default :
+ }
+ else
+ CPU.FastROMSpeed = SLOW_ONE_CYCLE;
+
+ 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 :
+ case 0x421e :
+ case 0x421f :
+ // Joypad values (read-only)
+ return;
+
+ case 0x4300 :
+ case 0x4310 :
+ case 0x4320 :
+ case 0x4330 :
+ case 0x4340 :
+ case 0x4350 :
+ case 0x4360 :
+ case 0x4370 :
+ d = (Address >> 4) & 0x7;
+ DMA[d].TransferDirection = (byte & 128) != 0 ? 1 : 0;
+ DMA[d].HDMAIndirectAddressing = (byte & 64) != 0 ? 1 : 0;
+ DMA[d].AAddressDecrement = (byte & 16) != 0 ? 1 : 0;
+ DMA[d].AAddressFixed = (byte & 8) != 0 ? 1 : 0;
+ DMA[d].TransferMode = (byte & 7);
+ break;
+
+ case 0x4301 :
+ case 0x4311 :
+ case 0x4321 :
+ case 0x4331 :
+ case 0x4341 :
+ case 0x4351 :
+ case 0x4361 :
+ case 0x4371 :
+ DMA[((Address >> 4) & 0x7)].BAddress = byte;
+ break;
+
+ case 0x4302 :
+ case 0x4312 :
+ case 0x4322 :
+ case 0x4332 :
+ case 0x4342 :
+ case 0x4352 :
+ case 0x4362 :
+ case 0x4372 :
+ d = (Address >> 4) & 0x7;
+ DMA[d].AAddress &= 0xFF00;
+ DMA[d].AAddress |= byte;
+ break;
+
+ case 0x4303 :
+ case 0x4313 :
+ case 0x4323 :
+ case 0x4333 :
+ case 0x4343 :
+ case 0x4353 :
+ case 0x4363 :
+ case 0x4373 :
+ d = (Address >> 4) & 0x7;
+ DMA[d].AAddress &= 0xFF;
+ DMA[d].AAddress |= byte << 8;
+ break;
+
+ case 0x4304 :
+ case 0x4314 :
+ case 0x4324 :
+ case 0x4334 :
+ case 0x4344 :
+ case 0x4354 :
+ case 0x4364 :
+ case 0x4374 :
+ DMA[((Address >> 4) & 0x7)].ABank = byte;
+ HDMAMemPointers[((Address >> 4) & 0x7)] = NULL;
+ break;
+
+ case 0x4305 :
+ case 0x4315 :
+ case 0x4325 :
+ case 0x4335 :
+ case 0x4345 :
+ case 0x4355 :
+ case 0x4365 :
+ case 0x4375 :
+ d = (Address >> 4) & 0x7;
+ DMA[d].TransferBytes &= 0xFF00;
+ DMA[d].TransferBytes |= byte;
+ DMA[d].IndirectAddress &= 0xff00;
+ DMA[d].IndirectAddress |= byte;
+ HDMAMemPointers[d] = NULL;
+ break;
+
+ case 0x4306 :
+ case 0x4316 :
+ case 0x4326 :
+ case 0x4336 :
+ case 0x4346 :
+ case 0x4356 :
+ case 0x4366 :
+ case 0x4376 :
+ d = (Address >> 4) & 0x7;
+ DMA[d].TransferBytes &= 0xFF;
+ DMA[d].TransferBytes |= byte << 8;
+ DMA[d].IndirectAddress &= 0xff;
+ DMA[d].IndirectAddress |= byte << 8;
+ HDMAMemPointers[d] = NULL;
+ break;
+
+ case 0x4307 :
+ case 0x4317 :
+ case 0x4327 :
+ case 0x4337 :
+ case 0x4347 :
+ case 0x4357 :
+ case 0x4367 :
+ case 0x4377 :
+ DMA[d = ((Address >> 4) & 0x7)].IndirectBank = byte;
+ HDMAMemPointers[d] = NULL;
+ break;
+
+ case 0x4308 :
+ case 0x4318 :
+ case 0x4328 :
+ case 0x4338 :
+ case 0x4348 :
+ case 0x4358 :
+ case 0x4368 :
+ case 0x4378 :
+ d = (Address >> 4) & 7;
+ DMA[d].Address &= 0xff00;
+ DMA[d].Address |= byte;
+ HDMAMemPointers[d] = NULL;
+ break;
+
+ case 0x4309 :
+ case 0x4319 :
+ case 0x4329 :
+ case 0x4339 :
+ case 0x4349 :
+ case 0x4359 :
+ case 0x4369 :
+ case 0x4379 :
+ d = (Address >> 4) & 0x7;
+ DMA[d].Address &= 0xff;
+ DMA[d].Address |= byte << 8;
+ HDMAMemPointers[d] = NULL;
+ break;
+
+ case 0x430A :
+ case 0x431A :
+ case 0x432A :
+ case 0x433A :
+ case 0x434A :
+ case 0x435A :
+ case 0x436A :
+ case 0x437A :
+ d = (Address >> 4) & 0x7;
+ DMA[d].LineCount = byte & 0x7f;
+ DMA[d].Repeat = !(byte & 0x80);
+ break;
+
+ case 0x430F:
+ case 0x431F:
+ case 0x432F:
+ case 0x433F:
+ case 0x434F:
+ case 0x435F:
+ case 0x436F:
+ case 0x437F:
+ Address &= ~4; // Convert 43xF to 43xB
+ /* fall through */
+ case 0x430B:
+ case 0x431B:
+ case 0x432B:
+ case 0x433B:
+ case 0x434B:
+ case 0x435B:
+ case 0x436B:
+ case 0x437B:
+
+ // Unknown, but they seem to be RAM-ish
+ break;
+ case 0x4800 :
+ case 0x4801 :
+ case 0x4802 :
+ case 0x4803 :
+ //printf ("%02x->%04x\n", byte, Address);
+ break;
+
+ case 0x4804 :
+ case 0x4805 :
+ case 0x4806 :
+ case 0x4807 :
+ //printf ("%02x->%04x\n", byte, Address);
+
+ S9xSetSDD1MemoryMap(Address - 0x4804, byte & 7);
+ break;
+ default :
#ifdef DEBUGGER
- missing.unknowncpu_write = Address;
- if (Settings.TraceUnknownRegisters)
- {
- sprintf(
- String,
- "Unknown register write: $%02X->$%04X\n",
- byte,
- Address);
- S9xMessage(S9X_TRACE, S9X_PPU_TRACE, String);
- }
+ missing.unknowncpu_write = Address;
+ if (Settings.TraceUnknownRegisters)
+ {
+ sprintf(
+ String,
+ "Unknown register write: $%02X->$%04X\n",
+ byte,
+ Address);
+ S9xMessage(S9X_TRACE, S9X_PPU_TRACE, String);
+ }
#endif
- break;
- }
- Memory.FillRAM[Address] = byte;
+ break;
+ }
+ Memory.FillRAM[Address] = byte;
}
/**********************************************************************************************/
@@ -633,784 +629,778 @@ void S9xSetCPU(uint8 byte, uint16 Address)
/**********************************************************************************************/
uint8 S9xGetCPU(uint16 Address)
{
- uint8 byte;
- if(Address>=0x4800&&Address<=0x4807&&Settings.SDD1)
- {
- return Memory.FillRAM[Address];
- }
-
- if (Address < 0x4200)
- {
+ uint8 byte;
+ if (Address >= 0x4800 && Address <= 0x4807 && Settings.SDD1)
+ return Memory.FillRAM[Address];
+
+ if (Address < 0x4200)
+ {
#ifdef VAR_CYCLES
- CPU.Cycles += ONE_CYCLE;
+ CPU.Cycles += ONE_CYCLE;
#endif
- switch (Address)
- {
- // Secret of the Evermore
- case 0x4000 :
- case 0x4001 :
- return (0x40);
-
- case 0x4016 :
- {
- if (Memory.FillRAM[0x4016] & 1)
- {
- return (0);
- }
-
- byte = IPPU.Joypads[0] >> (PPU.Joypad1ButtonReadPos ^ 15);
- PPU.Joypad1ButtonReadPos++;
- return (byte & 1);
- }
- case 0x4017 :
- {
- if (Memory.FillRAM[0x4016] & 1)
- {
- // MultiPlayer5 adaptor is only allowed to be plugged into port 2
- switch (IPPU.Controller)
- {
- case SNES_MULTIPLAYER5 :
- return (2);
-
- case SNES_MOUSE :
- if (++PPU.MouseSpeed[0] > 2)
- PPU.MouseSpeed[0] = 0;
- break;
- }
- return (0x00);
- }
-
- if (IPPU.Controller == SNES_MULTIPLAYER5)
- {
- if (Memory.FillRAM[0x4201] & 0x80)
- {
- byte =
- ((IPPU.Joypads[0]
- >> (PPU.Joypad2ButtonReadPos ^ 15))
- & 1)
- | (((IPPU.Joypads[2]
- >> (PPU.Joypad2ButtonReadPos ^ 15))
- & 1)
- << 1);
- PPU.Joypad2ButtonReadPos++;
- return (byte);
- }
- else
- {
- byte =
- ((IPPU.Joypads[3]
- >> (PPU.Joypad3ButtonReadPos ^ 15))
- & 1)
- | (((IPPU.Joypads[4]
- >> (PPU.Joypad3ButtonReadPos ^ 15))
- & 1)
- << 1);
- PPU.Joypad3ButtonReadPos++;
- return (byte);
- }
- }
- return (
- (IPPU.Joypads[1]
- >> (PPU.Joypad2ButtonReadPos++ ^ 15))
- & 1);
- }
- default :
+ switch (Address)
+ {
+ // Secret of the Evermore
+ case 0x4000 :
+ case 0x4001 :
+ return (0x40);
+
+ case 0x4016 :
+ {
+ if (Memory.FillRAM[0x4016] & 1)
+ return (0);
+
+ byte = IPPU.Joypads[0] >> (PPU.Joypad1ButtonReadPos ^ 15);
+ PPU.Joypad1ButtonReadPos++;
+ return (byte & 1);
+ }
+ case 0x4017 :
+ {
+ if (Memory.FillRAM[0x4016] & 1)
+ {
+ // MultiPlayer5 adaptor is only allowed to be plugged into port 2
+ switch (IPPU.Controller)
+ {
+ case SNES_MULTIPLAYER5 :
+ return (2);
+
+ case SNES_MOUSE :
+ if (++PPU.MouseSpeed[0] > 2)
+ PPU.MouseSpeed[0] = 0;
+ break;
+ }
+ return (0x00);
+ }
+
+ if (IPPU.Controller == SNES_MULTIPLAYER5)
+ {
+ if (Memory.FillRAM[0x4201] & 0x80)
+ {
+ byte =
+ ((IPPU.Joypads[0]
+ >> (PPU.Joypad2ButtonReadPos ^ 15))
+ & 1)
+ | (((IPPU.Joypads[2]
+ >> (PPU.Joypad2ButtonReadPos ^ 15))
+ & 1)
+ << 1);
+ PPU.Joypad2ButtonReadPos++;
+ return (byte);
+ }
+ else
+ {
+ byte =
+ ((IPPU.Joypads[3]
+ >> (PPU.Joypad3ButtonReadPos ^ 15))
+ & 1)
+ | (((IPPU.Joypads[4]
+ >> (PPU.Joypad3ButtonReadPos ^ 15))
+ & 1)
+ << 1);
+ PPU.Joypad3ButtonReadPos++;
+ return (byte);
+ }
+ }
+ return (
+ (IPPU.Joypads[1]
+ >> (PPU.Joypad2ButtonReadPos++ ^ 15))
+ & 1);
+ }
+ default :
#ifdef DEBUGGER
- missing.unknowncpu_read = Address;
- if (Settings.TraceUnknownRegisters)
- {
- sprintf(String, "Unknown register read: $%04X\n", Address);
- S9xMessage(S9X_TRACE, S9X_PPU_TRACE, String);
- }
+ missing.unknowncpu_read = Address;
+ if (Settings.TraceUnknownRegisters)
+ {
+ sprintf(String, "Unknown register read: $%04X\n", Address);
+ S9xMessage(S9X_TRACE, S9X_PPU_TRACE, String);
+ }
#endif
- break;
- }
- return (Memory.FillRAM[Address]);
- }
- else
- switch (Address)
- {
- // BS Dynami Tracer! needs to be able to check if NMIs are enabled
- // already, otherwise the game locks up.
- case 0x4200 :
- // NMI, h & v timers and joypad reading enable
- if (SNESGameFixes.Old_Read0x4200)
- {
+ break;
+ }
+ return (Memory.FillRAM[Address]);
+ }
+ else
+ switch (Address)
+ {
+ // BS Dynami Tracer! needs to be able to check if NMIs are enabled
+ // already, otherwise the game locks up.
+ case 0x4200 :
+ // NMI, h & v timers and joypad reading enable
+ if (SNESGameFixes.Old_Read0x4200)
+ {
#ifdef CPU_SHUTDOWN
- CPU.WaitAddress = CPU.PCAtOpcodeStart;
+ CPU.WaitAddress = CPU.PCAtOpcodeStart;
#endif
- return (REGISTER_4212());
- }
- case 0x4201 :
- // I/O port (output - write only?)
- case 0x4202 :
- case 0x4203 :
- // Multiplier and multiplicand (write)
- case 0x4204 :
- case 0x4205 :
- case 0x4206 :
- // Divisor and dividend (write)
- return (Memory.FillRAM[Address]);
- case 0x4207 :
- return (uint8) (PPU.IRQHBeamPos);
- case 0x4208 :
- return (PPU.IRQHBeamPos >> 8);
- case 0x4209 :
- return (uint8) (PPU.IRQVBeamPos);
- case 0x420a :
- return (PPU.IRQVBeamPos >> 8);
- case 0x420b :
- // General purpose DMA enable
- // Super Formation Soccer 95 della Serie A UCC Xaqua requires this
- // register should not always return zero.
- // .. But Aero 2 waits until this register goes zero..
- // Just keep toggling the value for now in the hope that it breaks
- // the game out of its wait loop...
- Memory.FillRAM[0x420b] = !Memory.FillRAM[0x420b];
- return (Memory.FillRAM[0x420b]);
- case 0x420c :
- // H-DMA enable
- return (IPPU.HDMA);
- case 0x420d :
- // Cycle speed 0 - 2.68Mhz, 1 - 3.58Mhz (banks 0x80 +)
- return (Memory.FillRAM[Address]);
- case 0x420e :
- case 0x420f :
- // --->>> Unknown
- return (Memory.FillRAM[Address]);
- case 0x4210 :
+ return (REGISTER_4212());
+ }
+ case 0x4201 :
+ // I/O port (output - write only?)
+ case 0x4202 :
+ case 0x4203 :
+ // Multiplier and multiplicand (write)
+ case 0x4204 :
+ case 0x4205 :
+ case 0x4206 :
+ // Divisor and dividend (write)
+ return (Memory.FillRAM[Address]);
+ case 0x4207 :
+ return (uint8)(PPU.IRQHBeamPos);
+ case 0x4208 :
+ return (PPU.IRQHBeamPos >> 8);
+ case 0x4209 :
+ return (uint8)(PPU.IRQVBeamPos);
+ case 0x420a :
+ return (PPU.IRQVBeamPos >> 8);
+ case 0x420b :
+ // General purpose DMA enable
+ // Super Formation Soccer 95 della Serie A UCC Xaqua requires this
+ // register should not always return zero.
+ // .. But Aero 2 waits until this register goes zero..
+ // Just keep toggling the value for now in the hope that it breaks
+ // the game out of its wait loop...
+ Memory.FillRAM[0x420b] = !Memory.FillRAM[0x420b];
+ return (Memory.FillRAM[0x420b]);
+ case 0x420c :
+ // H-DMA enable
+ return (IPPU.HDMA);
+ case 0x420d :
+ // Cycle speed 0 - 2.68Mhz, 1 - 3.58Mhz (banks 0x80 +)
+ return (Memory.FillRAM[Address]);
+ case 0x420e :
+ case 0x420f :
+ // --->>> Unknown
+ return (Memory.FillRAM[Address]);
+ case 0x4210 :
#ifdef CPU_SHUTDOWN
- CPU.WaitAddress = CPU.PCAtOpcodeStart;
+ CPU.WaitAddress = CPU.PCAtOpcodeStart;
#endif
- byte = Memory.FillRAM[0x4210];
- Memory.FillRAM[0x4210] = 0;
- return (byte);
- case 0x4211 :
- byte =
- (CPU.IRQActive
- & (PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE))
- ? 0x80
- : 0;
- // Super Robot Wars Ex ROM bug requires this.
- byte |= CPU.Cycles >= Settings.HBlankStart ? 0x40 : 0;
- CLEAR_IRQ_SOURCE(PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE);
- return (byte);
- case 0x4212 :
- // V-blank, h-blank and joypads being read flags (read-only)
+ byte = Memory.FillRAM[0x4210];
+ Memory.FillRAM[0x4210] = 0;
+ return (byte);
+ case 0x4211 :
+ byte =
+ (CPU.IRQActive
+ & (PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE))
+ ? 0x80
+ : 0;
+ // Super Robot Wars Ex ROM bug requires this.
+ byte |= CPU.Cycles >= Settings.HBlankStart ? 0x40 : 0;
+ CLEAR_IRQ_SOURCE(PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE);
+ return (byte);
+ case 0x4212 :
+ // V-blank, h-blank and joypads being read flags (read-only)
#ifdef CPU_SHUTDOWN
- CPU.WaitAddress = CPU.PCAtOpcodeStart;
+ CPU.WaitAddress = CPU.PCAtOpcodeStart;
#endif
- return (REGISTER_4212());
- case 0x4213 :
- // I/O port input
- case 0x4214 :
- case 0x4215 :
- // Quotient of divide result
- case 0x4216 :
- case 0x4217 :
- // Multiplcation result (for multiply) or remainder of
- // divison.
- return (Memory.FillRAM[Address]);
- case 0x4218 :
- case 0x4219 :
- case 0x421a :
- case 0x421b :
- case 0x421c :
- case 0x421d :
- case 0x421e :
- case 0x421f :
- // Joypads 1-4 button and direction state.
- return (Memory.FillRAM[Address]);
-
- case 0x4300 :
- case 0x4310 :
- case 0x4320 :
- case 0x4330 :
- case 0x4340 :
- case 0x4350 :
- case 0x4360 :
- case 0x4370 :
- // DMA direction, address type, fixed flag,
- return (Memory.FillRAM[Address]);
-
- case 0x4301 :
- case 0x4311 :
- case 0x4321 :
- case 0x4331 :
- case 0x4341 :
- case 0x4351 :
- case 0x4361 :
- case 0x4371 :
- return (Memory.FillRAM[Address]);
-
- case 0x4302 :
- case 0x4312 :
- case 0x4322 :
- case 0x4332 :
- case 0x4342 :
- case 0x4352 :
- case 0x4362 :
- case 0x4372 :
- return (Memory.FillRAM[Address]);
-
- case 0x4303 :
- case 0x4313 :
- case 0x4323 :
- case 0x4333 :
- case 0x4343 :
- case 0x4353 :
- case 0x4363 :
- case 0x4373 :
- return (Memory.FillRAM[Address]);
-
- case 0x4304 :
- case 0x4314 :
- case 0x4324 :
- case 0x4334 :
- case 0x4344 :
- case 0x4354 :
- case 0x4364 :
- case 0x4374 :
- return (Memory.FillRAM[Address]);
-
- case 0x4305 :
- case 0x4315 :
- case 0x4325 :
- case 0x4335 :
- case 0x4345 :
- case 0x4355 :
- case 0x4365 :
- case 0x4375 :
- return (Memory.FillRAM[Address]);
-
- case 0x4306 :
- case 0x4316 :
- case 0x4326 :
- case 0x4336 :
- case 0x4346 :
- case 0x4356 :
- case 0x4366 :
- case 0x4376 :
- return (Memory.FillRAM[Address]);
-
- case 0x4307 :
- case 0x4317 :
- case 0x4327 :
- case 0x4337 :
- case 0x4347 :
- case 0x4357 :
- case 0x4367 :
- case 0x4377 :
- return (DMA[(Address >> 4) & 7].IndirectBank);
-
- case 0x4308 :
- case 0x4318 :
- case 0x4328 :
- case 0x4338 :
- case 0x4348 :
- case 0x4358 :
- case 0x4368 :
- case 0x4378 :
- return (Memory.FillRAM[Address]);
-
- case 0x4309 :
- case 0x4319 :
- case 0x4329 :
- case 0x4339 :
- case 0x4349 :
- case 0x4359 :
- case 0x4369 :
- case 0x4379 :
- return (Memory.FillRAM[Address]);
-
- case 0x430A :
- case 0x431A :
- case 0x432A :
- case 0x433A :
- case 0x434A :
- case 0x435A :
- case 0x436A :
- case 0x437A :
- {
- int d = (Address & 0x70) >> 4;
- if (IPPU.HDMA & (1 << d))
- {
- return (DMA[d].LineCount);
- }
- return (Memory.FillRAM[Address]);
- }
- case 0x430F:
- case 0x431F:
- case 0x432F:
- case 0x433F:
- case 0x434F:
- case 0x435F:
- case 0x436F:
- case 0x437F:
- Address &= ~4; // Convert 43xF to 43xB
- /* fall through */
- case 0x430B:
- case 0x431B:
- case 0x432B:
- case 0x433B:
- case 0x434B:
- case 0x435B:
- case 0x436B:
- case 0x437B:
-
- // Unknown, but they seem to be RAM-ish
- return (Memory.FillRAM[Address]);
- default :
+ return (REGISTER_4212());
+ case 0x4213 :
+ // I/O port input
+ case 0x4214 :
+ case 0x4215 :
+ // Quotient of divide result
+ case 0x4216 :
+ case 0x4217 :
+ // Multiplcation result (for multiply) or remainder of
+ // divison.
+ return (Memory.FillRAM[Address]);
+ case 0x4218 :
+ case 0x4219 :
+ case 0x421a :
+ case 0x421b :
+ case 0x421c :
+ case 0x421d :
+ case 0x421e :
+ case 0x421f :
+ // Joypads 1-4 button and direction state.
+ return (Memory.FillRAM[Address]);
+
+ case 0x4300 :
+ case 0x4310 :
+ case 0x4320 :
+ case 0x4330 :
+ case 0x4340 :
+ case 0x4350 :
+ case 0x4360 :
+ case 0x4370 :
+ // DMA direction, address type, fixed flag,
+ return (Memory.FillRAM[Address]);
+
+ case 0x4301 :
+ case 0x4311 :
+ case 0x4321 :
+ case 0x4331 :
+ case 0x4341 :
+ case 0x4351 :
+ case 0x4361 :
+ case 0x4371 :
+ return (Memory.FillRAM[Address]);
+
+ case 0x4302 :
+ case 0x4312 :
+ case 0x4322 :
+ case 0x4332 :
+ case 0x4342 :
+ case 0x4352 :
+ case 0x4362 :
+ case 0x4372 :
+ return (Memory.FillRAM[Address]);
+
+ case 0x4303 :
+ case 0x4313 :
+ case 0x4323 :
+ case 0x4333 :
+ case 0x4343 :
+ case 0x4353 :
+ case 0x4363 :
+ case 0x4373 :
+ return (Memory.FillRAM[Address]);
+
+ case 0x4304 :
+ case 0x4314 :
+ case 0x4324 :
+ case 0x4334 :
+ case 0x4344 :
+ case 0x4354 :
+ case 0x4364 :
+ case 0x4374 :
+ return (Memory.FillRAM[Address]);
+
+ case 0x4305 :
+ case 0x4315 :
+ case 0x4325 :
+ case 0x4335 :
+ case 0x4345 :
+ case 0x4355 :
+ case 0x4365 :
+ case 0x4375 :
+ return (Memory.FillRAM[Address]);
+
+ case 0x4306 :
+ case 0x4316 :
+ case 0x4326 :
+ case 0x4336 :
+ case 0x4346 :
+ case 0x4356 :
+ case 0x4366 :
+ case 0x4376 :
+ return (Memory.FillRAM[Address]);
+
+ case 0x4307 :
+ case 0x4317 :
+ case 0x4327 :
+ case 0x4337 :
+ case 0x4347 :
+ case 0x4357 :
+ case 0x4367 :
+ case 0x4377 :
+ return (DMA[(Address >> 4) & 7].IndirectBank);
+
+ case 0x4308 :
+ case 0x4318 :
+ case 0x4328 :
+ case 0x4338 :
+ case 0x4348 :
+ case 0x4358 :
+ case 0x4368 :
+ case 0x4378 :
+ return (Memory.FillRAM[Address]);
+
+ case 0x4309 :
+ case 0x4319 :
+ case 0x4329 :
+ case 0x4339 :
+ case 0x4349 :
+ case 0x4359 :
+ case 0x4369 :
+ case 0x4379 :
+ return (Memory.FillRAM[Address]);
+
+ case 0x430A :
+ case 0x431A :
+ case 0x432A :
+ case 0x433A :
+ case 0x434A :
+ case 0x435A :
+ case 0x436A :
+ case 0x437A :
+ {
+ int d = (Address & 0x70) >> 4;
+ if (IPPU.HDMA & (1 << d))
+ return (DMA[d].LineCount);
+ return (Memory.FillRAM[Address]);
+ }
+ case 0x430F:
+ case 0x431F:
+ case 0x432F:
+ case 0x433F:
+ case 0x434F:
+ case 0x435F:
+ case 0x436F:
+ case 0x437F:
+ Address &= ~4; // Convert 43xF to 43xB
+ /* fall through */
+ case 0x430B:
+ case 0x431B:
+ case 0x432B:
+ case 0x433B:
+ case 0x434B:
+ case 0x435B:
+ case 0x436B:
+ case 0x437B:
+
+ // Unknown, but they seem to be RAM-ish
+ return (Memory.FillRAM[Address]);
+ default :
#ifdef DEBUGGER
- missing.unknowncpu_read = Address;
- if (Settings.TraceUnknownRegisters)
- {
- sprintf(String, "Unknown register read: $%04X\n", Address);
- S9xMessage(S9X_TRACE, S9X_PPU_TRACE, String);
- }
+ missing.unknowncpu_read = Address;
+ if (Settings.TraceUnknownRegisters)
+ {
+ sprintf(String, "Unknown register read: $%04X\n", Address);
+ S9xMessage(S9X_TRACE, S9X_PPU_TRACE, String);
+ }
#endif
- break;
- }
- return (Memory.FillRAM[Address]);
+ break;
+ }
+ return (Memory.FillRAM[Address]);
}
void S9xResetPPU()
{
- PPU.BGMode = 0;
- PPU.BG3Priority = 0;
- PPU.Brightness = 0;
- PPU.VMA.High = 0;
- PPU.VMA.Increment = 1;
- PPU.VMA.Address = 0;
- PPU.VMA.FullGraphicCount = 0;
- PPU.VMA.Shift = 0;
+ PPU.BGMode = 0;
+ PPU.BG3Priority = 0;
+ PPU.Brightness = 0;
+ PPU.VMA.High = 0;
+ PPU.VMA.Increment = 1;
+ PPU.VMA.Address = 0;
+ PPU.VMA.FullGraphicCount = 0;
+ PPU.VMA.Shift = 0;
uint8 B;
- for (B = 0; B != 4; B++)
- {
- PPU.BG[B].SCBase = 0;
- PPU.BG[B].VOffset = 0;
- PPU.BG[B].HOffset = 0;
- PPU.BG[B].BGSize = 0;
- PPU.BG[B].NameBase = 0;
- PPU.BG[B].SCSize = 0;
-
- PPU.ClipCounts[B] = 0;
- PPU.ClipWindowOverlapLogic[B] = CLIP_OR;
- PPU.ClipWindow1Enable[B] = FALSE;
- PPU.ClipWindow2Enable[B] = FALSE;
- PPU.ClipWindow1Inside[B] = TRUE;
- PPU.ClipWindow2Inside[B] = TRUE;
- }
-
- PPU.ClipCounts[4] = 0;
- PPU.ClipCounts[5] = 0;
- PPU.ClipWindowOverlapLogic[4] = PPU.ClipWindowOverlapLogic[5] = CLIP_OR;
- PPU.ClipWindow1Enable[4] = PPU.ClipWindow1Enable[5] = FALSE;
- PPU.ClipWindow2Enable[4] = PPU.ClipWindow2Enable[5] = FALSE;
- PPU.ClipWindow1Inside[4] = PPU.ClipWindow1Inside[5] = TRUE;
- PPU.ClipWindow2Inside[4] = PPU.ClipWindow2Inside[5] = TRUE;
-
- PPU.CGFLIP = 0;
- unsigned int c;
- for (c = 0; c < 256; c++)
- {
- IPPU.Red[c] = (c & 7) << 2;
- IPPU.Green[c] = ((c >> 3) & 7) << 2;
- IPPU.Blue[c] = ((c >> 6) & 2) << 3;
- PPU.CGDATA[c] =
- IPPU.Red[c] | (IPPU.Green[c] << 5) | (IPPU.Blue[c] << 10);
- }
-
- PPU.FirstSprite = 0;
- PPU.LastSprite = 127;
+ for (B = 0; B != 4; B++)
+ {
+ PPU.BG[B].SCBase = 0;
+ PPU.BG[B].VOffset = 0;
+ PPU.BG[B].HOffset = 0;
+ PPU.BG[B].BGSize = 0;
+ PPU.BG[B].NameBase = 0;
+ PPU.BG[B].SCSize = 0;
+
+ PPU.ClipCounts[B] = 0;
+ PPU.ClipWindowOverlapLogic[B] = CLIP_OR;
+ PPU.ClipWindow1Enable[B] = FALSE;
+ PPU.ClipWindow2Enable[B] = FALSE;
+ PPU.ClipWindow1Inside[B] = TRUE;
+ PPU.ClipWindow2Inside[B] = TRUE;
+ }
+
+ PPU.ClipCounts[4] = 0;
+ PPU.ClipCounts[5] = 0;
+ PPU.ClipWindowOverlapLogic[4] = PPU.ClipWindowOverlapLogic[5] = CLIP_OR;
+ PPU.ClipWindow1Enable[4] = PPU.ClipWindow1Enable[5] = FALSE;
+ PPU.ClipWindow2Enable[4] = PPU.ClipWindow2Enable[5] = FALSE;
+ PPU.ClipWindow1Inside[4] = PPU.ClipWindow1Inside[5] = TRUE;
+ PPU.ClipWindow2Inside[4] = PPU.ClipWindow2Inside[5] = TRUE;
+
+ PPU.CGFLIP = 0;
+ unsigned int c;
+ for (c = 0; c < 256; c++)
+ {
+ IPPU.Red[c] = (c & 7) << 2;
+ IPPU.Green[c] = ((c >> 3) & 7) << 2;
+ IPPU.Blue[c] = ((c >> 6) & 2) << 3;
+ PPU.CGDATA[c] =
+ IPPU.Red[c] | (IPPU.Green[c] << 5) | (IPPU.Blue[c] << 10);
+ }
+
+ PPU.FirstSprite = 0;
+ PPU.LastSprite = 127;
int Sprite;
- for (Sprite = 0; Sprite < 128; Sprite++)
- {
- PPU.OBJ[Sprite].HPos = 0;
- PPU.OBJ[Sprite].VPos = 0;
- PPU.OBJ[Sprite].VFlip = 0;
- PPU.OBJ[Sprite].HFlip = 0;
- PPU.OBJ[Sprite].Priority = 0;
- PPU.OBJ[Sprite].Palette = 0;
- PPU.OBJ[Sprite].Name = 0;
- PPU.OBJ[Sprite].Size = 0;
- }
- PPU.OAMPriorityRotation = 0;
- PPU.OAMWriteRegister = 0;
-
- PPU.OAMFlip = 0;
- PPU.OAMTileAddress = 0;
- PPU.OAMAddr = 0;
- PPU.IRQVBeamPos = 0;
- PPU.IRQHBeamPos = 0;
- PPU.VBeamPosLatched = 0;
- PPU.HBeamPosLatched = 0;
-
- PPU.HBeamFlip = 0;
- PPU.VBeamFlip = 0;
- PPU.HVBeamCounterLatched = 0;
-
- PPU.MatrixA = PPU.MatrixB = PPU.MatrixC = PPU.MatrixD = 0;
- PPU.CentreX = PPU.CentreY = 0;
- PPU.Joypad1ButtonReadPos = 0;
- PPU.Joypad2ButtonReadPos = 0;
- PPU.Joypad3ButtonReadPos = 0;
-
- PPU.CGADD = 0;
- PPU.FixedColourRed = PPU.FixedColourGreen = PPU.FixedColourBlue = 0;
- PPU.SavedOAMAddr = 0;
- PPU.SavedOAMAddr2 = 0;
- PPU.ScreenHeight = SNES_HEIGHT;
- PPU.WRAM = 0;
- PPU.BG_Forced = 0;
- PPU.ForcedBlanking = TRUE;
- PPU.OBJThroughMain = FALSE;
- PPU.OBJThroughSub = FALSE;
- PPU.OBJSizeSelect = 0;
- PPU.OBJNameSelect = 0;
- PPU.OBJNameBase = 0;
- PPU.OBJAddition = FALSE;
- PPU.OAMReadFlip = 0;
- PPU.BGnxOFSbyte = 0;
- ZeroMemory(PPU.OAMData, 512 + 32);
-
- PPU.VTimerEnabled = FALSE;
- PPU.HTimerEnabled = FALSE;
- PPU.HTimerPosition = Settings.H_Max + 1;
- PPU.Mosaic = 0;
- PPU.BGMosaic[0] = PPU.BGMosaic[1] = FALSE;
- PPU.BGMosaic[2] = PPU.BGMosaic[3] = FALSE;
- PPU.Mode7HFlip = FALSE;
- PPU.Mode7VFlip = FALSE;
- PPU.Mode7Repeat = 0;
- PPU.Window1Left = 1;
- PPU.Window1Right = 0;
- PPU.Window2Left = 1;
- PPU.Window2Right = 0;
- PPU.RecomputeClipWindows = TRUE;
- PPU.CGFLIPRead = 0;
- PPU.Need16x8Mulitply = FALSE;
- PPU.MouseSpeed[0] = PPU.MouseSpeed[1] = 0;
-
- IPPU.ColorsChanged = TRUE;
- IPPU.HDMA = 0;
- IPPU.HDMAStarted = FALSE;
- IPPU.MaxBrightness = 0;
- IPPU.LatchedBlanking = 0;
- IPPU.OBJChanged = TRUE;
- IPPU.RenderThisFrame = TRUE;
- IPPU.DirectColourMapsNeedRebuild = TRUE;
- IPPU.FrameCount = 0;
- IPPU.RenderedFramesCount = 0;
- IPPU.DisplayedRenderedFrameCount = 0;
- IPPU.SkippedFrames = 0;
- IPPU.FrameSkip = 0;
- ZeroMemory(IPPU.TileCached[TILE_2BIT], MAX_2BIT_TILES);
- ZeroMemory(IPPU.TileCached[TILE_4BIT], MAX_4BIT_TILES);
- ZeroMemory(IPPU.TileCached[TILE_8BIT], MAX_8BIT_TILES);
- IPPU.FirstVRAMRead = FALSE;
- IPPU.LatchedInterlace = FALSE;
- IPPU.DoubleWidthPixels = FALSE;
- IPPU.RenderedScreenWidth = SNES_WIDTH;
- IPPU.RenderedScreenHeight = SNES_HEIGHT;
- IPPU.XB = NULL;
- for (c = 0; c < 256; c++)
- IPPU.ScreenColors[c] = c;
- S9xFixColourBrightness();
- IPPU.PreviousLine = IPPU.CurrentLine = 0;
- IPPU.Joypads[0] = IPPU.Joypads[1] = IPPU.Joypads[2] = 0;
- IPPU.Joypads[3] = IPPU.Joypads[4] = 0;
- IPPU.SuperScope = 0;
- IPPU.Mouse[0] = IPPU.Mouse[1] = 0;
- IPPU.PrevMouseX[0] = IPPU.PrevMouseX[1] = 256 / 2;
- IPPU.PrevMouseY[0] = IPPU.PrevMouseY[1] = 224 / 2;
-
- if (Settings.ControllerOption == 0)
- IPPU.Controller = SNES_MAX_CONTROLLER_OPTIONS - 1;
- else
- IPPU.Controller = Settings.ControllerOption - 1;
- S9xNextController();
-
- for (c = 0; c < 2; c++)
- memset(& IPPU.Clip[c], 0, sizeof(ClipData));
-
- if (Settings.MouseMaster)
- {
- S9xProcessMouse(0);
- S9xProcessMouse(1);
- }
- for (c = 0; c < 0x8000; c += 0x100)
- memset(& Memory.FillRAM[c], c >> 8, 0x100);
-
- ZeroMemory(& Memory.FillRAM[0x2100], 0x100);
- ZeroMemory(& Memory.FillRAM[0x4200], 0x100);
- ZeroMemory(& Memory.FillRAM[0x4000], 0x100);
- // For BS Suttehakkun 2...
- ZeroMemory(& Memory.FillRAM[0x1000], 0x1000);
- Memory.FillRAM[0x4201]=Memory.FillRAM[0x4213]=0xFF;
-
- PPU.BG[0].OffsetsChanged = 0;
- PPU.BG[1].OffsetsChanged = 0;
- PPU.BG[2].OffsetsChanged = 0;
- PPU.BG[3].OffsetsChanged = 0;
- ROpCount = 0;
- ZeroMemory(&rops, MAX_ROPS);
- GFX.r212c_s = 0;
- GFX.r212d_s = 0;
- GFX.r212e_s = 0;
- GFX.r212f_s = 0;
- GFX.r2130_s = 0;
- GFX.r2131_s = 0;
+ for (Sprite = 0; Sprite < 128; Sprite++)
+ {
+ PPU.OBJ[Sprite].HPos = 0;
+ PPU.OBJ[Sprite].VPos = 0;
+ PPU.OBJ[Sprite].VFlip = 0;
+ PPU.OBJ[Sprite].HFlip = 0;
+ PPU.OBJ[Sprite].Priority = 0;
+ PPU.OBJ[Sprite].Palette = 0;
+ PPU.OBJ[Sprite].Name = 0;
+ PPU.OBJ[Sprite].Size = 0;
+ }
+ PPU.OAMPriorityRotation = 0;
+ PPU.OAMWriteRegister = 0;
+
+ PPU.OAMFlip = 0;
+ PPU.OAMTileAddress = 0;
+ PPU.OAMAddr = 0;
+ PPU.IRQVBeamPos = 0;
+ PPU.IRQHBeamPos = 0;
+ PPU.VBeamPosLatched = 0;
+ PPU.HBeamPosLatched = 0;
+
+ PPU.HBeamFlip = 0;
+ PPU.VBeamFlip = 0;
+ PPU.HVBeamCounterLatched = 0;
+
+ PPU.MatrixA = PPU.MatrixB = PPU.MatrixC = PPU.MatrixD = 0;
+ PPU.CentreX = PPU.CentreY = 0;
+ PPU.Joypad1ButtonReadPos = 0;
+ PPU.Joypad2ButtonReadPos = 0;
+ PPU.Joypad3ButtonReadPos = 0;
+
+ PPU.CGADD = 0;
+ PPU.FixedColourRed = PPU.FixedColourGreen = PPU.FixedColourBlue = 0;
+ PPU.SavedOAMAddr = 0;
+ PPU.SavedOAMAddr2 = 0;
+ PPU.ScreenHeight = SNES_HEIGHT;
+ PPU.WRAM = 0;
+ PPU.BG_Forced = 0;
+ PPU.ForcedBlanking = TRUE;
+ PPU.OBJThroughMain = FALSE;
+ PPU.OBJThroughSub = FALSE;
+ PPU.OBJSizeSelect = 0;
+ PPU.OBJNameSelect = 0;
+ PPU.OBJNameBase = 0;
+ PPU.OBJAddition = FALSE;
+ PPU.OAMReadFlip = 0;
+ PPU.BGnxOFSbyte = 0;
+ ZeroMemory(PPU.OAMData, 512 + 32);
+
+ PPU.VTimerEnabled = FALSE;
+ PPU.HTimerEnabled = FALSE;
+ PPU.HTimerPosition = Settings.H_Max + 1;
+ PPU.Mosaic = 0;
+ PPU.BGMosaic[0] = PPU.BGMosaic[1] = FALSE;
+ PPU.BGMosaic[2] = PPU.BGMosaic[3] = FALSE;
+ PPU.Mode7HFlip = FALSE;
+ PPU.Mode7VFlip = FALSE;
+ PPU.Mode7Repeat = 0;
+ PPU.Window1Left = 1;
+ PPU.Window1Right = 0;
+ PPU.Window2Left = 1;
+ PPU.Window2Right = 0;
+ PPU.RecomputeClipWindows = TRUE;
+ PPU.CGFLIPRead = 0;
+ PPU.Need16x8Mulitply = FALSE;
+ PPU.MouseSpeed[0] = PPU.MouseSpeed[1] = 0;
+
+ IPPU.ColorsChanged = TRUE;
+ IPPU.HDMA = 0;
+ IPPU.HDMAStarted = FALSE;
+ IPPU.MaxBrightness = 0;
+ IPPU.LatchedBlanking = 0;
+ IPPU.OBJChanged = TRUE;
+ IPPU.RenderThisFrame = TRUE;
+ IPPU.DirectColourMapsNeedRebuild = TRUE;
+ IPPU.FrameCount = 0;
+ IPPU.RenderedFramesCount = 0;
+ IPPU.DisplayedRenderedFrameCount = 0;
+ IPPU.SkippedFrames = 0;
+ IPPU.FrameSkip = 0;
+ ZeroMemory(IPPU.TileCached[TILE_2BIT], MAX_2BIT_TILES);
+ ZeroMemory(IPPU.TileCached[TILE_4BIT], MAX_4BIT_TILES);
+ ZeroMemory(IPPU.TileCached[TILE_8BIT], MAX_8BIT_TILES);
+ IPPU.FirstVRAMRead = FALSE;
+ IPPU.LatchedInterlace = FALSE;
+ IPPU.DoubleWidthPixels = FALSE;
+ IPPU.RenderedScreenWidth = SNES_WIDTH;
+ IPPU.RenderedScreenHeight = SNES_HEIGHT;
+ IPPU.XB = NULL;
+ for (c = 0; c < 256; c++)
+ IPPU.ScreenColors[c] = c;
+ S9xFixColourBrightness();
+ IPPU.PreviousLine = IPPU.CurrentLine = 0;
+ IPPU.Joypads[0] = IPPU.Joypads[1] = IPPU.Joypads[2] = 0;
+ IPPU.Joypads[3] = IPPU.Joypads[4] = 0;
+ IPPU.SuperScope = 0;
+ IPPU.Mouse[0] = IPPU.Mouse[1] = 0;
+ IPPU.PrevMouseX[0] = IPPU.PrevMouseX[1] = 256 / 2;
+ IPPU.PrevMouseY[0] = IPPU.PrevMouseY[1] = 224 / 2;
+
+ if (Settings.ControllerOption == 0)
+ IPPU.Controller = SNES_MAX_CONTROLLER_OPTIONS - 1;
+ else
+ IPPU.Controller = Settings.ControllerOption - 1;
+ S9xNextController();
+
+ for (c = 0; c < 2; c++)
+ memset(& IPPU.Clip[c], 0, sizeof(ClipData));
+
+ if (Settings.MouseMaster)
+ {
+ S9xProcessMouse(0);
+ S9xProcessMouse(1);
+ }
+ for (c = 0; c < 0x8000; c += 0x100)
+ memset(& Memory.FillRAM[c], c >> 8, 0x100);
+
+ ZeroMemory(& Memory.FillRAM[0x2100], 0x100);
+ ZeroMemory(& Memory.FillRAM[0x4200], 0x100);
+ ZeroMemory(& Memory.FillRAM[0x4000], 0x100);
+ // For BS Suttehakkun 2...
+ ZeroMemory(& Memory.FillRAM[0x1000], 0x1000);
+ Memory.FillRAM[0x4201] = Memory.FillRAM[0x4213] = 0xFF;
+
+ PPU.BG[0].OffsetsChanged = 0;
+ PPU.BG[1].OffsetsChanged = 0;
+ PPU.BG[2].OffsetsChanged = 0;
+ PPU.BG[3].OffsetsChanged = 0;
+ ROpCount = 0;
+ ZeroMemory(&rops, MAX_ROPS);
+ GFX.r212c_s = 0;
+ GFX.r212d_s = 0;
+ GFX.r212e_s = 0;
+ GFX.r212f_s = 0;
+ GFX.r2130_s = 0;
+ GFX.r2131_s = 0;
}
void S9xProcessMouse(int which1)
{
- int x, y;
- uint32 buttons;
-
- if ((IPPU.Controller == SNES_MOUSE
- || IPPU.Controller == SNES_MOUSE_SWAPPED)
- && S9xReadMousePosition(which1, &x, &y, &buttons))
- {
- int delta_x, delta_y;
+ int x, y;
+ uint32 buttons;
+
+ if ((IPPU.Controller == SNES_MOUSE
+ || IPPU.Controller == SNES_MOUSE_SWAPPED)
+ && S9xReadMousePosition(which1, &x, &y, &buttons))
+ {
+ int delta_x, delta_y;
#define MOUSE_SIGNATURE 0x1
- IPPU.Mouse[which1] =
- MOUSE_SIGNATURE
- | (PPU.MouseSpeed[which1] << 4)
- | ((buttons & 1) << 6)
- | ((buttons & 2) << 6);
-
- delta_x = x - IPPU.PrevMouseX[which1];
- delta_y = y - IPPU.PrevMouseY[which1];
-
- if (delta_x > 63)
- {
- delta_x = 63;
- IPPU.PrevMouseX[which1] += 63;
- }
- else if (delta_x < -63)
- {
- delta_x = -63;
- IPPU.PrevMouseX[which1] -= 63;
- }
- else
- IPPU.PrevMouseX[which1] = x;
-
- if (delta_y > 63)
- {
- delta_y = 63;
- IPPU.PrevMouseY[which1] += 63;
- }
- else if (delta_y < -63)
- {
- delta_y = -63;
- IPPU.PrevMouseY[which1] -= 63;
- }
- else
- IPPU.PrevMouseY[which1] = y;
-
- if (delta_x < 0)
- {
- delta_x = -delta_x;
- IPPU.Mouse[which1] |= (delta_x | 0x80) << 16;
- }
- else
- IPPU.Mouse[which1] |= delta_x << 16;
-
- if (delta_y < 0)
- {
- delta_y = -delta_y;
- IPPU.Mouse[which1] |= (delta_y | 0x80) << 24;
- }
- else
- IPPU.Mouse[which1] |= delta_y << 24;
-
- if (IPPU.Controller == SNES_MOUSE_SWAPPED)
- IPPU.Joypads[0] = IPPU.Mouse[which1];
- else
- IPPU.Joypads[1] = IPPU.Mouse[which1];
- }
+ IPPU.Mouse[which1] =
+ MOUSE_SIGNATURE
+ | (PPU.MouseSpeed[which1] << 4)
+ | ((buttons & 1) << 6)
+ | ((buttons & 2) << 6);
+
+ delta_x = x - IPPU.PrevMouseX[which1];
+ delta_y = y - IPPU.PrevMouseY[which1];
+
+ if (delta_x > 63)
+ {
+ delta_x = 63;
+ IPPU.PrevMouseX[which1] += 63;
+ }
+ else if (delta_x < -63)
+ {
+ delta_x = -63;
+ IPPU.PrevMouseX[which1] -= 63;
+ }
+ else
+ IPPU.PrevMouseX[which1] = x;
+
+ if (delta_y > 63)
+ {
+ delta_y = 63;
+ IPPU.PrevMouseY[which1] += 63;
+ }
+ else if (delta_y < -63)
+ {
+ delta_y = -63;
+ IPPU.PrevMouseY[which1] -= 63;
+ }
+ else
+ IPPU.PrevMouseY[which1] = y;
+
+ if (delta_x < 0)
+ {
+ delta_x = -delta_x;
+ IPPU.Mouse[which1] |= (delta_x | 0x80) << 16;
+ }
+ else
+ IPPU.Mouse[which1] |= delta_x << 16;
+
+ if (delta_y < 0)
+ {
+ delta_y = -delta_y;
+ IPPU.Mouse[which1] |= (delta_y | 0x80) << 24;
+ }
+ else
+ IPPU.Mouse[which1] |= delta_y << 24;
+
+ if (IPPU.Controller == SNES_MOUSE_SWAPPED)
+ IPPU.Joypads[0] = IPPU.Mouse[which1];
+ else
+ IPPU.Joypads[1] = IPPU.Mouse[which1];
+ }
}
void ProcessSuperScope()
{
- int x, y;
- uint32 buttons;
+ int x, y;
+ uint32 buttons;
- if (IPPU.Controller == SNES_SUPERSCOPE
- && S9xReadSuperScopePosition(&x, &y, &buttons))
- {
+ if (IPPU.Controller == SNES_SUPERSCOPE
+ && S9xReadSuperScopePosition(&x, &y, &buttons))
+ {
#define SUPERSCOPE_SIGNATURE 0x00ff
- uint32 scope;
-
- scope =
- SUPERSCOPE_SIGNATURE
- | ((buttons & 1) << (7 + 8))
- | ((buttons & 2) << (5 + 8))
- | ((buttons & 4) << (3 + 8))
- | ((buttons & 8) << (1 + 8));
- if (x > 255)
- x = 255;
- if (x < 0)
- x = 0;
- if (y > PPU.ScreenHeight - 1)
- y = PPU.ScreenHeight - 1;
- if (y < 0)
- y = 0;
-
- PPU.VBeamPosLatched = (uint16) (y + 1);
- PPU.HBeamPosLatched = (uint16) x;
- PPU.HVBeamCounterLatched = TRUE;
- Memory.FillRAM[0x213F] |= 0x40;
- IPPU.Joypads[1] = scope;
- }
+ uint32 scope;
+
+ scope =
+ SUPERSCOPE_SIGNATURE
+ | ((buttons & 1) << (7 + 8))
+ | ((buttons & 2) << (5 + 8))
+ | ((buttons & 4) << (3 + 8))
+ | ((buttons & 8) << (1 + 8));
+ if (x > 255)
+ x = 255;
+ if (x < 0)
+ x = 0;
+ if (y > PPU.ScreenHeight - 1)
+ y = PPU.ScreenHeight - 1;
+ if (y < 0)
+ y = 0;
+
+ PPU.VBeamPosLatched = (uint16)(y + 1);
+ PPU.HBeamPosLatched = (uint16) x;
+ PPU.HVBeamCounterLatched = TRUE;
+ Memory.FillRAM[0x213F] |= 0x40;
+ IPPU.Joypads[1] = scope;
+ }
}
void S9xNextController()
{
- switch (IPPU.Controller)
- {
- case SNES_MULTIPLAYER5 :
- IPPU.Controller = SNES_JOYPAD;
- break;
- case SNES_JOYPAD :
- if (Settings.MouseMaster)
- {
- IPPU.Controller = SNES_MOUSE_SWAPPED;
- break;
- }
- case SNES_MOUSE_SWAPPED :
- if (Settings.MouseMaster)
- {
- IPPU.Controller = SNES_MOUSE;
- break;
- }
- case SNES_MOUSE :
- if (Settings.SuperScopeMaster)
- {
- IPPU.Controller = SNES_SUPERSCOPE;
- break;
- }
- case SNES_SUPERSCOPE :
- if (Settings.MultiPlayer5Master)
- {
- IPPU.Controller = SNES_MULTIPLAYER5;
- break;
- }
- default :
- IPPU.Controller = SNES_JOYPAD;
- break;
- }
+ switch (IPPU.Controller)
+ {
+ case SNES_MULTIPLAYER5 :
+ IPPU.Controller = SNES_JOYPAD;
+ break;
+ case SNES_JOYPAD :
+ if (Settings.MouseMaster)
+ {
+ IPPU.Controller = SNES_MOUSE_SWAPPED;
+ break;
+ }
+ case SNES_MOUSE_SWAPPED :
+ if (Settings.MouseMaster)
+ {
+ IPPU.Controller = SNES_MOUSE;
+ break;
+ }
+ case SNES_MOUSE :
+ if (Settings.SuperScopeMaster)
+ {
+ IPPU.Controller = SNES_SUPERSCOPE;
+ break;
+ }
+ case SNES_SUPERSCOPE :
+ if (Settings.MultiPlayer5Master)
+ {
+ IPPU.Controller = SNES_MULTIPLAYER5;
+ break;
+ }
+ default :
+ IPPU.Controller = SNES_JOYPAD;
+ break;
+ }
}
void S9xUpdateJoypads()
{
#if defined (__WIZ__)
- IPPU.Joypads[0] = S9xReadJoypad (0);
-
- if (IPPU.Joypads[0] & SNES_LEFT_MASK)
- IPPU.Joypads[0] &= ~SNES_RIGHT_MASK;
- if (IPPU.Joypads[0] & SNES_UP_MASK)
- IPPU.Joypads[0] &= ~SNES_DOWN_MASK;
-
- if (Memory.FillRAM [0x4200] & 1)
- {
- PPU.Joypad1ButtonReadPos = 16;
-
- Memory.FillRAM [0x4218] = (uint8) IPPU.Joypads[0];
- Memory.FillRAM [0x4219] = (uint8) (IPPU.Joypads[0] >> 8);
- if (Memory.FillRAM [0x4201] & 0x80)
- {
- Memory.FillRAM [0x421c] = (uint8) IPPU.Joypads[0];
- Memory.FillRAM [0x421d] = (uint8) (IPPU.Joypads[0] >> 8);
- }
- }
+ IPPU.Joypads[0] = S9xReadJoypad(0);
+
+ if (IPPU.Joypads[0] & SNES_LEFT_MASK)
+ IPPU.Joypads[0] &= ~SNES_RIGHT_MASK;
+ if (IPPU.Joypads[0] & SNES_UP_MASK)
+ IPPU.Joypads[0] &= ~SNES_DOWN_MASK;
+
+ if (Memory.FillRAM [0x4200] & 1)
+ {
+ PPU.Joypad1ButtonReadPos = 16;
+
+ Memory.FillRAM [0x4218] = (uint8) IPPU.Joypads[0];
+ Memory.FillRAM [0x4219] = (uint8)(IPPU.Joypads[0] >> 8);
+ if (Memory.FillRAM [0x4201] & 0x80)
+ {
+ Memory.FillRAM [0x421c] = (uint8) IPPU.Joypads[0];
+ Memory.FillRAM [0x421d] = (uint8)(IPPU.Joypads[0] >> 8);
+ }
+ }
#else
- int i;
-
- for (i = 0; i < 5; i++)
- {
- IPPU.Joypads[i] = S9xReadJoypad(i);
- if (IPPU.Joypads[i] & SNES_LEFT_MASK)
- IPPU.Joypads[i] &= ~SNES_RIGHT_MASK;
- if (IPPU.Joypads[i] & SNES_UP_MASK)
- IPPU.Joypads[i] &= ~SNES_DOWN_MASK;
- }
-
- if (IPPU.Controller == SNES_JOYPAD
- || IPPU.Controller == SNES_MULTIPLAYER5)
- {
- for (i = 0; i < 5; i++)
- {
- if (IPPU.Joypads[i])
- IPPU.Joypads[i] |= 0xffff0000;
- }
- }
-
- // Read mouse position if enabled
- if (Settings.MouseMaster)
- {
- for (i = 0; i < 2; i++)
- S9xProcessMouse(i);
- }
-
- // Read SuperScope if enabled
- if (Settings.SuperScopeMaster)
- ProcessSuperScope();
-
- if (Memory.FillRAM[0x4200] & 1)
- {
- PPU.Joypad1ButtonReadPos = 16;
- if (Memory.FillRAM[0x4201] & 0x80)
- {
- PPU.Joypad2ButtonReadPos = 16;
- PPU.Joypad3ButtonReadPos = 0;
- }
- else
- {
- PPU.Joypad2ButtonReadPos = 0;
- PPU.Joypad3ButtonReadPos = 16;
- }
-
- Memory.FillRAM[0x4218] = (uint8) IPPU.Joypads[0];
- Memory.FillRAM[0x4219] = (uint8) (IPPU.Joypads[0] >> 8);
- Memory.FillRAM[0x421a] = (uint8) IPPU.Joypads[1];
- Memory.FillRAM[0x421b] = (uint8) (IPPU.Joypads[1] >> 8);
- if (Memory.FillRAM[0x4201] & 0x80)
- {
- Memory.FillRAM[0x421c] = (uint8) IPPU.Joypads[0];
- Memory.FillRAM[0x421d] = (uint8) (IPPU.Joypads[0] >> 8);
- Memory.FillRAM[0x421e] = (uint8) IPPU.Joypads[2];
- Memory.FillRAM[0x421f] = (uint8) (IPPU.Joypads[2] >> 8);
- }
- else
- {
- Memory.FillRAM[0x421c] = (uint8) IPPU.Joypads[3];
- Memory.FillRAM[0x421d] = (uint8) (IPPU.Joypads[3] >> 8);
- Memory.FillRAM[0x421e] = (uint8) IPPU.Joypads[4];
- Memory.FillRAM[0x421f] = (uint8) (IPPU.Joypads[4] >> 8);
- }
- }
+ int i;
+
+ for (i = 0; i < 5; i++)
+ {
+ IPPU.Joypads[i] = S9xReadJoypad(i);
+ if (IPPU.Joypads[i] & SNES_LEFT_MASK)
+ IPPU.Joypads[i] &= ~SNES_RIGHT_MASK;
+ if (IPPU.Joypads[i] & SNES_UP_MASK)
+ IPPU.Joypads[i] &= ~SNES_DOWN_MASK;
+ }
+
+ if (IPPU.Controller == SNES_JOYPAD
+ || IPPU.Controller == SNES_MULTIPLAYER5)
+ {
+ for (i = 0; i < 5; i++)
+ {
+ if (IPPU.Joypads[i])
+ IPPU.Joypads[i] |= 0xffff0000;
+ }
+ }
+
+ // Read mouse position if enabled
+ if (Settings.MouseMaster)
+ {
+ for (i = 0; i < 2; i++)
+ S9xProcessMouse(i);
+ }
+
+ // Read SuperScope if enabled
+ if (Settings.SuperScopeMaster)
+ ProcessSuperScope();
+
+ if (Memory.FillRAM[0x4200] & 1)
+ {
+ PPU.Joypad1ButtonReadPos = 16;
+ if (Memory.FillRAM[0x4201] & 0x80)
+ {
+ PPU.Joypad2ButtonReadPos = 16;
+ PPU.Joypad3ButtonReadPos = 0;
+ }
+ else
+ {
+ PPU.Joypad2ButtonReadPos = 0;
+ PPU.Joypad3ButtonReadPos = 16;
+ }
+
+ Memory.FillRAM[0x4218] = (uint8) IPPU.Joypads[0];
+ Memory.FillRAM[0x4219] = (uint8)(IPPU.Joypads[0] >> 8);
+ Memory.FillRAM[0x421a] = (uint8) IPPU.Joypads[1];
+ Memory.FillRAM[0x421b] = (uint8)(IPPU.Joypads[1] >> 8);
+ if (Memory.FillRAM[0x4201] & 0x80)
+ {
+ Memory.FillRAM[0x421c] = (uint8) IPPU.Joypads[0];
+ Memory.FillRAM[0x421d] = (uint8)(IPPU.Joypads[0] >> 8);
+ Memory.FillRAM[0x421e] = (uint8) IPPU.Joypads[2];
+ Memory.FillRAM[0x421f] = (uint8)(IPPU.Joypads[2] >> 8);
+ }
+ else
+ {
+ Memory.FillRAM[0x421c] = (uint8) IPPU.Joypads[3];
+ Memory.FillRAM[0x421d] = (uint8)(IPPU.Joypads[3] >> 8);
+ Memory.FillRAM[0x421e] = (uint8) IPPU.Joypads[4];
+ Memory.FillRAM[0x421f] = (uint8)(IPPU.Joypads[4] >> 8);
+ }
+ }
#endif
}
void S9xSuperFXExec()
{
- if ((Memory.FillRAM[0x3000 + GSU_SFR] & FLG_G)
- && (Memory.FillRAM[0x3000 + GSU_SCMR] & 0x18) == 0x18)
- {
- if (!Settings.WinterGold||Settings.StarfoxHack)
- FxEmulate(~0);
- else FxEmulate((Memory.FillRAM[0x3000 + GSU_CLSR] & 1) ? 700 : 350);
- int GSUStatus = Memory.FillRAM[0x3000
- + GSU_SFR] | (Memory.FillRAM[0x3000 + GSU_SFR + 1] << 8);
- if ((GSUStatus & (FLG_G | FLG_IRQ)) == FLG_IRQ)
- {
- // Trigger a GSU IRQ.
- S9xSetIRQ(GSU_IRQ_SOURCE);
- }
- }
+ if ((Memory.FillRAM[0x3000 + GSU_SFR] & FLG_G)
+ && (Memory.FillRAM[0x3000 + GSU_SCMR] & 0x18) == 0x18)
+ {
+ if (!Settings.WinterGold || Settings.StarfoxHack)
+ FxEmulate(~0);
+ else FxEmulate((Memory.FillRAM[0x3000 + GSU_CLSR] & 1) ? 700 : 350);
+ int GSUStatus = Memory.FillRAM[0x3000
+ + GSU_SFR] | (Memory.FillRAM[0x3000 + GSU_SFR + 1] << 8);
+ if ((GSUStatus & (FLG_G | FLG_IRQ)) == FLG_IRQ)
+ {
+ // Trigger a GSU IRQ.
+ S9xSetIRQ(GSU_IRQ_SOURCE);
+ }
+ }
}