Skip to content

#feature: Forced Reset Synchronization for BIOS Patching Stability and Bootloader preservation (PS1 JAP / European PSOne)#106

Open
AlSiSan wants to merge 5 commits intokalymos:masterfrom
AlSiSan:master
Open

#feature: Forced Reset Synchronization for BIOS Patching Stability and Bootloader preservation (PS1 JAP / European PSOne)#106
AlSiSan wants to merge 5 commits intokalymos:masterfrom
AlSiSan:master

Conversation

@AlSiSan
Copy link
Copy Markdown

@AlSiSan AlSiSan commented Apr 10, 2026

Description

This introduces a simple hardware reset synchronization mechanism to resolve the timing issues often encountered when patching the BIOS on late PS1 models (such as the SCPH-102 / PM-41 board) and Japanese consoles.

It also includes an update to the installation diagrams to document the new reset point for the PM-41 board.

The Problem: The "Race Condition"

On consoles requiring real-time BIOS patching (AX/DX bus), the MCU initialization delay (and bootloader wait time) can cause it to miss the start of the BIOS execution. This results in:

  • Random black screens on boot.
  • Failed multi-region boots.
  • Inconsistent behavior on cold starts.

The Solution: Forced Boot Sync

I have implemented an optional synchronization mechanism. When enabled, the Arduino takes control of the console’s reset line during the boot sequence:

  1. Pulse: The Arduino pulls the console's reset line LOW immediately upon power-up.
  2. Hold: This forces the PS1 to stay in a reset state while the MCU initializes and prepares the Bios_Patching() routine.
  3. Release: Once the Arduino is ready to intercept the bus, it releases the line (High Impedance), allowing the console to boot with the patcher already active.

Implementation Details

  • Toggle: Controlled via #define ENABLE_HOLD_RESET_ON_BOOT to preserve legacy wiring compatibility.
  • MCU.h Mapping:
    • ATmega328/168: Mapped to PB2 (Pin D10).
    • ATmega32u4: Mapped to PF7 (Pin A0).
  • PSNee.ino: Injected the sync pulse inside the initialization phase, ensuring the pin is restored to high impedance (INPUT) immediately after to avoid interference.
  • Diagrams Updated: Updated the PM-41 (PSOne Slim) and Arduino pinout JPGs to include the new reset point.

Validation & Impact

  • Hardware Tested: European PSOne SCPH-102 (PM-41 board) and Japanese SCPH-5500.

  • Stability: Tested with the "problematic" ATmega328PB variants; the sync pulse completely eliminates the sync issues previously documented.

  • Bootloader Preservation: Tested that this mechanism now allows users to keep the standard bootloader (no ISP flashing required), as the console will wait for the bootloader timeout to finish.

  • Results: I had 100% success on cold boots using original out-of-region discs in those two models (PsNee 8.6.2 + ATmega328PB with Bootloader flashed via built-in USB).

  • Known Limitations: While cold boot BIOS patching has been improved, manual resets remain "hit & miss" on Japanese FAT boards due to potential residual hardware states. A full power cycle is still recommended for successful BIOS patching on these models.

AlSiSan added 5 commits April 10, 2026 01:23
…der)

[Problem]
For European PSOne models (SCPH-102) and Japanese PS1s that require real-time BIOS patching on the AX/DX bus, the MCU initialization delay causes the Arduino to miss the critical boot execution window. This race condition leads to desyncs, resulting in random black screens or failed multi-region boots.

[Solution]
Implemented an optional hardware-level reset synchronization mechanism (ENABLE_HOLD_RESET_ON_BOOT). During MCU initialization, the Arduino takes control of the console's reset line, pulling it LOW to force the PS1 to wait. The console is only released once the MCU is fully initialized and ready to intercept the bus.

[Validation & Impact]
Tested Hardware: Verified on PS1 FAT JAP SCPH-5500 and PAL SLIM SCPH-102, tested both with and without the bootloader present on an ATmega328PB (known problematic Nano 3.0 board).

Hardware Compatibility: Significantly improves cold boot success rates. It is particularly useful for Chinese Nano boards using the ATmega328PB variant, ensuring stable pin state transitions while the oscillator stabilizes.

Bootloader Preservation: This mechanism eliminates the need to flash the AVR via ISP. Users can now safely preserve the standard Arduino bootloader while performing real-time BIOS patching.

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 100% success on these models.
Added details about hardware reset synchronization and its implementation, including wiring instructions and limitations.
Added reset point for PM-41 board
- Updated MUC images to reflect D10/A0 pin usage for Forced Boot Sync.
- Added visual warnings regarding the RST pin feedback loop.
- Clarified pinout differences between ATmega328P and ATmega32u4.
@kalymos
Copy link
Copy Markdown
Owner

kalymos commented Apr 10, 2026

I like this compilation option much better ;)

There are still two small things that aren't ideal in my opinion.

First, there's the name you gave the variables and the RESET schema. The name isn't wrong in itself, but it can be confusing. It could easily be renamed, for example, PIN_HRS.

Second, the explanations in the README are a bit long for an introduction page. I should create a dedicated wiki page for this compilation option.

P.S. I also need to update the README in the documentation, as it no longer reflects the current state of the project.

Have a good day.

@kalymos
Copy link
Copy Markdown
Owner

kalymos commented Apr 10, 2026

What it might look like with the HRS designation

PM-41A-HRS

@kalymos
Copy link
Copy Markdown
Owner

kalymos commented Apr 10, 2026

Since I have you here ;)
I was thinking of slightly modifying the style of the diagrams, what do you think of that?

PM-41A-HRS-test

@AlSiSan
Copy link
Copy Markdown
Author

AlSiSan commented Apr 13, 2026

Hi @kalymos,

I’m glad the optional feature approach works for you! It definitely keeps the core installation cleaner.

Regarding your suggestions:

  1. Naming: PIN_HRS sounds good and is consistent with the rest of the project. I’ll rename the variables in MCU.h and update the logic in PSNee.ino.
  2. Documentation: I completely agree with moving the technical part to a dedicated Wiki page. I’ll trim the README to keep it concise, leaving only a brief "Safety Note" regarding the wiring for this specific feature: reminding users to connect the console reset line to D10 (328P) or A0 (32U4) instead of the Arduino's physical RST pin to avoid infinite reset loops. I will also refer to the wiki when available and included descriptions in the code comments next to the #define.
  3. Diagram: The new one looks much better and ensures consistency across the project.

I will push the changes with the renamed variables and the trimmed README shortly so you can move forward with the release.

Have a great day!

@kalymos
Copy link
Copy Markdown
Owner

kalymos commented Apr 13, 2026

I'm just thinking about a couple of things.

Don't rush, I'm releasing V9 this week.

You mentioned a hardware reset issue on the Japanese FAT models. I had an idea, I don't know if it would work, but once the power-on is complete, wouldn't it be possible to invert the input PIN_HRS, check if there's a reset, return the PIN_HRS to its initial state, and so on? If it works, it could allow for unimpeded PlayStation functionality.

The last thing is that I have a level of stability on V9 that allows me to release it. I don't know if you'd be willing to test it on your problematic model, as the current implementation of the BIOS patch should theoretically bypass most of the problems you've encountered.

The old BIOS patch implementation started a timer at power-on, hoping to encounter a silence in the address range on the AX pin. This caused a significant number of problems with BP variants and consoles with a slow boot time.

The current implementation waits to detect this silence in the address range, which, in the most critical cases, allows 300 ms for mode initialization. Indirectly, this also resolves most fuse-setting issues.

@AlSiSan
Copy link
Copy Markdown
Author

AlSiSan commented Apr 13, 2026

No rush at all on this merge! I know V9 is the priority right now. I'll just push the final PIN_HRS renaming so the v8 PR is polished and ready for whenever you have a moment after the release.

Regarding your points:

Manual Reset Handling

That’s a great suggestion, and it actually aligns with how the logic is handled in the main loop of this PR:

  • Cold Boot: Upon power-up, the Arduino immediately pulls PIN_HRS LOW for 300 ms. This ensures the MCU is initialized and the Bios_Patching() routine is ready to intercept the bus before the console begins its BIOS execution.
  • Manual Reset: The loop inside main constantly monitors the reset line using the IS_RESET_PRESSED macro. When a manual reset is detected, the code waits for the button to be released and then triggers a reset of the Arduino itself. This restarts the entire flow, reapplying the synchronization pulse and the Bios_Patching() sequence exactly like a cold boot.

V9.0 Testing on PU-18

I’m glad to test the V9.0 implementation again on my PU-18 (SCPH-5500).

The shift from a "timer-on-power-on" to a "wait-for-silence" approach is a much more robust way to handle different boot timings. In my previous tests with the V9.0 dev branch, I was seeing roughly a 7/10 success rate on cold boots in any case scenario—whereas I had a 100% success rate on v8 (with and without bootloader) by forcing the reset line low on cold boot. I will restore the AX wiring to Pin A16 as required for v9 and report back if it becomes more consistent with the new optimizations. Since I didn't test the manual reset with v9, I'm also interested to see if it works better than with v8.

@kalymos
Copy link
Copy Markdown
Owner

kalymos commented Apr 13, 2026

P.S. In case you're worried about the LED flashing, it's extremely brief during the BIOS patch; I still use it as a trigger for the logic analyzer. I will restore a visible duration for the V9 release.

@AlSiSan
Copy link
Copy Markdown
Author

AlSiSan commented Apr 17, 2026

I can confirm that the current v9.0 dev is working now on the Japanese model SCPH-5500 (PU18). I got a 100% success rate on cold boot. Tested with forced reset on boot and bootloader present.

@kalymos
Copy link
Copy Markdown
Owner

kalymos commented Apr 17, 2026

Je peux confirmer que l'actuel v9.0 dev fonctionne maintenant sur le modèle japonais SCPH-5500 (PU18). J'ai obtenu un taux de réussite de 100% sur la chaussure froide. Testé avec réinitialisation forcée sur le démarrage et le chargeur de démarrage présent.

Thanks for the feedback

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants