From 062e6023c0c3c25d02bcf32de6342d0ec8d81e5b Mon Sep 17 00:00:00 2001 From: kalymos Date: Wed, 4 Mar 2026 21:27:50 +0100 Subject: [PATCH] refactor: fine-tune BIOS patch --- PSNee/BIOS_patching.h | 244 +++++++++++++----------------------------- PSNee/PSNee.ino | 14 +-- PSNee/settings.h | 68 ++++++------ 3 files changed, 113 insertions(+), 213 deletions(-) diff --git a/PSNee/BIOS_patching.h b/PSNee/BIOS_patching.h index 3ed7c7f..f8ced65 100644 --- a/PSNee/BIOS_patching.h +++ b/PSNee/BIOS_patching.h @@ -76,6 +76,7 @@ PIN_AX_INTERRUPT_RISING; PIN_AX_INTERRUPT_ENABLE; while (patchStep != 1); // Wait for the first stage of the patch to complete: +PIN_LED_OFF; } #endif @@ -200,190 +201,89 @@ * ====================================================================================== */ -#ifdef BIOS_PATCH_2 +#ifdef BIOS_PATCH_3 - volatile uint8_t pulseCounter = 0; - volatile uint8_t patchStep = 0; +// Shared variables between ISR and main loop +volatile uint8_t pulse_counter = 0; +volatile uint8_t patch_done = 0; - // --- MAIN INTERRUPT SERVICE ROUTINE (ADDRESS AX) --- - ISR(PIN_AX_INTERRUPT_VECTOR) { - /* - * PHASE 3: Pulse Counting (Inside ISR) - * Decrementing towards zero is the fastest operation on AVR architecture. - */ - if (--pulseCounter == 0) { - - /* PHASE 4: Precision Bit Alignment */ - _delay_us(BIT_OFFSET); - - /* PHASE 5: Data Bus Overdrive (The Patch on DX) */ - #ifdef INTERRUPT_RISING_HIGH_PATCH - PIN_DX_SET; // Pre-set HIGH state for Variant 3 - #endif - PIN_DX_OUTPUT; // Take control of the Data Bus - _delay_us(OVERRIDE); - - #ifdef INTERRUPT_RISING_HIGH_PATCH - PIN_DX_CLEAR; // Release HIGH state - #endif +// --- MAIN INTERRUPT SERVICE ROUTINE (ADDRESS AX) --- +ISR(PIN_AX_INTERRUPT_VECTOR) { + if (--pulse_counter == 0) { + // --- PHASE 4: Precision Bit Alignment --- + __builtin_avr_delay_cycles(BIT_OFFSET_CYCLES); - PIN_DX_INPUT; // Immediately release the Data Bus - PIN_AX_INTERRUPT_DISABLE; - patchStep = 1; // Notify Stage 1 completion + // --- PHASE 5: Data Bus Overdrive (Patch applied on DX) --- + #ifdef INTERRUPT_RISING_HIGH_PATCH + PIN_DX_SET; // Pre-set HIGH if needed for this variant + #endif + + PIN_DX_OUTPUT; // Take control of the data bus + __builtin_avr_delay_cycles(OVERRIDE_CYCLES); + + #ifdef INTERRUPT_RISING_HIGH_PATCH + PIN_DX_CLEAR; // Release HIGH state + #endif + + PIN_DX_INPUT; // Immediately release the data bus + PIN_AX_INTERRUPT_DISABLE; + PIN_LED_OFF; + patch_done = 1; // Signal completion of stage 1 } - } +} - // --- SECONDARY INTERRUPT SERVICE ROUTINE (ADDRESS AY - Variant 3) --- - #ifdef INTERRUPT_RISING_HIGH_PATCH - ISR(PIN_AY_INTERRUPT_VECTOR) { - if (--pulseCounter == 0) { - _delay_us(BIT_OFFSET_2); - PIN_DX_OUTPUT; - _delay_us(OVERRIDE_2); - PIN_DX_INPUT; - PIN_AY_INTERRUPT_DISABLE; - patchStep = 2; // Notify Stage 2 completion - } +// --- SECONDARY ISR (ADDRESS AY, HIGH_PATCH variant) --- +#ifdef INTERRUPT_RISING_HIGH_PATCH +ISR(PIN_AY_INTERRUPT_VECTOR) { + if (--pulse_counter == 0) { + delay_cycles(BIT_OFFSET_2_CYCLES); + PIN_DX_OUTPUT; + delay_cycles(OVERRIDE_2_CYCLES); + PIN_DX_INPUT; + PIN_AY_INTERRUPT_DISABLE; + patch_done = 2; // Signal completion of stage 2 } - #endif - - void Bios_Patching() { - /* - * PHASE 1: Signal Stabilization & Alignment (AX) - * Handles Cold Boot (Line High) vs Reset (Line Low) states. - */ - if (PIN_AX_READ != 0) { // Case: Power-on / Line high - while (PIN_AX_READ != 0); // Wait for falling edge - while (PIN_AX_READ == 0); // Wait for next rising edge to sync - } - else { // Case: Reset / Line low - while (PIN_AX_READ == 0); // Wait for the very first rising edge - } - - /* PHASE 2: Reaching the Target Memory Window */ - _delay_ms(BOOT_OFFSET); - - // Countdown Preparation (Optimized for speed) - pulseCounter = PULSE_COUNT; - patchStep = 0; - - // Dynamic Interrupt Configuration - #if defined(INTERRUPT_RISING) || defined(INTERRUPT_RISING_HIGH_PATCH) - PIN_AX_INTERRUPT_RISING; - #elif defined(INTERRUPT_FALLING) - PIN_AX_INTERRUPT_FALLING; - #endif - - // Arm Hardware Interrupt - PIN_AX_INTERRUPT_ENABLE; - while (patchStep != 1); // Block until first patch is applied - - /* - * OPTIONAL PHASE: Secondary Patch (Variant 3 only) - * Switches detection to the second Address line (AY). - */ - #ifdef INTERRUPT_RISING_HIGH_PATCH - while (PIN_AY_READ != 0); // Ensure AY is low before arming - _delay_ms(FOLLOWUP_OFFSET); - - pulseCounter = PULSE_COUNT_2; // Re-load counter for AY pulses - PIN_AY_INTERRUPT_RISING; - PIN_AY_INTERRUPT_ENABLE; - while (patchStep != 2); // Block until second patch is applied - #endif - } - +} #endif -// #ifdef BIOS_PATCH +// --- BIOS Patching Main Function --- +void Bios_Patching(void) { + // --- PHASE 1: Signal Stabilization & Alignment (AX) --- + if (PIN_AX_READ != 0) { // Case: Power-on, line is high + while (PIN_AX_READ != 0); // Wait for falling edge + while (PIN_AX_READ == 0); // Wait for next rising edge to sync + } else { // Case: Reset, line is low + while (PIN_AX_READ == 0); // Wait for first rising edge + } -// // Shared variables between ISR and main loop -// volatile uint8_t pulse_counter = 0; -// volatile uint8_t patch_done = 0; + // --- PHASE 2: Reaching the Target Memory Window --- + _delay_ms(BOOT_OFFSET_MS); +PIN_LED_ON; + // --- Prepare pulse counter and patch status flag --- + pulse_counter = PULSE_COUNT; + patch_done = 0; -// // --- Utility function for a CPU cycle delay (NOP) --- -// static inline void delay_cycles(uint8_t cycles) { -// while(cycles--) { -// asm volatile("nop"); -// } -// } + // --- Dynamic interrupt configuration --- + #if defined(INTERRUPT_RISING) || defined(INTERRUPT_RISING_HIGH_PATCH) + PIN_AX_INTERRUPT_RISING; + #elif defined(INTERRUPT_FALLING) + PIN_AX_INTERRUPT_FALLING; + #endif -// // --- MAIN INTERRUPT SERVICE ROUTINE (ADDRESS AX) --- -// ISR(PIN_AX_INTERRUPT_VECTOR) { -// if (--pulse_counter == 0) { -// // --- PHASE 4: Precision Bit Alignment --- -// delay_cycles(BIT_OFFSET_CYCLES); + PIN_AX_INTERRUPT_ENABLE; + while (patch_done != 1); // Wait until stage 1 is completed -// // --- PHASE 5: Data Bus Overdrive (Patch applied on DX) --- -// #ifdef INTERRUPT_RISING_HIGH_PATCH -// PIN_DX_SET; // Pre-set HIGH if needed for this variant -// #endif + // --- Optional secondary patch phase for HIGH_PATCH --- + #ifdef INTERRUPT_RISING_HIGH_PATCH + while (PIN_AY_READ != 0); // Ensure AY line is low before arming + _delay_ms(FOLLOWUP_OFFSET_MS); -// PIN_DX_OUTPUT; // Take control of the data bus -// delay_cycles(OVERRIDE_CYCLES); + pulse_counter = PULSE_COUNT_2; // Reload counter for AY pulses + PIN_AY_INTERRUPT_RISING; + PIN_AY_INTERRUPT_ENABLE; + while (patch_done != 2); // Wait until stage 2 is completed + #endif +} -// #ifdef INTERRUPT_RISING_HIGH_PATCH -// PIN_DX_CLEAR; // Release HIGH state -// #endif - -// PIN_DX_INPUT; // Immediately release the data bus -// PIN_AX_INTERRUPT_DISABLE; -// patch_done = 1; // Signal completion of stage 1 -// } -// } - -// // --- SECONDARY ISR (ADDRESS AY, HIGH_PATCH variant) --- -// #ifdef INTERRUPT_RISING_HIGH_PATCH -// ISR(PIN_AY_INTERRUPT_VECTOR) { -// if (--pulse_counter == 0) { -// delay_cycles(BIT_OFFSET_2_CYCLES); -// PIN_DX_OUTPUT; -// delay_cycles(OVERRIDE_2_CYCLES); -// PIN_DX_INPUT; -// PIN_AY_INTERRUPT_DISABLE; -// patch_done = 2; // Signal completion of stage 2 -// } -// } -// #endif - -// // --- BIOS Patching Main Function --- -// void Bios_Patching(void) { -// // --- PHASE 1: Signal Stabilization & Alignment (AX) --- -// if (PIN_AX_READ != 0) { // Case: Power-on, line is high -// while (PIN_AX_READ != 0); // Wait for falling edge -// while (PIN_AX_READ == 0); // Wait for next rising edge to sync -// } else { // Case: Reset, line is low -// while (PIN_AX_READ == 0); // Wait for first rising edge -// } - -// // --- PHASE 2: Reaching the Target Memory Window --- -// _delay_ms(BOOT_OFFSET_MS); - -// // --- Prepare pulse counter and patch status flag --- -// pulse_counter = PULSE_COUNT; -// patch_done = 0; - -// // --- Dynamic interrupt configuration --- -// #if defined(INTERRUPT_RISING) || defined(INTERRUPT_RISING_HIGH_PATCH) -// PIN_AX_INTERRUPT_RISING; -// #elif defined(INTERRUPT_FALLING) -// PIN_AX_INTERRUPT_FALLING; -// #endif - -// PIN_AX_INTERRUPT_ENABLE; -// while (patch_done != 1); // Wait until stage 1 is completed - -// // --- Optional secondary patch phase for HIGH_PATCH --- -// #ifdef INTERRUPT_RISING_HIGH_PATCH -// while (PIN_AY_READ != 0); // Ensure AY line is low before arming -// _delay_ms(FOLLOWUP_OFFSET_MS); - -// pulse_counter = PULSE_COUNT_2; // Reload counter for AY pulses -// PIN_AY_INTERRUPT_RISING; -// PIN_AY_INTERRUPT_ENABLE; -// while (patch_done != 2); // Wait until stage 2 is completed -// #endif -// } - -// #endif \ No newline at end of file +#endif \ No newline at end of file diff --git a/PSNee/PSNee.ino b/PSNee/PSNee.ino index aae3b8f..69431d9 100644 --- a/PSNee/PSNee.ino +++ b/PSNee/PSNee.ino @@ -497,7 +497,7 @@ void Init() { PIN_LED_OUTPUT; #endif -#ifdef BIOS_PATCH +#ifdef BIOS_PATCH_3 uint8_t skipPatch = 0; GLOBAL_INTERRUPT_ENABLE; @@ -510,18 +510,18 @@ void Init() { } #endif -#ifdef LED_RUN - PIN_LED_ON; -#endif +// #ifdef LED_RUN +// PIN_LED_ON; +// #endif // Execute BIOS patching unless bypassed by switch if (skipPatch == 0) { Bios_Patching(); } -#ifdef LED_RUN - PIN_LED_OFF; -#endif +// #ifdef LED_RUN +// PIN_LED_OFF; +// #endif #endif diff --git a/PSNee/settings.h b/PSNee/settings.h index 6e4ac6c..5d5335d 100644 --- a/PSNee/settings.h +++ b/PSNee/settings.h @@ -33,23 +33,23 @@ #define OVERRIDE 0.2 #endif -#ifdef SCPH_100 -#define BIOS_PATCH -#define INTERRUPT_RISING -#define BOOT_OFFSET 83.9 //83.72 - 84.15 -#define PULSE_COUNT 48 -#define BIT_OFFSET 2.75 //2.63 - 2.87 -#define OVERRIDE 0.2 -#endif +// #ifdef SCPH_100 +// #define BIOS_PATCH +// #define INTERRUPT_RISING +// #define BOOT_OFFSET 83.9 //83.72 - 84.15 +// #define PULSE_COUNT 48 +// #define BIT_OFFSET 2.75 //2.63 - 2.87 +// #define OVERRIDE 0.2 +// #endif -#ifdef SCPH_7500_9000 -#define BIOS_PATCH -#define INTERRUPT_RISING -#define BOOT_OFFSET 75.2 //74.95 - 75.55 -#define PULSE_COUNT 16 -#define BIT_OFFSET 2.8 -#define OVERRIDE 0.2 -#endif +// #ifdef SCPH_7500_9000 +// #define BIOS_PATCH +// #define INTERRUPT_RISING +// #define BOOT_OFFSET 75.2 //74.95 - 75.55 +// #define PULSE_COUNT 16 +// #define BIT_OFFSET 2.8 +// #define OVERRIDE 0.2 +// #endif #ifdef SCPH_7000 #define BIOS_PATCH @@ -134,10 +134,10 @@ // #endif // #endif -// // -------- SCPH 100 -------- -// #ifdef SCPH_100 -// #define BIOS_PATCH -// #define INTERRUPT_RISING +// -------- SCPH 100 -------- +#ifdef SCPH_100 +#define BIOS_PATCH_3 +#define INTERRUPT_RISING // #ifdef F_CPU_8MHZ // #define BOOT_OFFSET_MS 84 @@ -145,29 +145,29 @@ // #define BIT_OFFSET_CYCLES 22 // 2.75 / 0.125 ≈ 22 cycles // #define OVERRIDE_CYCLES 2 // 0.2 / 0.125 ≈ 2 cycles // #elif defined(F_CPU_16MHZ) -// #define BOOT_OFFSET_MS 84 -// #define PULSE_COUNT 48 -// #define BIT_OFFSET_CYCLES 44 // 2.75 / 0.0625 ≈ 44 cycles -// #define OVERRIDE_CYCLES 3 // 0.2 / 0.0625 ≈ 3 cycles -// #endif +#define BOOT_OFFSET_MS 84 +#define PULSE_COUNT 48 +#define BIT_OFFSET_CYCLES 47 // 2.75 / 0.0625 ≈ 44 cycles +3 +#define OVERRIDE_CYCLES 3 // 0.2 / 0.0625 ≈ 3 cycles +#endif // #endif // // -------- SCPH 7500 / 9000 -------- -// #ifdef SCPH_7500_9000 -// #define BIOS_PATCH -// #define INTERRUPT_RISING +#ifdef SCPH_7500_9000 +#define BIOS_PATCH_3 +#define INTERRUPT_RISING // #ifdef F_CPU_8MHZ // #define BOOT_OFFSET_MS 75 // #define PULSE_COUNT 16 // #define BIT_OFFSET_CYCLES 22 // 2.8 / 0.125 ≈ 22 cycles // #define OVERRIDE_CYCLES 2 // 0.2 / 0.125 ≈ 2 cycles -// #elif defined(F_CPU_16MHZ) -// #define BOOT_OFFSET_MS 75 -// #define PULSE_COUNT 16 -// #define BIT_OFFSET_CYCLES 45 // 2.8 / 0.0625 ≈ 45 cycles -// #define OVERRIDE_CYCLES 3 // 0.2 / 0.0625 ≈ 3 cycles -// #endif +//#elif defined(F_CPU_16MHZ) +#define BOOT_OFFSET_MS 75 +#define PULSE_COUNT 16 +#define BIT_OFFSET_CYCLES 47 // 2.8 / 0.0625 ≈ 45 cycles +#define OVERRIDE_CYCLES 3 // 0.2 / 0.0625 ≈ 3 cycles +#endif // #endif // // -------- SCPH 7000 --------