Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 21 additions & 7 deletions PSNee_V8.6/PSNee_V8.6/MUC.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@
#include <avr/interrupt.h>
#include <avr/sfr_defs.h>
#include <util/delay.h>
#include <avr/wdt.h>

// Global interrupt control settings
#define GLOBAL_INTERRUPT_ENABLE SREG |= (1<<7) // Set the I-bit (bit 7) in the Status Register to enable global interrupts
Expand All @@ -260,7 +261,13 @@
#define PIN_WFCK_INPUT DDRB &= ~(1<<DDB1) // Set DDRB register to configure PINB1 as input
#define PIN_SQCK_INPUT DDRD &= ~(1<<DDD6) // Set DDRB register to configure PINB6 as input
#define PIN_SUBQ_INPUT DDRD &= ~(1<<DDD7) // Set DDRB register to configure PINB7 as input


// AUTO BOOT RESET (D10 / PB2)
#define PIN_RESET_OUTPUT DDRB |= (1 << DDB2) // Set PINB2 as output
#define PIN_RESET_INPUT DDRB &= ~(1 << DDB2) // Set PINB2 as input -High Impedance-
#define PIN_RESET_LOW PORTB &= ~(1 << PB2) // Set PINB2 low
#define IS_RESET_PRESSED (!(PINB & (1 << PB2)))

// Enable pull-ups and set high on the main pins. Equivalent Arduino code: pinMode(x, OUTPUT);
#define PIN_DATA_OUTPUT DDRB |= (1<<DDB0) // Set DDRB register to configure PINB0 as output
#define PIN_WFCK_OUTPUT DDRB |= (1<<DDB1) // Set DDRB register to configure PINB1 as output
Expand Down Expand Up @@ -330,7 +337,7 @@
// Handle switch input for BIOS patch
#define PIN_SWITCH_INPUT DDRD &= ~(1<<DDD5) // Configure PIND5 as input for switch
#define PIN_SWITCH_SET PORTD |= (1<<PD5) // Set PIND5 high (enable pull-up)
#define PIN_SWICHE_READ (PIND & (1<<PIND5)) // Read the state of PIND5 (switch input)
#define PIN_SWITCH_READ (PIND & (1<<PIND5)) // Read the state of PIND5 (switch input)

#endif

Expand All @@ -350,6 +357,7 @@
#include <avr/interrupt.h>
#include <avr/sfr_defs.h>
#include <util/delay.h>
#include <avr/wdt.h>

// Globale interrupt seting
#define GLOBAL_INTERRUPT_ENABLE SREG |= (1<<7)
Expand All @@ -368,6 +376,12 @@

#define PIN_DATA_OUTPUT DDRB |= (1<<DDB4)
#define PIN_WFCK_OUTPUT DDRB |= (1<<DDB5)

// AUTO BOOT RESET (A0 / PF7)
#define PIN_RESET_OUTPUT DDRF |= (1 << DDF7) // Set A0 as output
#define PIN_RESET_INPUT DDRF &= ~(1 << DDF7) // Set A0 as input -High Impedance-
#define PIN_RESET_LOW PORTF &= ~(1 << PF7) // Set A0 low
#define IS_RESET_PRESSED (!(PINF & (1 << PF7)))

// Define pull-ups and set high at the main pin
#define PIN_DATA_SET PORTB |= (1<<PB4)
Expand Down Expand Up @@ -403,7 +417,7 @@
// Handling and reading the switch pin for patch BIOS
#define PIN_SWITCH_INPUT DDRC &= ~(1<<DDC6)
#define PIN_SWITCH_SET PORTC |= (1<<PC6)
#define PIN_SWICHE_READ (PINC & (1<<PINC6))
#define PIN_SWITCH_READ (PINC & (1<<PINC6))

// BIOS timer clear
#define TIMER_TCNT_CLEAR TCNT0 = 0x00
Expand Down Expand Up @@ -588,7 +602,7 @@
// Handling and reading the switch pin for patch BIOS
#define PIN_SWITCH_INPUT DDRD &= ~(1<<DDD5)
#define PIN_SWITCH_SET PORTD |= (1<<PD5)
#define PIN_SWICHE_READ (PIND & (1<<PIND5))
#define PIN_SWITCH_READ (PIND & (1<<PIND5))

#endif

Expand Down Expand Up @@ -691,7 +705,7 @@
// Handling and reading the switch pin for patch BIOS
#define PIN_SWITCH_INPUT PORTA.DIR &= ~PIN5_bm
#define PIN_SWITCH_SET PORTA.OUT |= PIN5_bm
#define PIN_SWICHE_READ PORTA.IN & PIN5_bm
#define PIN_SWITCH_READ PORTA.IN & PIN5_bm

#endif

Expand Down Expand Up @@ -789,7 +803,7 @@
// Handling and reading the switch pin for patch BIOS
#define PIN_SWITCH_INPUT DDRD &= ~(1<<DDD5)
#define PIN_SWITCH_SET PORTD |= (1<<PD5)
#define PIN_SWICHE_READ (PIND & (1<<PIND5))
#define PIN_SWITCH_READ (PIND & (1<<PIND5))

#endif

Expand Down Expand Up @@ -876,7 +890,7 @@
// Gestion de la broche de commutation pour le BIOS
#define PIN_SWITCH_INPUT GPIOA->MODER &= ~(GPIO_MODER_MODER5)
#define PIN_SWITCH_SET GPIOA->ODR |= (GPIO_ODR_ODR_5)
#define PIN_SWICHE_READ (GPIOA->IDR & (GPIO_IDR_IDR_5))
#define PIN_SWITCH_READ (GPIOA->IDR & (GPIO_IDR_IDR_5))

#endif

Expand Down
130 changes: 98 additions & 32 deletions PSNee_V8.6/PSNee_V8.6/PSNee_V8.6.ino
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
//#define SCPH_102 // DX - D0, AX - A7. BIOS ver. 4.4e, CRC 0BAD7EA9 | 4.5e, CRC 76B880E5
//#define SCPH_100 // DX - D0, AX - A7. BIOS ver. 4.3j, CRC F2AF798B
//#define SCPH_7000_9000 // DX - D0, AX - A7. BIOS ver. 4.0j, CRC EC541CD0
//#define SCPH_5500 // DX - D0, AX - A5. BIOS ver. 3.0j, CRC FF3EEB8C
#define SCPH_5500 // DX - D0, AX - A5. BIOS ver. 3.0j, CRC FF3EEB8C
//#define SCPH_5000 // DX - D0, for 40-pin BIOS: AX - A4, for 32-pin BIOS: AX - A5. BIOS ver. 2.2j, CRC 24FC7E17 | 2.1j, CRC BC190209
//#define SCPH_3500 // DX - D0, for 40-pin BIOS: AX - A4, for 32-pin BIOS: AX - A5. BIOS ver. 2.2j, CRC 24FC7E17 | 2.1j, CRC BC190209
//#define SCPH_3000 // DX - D5, for 40-pin BIOS: AX - A6, AY - A7, for 32-pin BIOS: AX - A7, AY - A8. BIOS ver. 1.1j, CRC 3539DEF6
Expand Down Expand Up @@ -49,7 +49,7 @@
D7-SUBQ
D8-DATA
D9-WFCK
RST-RESET* (Only for JAP_FAT)
RST-RESET* (Only for JAP_FAT). If using ENABLE_HOLD_RESET_ON_BOOT see description below.
GND-GND

Pinout ATtiny:
Expand All @@ -68,8 +68,17 @@
// Options
//------------------------------------------------------------------------------------------------

#define LED_RUN // Turns on the LED when injections occur. D13 for Arduino, ATtiny add a led between PB3 (pin 2) and gnd with a 1k resistor in series, ATmega32U4 (Pro Micro) add a led between PB6 (pin 10) and gnd with a 1k resistor in series
//#define PATCH_SWITCHE // Enables hardware support for disabling BIOS patching, to allow access to the console memory card menu for model 7000. Useful in rare cases where the BIOS patch prevents the playback of original games
//#define LED_RUN // Turns on the LED when injections occur. D13 for Arduino, ATtiny add a led between PB3 (pin 2) and gnd with a 1k resistor in series, ATmega32U4 (Pro Micro) add a led between PB6 (pin 10) and gnd with a 1k resistor in series
//#define PATCH_SW // Enables hardware support for disabling BIOS patching, to allow access to the console memory card menu for model 7000. Useful in rare cases where the BIOS patch prevents the playback of original games

// Holds PS1 reset on boot for more stability in BIOS PATCH for all JAP PS1 and European SCHP-102. D10 for ATMEGA328. A0 for ATMEGA32U4.
// This also makes possible to preserve the bootloader without needing a programmer.
// Caution:
// FAT Models. Instead of connecting PS1's reset line to RST connect it to D10 (ATMEGA328) or A0 (ATMEGA32U4) in Arduino.
// This needs a power cycle for stability. The use of manually pressing PS1's reset button or IGR mod leads to instability in BIOS PATCH (hit and miss).
//
// SLIM Models. Connect PS1's reset line to D10 (ATMEGA328) or A0 (ATMEGA32U4) in Arduino.
#define ENABLE_HOLD_RESET_ON_BOOT

//------------------------------------------------------------------------------------------------
// pointer and variable section
Expand Down Expand Up @@ -289,32 +298,77 @@ void inject_SCEX(const char region) {
_delay_ms(DELAY_BETWEEN_INJECTIONS);
}

void hold_reset(uint8_t hold_rst_time){
// AUTO BOOT RESET - PIN D10 ATMEGA328/ A0 ATMEGA32U4
PIN_RESET_OUTPUT; // Set as output
PIN_RESET_LOW; // Set GND
_delay_ms(hold_rst_time); // Hold reset
PIN_RESET_INPUT; // Set High Impedance
}

void Init() {
#if defined(ATmega328_168) || defined(ATmega32U4_16U4) || defined(ATtiny85_45_25)
TIMER_TCNT_CLEAR;
SET_OCROA_DIV;
SET_TIMER_TCCROA;
SET_TIMER_TCCROB;
#endif
// Disable watchdog after reset
#if defined(ENABLE_HOLD_RESET_ON_BOOT) && defined(BIOS_PATCH) && (defined(ATmega328_168) || defined(ATmega32U4_16U4))
MCUSR = 0;
wdt_disable();
#endif

#if defined(PATCH_SWITCHE) && defined(BIOS_PATCH)
PIN_SWITCH_INPUT;
PIN_SWITCH_SET;
if (PIN_SWICHE_READ == 0){
Flag_Switch =1;
}
#endif
#if defined(ATmega328_168) || defined(ATmega32U4_16U4) || defined(ATtiny85_45_25)
TIMER_TCNT_CLEAR;
SET_OCROA_DIV;
SET_TIMER_TCCROA;
SET_TIMER_TCCROB;
#endif

#ifdef LED_RUN
PIN_LED_OUTPUT;
#endif
#if defined(PATCH_SW) && defined(BIOS_PATCH) && (defined(ATmega328_168) || defined(ATmega32U4_16U4))
PIN_SWITCH_INPUT;
PIN_SWITCH_SET;
if (PIN_SWITCH_READ == 0){
Flag_Switch =1;
}
#endif

// Reset PS1 when booting
#if defined(ENABLE_HOLD_RESET_ON_BOOT) && defined(BIOS_PATCH) && (defined(ATmega328_168) || defined(ATmega32U4_16U4))
#ifdef PATCH_SW
if (Flag_Switch == 0) {
#ifdef FAT
hold_reset(1000);
#else
hold_reset(300);
#endif
}
#else
#ifdef FAT
hold_reset(1000);
#else
hold_reset(300);
#endif
#endif
#endif

#ifdef LED_RUN
PIN_LED_OUTPUT;
#endif

GLOBAL_INTERRUPT_ENABLE;

PIN_SQCK_INPUT;
PIN_SUBQ_INPUT;
}

// CAPTURE MANUAL RESET FOR JAP FAT MODELS THAT REQUIRE BIOS PATCH
void capture_reset(){
_delay_ms(50);
if (IS_RESET_PRESSED) {
while (IS_RESET_PRESSED);
PIN_RESET_OUTPUT;
PIN_RESET_LOW;
wdt_enable(WDTO_250MS);
while(1);
}
}

int main() {
uint8_t hysteresis = 0;
uint8_t scbuf[12] = { 0 }; // SUBQ bit storage
Expand All @@ -326,21 +380,25 @@ int main() {

Init();

#if defined(BIOS_PATCH)
#if defined(BIOS_PATCH) && (defined(ATmega328_168) || defined(ATmega32U4_16U4))

#ifdef LED_RUN
PIN_LED_ON;
#endif
#ifdef LED_RUN
PIN_LED_ON;
#endif

if (Flag_Switch == 0) {
Bios_Patching();
}
#if defined(PATCH_SW)
if (Flag_Switch == 0) {
Bios_Patching();
}
#else
Bios_Patching();
#endif

#ifdef LED_RUN
PIN_LED_OFF;
#endif
#ifdef LED_RUN
PIN_LED_OFF;
#endif

#endif
#endif

Timer_Start();
//************************************************************************
Expand Down Expand Up @@ -375,7 +433,15 @@ int main() {
}

while (1) {

// CAPTURE MANUAL RESET FOR JAP FAT MODELS THAT REQUIRE BIOS PATCH
#if defined(FAT) && defined(ENABLE_HOLD_RESET_ON_BOOT) && (defined(ATmega328_168) || defined(ATmega32U4_16U4))
#ifdef PATCH_SW
if (Flag_Switch == 0 && IS_RESET_PRESSED) capture_reset();
#else
if (IS_RESET_PRESSED) capture_reset();
#endif
#endif

_delay_ms(1); /* Start with a small delay, which can be necessary
in cases where the MCU loops too quickly and picks up the laster SUBQ trailing end*/

Expand Down
10 changes: 9 additions & 1 deletion PSNee_V8.6/PSNee_V8.6/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
#define PATCHING _delay_us(0.1)
#define CHECKPOINT 75270
#define TRIGGER 16
#define FAT
#endif

#ifdef SCPH_5500
Expand All @@ -68,6 +69,7 @@
#define CHECKPOINT 76100
#define TRIGGER 21
#define LOW_TRIGGER
#define FAT
#endif

// #ifdef SCPH_3500_5000
Expand All @@ -78,6 +80,7 @@
// #define CHECKPOINT 75260
// #define TRIGGER 21
// #define LOW_TRIGGER
// #define FAT
// #endif

// #ifdef SCPH_5500
Expand All @@ -88,6 +91,7 @@
// #define CHECKPOINT 76130
// #define TRIGGER 21
// #define LOW_TRIGGER
// #define FAT
// #endif

#ifdef SCPH_5000
Expand All @@ -98,6 +102,7 @@
#define CHECKPOINT 75260
#define TRIGGER 21
#define LOW_TRIGGER
#define FAT
#endif

#ifdef SCPH_3500
Expand All @@ -108,6 +113,7 @@
#define TRIGGER 21
#define HOLD _delay_us(2.75) //2.65 - 2.85
#define PATCHING _delay_us(0.2)
#define FAT
#endif

#ifdef SCPH_3000
Expand All @@ -123,7 +129,8 @@
#define HOLD2 _delay_us(2.88)
#define PATCHING2 _delay_us(0.15)
#define CHECKPOINT2 253300
#define TRIGGER2 43
#define TRIGGER2 43
#define FAT
#endif

#ifdef SCPH_1000
Expand All @@ -140,6 +147,7 @@
#define PATCHING2 _delay_us(0.15)
#define CHECKPOINT2 272800
#define TRIGGER2 71
#define FAT
#endif

#ifdef SCEA
Expand Down
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,25 @@ THE modechip supports the largest number of Playstation 1 variants, and the larg
- Remove Disk Region Protection
- Patch BIOS
- A specific library for card support, to solve the fuse setting problem.
- The mode does not take care of changing PAL <-> NTSC video output (in other words if you use a Japanese console and you put European games, or in older European models you use American or Japanese games... the display will not be correct)
- Hardware Reset Synchronization (Forced Boot Sync): Solves the "race condition" where the console starts faster than the PsNee.
The MCU holds the console in reset until it is fully initialized, ensuring a better success rate on cold boots.
Critical for PSOne (SCPH-102), Japanese models, and known problematic boards using the ATmega328PB.
- Bootloader Friendly: This sync mechanism allows you to keep the standard bootloader, making it easier to update without extra hardware (ISP).
- The PsNee does not take care of changing PAL <-> NTSC video output (in other words if you use a Japanese console and you put European games, or in older European models you use American or Japanese games... the display will not be correct). This is normal. You can either use patches or an RGB cable.

> [!CAUTION]
>## Forced Boot Sync Implementation
> This section applies only if you enable the hardware-level reset synchronization (e.g., ENABLE_HOLD_RESET_ON_BOOT) for improved stability.
>### Critical Wiring Warning
> **DO NOT connect the console's Reset point to the Arduino’s physical RST pin.**
> Reason: This creates a feedback loop. When the Arduino pulls the line LOW to sync the console, it would simultaneously trigger its own physical reset. This causes the MCU to restart before finishing the sync pulse, leading to an infinite reset cycle.
> Correct Connection:
> - ATmega328/168: Connect console Reset to D10.
> - ATmega32u4: Connect console Reset to A0.
>#### Manual Reset Behavior
> Known Limitations: While cold boot BIOS patching is highly reliable, manual resets remain "hit & miss" on Japanese FAT boards due to potential residual hardware states. A full power cycle is still recommended for best reliability on these models.
>#### Bootloader Preservation
>This mechanism allows you to safely keep the standard Arduino bootloader. You can perform real-time BIOS patching without needing to flash the AVR via ISP, making future updates much easier.

## Supported Playstation 1
All US models, all European models, and the vast majority of Japanese models.
Expand Down
Binary file modified images/MUC Arduino/Nano.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/MUC Arduino/PSNee_V8_pinout.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/MUC Arduino/Pro Micro.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/MUC Arduino/micro.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/MUC Arduino/pro mini.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/motherboard/PM-41.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.