diff --git a/snes/config/config.cpp b/snes/config/config.cpp index 701af94c..206daae0 100755 --- a/snes/config/config.cpp +++ b/snes/config/config.cpp @@ -13,6 +13,7 @@ Configuration::Configuration() { cpu.ntsc_frequency = 21477272; //315 / 88 * 6000000 cpu.pal_frequency = 21281370; cpu.wram_init_value = 0x55; + cpu.alt_poll_timings = false; smp.ntsc_frequency = 24607104; //32040.5 * 768 smp.pal_frequency = 24607104; diff --git a/snes/config/config.hpp b/snes/config/config.hpp index 1f4d037c..dabde597 100755 --- a/snes/config/config.hpp +++ b/snes/config/config.hpp @@ -10,6 +10,7 @@ struct Configuration { unsigned ntsc_frequency; unsigned pal_frequency; unsigned wram_init_value; + bool alt_poll_timings; } cpu; struct SMP { diff --git a/snes/cpu/timing/joypad.cpp b/snes/cpu/timing/joypad.cpp index 6a98de00..ae8e94f8 100755 --- a/snes/cpu/timing/joypad.cpp +++ b/snes/cpu/timing/joypad.cpp @@ -29,4 +29,44 @@ void CPU::step_auto_joypad_poll() { } } +//called every 128 clocks; see CPU::add_clocks() +void CPU::step_auto_joypad_poll_NEW(bool polarity) { + if(status.auto_joypad_counter > 0 && status.auto_joypad_counter <= 34) { + if(!status.auto_joypad_latch) { + //FIXME: Is this right, busy flag goes on even if not enabled??? + if(status.auto_joypad_counter == 1) + status.auto_joypad_active = true; + if(status.auto_joypad_counter == 34) + status.auto_joypad_active = false; + } else { + if(status.auto_joypad_counter == 1) { + status.auto_joypad_active = true; + input.port1->latch(1); + input.port2->latch(1); + } + if(status.auto_joypad_counter == 3) { + input.port1->latch(0); + input.port2->latch(0); + } + if((status.auto_joypad_counter & 1) != 0 && status.auto_joypad_counter != 1) { + uint2 port0 = input.port1->data(); + uint2 port1 = input.port2->data(); + + status.joy1 = (status.joy1 << 1) | (bool)(port0 & 1); + status.joy2 = (status.joy2 << 1) | (bool)(port1 & 1); + status.joy3 = (status.joy3 << 1) | (bool)(port0 & 2); + status.joy4 = (status.joy4 << 1) | (bool)(port1 & 2); + } + if(status.auto_joypad_counter == 34) + status.auto_joypad_active = false; + } + status.auto_joypad_counter++; + } + if(vcounter() >= (ppu.overscan() == false ? 225 : 240) && status.auto_joypad_counter == 0 && !polarity) { + status.auto_joypad_latch = status.auto_joypad_poll; + status.auto_joypad_counter = 1; + } +} + + #endif diff --git a/snes/cpu/timing/timing.cpp b/snes/cpu/timing/timing.cpp index f1378f0c..d7cf24f3 100755 --- a/snes/cpu/timing/timing.cpp +++ b/snes/cpu/timing/timing.cpp @@ -17,10 +17,18 @@ void CPU::add_clocks(unsigned clocks) { step(clocks); - status.auto_joypad_clock += clocks; - if(status.auto_joypad_clock >= 256) { - status.auto_joypad_clock -= 256; - step_auto_joypad_poll(); + if(config.cpu.alt_poll_timings) { + bool opolarity = (status.auto_joypad_clock & 128); + status.auto_joypad_clock = (status.auto_joypad_clock + clocks) & 0xFF; + bool npolarity = (status.auto_joypad_clock & 128); + if(opolarity != npolarity) + step_auto_joypad_poll_NEW(opolarity); + } else { + status.auto_joypad_clock += clocks; + if(status.auto_joypad_clock >= 256) { + status.auto_joypad_clock -= 256; + step_auto_joypad_poll(); + } } if(status.dram_refreshed == false && hcounter() >= status.dram_refresh_position) { diff --git a/snes/cpu/timing/timing.hpp b/snes/cpu/timing/timing.hpp index 6c225dab..bf15a727 100755 --- a/snes/cpu/timing/timing.hpp +++ b/snes/cpu/timing/timing.hpp @@ -22,3 +22,4 @@ alwaysinline bool irq_test(); //joypad.cpp void step_auto_joypad_poll(); +void step_auto_joypad_poll_NEW(bool polarity); diff --git a/snes/snes.hpp b/snes/snes.hpp index dffeeee3..469d1ec9 100755 --- a/snes/snes.hpp +++ b/snes/snes.hpp @@ -1,5 +1,6 @@ #ifndef SNES_HPP #define SNES_HPP +#define BSNES_SUPPORTS_ALT_TIMINGS namespace SNES { namespace Info {