1
0
mirror of https://github.com/kalymos/PsNee.git synced 2026-01-11 23:53:07 +00:00

Add files via upload

This commit is contained in:
kalymos 2025-02-07 15:31:58 +01:00 committed by GitHub
parent bdaf5ecfa4
commit 3c09d0b048
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 635 additions and 0 deletions

341
PSNee_V8/PSNee_V8.ino Normal file
View File

@ -0,0 +1,341 @@
// PSNee V8 - Ultimate PSX unlocker. /ver. 8.0.1
// Developed by brill & postal2201, based on PSNee V7 open source project. /Emu-land.net
#define F_CPU 16000000L
#include <stdint.h>
#include <stdbool.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sfr_defs.h>
#include <util/delay.h>
//------------------------------------------------------------------------------------------------
// Select your chip
//------------------------------------------------------------------------------------------------
#define ATmega328_168 // Fuses: JAP_FAT - H: DF, L: EE, E: FF; Other - H: DF, L: FF, E: FF.
/* PinVCC-3.5v, PinGND-GND, Pin2-BIOS AX, Pin3-BIOS AY, Pin4-BIOS DX, Pin5-Switch*(optional),
Pin6-SQCK, Pin7-SUBQ, Pin8-DATA, Pin9-GATE_WFCK, PinRST-RESET*(Only for JAP_FAT) */
//------------------------------------------------------------------------------------------------
// Select your console
//------------------------------------------------------------------------------------------------
// Attention!
// If a BIOS checksum is specified, it is more important than the SCPH model number!
//------------------------------------------------------------------------------------------------
//#define UC_ALL // Use for all NTSC-U/C models. No BIOS patching needed.
//#define PAL_FAT // Use for all PAL FAT models. No BIOS patching needed.
//#define SCPH_103 // No BIOS patching needed.
//#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_3500_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_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
//#define SCPH_1000 // DX - D5, for 40-pin BIOS: AX - A6, AY - A7, for 32-pin BIOS: AX - A7, AY - A8. BIOS ver. 1.0j, CRC 3B601FC8
//------------------------------------------------------------------------------------------------
// Options
//------------------------------------------------------------------------------------------------
#define AUTOREGION // If disable, send all SCEX codes, instead of the code selected model.
#define PATCH_SW // Enables hardware support for disabling BIOS patching.
//------------------------------------------------------------------------------------------------
// Code section
//------------------------------------------------------------------------------------------------
#include "config.h"
#include "settings.h"
#include "patching.h"
volatile uint8_t count_isr = 0;
volatile uint32_t microsec = 0;
volatile uint16_t millisec = 0;
bool wfck_mode;
const int16_t delay_between_bits = 4000;
const int16_t delay_between_injections = 90;
uint8_t readBit(uint8_t index, const uint8_t * ByteSet)
{
return !!(ByteSet[index / 8] & (1 << (index % 8)));
}
ISR(TIMER0_COMPA_vect)
{
microsec += 10;
count_isr++;
if (count_isr == 100)
{
millisec++;
count_isr = 0;
}
}
void Timer_Start()
{
TIMER_TCNT_CLEAR;
TIMER_TIFR_CLEAR;
TIMER_INTERRUPT_ENABLE;
}
void Timer_Stop()
{
TIMER_INTERRUPT_DISABLE;
TIMER_TCNT_CLEAR;
count_isr = 0;
microsec = 0;
millisec = 0;
}
void inject_SCEX(const char region)
{
static const uint8_t SCEEData[] = {
0b01011001,
0b11001001,
0b01001011,
0b01011101,
0b11101010,
0b00000010
};
static const uint8_t SCEAData[] = {
0b01011001,
0b11001001,
0b01001011,
0b01011101,
0b11111010,
0b00000010
};
static const uint8_t SCEIData[] = {
0b01011001,
0b11001001,
0b01001011,
0b01011101,
0b11011010,
0b00000010
};
uint8_t bit_counter;
for (bit_counter = 0; bit_counter < 44; bit_counter++)
{
if (readBit(bit_counter, region == 'e' ? SCEEData : region == 'a' ? SCEAData : SCEIData) == 0)
{
DATA_OUTPUT;
DATA_CLEAR;
_delay_us(delay_between_bits);
}
else
{
if (wfck_mode)
{
DATA_OUTPUT;
Timer_Start();
do
{
if(WFCK_READ)
{
DATA_SET;
}
else
{
DATA_CLEAR;
}
}
while (microsec < delay_between_bits);
Timer_Stop();
}
else
{
DATA_INPUT;
_delay_us(delay_between_bits);
}
}
}
DATA_OUTPUT;
DATA_CLEAR;
_delay_ms(delay_between_injections);
}
int main()
{
uint8_t hysteresis = 0;
uint8_t scbuf[12] = {0};
uint16_t timeout_clock_counter = 0;
uint8_t bitbuf = 0;
uint8_t bitpos = 0;
uint8_t scpos = 0;
uint16_t highs = 0, lows = 0;
#if !defined(UC_ALL) && !defined(PAL_FAT) && !defined(SCPH_103) && \
!defined(SCPH_102) && !defined(SCPH_100) && !defined(SCPH_7000_9000) && \
!defined(SCPH_5500) && !defined(SCPH_3500_5000) && !defined(SCPH_3000) && \
!defined(SCPH_1000)
#error "Console not selected! Please uncoment #define with SCPH model number."
#elif !(defined(UC_ALL) ^ defined(PAL_FAT) ^ defined(SCPH_103) ^ \
defined(SCPH_102) ^ defined(SCPH_100) ^ defined(SCPH_7000_9000) ^ \
defined(SCPH_5500) ^ defined(SCPH_3500_5000) ^ defined(SCPH_3000) ^ \
defined(SCPH_1000))
#error "May be selected only one console! Please check #define with SCPH model number."
#endif
#ifndef AUTOREGION
const char region[3] = {'e', 'a', 'i'};
#endif
Init();
#ifdef LED_USE
LED_ON;
#endif
#if defined(BIOS_PATCH) && !defined(PATCH_SW)
Bios_Patching();
#elif defined(BIOS_PATCH) && defined(PATCH_SW)
if (SW_CHECK != 0)
{
Bios_Patching();
}
else
{
while (SQCK_READ == 0);
while (WFCK_READ == 0);
}
#else
while (SQCK_READ == 0);
while (WFCK_READ == 0);
#endif
Timer_Start();
do
{
if (WFCK_READ == 1) highs++;
if (WFCK_READ == 0) lows++;
_delay_us(200);
}
while (millisec < 1000);
Timer_Stop();
if (lows > 100)
{
wfck_mode = 1;
}
else
{
wfck_mode = 0;
}
#ifdef LED_USE
LED_OFF;
#endif
while(1)
{
_delay_ms(1);
cli();
do
{
for (bitpos = 0; bitpos < 8; bitpos++)
{
while (SQCK_READ != 0)
{
timeout_clock_counter++;
if (timeout_clock_counter > 1000)
{
scpos = 0;
timeout_clock_counter = 0;
bitbuf = 0;
bitpos = 0;
continue;
}
}
while (SQCK_READ == 0);
if(SUBQ_READ)
{
bitbuf |= 1 << bitpos;
}
timeout_clock_counter = 0;
}
scbuf[scpos] = bitbuf;
scpos++;
bitbuf = 0;
}
while (scpos < 12);
sei();
uint8_t isDataSector = (((scbuf[0] & 0x40) == 0x40) && (((scbuf[0] & 0x10) == 0) && ((scbuf[0] & 0x80) == 0)));
if (
(isDataSector && scbuf[1] == 0x00 && scbuf[6] == 0x00) && // [0] = 41 means psx game disk. the other 2 checks are garbage protection
(scbuf[2] == 0xA0 || scbuf[2] == 0xA1 || scbuf[2] == 0xA2 || // if [2] = A0, A1, A2 ..
(scbuf[2] == 0x01 && (scbuf[3] >= 0x98 || scbuf[3] <= 0x02))) // .. or = 01 but then [3] is either > 98 or < 02
)
{
hysteresis++;
}
else if (hysteresis > 0 && ((scbuf[0] == 0x01 || isDataSector) && (scbuf[1] == 0x00 /*|| scbuf[1] == 0x01*/ ) && scbuf[6] == 0x00))
{
hysteresis++;
}
else if (hysteresis > 0)
{
hysteresis--;
}
if (hysteresis >= 14)
{
hysteresis = 11;
#ifdef LED_USE
LED_ON;
#endif
DATA_OUTPUT;
DATA_CLEAR;
if (!wfck_mode)
{
WFCK_OUTPUT;
WFCK_CLEAR;
}
_delay_ms(delay_between_injections);
uint8_t scex;
for (scex = 0; scex < 2; scex++)
{
inject_SCEX(region[scex]);
}
if (!wfck_mode)
{
WFCK_INPUT;
}
DATA_INPUT;
#ifdef LED_USE
LED_OFF;
#endif
}
}
}

60
PSNee_V8/include/config.h Normal file
View File

@ -0,0 +1,60 @@
#pragma once
#ifdef ATmega328_168
#define DATA_OUTPUT DDRB |= (1<<0)
#define DATA_INPUT DDRB &= ~(1<<0)
#define DATA_CLEAR PORTB &= ~(1<<0)
#define DATA_SET PORTB |= (1<<0)
#define WFCK_OUTPUT DDRB |= (1<<1)
#define WFCK_INPUT DDRB &= ~(1<<1)
#define WFCK_CLEAR PORTB &= ~(1<<1)
#define DX_OUTPUT DDRD |= (1<<4)
#define DX_INPUT DDRD &= ~(1<<4)
#define DX_CLEAR PORTD &= ~(1<<4)
#define DX_SET PORTD |= (1<<4)
#define SQCK_READ (PIND & (1<<6))
#define SUBQ_READ (PIND & (1<<7))
#define WFCK_READ (PINB & (1<<1))
#define AX_READ (PIND & (1<<2))
#define AY_READ (PIND & (1<<3))
#define TIMER_INTERRUPT_ENABLE TIMSK0 |= (1<<OCIE0A)
#define TIMER_INTERRUPT_DISABLE TIMSK0 &= ~(1<<OCIE0A)
#define TIMER_TCNT_CLEAR TCNT0 = 0x00
#define TIMER_TIFR_CLEAR TIFR0 |= (1<<OCF0A)
#define AX_INTERRUPT_ENABLE EIMSK = (1<<INT0)
#define AX_INTERRUPT_DISABLE EIMSK &= ~(1<<INT0)
#define AX_INTERRUPT_RISING EICRA = (1<<ISC01)|(1<<ISC00)
#define AX_INTERRUPT_FALLING EICRA = (1<<ISC01)
#define AY_INTERRUPT_ENABLE EIMSK = (1<<INT1)
#define AY_INTERRUPT_DISABLE EIMSK &= ~(1<<INT1)
#define AY_INTERRUPT_RISING EICRA = (1<<ISC11)|(1<<ISC10)
#define AY_INTERRUPT_FALLING EICRA = (1<<ISC11)
#define SW_USE PORTD |= (1<<5)
#define SW_CHECK (PIND & (1<<5))
#define LED_USE DDRB |= (1<<5)
#define LED_ON PORTB |= (1<<5)
#define LED_OFF PORTB &= ~(1<<5)
void Init()
{
TCNT0 = 0x00;
OCR0A = 159;
TCCR0A |= (1<<WGM01);
TCCR0B |= (1<<CS00);
#ifdef PATCH_SW
SW_USE;
#endif
LED_USE;
sei();
}
#endif

104
PSNee_V8/include/patching.h Normal file
View File

@ -0,0 +1,104 @@
#pragma once
#ifdef BIOS_PATCH
void Timer_Start(void);
void Timer_Stop(void);
extern volatile uint8_t count_isr;
extern volatile uint32_t microsec;
extern volatile uint16_t millisec;
volatile uint8_t impulse = 0;
volatile uint8_t patch = 0;
ISR(INT0_vect)
{
impulse++;
if (impulse == TRIGGER)
{
HOLD;
#ifdef HIGH_PATCH
DX_SET;
#endif
DX_OUTPUT;
PATCHING;
#ifdef HIGH_PATCH
DX_CLEAR;
#endif
DX_INPUT;
AX_INTERRUPT_DISABLE;
impulse = 0;
patch = 1;
}
}
#ifdef DOUBLE_PATCH
ISR(INT1_vect)
{
impulse++;
if (impulse == TRIGGER2)
{
HOLD2;
DX_OUTPUT;
PATCHING2;
DX_INPUT;
AY_INTERRUPT_DISABLE;
patch = 2;
}
}
#endif
void Bios_Patching()
{
#ifdef LOW_TRIGGER
AX_INTERRUPT_FALLING;
#else
AX_INTERRUPT_RISING;
#endif
if (AX_READ != 0)
{
while (AX_READ != 0);
while (AX_READ == 0);
}
else
{
while (AX_READ == 0);
}
Timer_Start();
while (microsec < CHECKPOINT);
Timer_Stop();
AX_INTERRUPT_ENABLE;
while (patch != 1);
#ifdef DOUBLE_PATCH
#ifdef LOW_TRIGGER2
AY_INTERRUPT_FALLING;
#else
AY_INTERRUPT_RISING;
#endif
while (AY_READ != 0);
Timer_Start();
while (microsec < CHECKPOINT2);
Timer_Stop();
AY_INTERRUPT_ENABLE;
while (patch != 2);
#endif
}
#endif

View File

@ -0,0 +1,92 @@
#pragma once
#ifdef UC_ALL
const char region[3] = {'a', 'a', 'a'};
#endif
#ifdef PAL_FAT
const char region[3] = {'e', 'e', 'e'};
#endif
#ifdef SCPH_103
const char region[3] = {'i', 'i', 'i'};
#endif
#ifdef SCPH_102
#define BIOS_PATCH
#define HOLD _delay_us(2.75)
#define PATCHING _delay_us(0.2)
#define CHECKPOINT 83900
#define TRIGGER 48
const char region[3] = {'e', 'e', 'e'};
#endif
#ifdef SCPH_100
#define BIOS_PATCH
#define HOLD _delay_us(2.7)
#define PATCHING _delay_us(0.2)
#define CHECKPOINT 83900
#define TRIGGER 48
const char region[3] = {'i', 'i', 'i'};
#endif
#ifdef SCPH_7000_9000
#define BIOS_PATCH
#define HOLD _delay_us(2.85)
#define PATCHING _delay_us(0.1)
#define CHECKPOINT 75270
#define TRIGGER 16
const char region[3] = {'i', 'i', 'i'};
#endif
#ifdef SCPH_5500
#define BIOS_PATCH
#define LOW_TRIGGER
#define HOLD _delay_us(2.85)
#define PATCHING _delay_us(0.1)
#define CHECKPOINT 76130
#define TRIGGER 21
const char region[3] = {'i', 'i', 'i'};
#endif
#ifdef SCPH_3500_5000
#define BIOS_PATCH
#define LOW_TRIGGER
#define HOLD _delay_us(2.85)
#define PATCHING _delay_us(0.1)
#define CHECKPOINT 75260
#define TRIGGER 21
const char region[3] = {'i', 'i', 'i'};
#endif
#ifdef SCPH_3000
#define BIOS_PATCH
#define HIGH_PATCH
#define DOUBLE_PATCH
#define CHECKPOINT 83000
#define TRIGGER 60
#define HOLD _delay_us(2.75)
#define PATCHING _delay_us(0.1)
#define LOW_TRIGGER2
#define CHECKPOINT2 253300
#define TRIGGER2 43
#define HOLD2 _delay_us(2.88)
#define PATCHING2 _delay_us(0.15)
const char region[3] = {'i', 'i', 'i'};
#endif
#ifdef SCPH_1000
#define BIOS_PATCH
#define HIGH_PATCH
#define DOUBLE_PATCH
#define CHECKPOINT 83000
#define TRIGGER 92
#define HOLD _delay_us(2.7)
#define PATCHING _delay_us(0.1)
#define LOW_TRIGGER2
#define CHECKPOINT2 272800
#define TRIGGER2 71
#define HOLD2 _delay_us(2.88)
#define PATCHING2 _delay_us(0.15)
const char region[3] = {'i', 'i', 'i'};
#endif

38
README.md Normal file
View File

@ -0,0 +1,38 @@
# PSNee V8
The first stealth modchip supporting unlocking BIOS of Japanese versions Sony PlayStation 1
![Logo](images/PSNee_V8_logo.png)
Developed by **brill** & **postal2201**, based on PSNee V7 open source project.
- http://www.emu-land.net/forum/index.php/topic,85934.0.html
## Supported platforms
PsNee V8 supports the following MCU's:
- ATmega328(A/P/PA) @16Mhz
- ATmega168(A/P/PA) @16Mhz
## Installation
Use the programmer to flash MCU.
**Flashing via COM port is not supported.**
### Fuses
Before flashing the MCU, you need to configure the fuses.
- Fuses for JAP_FAT consoles: **H: DF, L: EE, E: FF**
- Fuses for all other consoles: **H: DF, L: FF, E: FF**
### Arduino
To install via the Arduino IDE may require the installation of the [MiniCore](https://github.com/MCUdude/MiniCore) package.
Example of correct setting for ATmega328P:\
**Don't use a bootloader!**
![ArduinoIDE](images/example.png)
After that select the type console - uncoment define in file project(*.ino)
![Console](images/console.png)
Final step: Sketch -> Upload Using Programmer
## Installation diagram
![Board](images/PSNee_V8_pinout.png)

BIN
images/PSNee_V8_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

BIN
images/PSNee_V8_pinout.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

BIN
images/console.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
images/example.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB