diff options
Diffstat (limited to 'src/ppu.c')
-rw-r--r-- | src/ppu.c | 2464 |
1 files changed, 1227 insertions, 1237 deletions
@@ -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); + } + } } |