From 4a7a429a92bea1502a7d1a4bcca91556bdbc7ac0 Mon Sep 17 00:00:00 2001 From: kalymos Date: Sat, 14 Mar 2026 22:44:57 +0100 Subject: [PATCH] Refactor BIOS patching logic and clean up codebase New 2-phase sync (Stabilization + Silence detection). Refactored GPIO macros for faster execution. Cleaned up SCPH model definitions and fixed backslash warnings. Removed unused global variables to save RAM. --- PSNee/BIOS_patching.h | 410 ++++++++++++---------------------------- PSNee/MCU.h | 78 ++++---- PSNee/PSNee.ino | 319 ++++++++++++++----------------- PSNee/settings.h | 426 ++++++++++++++---------------------------- 4 files changed, 434 insertions(+), 799 deletions(-) diff --git a/PSNee/BIOS_patching.h b/PSNee/BIOS_patching.h index c045040..64d23cb 100644 --- a/PSNee/BIOS_patching.h +++ b/PSNee/BIOS_patching.h @@ -1,320 +1,152 @@ #pragma once - - -#ifdef BIOS_PATCH - - volatile uint8_t pulseCounter = 0; - volatile uint8_t patchStep = 0; - - - #ifdef INTERRUPT_RISING - - ISR(PIN_AX_INTERRUPT_VECTOR) { - - /* - * PHASE 3: Pulse Counting (Inside ISR) - * The hardware Interrupt Service Routine (ISR) now takes over. - * It counts the exact number of incoming pulses on PIN_AX until it - * matches the PULSE_COUNT value. - */ - - - //if (--pulseCounter == 0) { - pulseCounter++; - if (pulseCounter == PULSE_COUNT){ // If pulseCounter reaches the value defined by PULSE_COUNT - /* - * PHASE 4: Precision Bit Alignment - * Once the PULSE_COUNT is reached, a micro-delay (BIT_OFFSET) is applied. - * This shifts the timing from the clock edge to the exact bit position - * within the data stream that needs modification. - */ - _delay_us(BIT_OFFSET); - /* - * PHASE 5: Data Bus Overdrive (The Patch) - * Briefly forcing PIN_DX to OUTPUT to pull the line and "nullify" the target bit. - * This effectively overwrites the BIOS data on-the-fly - * before reverting the pin to INPUT to release the bus. - */ - PIN_DX_OUTPUT; - _delay_us (OVERRIDE); - PIN_DX_INPUT; - PIN_AX_INTERRUPT_DISABLE; - pulseCounter = 0; - patchStep = 1; // patchStep is set to 1, indicating that the first patch is completed. - } - } - - void Bios_Patching(){ - - /* - * PHASE 1: Signal Stabilization & Alignment - * Detects the startup state (Cold Boot vs. Reset). - * If the line is already HIGH (Cold Boot), we wait for a full LOW-to-HIGH transition - * to ensure we are aligned with the start of a clean clock cycle. - */ - - 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 - * 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: -_-_//-_-_________-_-_-_ - */ - _delay_ms(BOOT_OFFSET); - // Armed for hardware detection - //pulseCounter = PULSE_COUNT; - 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 - - #ifdef INTERRUPT_FALLING - - ISR(PIN_AX_INTERRUPT_VECTOR) { - - pulseCounter++; - if (pulseCounter == PULSE_COUNT){ - _delay_us (BIT_OFFSET); - PIN_DX_OUTPUT; - _delay_us (OVERRIDE); - PIN_DX_INPUT; - - PIN_AX_INTERRUPT_DISABLE; - - pulseCounter = 0; - patchStep = 1; - } - } - - void Bios_Patching(){ - - if (PIN_AX_READ != 0) { - while (PIN_AX_READ != 0); - while (PIN_AX_READ == 0); - } - else { - while (PIN_AX_READ == 0); - } - - _delay_ms(BOOT_OFFSET); - - PIN_AX_INTERRUPT_FALLING; - PIN_AX_INTERRUPT_ENABLE; - - while (patchStep != 1); - } - #endif - - #ifdef INTERRUPT_RISING_HIGH_PATCH - ISR(PIN_AX_INTERRUPT_VECTOR) { - pulseCounter++; - if (pulseCounter == PULSE_COUNT){ - _delay_us (BIT_OFFSET); - PIN_DX_SET; - PIN_DX_OUTPUT; - _delay_us (OVERRIDE); - PIN_DX_CLEAR; - PIN_DX_INPUT; - PIN_AX_INTERRUPT_DISABLE; - pulseCounter = 0; - patchStep = 1; - } - } - - ISR(PIN_AY_INTERRUPT_VECTOR){ - - pulseCounter++; - - if (pulseCounter == PULSE_COUNT_2) { - _delay_us (BIT_OFFSET_2); - PIN_DX_OUTPUT; - _delay_us (OVERRIDE_2); - PIN_DX_INPUT; - PIN_AY_INTERRUPT_DISABLE; - patchStep = 2; - } - } - - void Bios_Patching(){ - if (PIN_AX_READ != 0) { - while (PIN_AX_READ != 0); - while (PIN_AX_READ == 0); - } - else { - while (PIN_AX_READ == 0); - } - - _delay_ms(BOOT_OFFSET); - - PIN_AX_INTERRUPT_RISING; - - PIN_AX_INTERRUPT_ENABLE; - - while (patchStep != 1); - - while (PIN_AY_READ != 0); - - _delay_ms(FOLLOWUP_OFFSET); - - PIN_AY_INTERRUPT_RISING; - PIN_AY_INTERRUPT_ENABLE; - while (patchStep != 2); - } - - #endif - -#endif - /* * ====================================================================================== * FUNCTION : Bios_Patching() * TARGET : Data Bus (DX) synchronized via Address Bus (AX / AY) * * OPERATIONAL LOGIC: - * This function intercepts a specific memory transaction by counting clock cycles - * on Address lines (AX/AY) to inject modified data onto the Data line (DX) - * in real-time (On-the-fly patching). + * Intercepts specific memory transactions by monitoring address lines (AX/AY). + * Uses precise pulse counting and timed delays to inject modified data onto + * the Data line (DX) in real-time (On-the-fly patching). * * KEY PHASES: - * 1. SYNC (AX): Aligns the CPU with the first valid address cycle after boot/reset - * to establish a deterministic T0 reference point. - * 2. GATING (BOOT_OFFSET): Skips initial BIOS noise/calls to reach the target - * memory window. - * 3. ADDRESS COUNTING (ISR AX): Hardware-based pulse counting using ultra-fast - * decrement-to-zero logic to identify the exact target bit location. - * 4. DATA OVERDRIVE (DX): Momentarily forces DX pin to OUTPUT mode to overwrite - * the original BIOS bit with a custom logic state. - * 5. SEQUENCING (Optional AY): Transitions to a secondary address line (AY) for - * multi-stage patching or follow-up verification. + * 1. STABILIZATION & ALIGNMENT (AX): Ensures the CPU is synchronized with a + * clean rising edge of the AX signal to establish a stable reference point. + * + * 2. SILENCE DETECTION (GATING): Scans for a specific window of bus inactivity + * (SILENCE_THRESHOLD) to identify the correct pre-patching state and + * avoid false triggers from boot noise. + * + * 3. PULSE COUNTING (AX): Implements a high-speed countdown of address pulses. + * The code blocks on each edge to maintain cycle-accurate synchronization + * with the target memory access. + * + * 4. DATA OVERDRIVE (DX): At the exact target pulse, triggers a calibrated + * delay (BIT_OFFSET) before forcing the DX pin to OUTPUT mode to + * overwrite the original BIOS bit for a specific duration (OVERRIDE). + * + * 5. SECONDARY PATCH (AY): If enabled, repeats the silence detection and + * pulse counting logic on a secondary address line (AY) for multi-stage + * memory patching. * ====================================================================================== */ -#ifdef BIOS_PATCH_3 -// 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) { - if (--pulse_counter == 0) { - // --- PHASE 4: Precision Bit Alignment --- - __builtin_avr_delay_cycles(BIT_OFFSET_CYCLES); - - // --- 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 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 +#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 - } - //--- PHASE 2: Reaching the Target Memory Window --- - //_delay_ms(BOOT_OFFSET_MS); + uint8_t pulse_counter = 0; + uint8_t current_confirms = 0; - // --- PHASE 2: Reaching the Target Memory Window (Silence Detection) --- - // Replaces the fixed _delay_ms(BOOT_OFFSET_MS) + PIN_AX_INPUT; + // --- PHASE 1: Signal Stabilization & Alignment (AX) --- + if (PIN_AX_READ != 0) { + while WAIT_AX_FALLING; // Wait for falling edge + while WAIT_AX_RISING; // Wait for next rising edge to sync + } else { + while WAIT_AX_RISING; // Wait for first rising edge + } -uint8_t current_confirms = 0; + // --- PHASE 2: Silence Detection (AX) --- -while (current_confirms < CONFIRM_COUNTER_TARGET) { - uint16_t count = SILENCE_THRESHOLD; + while (current_confirms < CONFIRM_COUNTER_TARGET) { + uint16_t count = SILENCE_THRESHOLD; + + // --- Scan for ONE continuous block of silence --- + while (count > 0) { + if (PIN_AX_READ != 0) { + while WAIT_AX_FALLING; // Pulse detected: wait for bus to clear + break; // Reset and try a new silence block + } + count--; + } + + // If count reaches 0, a silent block is validated + if (count == 0) { + current_confirms++; + } + } + + PIN_LED_ON; + + // --- PHASE 3: Pulse Counting & Patch 1 (AX) --- + pulse_counter = PULSE_COUNT; + + + while (pulse_counter > 0) { + while WAIT_AX_RISING; // Block here until rising edge - // --- Attempt to find ONE block of silence --- - while (count > 0) { - if (PIN_AX_READ != 0) { - // Activity detected: current block is invalid - // Wait for bus to clear before trying a NEW block - while (PIN_AX_READ != 0); - break; + pulse_counter--; + + if (pulse_counter == 0) { + // Precise cycle-accurate delay before triggering + __builtin_avr_delay_cycles(BIT_OFFSET_CYCLES); + + #ifdef INTERRUPT_RISING_HIGH_PATCH + PIN_DX_SET; + #endif + + PIN_DX_OUTPUT; // Pull the line (Override start) + __builtin_avr_delay_cycles(OVERRIDE_CYCLES); + + #ifdef INTERRUPT_RISING_HIGH_PATCH + PIN_DX_CLEAR; // Release the bus (Override end) + #endif + + PIN_DX_INPUT; + + PIN_LED_OFF; + break; + } + + while WAIT_AX_FALLING; // Wait for pulse to clear + } + + //PIN_LED_OFF; + // -------- Secondary Patch ---------- + #ifdef INTERRUPT_RISING_HIGH_PATCH + + current_confirms = 0; + while (current_confirms < CONFIRM_COUNTER_TARGET_2) { + uint16_t count = SILENCE_THRESHOLD; + + while (count > 0) { + if (PIN_AX_READ != 0) { + + while WAIT_AX_FALLING; + break; + } + count--; + } + + if (count == 0) { + current_confirms++; } - count--; } - // If count reached 0, we found 500us of silence - if (count == 0) { - current_confirms++; - } else { + PIN_LED_ON; + pulse_counter = PULSE_COUNT_2; - } -} + while (pulse_counter > 0) { + while WAIT_AY_RISING; + + pulse_counter--; -PIN_LED_ON; + if (pulse_counter == 0) { + __builtin_avr_delay_cycles(BIT_OFFSET_2_CYCLES); - + PIN_DX_OUTPUT; + __builtin_avr_delay_cycles(OVERRIDE_2_CYCLES); + PIN_DX_INPUT; + + PIN_LED_OFF; + break; + } + while WAIT_AY_FALLING; - // --- 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 diff --git a/PSNee/MCU.h b/PSNee/MCU.h index 2492332..989311d 100644 --- a/PSNee/MCU.h +++ b/PSNee/MCU.h @@ -227,30 +227,38 @@ #ifdef ATmega328_168 static inline void optimizePeripherals(void) { - // --- Port C & Digital Input Configuration (A0-A5) --- - // 1. Set Port C as inputs (DDRC bits 0-5 to 0) - DDRC &= ~((1< #include @@ -259,12 +267,6 @@ #include #include - // Global interrupt control settings - #define GLOBAL_INTERRUPT_ENABLE sei() - #define GLOBAL_INTERRUPT_DISABLE cli() - // #define GLOBAL_INTERRUPT_ENABLE SREG |= (1 << 7) // Set the I-bit (bit 7) in the Status Register to enable global interrupts - // #define GLOBAL_INTERRUPT_DISABLE SREG &= ~(1 << 7) // Clear the I-bit (bit 7) in the Status Register to disable global interrupts - // Main pin configuration // Define the main pins as inputs @@ -297,10 +299,7 @@ #endif // Handling the BIOS patch - #if defined(SCPH_102) || defined(SCPH_100) || defined(SCPH_7500_9000) || defined(SCPH_7000) || defined(SCPH_5500) || defined(SCPH_5000) || defined(SCPH_3500) || defined(SCPH_3000) || defined(SCPH_1000) - - // Clear the timer interrupt flag - //#define TIMER_TIFR_CLEAR TIFR0 |= (1 << OCF0A) // Clear the Timer0 Compare Match A interrupt flag + #if defined(SCPH_102) || defined(SCPH_100) || defined(SCPH_7500_9000) || defined(SCPH_7000) || defined(SCPH_5000_5500) || defined(SCPH_3500) || defined(SCPH_3000) || defined(SCPH_1000) // Define input pins for the BIOS patch #define PIN_AX_INPUT DDRD &= ~(1 << DDD2) // Set DDRD register to configure PIND2 as input @@ -315,28 +314,19 @@ // Set pull-ups low on output pins #define PIN_DX_CLEAR PORTD &= ~(1 << PD4) // Set PORTD register to make PIND4 low + + #define WAIT_AX_RISING (!(PIND & (1 << PIND2))) // Attend le début de l'impulsion + #define WAIT_AX_FALLING (PIND & (1 << PIND2)) // Attend la fin de l'impulsion + // Read the input pins for the BIOS patch #define PIN_AX_READ (!!(PIND & (1 << PIND2))) // Read the state of PIND2 - // External interrupt configuration for BIOS patch - #define PIN_AX_INTERRUPT_ENABLE EIMSK |= (1 << INT0) // Enable external interrupt on INT0 (PINB2) - #define PIN_AX_INTERRUPT_DISABLE EIMSK &= ~(1 << INT0) // Disable external interrupt on INT0 - #define PIN_AX_INTERRUPT_RISING EICRA |= (1 << ISC01) | (1 << ISC00) // Configure INT0 for rising edge trigger - //#define PIN_AX_INTERRUPT_FALLING (EICRA = (1 << ISC01)) - #define PIN_AX_INTERRUPT_FALLING (EICRA = (EICRA & ~(1 << ISC00)) | (1 << ISC01)) // Configure INT0 for falling edge trigger - - // Interrupt vectors for external interrupts - #define PIN_AX_INTERRUPT_VECTOR INT0_vect // Interrupt vector for INT0 (external interrupt) - // Defin PIN_AY for HIGH_PATCH #if defined(SCPH_3000) || defined(SCPH_1000) #define PIN_AY_INPUT DDRD &= ~(1 << DDD3) // Set DDRD register to configure PIND3 as input - #define PIN_AY_READ (!!(PIND & (1 << PIND3))) // Read the state of PIND3 - #define PIN_AY_INTERRUPT_ENABLE EIMSK |= (1 << INT1) // Enable external interrupt on INT1 (PINB3) - #define PIN_AY_INTERRUPT_DISABLE EIMSK &= ~(1 << INT1) // Disable external interrupt on INT1 - #define PIN_AY_INTERRUPT_RISING EICRA |= (1 << ISC11) | (1 << ISC10) // Configure INT1 for rising edge trigger - #define PIN_AY_INTERRUPT_FALLING (EICRA = (EICRA & ~(1 << ISC10)) | (1 << ISC11)) // Configure INT1 for falling edge trigger - #define PIN_AY_INTERRUPT_VECTOR INT1_vect // Interrupt vector for INT1 (external interrupt) + #define WAIT_AY_RISING (!(PIND & (1 << PIND3))) // AY est sur PIND3 + #define WAIT_AY_FALLING (PIND & (1 << PIND3)) + #endif // Handle switch input for BIOS patch #if defined(SCPH_7000) diff --git a/PSNee/PSNee.ino b/PSNee/PSNee.ino index 69431d9..bd85481 100644 --- a/PSNee/PSNee.ino +++ b/PSNee/PSNee.ino @@ -6,7 +6,7 @@ // MCU // Arduino //------------------------------------------------------------------------------------------------ -//#define ATmega328_168 // Nano, Pro Mini, Uno +#define ATmega328_168 // Nano, Pro Mini, Uno //#define ATmega32U4_16U4 // Micro, Pro Micro //#define ATtiny85_45_25 // ATtiny @@ -47,9 +47,8 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX //#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_5000_5500 // DX - D0 | AX - A15 | | 3.0j - CRC FF3EEB8C, 2.2j - CRC 24FC7E17 +//#define SCPH_3500 // DX - D0 | AX - A15 | AX - A15 | 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 @@ -130,28 +129,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX //Flag initializing for automatic console generation selection 0 = old, 1 = pu-22 end ++ volatile uint8_t wfck_mode = 0; - -// --- Prototypes (Forward declarations) --- -// These tell the compiler that the functions exist later in the code. - - -// Function pointer type definition for the console detection logic. -// This allows switching between 'Standard' and 'SCPH-5903' heuristics dynamically. -// Définition du type de pointeur de fonction pour la logique de console -typedef void (*ConsoleLogicPtr)(uint8_t isDataSector); - -// Déclarations forward des deux fonctions -void processStandardLogic(uint8_t isDataSector); -void processScph5903Logic(uint8_t isDataSector); - -// Pointeur global vers la fonction active -#ifdef SCPH_5903 - volatile ConsoleLogicPtr currentLogic = processScph5903Logic; -#else - volatile ConsoleLogicPtr currentLogic = processStandardLogic; -#endif - - // Variables de contrôle globales // Global buffer to store the 12-byte Sub-Q channel data uint8_t subqBuffer[12]; @@ -225,16 +202,11 @@ void board_detection() { } } -#if defined(PSNEE_DEBUG_SERIAL_MONITOR) - Debug_Log(wfck_mode); -#endif + #if defined(PSNEE_DEBUG_SERIAL_MONITOR) + Debug_Log(wfck_mode); + #endif } - - - - - //****************************************************************************************************************** // Reads a complete 12-byte SUBQ transmission from the CD drive. // Uses clock-edge synchronization and includes a safety timeout for malformatted streams. @@ -265,9 +237,9 @@ void captureSubQ(void) { *bufferPtr++ = currentByte; } while (--bytesRemaining); // Faster than (bytesRemaining < 12) -#if defined(PSNEE_DEBUG_SERIAL_MONITOR) - logSubQ(subqBuffer); -#endif + #if defined(PSNEE_DEBUG_SERIAL_MONITOR) + logSubQ(subqBuffer); + #endif } /************************************************************************************** @@ -282,8 +254,9 @@ void captureSubQ(void) { * isDataSector Boolean flag indicating if the current sector contains data. **************************************************************************************/ +#ifdef SCPH_5903 -void processScph5903Logic(uint8_t isDataSector) { + void processLogic(uint8_t isDataSector) { uint8_t currentHysteresis = hysteresis; // Fast filtering: most sectors fail here by checking sync markers (index 1 and 6) @@ -310,8 +283,8 @@ void processScph5903Logic(uint8_t isDataSector) { if (currentHysteresis > 0) { hysteresis = currentHysteresis - 1; } -} - + } +#else /****************************************************************************************** * Heuristic logic for standard PlayStation hardware (Non-VCD models). * @@ -325,7 +298,8 @@ void processScph5903Logic(uint8_t isDataSector) { ******************************************************************************************/ -void processStandardLogic(uint8_t isDataSector) { + +void processLogic(uint8_t isDataSector) { uint8_t currentHysteresis = hysteresis; // Fast filtering: most sectors fail here by checking sync markers (index 1 and 6) @@ -357,7 +331,9 @@ void processStandardLogic(uint8_t isDataSector) { if (currentHysteresis > 0) { hysteresis = currentHysteresis - 1; } -} + } + +#endif /********************************************************************************************* * Executes the SCEx injection sequence to bypass the CD-ROM regional lockout. @@ -374,168 +350,159 @@ void processStandardLogic(uint8_t isDataSector) { *********************************************************************************************/ void performInjectionSequence(uint8_t injectSCEx) { - /* - Security strings (44-bit SCEx) for the three main regions: - 0: NTSC-J (SCEI - Sony Computer Entertainment Inc.) - 1: NTSC-U/C (SCEA - Sony Computer Entertainment America) - 2: PAL (SCEE - Sony Computer Entertainment Europe) - Stored in 6 bytes (48 bits); only the first 44 bits are used during injection. - */ - static const uint8_t allRegionsSCEx[3][6] = { - { 0x59, 0xC9, 0x4B, 0x5D, 0xDA, 0x02 }, // SCEI - { 0x59, 0xC9, 0x4B, 0x5D, 0xFA, 0x02 }, // SCEA - { 0x59, 0xC9, 0x4B, 0x5D, 0xEA, 0x02 } // SCEE - }; + /* + Security strings (44-bit SCEx) for the three main regions: + 0: NTSC-J (SCEI - Sony Computer Entertainment Inc.) + 1: NTSC-U/C (SCEA - Sony Computer Entertainment America) + 2: PAL (SCEE - Sony Computer Entertainment Europe) + Stored in 6 bytes (48 bits); only the first 44 bits are used during injection. + */ + static const uint8_t allRegionsSCEx[3][6] = { + { 0x59, 0xC9, 0x4B, 0x5D, 0xDA, 0x02 }, // SCEI + { 0x59, 0xC9, 0x4B, 0x5D, 0xFA, 0x02 }, // SCEA + { 0x59, 0xC9, 0x4B, 0x5D, 0xEA, 0x02 } // SCEE + }; - hysteresis = 11; // Reset hysteresis to mid-point after triggering - #ifdef LED_RUN - PIN_LED_ON; - #endif + hysteresis = 11; // Reset hysteresis to mid-point after triggering + #ifdef LED_RUN + PIN_LED_ON; + #endif - // Cache wfck_mode to save CPU cycles during the bit loop - uint8_t isWfck = wfck_mode; + // Cache wfck_mode to save CPU cycles during the bit loop + uint8_t isWfck = wfck_mode; + PIN_DATA_OUTPUT; + PIN_DATA_CLEAR; + + // Legacy boards require the chip to drive the simulated WFCK/Gate + if (!isWfck) { + PIN_WFCK_OUTPUT; + PIN_WFCK_CLEAR; + } + + _delay_ms(DELAY_BETWEEN_INJECTIONS); + + // Loop through the selected region(s) + for (uint8_t i = 0; i < 3; i++) { + uint8_t regionIndex = (injectSCEx == 3) ? i : injectSCEx; + const uint8_t* bytePtr = allRegionsSCEx[regionIndex]; + + uint8_t currentByte = *bytePtr++; + uint8_t bitIdx = 0; + + // Process the 44-bit SCEx stream + for (uint8_t totalBits = 44; totalBits > 0; totalBits--) { + uint8_t currentBit = currentByte & 0x01; + currentByte >>= 1; + bitIdx++; + + // Reload next byte every 8 bits (except the last partial one) + if (bitIdx == 8 && totalBits > 4) { + currentByte = *bytePtr++; + bitIdx = 0; + } + + if (currentBit == 0) { + // BIT 0: Pull DATA low- + PIN_DATA_CLEAR; + if (!isWfck) PIN_DATA_OUTPUT; + _delay_us(DELAY_BETWEEN_BITS); + } else { + // BIT 1: Handle based on board generation + if (!isWfck) { + // Legacy Mode: Set DATA to High-Z (floating) + PIN_DATA_INPUT; + _delay_us(DELAY_BETWEEN_BITS); + } else { + /* + WFCK Modulation Loop: Syncs to 7.3kHz or 14.6kHz. + Follows hardware edges to stay bit-perfect with the console. + */ + uint8_t count = 30; + while (count--) { + while (PIN_WFCK_READ); // Wait for Falling Edge + PIN_DATA_CLEAR; + while (!PIN_WFCK_READ); // Wait for Rising Edge + PIN_DATA_SET; + } + } + } + } + + // Clean up state between region cycles PIN_DATA_OUTPUT; PIN_DATA_CLEAR; - - // Legacy boards require the chip to drive the simulated WFCK/Gate - if (!isWfck) { - PIN_WFCK_OUTPUT; - PIN_WFCK_CLEAR; - } - _delay_ms(DELAY_BETWEEN_INJECTIONS); - // Loop through the selected region(s) - for (uint8_t i = 0; i < 3; i++) { - uint8_t regionIndex = (injectSCEx == 3) ? i : injectSCEx; - const uint8_t* bytePtr = allRegionsSCEx[regionIndex]; - - uint8_t currentByte = *bytePtr++; - uint8_t bitIdx = 0; + /* + EXIT CONDITION: + If we are NOT in Universal mode (3), we stop after the first + successful region injection. + */ + if (injectSCEx != 3) break; + } - // Process the 44-bit SCEx stream - for (uint8_t totalBits = 44; totalBits > 0; totalBits--) { - uint8_t currentBit = currentByte & 0x01; - currentByte >>= 1; - bitIdx++; + // Restore pins to Input/High-Z to avoid signal interference after injection + if (!isWfck) { + PIN_WFCK_INPUT; + PIN_DATA_INPUT; + } - // Reload next byte every 8 bits (except the last partial one) - if (bitIdx == 8 && totalBits > 4) { - currentByte = *bytePtr++; - bitIdx = 0; - } - - if (currentBit == 0) { - // BIT 0: Pull DATA low- - PIN_DATA_CLEAR; - if (!isWfck) PIN_DATA_OUTPUT; - _delay_us(DELAY_BETWEEN_BITS); - } else { - // BIT 1: Handle based on board generation - if (!isWfck) { - // Legacy Mode: Set DATA to High-Z (floating) - PIN_DATA_INPUT; - _delay_us(DELAY_BETWEEN_BITS); - } else { - /* - WFCK Modulation Loop: Syncs to 7.3kHz or 14.6kHz. - Follows hardware edges to stay bit-perfect with the console. - */ - uint8_t count = 30; - while (count--) { - while (PIN_WFCK_READ); // Wait for Falling Edge - PIN_DATA_CLEAR; - while (!PIN_WFCK_READ); // Wait for Rising Edge - PIN_DATA_SET; - } - } - } - } - - // Clean up state between region cycles - PIN_DATA_OUTPUT; - PIN_DATA_CLEAR; - _delay_ms(DELAY_BETWEEN_INJECTIONS); - - /* - EXIT CONDITION: - If we are NOT in Universal mode (3), we stop after the first - successful region injection. - */ - if (injectSCEx != 3) break; - } - - // Restore pins to Input/High-Z to avoid signal interference after injection - if (!isWfck) { - PIN_WFCK_INPUT; - PIN_DATA_INPUT; - } - #ifdef LED_RUN - PIN_LED_OFF; - #endif + #ifdef LED_RUN + PIN_LED_OFF; + #endif -#if defined(PSNEE_DEBUG_SERIAL_MONITOR) - Debug_Inject(); -#endif - + #if defined(PSNEE_DEBUG_SERIAL_MONITOR) + Debug_Inject(); + #endif } - - - - - void Init() { -#if defined(ATmega328_168) - optimizePeripherals(); -#endif + #if defined(ATmega328_168) + optimizePeripherals(); + #endif -#ifdef LED_RUN - PIN_LED_OUTPUT; -#endif + #ifdef LED_RUN + PIN_LED_OUTPUT; + #endif -#ifdef BIOS_PATCH_3 - uint8_t skipPatch = 0; - GLOBAL_INTERRUPT_ENABLE; + #ifdef BIOS_PATCH + //uint8_t skipPatch = 0; -#ifdef SCPH_7000 - // Check hardware switch for SCPH-7000 models - PIN_SWITCH_INPUT; - PIN_SWITCH_SET; - if (PIN_SWITCH_READ == 0){ - skipPatch =1; // Disable patching if switch is triggered - } -#endif +// #ifdef SCPH_7000 +// // Check hardware switch for SCPH-7000 models +// PIN_SWITCH_INPUT; +// PIN_SWITCH_SET; +// if (PIN_SWITCH_READ == 0){ +// skipPatch =1; // Disable patching if switch is triggered +// } +// #endif // #ifdef LED_RUN // PIN_LED_ON; // #endif // Execute BIOS patching unless bypassed by switch - if (skipPatch == 0) { + // if (skipPatch == 0) { Bios_Patching(); - } + // } // #ifdef LED_RUN // PIN_LED_OFF; // #endif -#endif + #endif - - // Disable interrupts and set CD-ROM interface pins to Input - GLOBAL_INTERRUPT_DISABLE; PIN_SQCK_INPUT; PIN_SUBQ_INPUT; -#if defined(PSNEE_DEBUG_SERIAL_MONITOR) && defined(ATtiny85_45_25) - //pinMode(debugtx, OUTPUT); // software serial tx pin - mySerial.begin(115200); // 13,82 bytes in 12ms, max for softwareserial. (expected data: ~13 bytes / 12ms) // update: this is actually quicker -#elif defined(PSNEE_DEBUG_SERIAL_MONITOR) && !defined(ATtiny85_45_25) - Serial.begin(500000); // 60 bytes in 12ms (expected data: ~26 bytes / 12ms) // update: this is actually quicker -#endif + #if defined(PSNEE_DEBUG_SERIAL_MONITOR) && defined(ATtiny85_45_25) + //pinMode(debugtx, OUTPUT); // software serial tx pin + mySerial.begin(115200); // 13,82 bytes in 12ms, max for softwareserial. (expected data: ~13 bytes / 12ms) // update: this is actually quicker + #elif defined(PSNEE_DEBUG_SERIAL_MONITOR) && !defined(ATtiny85_45_25) + Serial.begin(500000); // 60 bytes in 12ms (expected data: ~26 bytes / 12ms) // update: this is actually quicker + #endif // Detect board generation (PU-7 to PU-22+) before starting the main loop board_detection(); @@ -545,12 +512,6 @@ int main() { Init(); -// #ifdef SCPH_5903 -// currentLogic = logic_SCPH_5903; -// #else -// currentLogic = logic_Standard; -// #endif - while (1) { @@ -569,8 +530,8 @@ int main() { uint8_t isDataSector = ((subqBuffer[0] & 0xD0) == 0x40); - // Execute selected logic through function pointer - currentLogic(isDataSector); + // Execute selected logic + processLogic(isDataSector); //Trigger SCEx injection once the confidence threshold is reached if (hysteresis >= HYSTERESIS_MAX) { diff --git a/PSNee/settings.h b/PSNee/settings.h index 9cd9adf..11a1f36 100644 --- a/PSNee/settings.h +++ b/PSNee/settings.h @@ -7,12 +7,6 @@ The temporal precision of _delay_us depends on the microcontroller's clock frequency (F_CPU). For the ATmega328 operating at a typical frequency of 16 MHz, here are some details on the precision. - Clock Frequency: F_CPU must be defined correctly before using the function. For an ATmega328 operating at 16 MHz: - 1 clock cycle = 1 / 16,000,000 s ≈ 62.5 ns - 1 µs ≈ 16 clock cycles - - BIT_OFFSET _delay_us(2.75) = 44 clock cycles - OVERRIDE _delay_us(0.2) = 3,2 clock cycles */ @@ -23,304 +17,138 @@ // tested with an Atmega328P -#ifdef SCPH_102 -#define BIOS_PATCH_2 -#define INTERRUPT_RISING -#define BOOT_OFFSET 83.9 -#define PULSE_COUNT 48 -//#define BIT_OFFSET 2.75 -#define BIT_OFFSET 3.25 //BIOS_PATCH_2 -#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_7000 -#define BIOS_PATCH -#define INTERRUPT_RISING -#define BOOT_OFFSET 75.2 //75.3 -#define PULSE_COUNT 16 -#define BIT_OFFSET 2.8 -#define OVERRIDE 0.2 -#endif - -#ifdef SCPH_5500 -#define BIOS_PATCH -#define INTERRUPT_FALLING -#define BOOT_OFFSET 76.04 //75.99 - 76.14 -#define PULSE_COUNT 21 -#define BIT_OFFSET 2.8 -#define OVERRIDE 0.2 -#endif - -#ifdef SCPH_5000 -#define BIOS_PATCH -#define INTERRUPT_FALLING -#define BOOT_OFFSET 75.2 //75.12 - 75.27 -#define PULSE_COUNT 21 -#define BIT_OFFSET 2.8 //2.7 - 2.85 -#define OVERRIDE 0.1 -#endif - -#ifdef SCPH_3500 -#define BIOS_PATCH -#define INTERRUPT_FALLING -#define BOOT_OFFSET 75.2 //75.12 - 75.27 -#define PULSE_COUNT 21 -#define BIT_OFFSET 2.75 //2.65 - 2.85 -#define OVERRIDE 0.2 -#endif - -#ifdef SCPH_3000 -#define BIOS_PATCH -#define INTERRUPT_RISING_HIGH_PATCH -#define BOOT_OFFSET 82.9 //82.65 - 83.26 -#define PULSE_COUNT 60 -#define BIT_OFFSET 2.7 //2.58 - 2.8 -#define OVERRIDE 0.15 -#define HIGH_PATCH -#define FOLLOWUP_OFFSET 253.3 -#define PULSE_COUNT_2 43 -#define BIT_OFFSET_2 2.88 -#define OVERRIDE_2 0.15 -#endif - -#ifdef SCPH_1000 -#define BIOS_PATCH -#define INTERRUPT_RISING_HIGH_PATCH -#define BOOT_OFFSET 82.9 // 82.63 - 83.26 -#define PULSE_COUNT 92 -#define BIT_OFFSET 2.65 // 2.58 - 2.75 -#define OVERRIDE 0.15 -#define HIGH_PATCH -#define FOLLOWUP_OFFSET 272.8 -#define PULSE_COUNT_2 71 -#define BIT_OFFSET_2 2.88 -#define OVERRIDE_2 0.15 -#endif -// // -------- SCPH 102 -------- -// #ifdef SCPH_102 -// #define BIOS_PATCH_2 -// #define INTERRUPT_RISING +// ------ SCPH 100 / 102 ------ +#if defined(SCPH_100) || \ + defined(SCPH_102) -// #ifdef F_CPU_8MHZ -// #define BOOT_OFFSET_MS 84 -// #define PULSE_COUNT 48 -// #define BIT_OFFSET_CYCLES 26 // 3.25us / 0.125us ≈ 26 cycles -// #define OVERRIDE_CYCLES 2 // 0.2us / 0.125us ≈ 2 cycles -// #elif defined(F_CPU_16MHZ) -// #define BOOT_OFFSET_MS 84 -// #define PULSE_COUNT 48 -// #define BIT_OFFSET_CYCLES 52 // 3.25 / 0.0625 ≈ 52 cycles -// #define OVERRIDE_CYCLES 3 // 0.2 / 0.0625 ≈ 3 cycles -// #endif -// #endif - -// -------- SCPH 100 -------- -#ifdef SCPH_100 -#define BIOS_PATCH_3 -#define INTERRUPT_RISING - -// #ifdef F_CPU_8MHZ -// #define BOOT_OFFSET_MS 84 -// #define PULSE_COUNT 48 -// #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 SILENCE_THRESHOLD 1428 -#define CONFIRM_COUNTER_TARGET 8 -#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 + #define BIOS_PATCH + #define SILENCE_THRESHOLD 1400 + #define CONFIRM_COUNTER_TARGET 8 + #define PULSE_COUNT 47 + #define BIT_OFFSET_CYCLES 67 //60+7 + #define OVERRIDE_CYCLES 3 #endif // #endif // // -------- SCPH 7500 / 9000 -------- #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 SILENCE_THRESHOLD 1428 -#define CONFIRM_COUNTER_TARGET 1 -#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 + #define BIOS_PATCH + #define SILENCE_THRESHOLD 1400 + #define CONFIRM_COUNTER_TARGET 1 + #define PULSE_COUNT 15 + #define BIT_OFFSET_CYCLES 66 //60+ + #define OVERRIDE_CYCLES 4 #endif -// #endif -// // -------- SCPH 7000 -------- -// #ifdef SCPH_7000 -// #define BIOS_PATCH -// #define INTERRUPT_RISING -// #ifdef F_CPU_8MHZ -// #define BOOT_OFFSET_MS 75 -// #define PULSE_COUNT 16 -// #define BIT_OFFSET_CYCLES 22 -// #define OVERRIDE_CYCLES 2 -// #elif defined(F_CPU_16MHZ) -// #define BOOT_OFFSET_MS 75 -// #define PULSE_COUNT 16 -// #define BIT_OFFSET_CYCLES 45 -// #define OVERRIDE_CYCLES 3 -// #endif -// #endif +// -------- SCPH 7000 -------- +#ifdef SCPH_7000 + #define BIOS_PATCH + #define SILENCE_THRESHOLD 1400 + #define CONFIRM_COUNTER_TARGET 1 + #define PULSE_COUNT 15 + #define BIT_OFFSET_CYCLES 66 + #define OVERRIDE_CYCLES 4 +#endif -// // -------- SCPH 5500 -------- -// #ifdef SCPH_5500 -// #define BIOS_PATCH -// #define INTERRUPT_FALLING -// #ifdef F_CPU_8MHZ -// #define BOOT_OFFSET_MS 76 -// #define PULSE_COUNT 21 -// #define BIT_OFFSET_CYCLES 22 -// #define OVERRIDE_CYCLES 2 -// #elif defined(F_CPU_16MHZ) -// #define BOOT_OFFSET_MS 76 -// #define PULSE_COUNT 21 -// #define BIT_OFFSET_CYCLES 45 -// #define OVERRIDE_CYCLES 3 -// #endif -// #endif +// // ----- SCPH 5000 / 5500 ----- +#ifdef SCPH_5000_5500 + #define BIOS_PATCH + #define SILENCE_THRESHOLD 35000 + #define CONFIRM_COUNTER_TARGET 1 + #define PULSE_COUNT 84 + #define BIT_OFFSET_CYCLES 60 + #define OVERRIDE_CYCLES 3 +#endif -// // -------- SCPH 5000 -------- + +// // // -------- SCPH 5000 -------- // #ifdef SCPH_5000 -// #define BIOS_PATCH -// #define INTERRUPT_FALLING - -// #ifdef F_CPU_8MHZ -// #define BOOT_OFFSET_MS 75 -// #define PULSE_COUNT 21 -// #define BIT_OFFSET_CYCLES 22 -// #define OVERRIDE_CYCLES 1 -// #elif defined(F_CPU_16MHZ) -// #define BOOT_OFFSET_MS 75 -// #define PULSE_COUNT 21 -// #define BIT_OFFSET_CYCLES 45 -// #define OVERRIDE_CYCLES 2 -// #endif +// #define BIOS_PATCH_3 +// #define INTERRUPT_RISING +// #define SILENCE_THRESHOLD 35000 +// #define CONFIRM_COUNTER_TARGET 1 +// #define PULSE_COUNT 84 +// #define BIT_OFFSET_CYCLES 60 +// #define OVERRIDE_CYCLES 3 // #endif +// // #endif // // -------- SCPH 3500 -------- -// #ifdef SCPH_3500 -// #define BIOS_PATCH -// #define INTERRUPT_FALLING +#ifdef SCPH_3500 + #define BIOS_PATCH + #define SILENCE_THRESHOLD 34000 + #define CONFIRM_COUNTER_TARGET 1 + #define PULSE_COUNT 85 + #define BIT_OFFSET_CYCLES 44 + #define OVERRIDE_CYCLES 3 +#endif -// #ifdef F_CPU_8MHZ -// #define BOOT_OFFSET_MS 75 -// #define PULSE_COUNT 21 -// #define BIT_OFFSET_CYCLES 22 -// #define OVERRIDE_CYCLES 2 -// #elif defined(F_CPU_16MHZ) -// #define BOOT_OFFSET_MS 75 -// #define PULSE_COUNT 21 -// #define BIT_OFFSET_CYCLES 44 -// #define OVERRIDE_CYCLES 3 -// #endif -// #endif // // -------- SCPH 3000 -------- -// #ifdef SCPH_3000 -// #define BIOS_PATCH -// #define INTERRUPT_RISING_HIGH_PATCH -// #define HIGH_PATCH +#ifdef SCPH_3000 + #define BIOS_PATCH + #define INTERRUPT_RISING_HIGH_PATCH + #define SILENCE_THRESHOLD 1200 + #define CONFIRM_COUNTER_TARGET 9 + #define PULSE_COUNT 60 + #define BIT_OFFSET_CYCLES 46 + #define OVERRIDE_CYCLES 3 + #define SILENCE_THRESHOLD_2 1200 + #define CONFIRM_COUNTER_TARGET_2 206 + #define PULSE_COUNT_2 43 + #define BIT_OFFSET_2_CYCLES 54 + #define OVERRIDE_2_CYCLES 2 +#endif -// #ifdef F_CPU_8MHZ -// #define BOOT_OFFSET_MS 83 -// #define PULSE_COUNT 60 -// #define BIT_OFFSET_CYCLES 22 -// #define OVERRIDE_CYCLES 1 -// #define FOLLOWUP_OFFSET_MS 253 -// #define PULSE_COUNT_2 43 -// #define BIT_OFFSET_2_CYCLES 23 -// #define OVERRIDE_2_CYCLES 1 -// #elif defined(F_CPU_16MHZ) -// #define BOOT_OFFSET_MS 83 -// #define PULSE_COUNT 60 -// #define BIT_OFFSET_CYCLES 43 -// #define OVERRIDE_CYCLES 2 -// #define FOLLOWUP_OFFSET_MS 253 -// #define PULSE_COUNT_2 43 -// #define BIT_OFFSET_2_CYCLES 46 -// #define OVERRIDE_2_CYCLES 2 -// #endif -// #endif // // -------- SCPH 1000 -------- -// #ifdef SCPH_1000 -// #define BIOS_PATCH -// #define INTERRUPT_RISING_HIGH_PATCH -// #define HIGH_PATCH - -// #ifdef F_CPU_8MHZ -// #define BOOT_OFFSET_MS 83 -// #define PULSE_COUNT 92 -// #define BIT_OFFSET_CYCLES 21 -// #define OVERRIDE_CYCLES 1 -// #define FOLLOWUP_OFFSET_MS 273 -// #define PULSE_COUNT_2 71 -// #define BIT_OFFSET_2_CYCLES 23 -// #define OVERRIDE_2_CYCLES 1 -// #elif defined(F_CPU_16MHZ) -// #define BOOT_OFFSET_MS 83 -// #define PULSE_COUNT 92 -// #define BIT_OFFSET_CYCLES 42 -// #define OVERRIDE_CYCLES 2 -// #define FOLLOWUP_OFFSET_MS 273 -// #define PULSE_COUNT_2 71 -// #define BIT_OFFSET_2_CYCLES 46 -// #define OVERRIDE_2_CYCLES 2 -// #endif +#ifdef SCPH_1000 + #define BIOS_PATCH + #define INTERRUPT_RISING_HIGH_PATCH + #define SILENCE_THRESHOLD 1300 + #define CONFIRM_COUNTER_TARGET 9 + #define PULSE_COUNT 91 + #define BIT_OFFSET_CYCLES 58 + #define OVERRIDE_CYCLES 3 + #define CONFIRM_COUNTER_TARGET_2 222 + #define PULSE_COUNT_2 71 + #define BIT_OFFSET_2_CYCLES 54 + #define OVERRIDE_2_CYCLES 3 +#endif // #endif /*------------------------------------------------------------------------------------------------ Region Settings Section ------------------------------------------------------------------------------------------------*/ -#if defined(SCPH_100) || defined(SCPH_7500_9000) || defined(SCPH_7000) || \ - defined(SCPH_5500) || defined(SCPH_5000) ||defined(SCPH_3500) || defined(SCPH_3000) || \ - defined(SCPH_1000) || defined(SCPH_xxx3) || defined(SCPH_5903) - #define INJECT_SCEx 0 // NTSC-J -#endif +#if defined(SCPH_100) || \ + defined(SCPH_7500_9000) || \ + defined(SCPH_7000) || \ + defined(SCPH_5000_5500) || \ + defined(SCPH_3500) || \ + defined(SCPH_3000) || \ + defined(SCPH_1000) || \ + defined(SCPH_xxx3) || \ + defined(SCPH_5903) -#if defined(SCPH_xxx1) - #define INJECT_SCEx 1 // NTSC-U/C -#endif + #define INJECT_SCEx 0 // NTSC-J -#if defined(SCPH_xxx2) || defined(SCPH_102) - #define INJECT_SCEx 2 // PAL -#endif +#elif defined(SCPH_xxx1) + + #define INJECT_SCEx 1 // NTSC-U/C + +#elif defined(SCPH_xxx2) || \ + defined(SCPH_102) + + #define INJECT_SCEx 2 // PAL + +#elif defined(SCPH_xxxx) + + #define INJECT_SCEx 3 // Universal: NTSC-J -> NTSC-U/C -> PAL -#if defined(SCPH_xxxx) - #define INJECT_SCEx 3 // Universal: NTSC-J -> NTSC-U/C -> PAL #endif @@ -335,7 +163,7 @@ void Debug_Log (int Wfck_mode){ //Information about the MCU, and old or #if defined(ATtiny85_45_25) mySerial.print("m "); mySerial.println(Wfck_mode); -#elif !defined(ATtiny85_45_25) +#else Serial.print(" MCU frequency: "); Serial.print(F_CPU); Serial.println(" Hz"); //Serial.print(" lows: "); Serial.println(Lows); Serial.print(" wfck_mode: "); Serial.println(Wfck_mode); @@ -380,7 +208,7 @@ void Debug_Inject(){ // Confirmation of region code injection #if defined(ATtiny85_45_25) mySerial.print("!"); -#elif !defined(ATtiny85_45_25)|| defined(SCPH_102_legacy) +#else Serial.println(" INJECT ! "); #endif } @@ -391,26 +219,50 @@ void Debug_Inject(){ // Confirmation of region code injection Compilation message -----------------------------------------------------------------------------------------------*/ -#if !defined(SCPH_xxx3) && \ - !defined(SCPH_102) && !defined(SCPH_101) && !defined(SCPH_100) && !defined(SCPH_7500_9000) && \ - !defined(SCPH_7000) && !defined(SCPH_5500) && !defined(SCPH_5000) && !defined(SCPH_3500) && !defined(SCPH_3000) && \ - !defined(SCPH_1000) && !defined(SCPH_5903) &&\ - !defined(SCPH_xxx1) && !defined(SCPH_xxx2) && !defined(SCPH_xxxx) +#if !defined(SCPH_xxx3) && \ + !defined(SCPH_102) && \ + !defined(SCPH_101) && \ + !defined(SCPH_100) && \ + !defined(SCPH_7500_9000) && \ + !defined(SCPH_7000) && \ + !defined(SCPH_5000_5500) && \ + !defined(SCPH_3500) && \ + !defined(SCPH_3000) && \ + !defined(SCPH_1000) && \ + !defined(SCPH_5903) && \ + !defined(SCPH_xxx1) && \ + !defined(SCPH_xxx2) && \ + !defined(SCPH_xxxx) #error "Console not selected! Please uncoment #define with SCPH model number." -#elif !defined(SCPH_xxx3) ^ \ - defined(SCPH_102) ^ defined(SCPH_101) ^ defined(SCPH_100) ^ defined(SCPH_7500_9000) ^ \ - defined(SCPH_7000) ^ defined(SCPH_5500) ^ defined(SCPH_5000) ^ defined(SCPH_3500) ^ defined(SCPH_3000) ^ \ - defined(SCPH_1000) ^ defined(SCPH_xxxx) ^ defined(SCPH_5903) ^ \ - defined(SCPH_xxx1) ^ defined(SCPH_xxx2) +#elif !defined(SCPH_xxx3) ^ \ + defined(SCPH_102) ^ \ + defined(SCPH_101) ^ \ + defined(SCPH_100) ^ \ + defined(SCPH_7500_9000) ^ \ + defined(SCPH_7000) ^ \ + defined(SCPH_5000_5500) ^ \ + defined(SCPH_3500) ^ \ + defined(SCPH_3000) ^ \ + defined(SCPH_1000) ^ \ + defined(SCPH_xxxx) ^ \ + defined(SCPH_5903) ^ \ + defined(SCPH_xxx1) ^ \ + defined(SCPH_xxx2) #error "May be selected only one console! Please check #define with SCPH model number." #endif -#if !defined(ATmega328_168) && !defined(ATmega32U4_16U4) && !defined(ATtiny85_45_25) +#if !defined(ATmega328_168) && \ + !defined(ATmega32U4_16U4) && \ + !defined(ATtiny85_45_25) #error "MCU not selected! Please choose one" -#elif !defined(ATmega328_168) ^ defined(ATmega32U4_16U4 ) ^ defined(ATtiny85_45_25) +#elif !defined(ATmega328_168) ^ \ + defined(ATmega32U4_16U4 ) ^ \ + defined(ATtiny85_45_25) #error "May be selected only one MCU" #endif -#if defined(LED_RUN) && defined(PSNEE_DEBUG_SERIAL_MONITOR) && defined(ATtiny85_45_25) +#if defined(LED_RUN) && \ + defined(PSNEE_DEBUG_SERIAL_MONITOR) && \ + defined(ATtiny85_45_25) #error"Compilation options LED_RUN and PSNEE_DEBUG_SERIAL_MONITOR are not simultaneously compatible with ATtiny85_45_25" #endif