From b29ea35d156e1b10b7c04dfd51cf65244982baab Mon Sep 17 00:00:00 2001 From: kalymos Date: Thu, 12 Feb 2026 22:06:03 +0100 Subject: [PATCH] test refactor: optimize PS1 patch for SCPH-100 using zero-latency polling Ported the BIOS patch from ISR to manual polling to achieve cycle-accurate precision for 33.86MHz bus timing. --- PSNee/BIOS_patching.h | 80 +++++++++++++++++++++++++++++++++++++++---- PSNee/PSNee.ino | 4 +-- PSNee/settings.h | 10 ++++++ 3 files changed, 86 insertions(+), 8 deletions(-) diff --git a/PSNee/BIOS_patching.h b/PSNee/BIOS_patching.h index a00d22e..3c6dbc0 100644 --- a/PSNee/BIOS_patching.h +++ b/PSNee/BIOS_patching.h @@ -6,6 +6,71 @@ volatile uint8_t pulse_counter = 0; volatile uint8_t patch_done = 0; + #ifdef TEST_BIOS + + void Bios_Patching() { + PIN_DX_INPUT; + PIN_DX_LOW; + + /* + * PHASE 1: Signal Stabilization & Alignment + * Synchronizes the MCU with the PS1 startup state (Cold Boot vs Reset). + */ + if (PIN_AX_READ != 0) { + while (PIN_AX_READ != 0); // Wait for falling edge + while (PIN_AX_READ == 0); // Sync on first clean rising edge + } else { + while (PIN_AX_READ == 0); // Wait for rising edge + } + + /* + * PHASE 2: Address Bus Window Alignment + * Bypassing initial boot routines to reach the target memory-access cycle. + */ + _delay_ms(BOOT_OFFSET); + + /* + * PHASE 3: Zero-Latency Software Pulse Counting + * Using manual polling to eliminate the jitter (0.5us) caused by ISR overhead. + * cli() locks the CPU for cycle-accurate timing. + */ + uint8_t current_pulses = 0; + cli(); // Disable interrupts for timing integrity + + while (current_pulses < PULSE_COUNT) { + // Wait for AX line to go HIGH (Target Rising Edge) + while (PIN_AX_READ == 0); + current_pulses++; + + // If not the final pulse, wait for the line to go LOW before next loop + if (current_pulses < PULSE_COUNT) { + while (PIN_AX_READ != 0); + } + // At the 48th pulse, we exit immediately to Phase 4 + } + + /* + * PHASE 4: Precision Bit Alignment + * Strategic delay to shift from AX address edge to the DX data bit. + */ + _delay_us(BIT_OFFSET); + + /* + * PHASE 5: Data Bus Overdrive (The Patch) + * Overwriting the 0.2us pulse on the DX line. + * Direct register access (Psnee v8.7 macros) ensures instantaneous execution. + */ + PIN_DX_OUTPUT; // Force line (Low/High-Z override) + _delay_us(OVERRIDE); + PIN_DX_INPUT; // Release bus immediately + + sei(); // Restore global interrupts + patch_done = 1; + } + + #endif + + #ifdef INTERRUPT_RISING ISR(PIN_AX_INTERRUPT_VECTOR) { @@ -59,12 +124,15 @@ } /* - * PHASE 2: Reaching the Target Memory Window - * We introduce a strategic delay (BOOT_OFFSET) to skip initial noise. - * This points the execution to a known idle gap in the - * address range calls before the critical data appears. - * DELAY: |---//-----| - * AX: -_-_//-_-_________-_-_-_ + * PHASE 2: Address Bus Window Alignment + * Introduces a BOOT_OFFSET delay to skip initial noise. + * This aligns the execution window with a + * known "idle gap" in the address bus activity, positioned + * immediately before the target memory-access cycle. + * + * BOOT_OFFSET: |---------//---------| + * AX LINE: -_-_-_-//-_-_-_-__________-_-_-_ + * BUS IDLE: |--------| */ _delay_ms(BOOT_OFFSET); diff --git a/PSNee/PSNee.ino b/PSNee/PSNee.ino index 7a0d1ac..c8c6add 100644 --- a/PSNee/PSNee.ino +++ b/PSNee/PSNee.ino @@ -44,14 +44,14 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX SCPH model number // Data pin | 32-pin BIOS | 40-pin BIOS | BIOS version -------------------------------------------------------------------------------------------------*/ //#define SCPH_102 // DX - D0 | AX - A7 | | 4.4e - CRC 0BAD7EA9, 4.5e -CRC 76B880E5 -#define SCPH_100 // DX - D0 | AX - A7 | | 4.3j - CRC F2AF798B +//#define SCPH_100 // DX - D0 | AX - A7 | | 4.3j - CRC F2AF798B //#define SCPH_7500_9000 // DX - D0 | AX - A7 | | 4.0j - CRC EC541CD0 //#define SCPH_7000 // DX - D0 | AX - A7 | | 4.0j - CRC EC541CD0 Enables hardware support for disabling BIOS patching. //#define SCPH_5500 // DX - D0 | AX - A5 | | 3.0j - CRC FF3EEB8C //#define SCPH_5000 // DX - D0 | AX - A5 | AX - A4 | 2.2j - CRC 24FC7E17 //#define SCPH_3500 // DX - D0 | AX - A5 | AX - A4 | 2.1j - CRC BC190209 //#define SCPH_3000 // DX - D5 | AX - A7, AY - A8 | AX - A6, AY - A7 | 1.1j - CRC 3539DEF6 -//#define SCPH_1000 // DX - D5 | AX - A7, AY - A8 | AX - A6, AY - A7 | 1.0j - CRC 3B601FC8 +#define SCPH_1000 // DX - D5 | AX - A7, AY - A8 | AX - A6, AY - A7 | 1.0j - CRC 3B601FC8 /*------------------------------------------------------------------------------------------------ Options diff --git a/PSNee/settings.h b/PSNee/settings.h index 3f5e3e4..0e1aa31 100644 --- a/PSNee/settings.h +++ b/PSNee/settings.h @@ -42,6 +42,16 @@ #define OVERRIDE 0.2 #endif + +// #ifdef SCPH_100 +// #define BIOS_PATCH +// #define TEST_BIOS +// #define BOOT_OFFSET 83.9 // Stabilization window (ms) +// #define PULSE_COUNT 48 // Targeted AX address cycles +// #define BIT_OFFSET 3.15 // Precision data alignment (us) +// #define OVERRIDE 0.2 // DX injection width (us) +// #endif + #ifdef SCPH_7500_9000 #define BIOS_PATCH #define INTERRUPT_RISING