mirror of
https://github.com/kalymos/PsNee.git
synced 2026-05-09 16:46:23 +00:00
* MUC-MCU Fixed the MUC-MCU file name. Fixed a bug that prevented additional MCUs from being compiled. Modified the clock registers for ATtiny 48-88s; the TCCROB register is missing in these MUCs. * Too many things to summarize Refactoring of the setting file, to be able to have settings specifying the HYSTERESIS_MAX variable. Renamed precompilation variable in BIOS_patching file. Changing console selection in .ino file * Renaming files to make updating easier * Update README.md * logo 8.7 * optimization on regin injection * Ad bios patch 102A, and correct some images. * SCPH_102A bios patch WIP * Cleaning the selection area Redesign of the selection area, and addition of the SCPH_hyma mode equivalent to the legacy mode with the difference of a hysteresis of 25 * Layout modification * clining * ad debug mode * debug mesga * creation of debug functions, and cleaning * Update PSNee.ino * serial debug cleaning * added compilation message * some comment cleaning * removal of the TIMER removal of the ISR(CTC_TIMER_VECTOR) function, and all its dependencies. - Timer_Start - Timer_Stop modification - Board detection - inject_SCEX - BIOS_PATCH - MCU - Setting * Update PSNee.ino Implementing a dedicated board_detection function with optimized logic. Remodeling the inject_SCEX function. * timer optimization * Breaking down the main function into smaller modules. Modular breakdown: Separated main logic into - captureSubQ, - logic_SCPH_5903, - logic_Standard, - performInjectionSequence. Added support for SCPH-5903 by RepairBox Co-Authored-By: RepairBox <33960601+danielfergisz@users.noreply.github.com> * Optimization performInjectionSequence(): Deep refactor with a cleaner. captureSubQ(): Faster bit-banging and improved timing accuracy. board_detection(): Optimized logic . General Cleanup: Fixed all warnings and minimized memory footprint. * Optimization Optimization of the performInjectionSequence function BIOS patch verification (work in progress) and general code cleanup * BIOS patch obtimisation * opti patch bios 3500 * opti bios patch SCPH-1000 * opti BIOS patch SCPH-3000, SCPH-100. * refactor: optimize BIOS patching sequence with refined timing nomenclature Refined the BIOS patching and standardized timing nomenclature for better technical clarity. Changes: - Ad technical documentation within the code. - Standardized timing variables for better clarity: - BOOT_OFFSET: Replaces initial checkpoint. - FOLLOWUP_OFFSET: Replaces initial checkpoint2. - PULSE_COUNT: Replaces trigger . - BIT_OFFSET: Replaces hold . - OVERRIDE: Replaces patching. * 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. * test neo BIOS patch * Refactor pulse counting logic for jitter reduction * BIOS patch simplification Removal of ISR and reduction of code in the BIOS patch, for improved portability and robustness. For now it is only available for the SCPH-100 and 102. * BIOS patche neo for SCPH-9000_7500 SCPH-7000 SCPH-5500 * BIOS patch neo SCPH-5000 SCPH-3500 * BIOS patche neo SCPH-3000 SCPH-1000 I finally completed the value conversion for the BIOS patch without IRS * refactor: optimize core detection and injection logic for performance and size - board_detection: Added early exit for newer boards and tightened the sampling loop to reduce CPU overhead. - captureSubQ: Simplified clock-edge synchronization and localized buffers to improve register allocation. - performInjectionSequence: Replaced bit-calculation math with a streamlined byte-shift approach. Refined WFCK modulation to ensure zero-jitter phase locking. - logic_Standard/5903: Refactored pattern matching into a decision tree. Factorized redundant buffer checks (scbuf[1]/[6]) and replaced multiple equality tests with range comparisons. Optimization results: - Reduced Flash memory footprint (smaller binary size). - Improved execution speed by removing redundant logical operations. - Increased signal stability during the critical injection phase. * PSNee v9.0 Update New PSNeeCore v2: Completely rewritten core engine for all supported MCUs. Auto-MCU Detection: Manual board selection removed. Automatically detects ATmega (328/168/128/PB), 32U4, and ATtiny families at compile time. Deep Init Optimization: Hard-shutdown of unused internal modules (ADC, DAC, Timers) to minimize power draw and electrical noise. Native PB Support: Full compatibility for 128PB and 328PB (PRR2 registers and extra Ports). * PSNee v9.0 Update New PSNeeCore v2: Completely rewritten core engine for all supported MCUs. Auto-MCU Detection: Manual board selection removed. Automatically detects ATmega (328/168/128/PB), 32U4, and ATtiny families at compile time. Deep Init Optimization: Hard-shutdown of unused internal modules (ADC, DAC, Timers) to minimize power draw and electrical noise. Native PB Support: Full compatibility for 128PB and 328PB (PRR2 registers and extra Ports). logo --------- Co-authored-by: RepairBox <33960601+danielfergisz@users.noreply.github.com>
334 lines
9.8 KiB
C
334 lines
9.8 KiB
C
#pragma once
|
|
|
|
/*
|
|
*
|
|
*
|
|
*/
|
|
|
|
/*------------------------------------------------------------------------------------------------
|
|
Specific parameter section for BIOS patches
|
|
------------------------------------------------------------------------------------------------*/
|
|
|
|
// Results of the maximum values
|
|
// tested with an Atmega328P
|
|
|
|
#if defined(IS_32U4_FAMILY)
|
|
|
|
// ------ SCPH 100 / 102 ------
|
|
#if defined(SCPH_100) || \
|
|
defined(SCPH_102)
|
|
#define BIOS_PATCH
|
|
#define SILENCE_THRESHOLD 1100
|
|
#define CONFIRM_COUNTER_TARGET 8
|
|
#define PULSE_COUNT 47
|
|
#define BIT_OFFSET_CYCLES 47
|
|
#define OVERRIDE_CYCLES 3
|
|
#endif
|
|
|
|
|
|
// // -------- SCPH 7000 / 7500 / 9000 --------
|
|
#ifdef SCPH_7000_7500_9000
|
|
#define BIOS_PATCH
|
|
#define SILENCE_THRESHOLD 1100
|
|
#define CONFIRM_COUNTER_TARGET 1
|
|
#define PULSE_COUNT 15
|
|
#define BIT_OFFSET_CYCLES 47
|
|
#define OVERRIDE_CYCLES 3
|
|
#endif
|
|
|
|
// // ----- SCPH 3500 / 5000 / 5500 -----
|
|
#ifdef SCPH_3500_5000_5500
|
|
#define BIOS_PATCH
|
|
#define SILENCE_THRESHOLD 25000
|
|
#define CONFIRM_COUNTER_TARGET 1
|
|
#define PULSE_COUNT 84
|
|
#define BIT_OFFSET_CYCLES 47
|
|
#define OVERRIDE_CYCLES 3
|
|
#endif
|
|
|
|
// // -------- SCPH 3000 --------
|
|
#ifdef SCPH_3000
|
|
#define BIOS_PATCH
|
|
#define PHASE_TWO_PATCH
|
|
#define SILENCE_THRESHOLD 1100
|
|
#define CONFIRM_COUNTER_TARGET 9
|
|
#define PULSE_COUNT 59
|
|
#define BIT_OFFSET_CYCLES 45
|
|
#define OVERRIDE_CYCLES 4
|
|
#define CONFIRM_COUNTER_TARGET_2 206
|
|
#define PULSE_COUNT_2 42
|
|
#define BIT_OFFSET_2_CYCLES 48
|
|
#define OVERRIDE_2_CYCLES 3
|
|
#endif
|
|
|
|
|
|
// // -------- SCPH 1000 --------
|
|
#ifdef SCPH_1000
|
|
#define BIOS_PATCH
|
|
#define PHASE_TWO_PATCH
|
|
#define SILENCE_THRESHOLD 1100
|
|
#define CONFIRM_COUNTER_TARGET 9
|
|
#define PULSE_COUNT 91
|
|
#define BIT_OFFSET_CYCLES 43
|
|
#define OVERRIDE_CYCLES 3
|
|
#define CONFIRM_COUNTER_TARGET_2 222
|
|
#define PULSE_COUNT_2 70
|
|
#define BIT_OFFSET_2_CYCLES 48
|
|
#define OVERRIDE_2_CYCLES 3
|
|
#endif
|
|
#endif
|
|
|
|
#if defined(IS_328_168_FAMILY)
|
|
|
|
// ------ SCPH 100 / 102 ------
|
|
#if defined(SCPH_100) || \
|
|
defined(SCPH_102)
|
|
#define BIOS_PATCH
|
|
#define SILENCE_THRESHOLD 1500
|
|
#define CONFIRM_COUNTER_TARGET 8
|
|
#define PULSE_COUNT 47
|
|
#define BIT_OFFSET_CYCLES 47
|
|
#define OVERRIDE_CYCLES 3
|
|
#endif
|
|
|
|
|
|
// // -------- SCPH 7000 / 7500 / 9000 --------
|
|
#ifdef SCPH_7000_7500_9000
|
|
#define BIOS_PATCH
|
|
#define SILENCE_THRESHOLD 1500
|
|
#define CONFIRM_COUNTER_TARGET 1
|
|
#define PULSE_COUNT 15
|
|
#define BIT_OFFSET_CYCLES 47
|
|
#define OVERRIDE_CYCLES 3
|
|
#endif
|
|
|
|
// // ----- SCPH 3500 / 5000 / 5500 -----
|
|
#ifdef SCPH_3500_5000_5500
|
|
#define BIOS_PATCH
|
|
#define SILENCE_THRESHOLD 32000
|
|
#define CONFIRM_COUNTER_TARGET 1
|
|
#define PULSE_COUNT 84
|
|
#define BIT_OFFSET_CYCLES 47
|
|
#define OVERRIDE_CYCLES 3
|
|
#endif
|
|
|
|
// // -------- SCPH 3000 --------
|
|
#ifdef SCPH_3000
|
|
#define BIOS_PATCH
|
|
#define PHASE_TWO_PATCH
|
|
#define SILENCE_THRESHOLD 1500
|
|
#define CONFIRM_COUNTER_TARGET 9
|
|
#define PULSE_COUNT 59
|
|
#define BIT_OFFSET_CYCLES 45
|
|
#define OVERRIDE_CYCLES 3
|
|
#define CONFIRM_COUNTER_TARGET_2 206
|
|
#define PULSE_COUNT_2 42
|
|
#define BIT_OFFSET_2_CYCLES 48
|
|
#define OVERRIDE_2_CYCLES 3
|
|
#endif
|
|
|
|
|
|
// // -------- SCPH 1000 --------
|
|
#ifdef SCPH_1000
|
|
#define BIOS_PATCH
|
|
#define PHASE_TWO_PATCH
|
|
#define SILENCE_THRESHOLD 1500
|
|
#define CONFIRM_COUNTER_TARGET 9
|
|
#define PULSE_COUNT 91
|
|
#define BIT_OFFSET_CYCLES 45
|
|
#define OVERRIDE_CYCLES 3
|
|
#define CONFIRM_COUNTER_TARGET_2 222
|
|
#define PULSE_COUNT_2 70
|
|
#define BIT_OFFSET_2_CYCLES 48
|
|
#define OVERRIDE_2_CYCLES 3
|
|
#endif
|
|
#endif
|
|
|
|
/*------------------------------------------------------------------------------------------------
|
|
Region Settings Section
|
|
------------------------------------------------------------------------------------------------*/
|
|
|
|
#if defined(SCPH_100) || \
|
|
defined(SCPH_7000_7500_9000) || \
|
|
defined(SCPH_3500_5000_5500) || \
|
|
defined(SCPH_3000) || \
|
|
defined(SCPH_1000) || \
|
|
defined(SCPH_xxx3) || \
|
|
defined(SCPH_5903)
|
|
|
|
#define INJECT_SCEx 0 // NTSC-J
|
|
|
|
#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
|
|
|
|
#endif
|
|
|
|
/*------------------------------------------------------------------------------------------------
|
|
serial debug section
|
|
------------------------------------------------------------------------------------------------*/
|
|
|
|
#if defined(DEBUG_SERIAL_MONITOR)
|
|
extern uint8_t request_counter;
|
|
|
|
#if defined(IS_32U4_FAMILY)
|
|
#define DEBUG_OUT Serial1
|
|
#else
|
|
#define DEBUG_OUT Serial
|
|
#endif
|
|
|
|
void BoardDetectionLog (uint16_t window_result, uint8_t Wfck_mode, uint8_t region){ //Information about the MCU, and old or late console mode.
|
|
|
|
#if defined(IS_ATTINY_FAMILY)
|
|
mySerial.print("m "); mySerial.println(Wfck_mode);
|
|
#else
|
|
static const char* regionNames[] = {
|
|
"NTSC-J", // 0
|
|
"NTSC-U/C", // 1
|
|
"PAL", // 2
|
|
"Universal" // 3
|
|
};
|
|
|
|
DEBUG_OUT.println("");
|
|
DEBUG_OUT.print(F(" CPU Speed: ")); DEBUG_OUT.print(F_CPU / 1000000L); DEBUG_OUT.println(F(" MHz"));
|
|
DEBUG_OUT.print(F(" Sync Window: ")); DEBUG_OUT.println(window_result); // Real-time diagnostic
|
|
DEBUG_OUT.print(F(" WFCK Mode: ")); DEBUG_OUT.println(Wfck_mode);
|
|
DEBUG_OUT.print(F(" Region ID: ")); DEBUG_OUT.println(regionNames[region]);
|
|
DEBUG_OUT.println("");
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
void CaptureSUBQLog(uint8_t *dataBuffer) {
|
|
static uint16_t errorCount = 0; // Tracks missed sectors between valid reads
|
|
|
|
// Cache the first 4 bytes for a quick null check (failed read)
|
|
uint8_t b0 = dataBuffer[0], b1 = dataBuffer[1], b2 = dataBuffer[2], b3 = dataBuffer[3];
|
|
|
|
// --- ERROR FILTERING ---
|
|
// If the sector is empty (all zeros), increment error counter and exit
|
|
if (b0 == 0 && b1 == 0 && b2 == 0 && b3 == 0) {
|
|
errorCount++;
|
|
return;
|
|
}
|
|
|
|
|
|
// --- DATA & request_counter DISPLAY ---
|
|
#if defined(IS_ATTINY_FAMILY)
|
|
// Compact hex output for ATtiny to maintain 12ms timing
|
|
for (uint8_t i = 0; i < 12; i++) {
|
|
uint8_t val = dataBuffer[i];
|
|
if (val < 0x10) mySerial.print("0");
|
|
mySerial.print(val, HEX);
|
|
}
|
|
// Append global request_counter on the same line
|
|
mySerial.print(F(" h:"));
|
|
mySerial.println(request_counter);
|
|
#else
|
|
// Formatted hex output for ATmega
|
|
for (uint8_t i = 0; i < 12; i++) {
|
|
uint8_t val = dataBuffer[i];
|
|
if (val < 0x10) DEBUG_OUT.print("0");
|
|
DEBUG_OUT.print(val, HEX);
|
|
DEBUG_OUT.print(" ");
|
|
}
|
|
// Append global request_counter on the same line
|
|
DEBUG_OUT.print(F("| Hyst: "));
|
|
DEBUG_OUT.println(request_counter);
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
void InjectLog(){
|
|
|
|
#if defined(IS_ATTINY_FAMILY)
|
|
mySerial.print("!"); // --- MINIMALIST NOTIFICATION (ATtiny) ---
|
|
#else
|
|
DEBUG_OUT.println(" INJECT ! ");
|
|
#endif
|
|
}
|
|
|
|
#endif
|
|
|
|
/*------------------------------------------------------------------------------------------------
|
|
Compilation message
|
|
-----------------------------------------------------------------------------------------------*/
|
|
#if (REQUEST_INJECT_GAP >= REQUEST_INJECT_TRIGGER)
|
|
#error "Critical Error: REQUEST_INJECT_GAP must be smaller than REQUEST_INJECT_TRIGGER!"
|
|
#endif
|
|
|
|
#ifdef LED_RUN
|
|
#pragma message "Feature: Status LED ENABLED"
|
|
#endif
|
|
|
|
// SECURITY CHECK: Ensure only one console is selected
|
|
// If you get "not portable" warnings here, it's only because multiple models are active.
|
|
#if (defined(SCPH_1000) + defined(SCPH_3000) + defined(SCPH_3500_5000_5500) + \
|
|
defined(SCPH_7000_7500_9000) + defined(SCPH_100) + \
|
|
defined(SCPH_102) + defined(SCPH_xxx1) + defined(SCPH_xxx2) + \
|
|
defined(SCPH_xxx3) + defined(SCPH_5903) + defined(SCPH_xxxx)) > 1
|
|
#error "Too many consoles selected! Please uncomment ONLY ONE model."
|
|
#endif
|
|
|
|
// Show target console.
|
|
#if defined(SCPH_1000)
|
|
#pragma message "Target Console: SCPH-1000 (NTSC-J)"
|
|
#elif defined(SCPH_3000)
|
|
#pragma message "Target Console: SCPH-3000 (NTSC-J)"
|
|
#elif defined(SCPH_3500_5000_5500)
|
|
#pragma message "Target Console: SCPH-3500/5000/5500 (NTSC-J)"
|
|
#elif defined(SCPH_7000_7500_9000)
|
|
#pragma message "Target Console: SCPH-7500/9000 (NTSC-J)"
|
|
#elif defined(SCPH_100)
|
|
#pragma message "Target Console: SCPH-100 (NTSC-J)"
|
|
#elif defined(SCPH_102)
|
|
#pragma message "Target Console: SCPH-102 (PAL)"
|
|
#elif defined(SCPH_xxx1)
|
|
#pragma message "Target Console: SCPH_xxx1 Generic NTSC-U/C"
|
|
#elif defined(SCPH_xxx2)
|
|
#pragma message "Target Console: SCPH_xxx2 Generic PAL"
|
|
#elif defined(SCPH_xxx3)
|
|
#pragma message "Target Console: SCPH_xxx3 Generic NTSC-J"
|
|
#elif defined(SCPH_5903)
|
|
#pragma message "Target Console: SCPH-5903 (Video CD Dual-Interface)"
|
|
#elif defined(SCPH_xxxx)
|
|
#pragma message "Target Console: SCPH_xxxx Universal Region Mode"
|
|
#else
|
|
// Error if no console is uncommented
|
|
#error "Console not selected! Please uncomment one SCPH model."
|
|
#endif
|
|
|
|
// Show detected microcontroller (e.g. __AVR_atmega328p__)
|
|
#define STRINGIZE(x) #x
|
|
#define TO_STR(x) STRINGIZE(x)
|
|
|
|
#ifdef __AVR_DEVICE_NAME__
|
|
#pragma message "Microcontroller: __AVR_" TO_STR(__AVR_DEVICE_NAME__) "__"
|
|
#endif
|
|
|
|
// --- RESOURCE CONFLICT CHECK (ATtiny) ---
|
|
#if defined(IS_ATTINY_FAMILY) && \
|
|
defined(LED_RUN) && \
|
|
defined(DEBUG_SERIAL_MONITOR)
|
|
#error "Resource conflict: LED_RUN and DEBUG_SERIAL are incompatible on ATtiny."
|
|
#endif
|
|
|
|
// --- Feature Status ---
|
|
|
|
#ifdef DEBUG_SERIAL_MONITOR
|
|
#pragma message "Feature: Serial Debug Monitor ENABLED"
|
|
#endif
|
|
|
|
|