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

225 lines
6.1 KiB
C++

// ATTYNee!!! Universal mod for PS1 & PSOne.
//--------------------------------------------------
// Pinouts!
//--------------------------------------------------
//FOR ARDUINO UNO (WITH ATMEGA328):
// - Arduino pin 8 = data = ATMega pin 14
// - Arduino pin 9 = gate = ATMega pin 15
// - Arduino pin 10 = lid = ATMega pin 16
// - Arduino pin 11 = biosA18 = ATMega pin 2 Only used in SCPH-102 PAL mode
// - Arduino pin 12 = biosD2 = ATMega pin 18 Only used in SCPH-102 PAL mode
//FOR ATTINY13/25/45/85:
// - PB0 = data = ATTiny pin 5
// - PB1 = gate = ATTiny pin 6
// - PB2 = lid = ATTiny pin 7
// - PB3 = biosA18 = ATTiny pin 2 Only used in SCPH-102 PAL mode
// - PB4 = biosD2 = ATTiny pin 3 Only used in SCPH-102 PAL mode
//--------------------------------------------------
// Chip selection!
//--------------------------------------------------
#define ARDUINO_UNO //Make that "#define ARDUINO_UNO" if you want to compile for Arduino Uno instead of ATTiny25/45/85
#ifdef ARDUINO_UNO
//Pins
unsigned char data = 8; //The pin that outputs the SCEE SCEA SCEI string
unsigned char gate = 9; //The pin that outputs the SCEE SCEA SCEI string
unsigned char lid = 10; //The pin that gets connected to the internal CD lid signal; active high
unsigned char biosA18 = 11; //Only used in SCPH-102 PAL mode
unsigned char biosD2 = 12; //Only used in SCPH-102 PAL mode
unsigned short delay_ntsc = 2350;
boolean injectFlag = 0;
unsigned char delay_between_bits = 4;
unsigned char delay_between_injections = 74;
#endif
#ifdef ATTiny25/45/85
//Pins
unsigned char data = 0; //The pin that outputs the SCEE SCEA SCEI string
unsigned char gate = 1;
unsigned char lid = 2; //The pin that gets connected to the internal CD lid signal; active high
unsigned char biosA18 = 3; //Only used in SCPH-102 PAL mode
unsigned char biosD2 = 4; //Only used in SCPH-102 PAL mode
unsigned short delay_ntsc = 2400;
boolean injectFlag = 0;
unsigned char delay_between_bits = 4;
unsigned char delay_between_injections = 68;
#endif
#ifdef ATTiny13A
//Pins
unsigned char data = 0; //The pin that outputs the SCEE SCEA SCEI string
unsigned char gate = 1;
unsigned char lid = 2; //The pin that gets connected to the internal CD lid signal; active high
unsigned char biosA18 = 3; //Only used in SCPH-102 PAL mode
unsigned char biosD2 = 4; //Only used in SCPH-102 PAL mode
unsigned short delay_ntsc = 2400;
boolean injectFlag = 0;
unsigned char delay_between_bits = 4;
unsigned char delay_between_injections = 72;
#endif
bool readBit(int index, const unsigned char *ByteSet)
{
int byte_index = index >> 3;
byte bits = pgm_read_byte(&(ByteSet[byte_index]));
int bit_index = index & 0x7; // same as (index - byte_index<<3) or (index%8)
byte mask = 1 << bit_index;
return (0 != (bits & mask));
}
void NTSC_fix()
{
DDRB = 0x00;
delay(delay_ntsc);
while (!(PINB & 0b00001000))
{
; //Wait
}
delayMicroseconds(12);
PORTB = 0b00000000;
DDRB = 0b00010000;
delayMicroseconds(5);
DDRB = 0x00;
//Serial.println("NTSC_fixed!"); //Debug only
}
void inject_SCEE()
{
static const unsigned char ByteSet[] PROGMEM = {0b01011001, 0b11001001, 0b01001011, 0b01011101, 0b11101010, 0b00000010};
//Serial.println("inject_SCEE"); //Debug only
for (unsigned char i = 0; i < 44; i++) {
if (readBit(i, ByteSet) == 0)
{
// Serial.print(0); //Debug only
pinMode(data, OUTPUT);
digitalWrite(data, 0);
delay(delay_between_bits);
}
else
{
// Serial.print(1); //Debug only
pinMode(data, INPUT);
delay(delay_between_bits);
}
}
pinMode(data, OUTPUT);
digitalWrite(data, 0);
delay(delay_between_injections);
}
void inject_SCEA()
{
static const unsigned char ByteSet[] PROGMEM = {0b01011001, 0b11001001, 0b01001011, 0b01011101, 0b11111010, 0b00000010};
// Serial.println("inject_SCEA"); //Debug only
for (unsigned char i = 0; i < 44; i++) {
if (readBit(i, ByteSet) == 0)
{
// Serial.print(0); //Debug only
pinMode(data, OUTPUT);
digitalWrite(data, 0);
delay(delay_between_bits);
}
else
{
// Serial.print(1); //Debug only
pinMode(data, INPUT);
delay(delay_between_bits);
}
}
pinMode(data, OUTPUT);
digitalWrite(data, 0);
delay(delay_between_injections);
}
void inject_SCEI()
{
static const unsigned char ByteSet[] PROGMEM = {0b01011001, 0b11001001, 0b01001011, 0b01011101, 0b11011010, 0b00000010};
// Serial.println("inject_SCEI"); //Debug only
for (unsigned char i = 0; i < 44; i++) {
if (readBit(i, ByteSet) == 0)
{
// Serial.print(0); //Debug only
pinMode(data, OUTPUT);
digitalWrite(data, 0);
delay(delay_between_bits);
}
else
{
// Serial.print(1); //Debug only
pinMode(data, INPUT);
delay(delay_between_bits);
}
}
pinMode(data, OUTPUT);
digitalWrite(data, 0);
delay(delay_between_injections);
}
void inject_SCEx()
{
unsigned char loop_counter;
NTSC_fix(); //Only for SCPH-102 PAL. For other please, comment this function, and uncomment next delay.
//delay(3000);
delay(1200);
pinMode(gate, OUTPUT);
digitalWrite(gate, 0);
delay(100);
for (loop_counter = 0; loop_counter < 40; loop_counter = loop_counter + 1)
if (digitalRead(lid) == HIGH)
{
DDRB = 0x00;
void loop();
}
else
{
inject_SCEE();
inject_SCEA();
inject_SCEI();
}
pinMode(gate, INPUT);
pinMode(data, INPUT);
injectFlag = 1;
// Serial.println("inject_DONE!"); //Debug only
}
void setup()
{
// Serial.begin(9600); //Debug only
pinMode(lid, INPUT);
pinMode(biosA18, INPUT);
pinMode(data, INPUT);
pinMode(gate, INPUT);
}
void loop()
{
if (digitalRead(lid) == HIGH && injectFlag == 1)
{
// Serial.println("Wait new cycle"); //Debug only
injectFlag = 0;
}
if (digitalRead(lid) == LOW && injectFlag == 0)
{
// Serial.println("Start Inject"); //Debug only
inject_SCEx();
}
// if (digitalRead(lid) == HIGH && injectFlag == 0)
// {
// Serial.println("Opened before injecting!"); //Debug only
// }
}