1
0
mirror of https://github.com/kalymos/PsNee.git synced 2026-05-11 01:19:38 +00:00

refactor: MCU-specific power optimization and 32U4 BIOS patch

Implemented OptimizePeripherals for ATmega328PB  (dual-rail PRR support).
Tuned ATmega32U4 for BIOS patching: disabled USB interrupts and optimized peripheral shutdown.
Cleaned up ATtiny85/45/25 peripheral management for better timing reliability.
This commit is contained in:
kalymos
2026-03-19 20:10:27 +01:00
parent bd542e78d0
commit a0df6f1572
4 changed files with 241 additions and 126 deletions

View File

@@ -47,7 +47,7 @@ ISR(PIN_AX_INTERRUPT_VECTOR) {
// Precise bit-alignment delay within the memory cycle
__builtin_avr_delay_cycles(BIT_OFFSET_CYCLES);
#ifdef INTERRUPT_RISING_HIGH_PATCH
#ifdef PHASE_TWO_PATCH
PIN_DX_SET; // Pre-drive high if required by specific logic
#endif
@@ -55,7 +55,7 @@ ISR(PIN_AX_INTERRUPT_VECTOR) {
PIN_DX_OUTPUT;
__builtin_avr_delay_cycles(OVERRIDE_CYCLES);
#ifdef INTERRUPT_RISING_HIGH_PATCH
#ifdef PHASE_TWO_PATCH
PIN_DX_CLEAR;
#endif
@@ -68,7 +68,7 @@ ISR(PIN_AX_INTERRUPT_VECTOR) {
}
}
#ifdef INTERRUPT_RISING_HIGH_PATCH
#ifdef PHASE_TWO_PATCH
/**
* PHASE 5: Secondary Interrupt Service Routine (AY)
* Handles the second injection stage if multi-patching is active.
@@ -130,6 +130,10 @@ void Bios_Patching(void) {
while (WAIT_AX_FALLING);
break; // Impulse detected: retry current silence block
}
#ifdef ATmega32U4_16U4
__asm__ __volatile__ ("nop");
#endif
count--;
}
if (count == 0) {
@@ -148,7 +152,7 @@ void Bios_Patching(void) {
// --- PHASE 4 & 5: SECONDARY PATCHING SEQUENCE ---
#ifdef INTERRUPT_RISING_HIGH_PATCH
#ifdef PHASE_TWO_PATCH
PIN_AY_INPUT;
current_confirms = 0;
impulse = PULSE_COUNT_2;
@@ -160,6 +164,11 @@ void Bios_Patching(void) {
while (WAIT_AX_FALLING);
break;
}
#ifdef ATmega32U4_16U4
__asm__ __volatile__ ("nop");
#endif
count--;
}
if (count == 0) {
@@ -209,14 +218,14 @@ void Bios_Patching(void) {
// // Precise cycle-accurate delay before triggering
// __builtin_avr_delay_cycles(BIT_OFFSET_CYCLES);
// #ifdef INTERRUPT_RISING_HIGH_PATCH
// #ifdef PHASE_TWO_PATCH
// PIN_DX_SET;
// #endif
// PIN_DX_OUTPUT; // Pull the line (Override start)
// __builtin_avr_delay_cycles(OVERRIDE_CYCLES);
// #ifdef INTERRUPT_RISING_HIGH_PATCH
// #ifdef PHASE_TWO_PATCH
// PIN_DX_CLEAR; // Release the bus (Override end)
// #endif
@@ -228,7 +237,7 @@ void Bios_Patching(void) {
// }
// }
// #ifdef INTERRUPT_RISING_HIGH_PATCH
// #ifdef PHASE_TWO_PATCH
// ISR(PIN_AY_INTERRUPT_VECTOR){
@@ -292,7 +301,7 @@ void Bios_Patching(void) {
// //PIN_LED_OFF;
// // -------- Secondary Patch ----------
// #ifdef INTERRUPT_RISING_HIGH_PATCH
// #ifdef PHASE_TWO_PATCH
// current_confirms = 0;
// while (current_confirms < CONFIRM_COUNTER_TARGET_2) {

View File

@@ -224,7 +224,8 @@
#pragma once
#ifdef ATmega328_168
#if defined(ATmega328_168) || \
defined(ATmega328_168PB)
/*------------------------------------------------------------------------------------------------
* FUNCTION : optimizePeripherals()
*
@@ -252,16 +253,30 @@
// 4. GPIO Strategy (Unused pins to Pull-up)
// PORTx = 0xFF (Pull-ups) | DDRx = 0x00 (Inputs)
PORTC |= 0xFF;
// 5. Power Reduction Register (PRR)
// We KEEP PRUSART0 (UART) and shut down EVERYTHING else.
// _delay_ms() will still work (it's cycle-based, not timer-based).
PRR = (1 << PRTWI) | // I2C Off
(1 << PRSPI) | // SPI Off
(1 << PRTIM0) | // Timer 0 Off (millis/delay Arduino Off)
(1 << PRTIM1) | // Timer 1 Off
(1 << PRTIM2) | // Timer 2 Off
(1 << PRADC); // ADC Clock Off
#if defined(ATmega328_168PB)
PRR0 = (1 << PRTWI0) | // I2C Off
(1 << PRSPI0) | // SPI Off
(1 << PRTIM0) | // Timer 0 Off
(1 << PRTIM1) | // Timer 1 Off
(1 << PRTIM2) | // Timer 2 Off
(1 << PRADC); // ADC Clock Off
PRR1 = (1 << PRTWI1) | // TWI 1 Off
(1 << PRSPI1) | // SPI 1 Off
(1 << PRTIM3) | // Timer 3 Off
(1 << PRTIM4); // Timer 4 Off
#else
PRR = (1 << PRTWI) | // I2C Off
(1 << PRSPI) | // SPI Off
(1 << PRTIM0) | // Timer 0 Off (millis/delay Arduino Off)
(1 << PRTIM1) | // Timer 1 Off
(1 << PRTIM2) | // Timer 2 Off
(1 << PRADC); // ADC Clock Off
#endif
// 6. Double Security for Timer 0
TCCR0B = 0;
@@ -391,21 +406,23 @@
// 5. Power Reduction Registers (PRR0 & PRR1)
// PRR0 handles TWI, SPI, Timers 0, 1 and ADC.
PRR0 = (1 << PRTWI) | // I2C Off
(1 << PRSPI) | // SPI Off
(1 << PRTIM0) | // Timer 0 Off
(1 << PRTIM1) | // Timer 1 Off
(1 << PRADC); // ADC Clock Off
(1 << PRSPI) | // SPI Off
(1 << PRTIM0) | // Timer 0 Off
(1 << PRTIM1) | // Timer 1 Off
(1 << PRADC); // ADC Clock Off
// PRR1 handles Timer 3, Timer 4 and USB.
// We KEEP PRUSART1 (Serial1) and PRUSB active for communication.
PRR1 = (1 << PRTIM3) | // Timer 3 Off
(1 << 4); // Timer 4 Off (High speed timer)
PRR1 = (1 << PRUSB) | // Disable USB Controller (Stops SOF interrupts)
(1 << PRTIM3) | // Timer 3 Off
(1 << 4) | // Timer 4 Off (High speed timer)
(1 << PRUSART1); // Disable Serial1 (UART)
// 6. Double Security for Timer 0 (Redundancy)
TCCR0B = 0;
TIMSK0 = 0;
// 7. Note: USB/Serial1 remain functional unless PRUSB/PRUSART1 are set.
}
//#define F_CPU 16000000L
@@ -509,7 +526,7 @@
cli();
// 2. Analog Modules Shutdown
ADCSRA &= ~(1 << ADEN); // Disable ADC
ADCSRA = 0; // Power off ADC completely
ACSR |= (1 << ACD); // Disable Analog Comparator
// 3. Digital Input Buffer Disable (DIDR0)
@@ -524,7 +541,14 @@
// 5. Timer 0 Specific Shutdown (Hardware Redundancy)
TCCR0B = 0;
TCCR0B = 0;
TIMSK &= ~((1 << OCIE0A) | (1 << OCIE0B) | (1 << TOIE0)); // Disable Timer 0 interrupts
//TIMSK &= ~((1 << OCIE0A) | (1 << OCIE0B) | (1 << TOIE0)); // Disable Timer 0 interrupts
TIMSK = 0; // Disable ALL timer interrupts (OCIE0A, OCIE0B, TOIE0, etc.)
// 6. Watchdog: Ensure it's disabled to prevent random resets
MCUSR &= ~(1 << WDRF);
WDTCR |= (1 << WDCE) | (1 << WDE);
WDTCR = 0x00;
}
@@ -579,7 +603,8 @@
defined(SCPH_3000) || \
defined(SCPH_3500_5000) || \
defined(SCPH_5500) || \
defined(SCPH_7000_9000) || \
defined(SCPH_7000) || \
defined(SCPH_7500_9000) || \
defined(SCPH_100) || \
defined(SCPH_102)
#error "ATtiny85/45/25 architecture is not compatible with the BIOS patch feature."

View File

@@ -7,6 +7,7 @@
// MCU // Arduino
//------------------------------------------------------------------------------------------------
//#define ATmega328_168 // Nano, Pro Mini, Uno
//#define ATmega328_168PB
//#define ATmega32U4_16U4 // Micro, Pro Micro
//#define ATtiny85_45_25 // ATtiny

View File

@@ -27,113 +27,191 @@
// tested with an Atmega328P
#if defined(ATmega32U4_16U4)
// ------ 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 //47
#define BIT_OFFSET_CYCLES 47 //60
#define OVERRIDE_CYCLES 3
#endif
// #endif
// // -------- SCPH 7500 / 9000 --------
#ifdef SCPH_7500_9000
#define BIOS_PATCH
#define SILENCE_THRESHOLD 1500
#define CONFIRM_COUNTER_TARGET 1
#define PULSE_COUNT 15 //15
#define BIT_OFFSET_CYCLES 47 //60
#define OVERRIDE_CYCLES 3
#endif
// -------- SCPH 7000 --------
#ifdef SCPH_7000
#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_5500
#define BIOS_PATCH
#define SILENCE_THRESHOLD 35600
#define CONFIRM_COUNTER_TARGET 1
#define PULSE_COUNT 84 //84
#define BIT_OFFSET_CYCLES 47 //60
#define OVERRIDE_CYCLES 3
#endif
// // -------- SCPH 3000 --------
#ifdef SCPH_3000
#define BIOS_PATCH
#define INTERRUPT_RISING_HIGH_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 INTERRUPT_RISING_HIGH_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
/*------------------------------------------------------------------------------------------------
Region Settings Section
------------------------------------------------------------------------------------------------*/
#if defined(SCPH_100) || \
defined(SCPH_7500_9000) || \
defined(SCPH_7000) || \
defined(SCPH_3500_5500) || \
defined(SCPH_3500) || \
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) || \
// ------ 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 //47
#define BIT_OFFSET_CYCLES 47 //60
#define OVERRIDE_CYCLES 3
#endif
#define INJECT_SCEx 2 // PAL
#elif defined(SCPH_xxxx)
#define INJECT_SCEx 3 // Universal: NTSC-J -> NTSC-U/C -> PAL
// // -------- SCPH 7500 / 9000 --------
#ifdef SCPH_7500_9000
#define BIOS_PATCH
#define SILENCE_THRESHOLD 1100
#define CONFIRM_COUNTER_TARGET 1
#define PULSE_COUNT 15 //15
#define BIT_OFFSET_CYCLES 47 //60
#define OVERRIDE_CYCLES 3
#endif
// -------- SCPH 7000 --------
#ifdef SCPH_7000
#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_5500
#define BIOS_PATCH
#define SILENCE_THRESHOLD 25000
#define CONFIRM_COUNTER_TARGET 1
#define PULSE_COUNT 84 //84
#define BIT_OFFSET_CYCLES 47 //60
#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 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 1100
#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
#else
// ------ 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 //47
#define BIT_OFFSET_CYCLES 47 //60
#define OVERRIDE_CYCLES 3
#endif
// // -------- SCPH 7500 / 9000 --------
#ifdef SCPH_7500_9000
#define BIOS_PATCH
#define SILENCE_THRESHOLD 1500
#define CONFIRM_COUNTER_TARGET 1
#define PULSE_COUNT 15 //15
#define BIT_OFFSET_CYCLES 47 //60
#define OVERRIDE_CYCLES 3
#endif
// -------- SCPH 7000 --------
#ifdef SCPH_7000
#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_5500
#define BIOS_PATCH
#define SILENCE_THRESHOLD 32000
#define CONFIRM_COUNTER_TARGET 1
#define PULSE_COUNT 84 //84
#define BIT_OFFSET_CYCLES 47 //60
#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_7500_9000) || \
defined(SCPH_7000) || \
defined(SCPH_3500_5500) || \
defined(SCPH_3500) || \
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
/*------------------------------------------------------------------------------------------------
@@ -295,11 +373,13 @@ void DebugInject(){
// --- MCU SELECTION CHECK ---
#if !defined(ATmega328_168) && \
!defined(ATmega328_168PB) && \
!defined(ATmega32U4_16U4) && \
!defined(ATtiny85_45_25)
#error "No MCU selected! Please choose one supported architecture."
#elif (defined(ATmega328_168) + \
defined(ATmega328_168PB) + \
defined(ATmega32U4_16U4) + \
defined(ATtiny85_45_25) > 1)
#error "Multiple MCUs selected! Please enable only one architecture."