PSNee further development

General information to do with the PlayStation 1 Hardware. Including modchips, pinouts, rare or obscure development equipment, etc.
Post Reply
MrPeach
What is PSXDEV?
What is PSXDEV?
Posts: 1
Joined: Jun 09, 2017

Post by MrPeach » June 9th, 2017, 10:00 am

Why are you returning while you are still holding the interrupt lock?

Code: Select all

  if (scpos < 12){
    return;
  }

  interrupts(); // end critical section

Element18592
What is PSXDEV?
What is PSXDEV?
Posts: 3
Joined: Jun 09, 2017

Post by Element18592 » June 9th, 2017, 10:34 am

Great work rama. Glad I stumbled across this being that assembler has been down for some time. Would you happen to have a diagram for PU18?

likeabaus
Extreme PSXDEV User
Extreme PSXDEV User
Posts: 133
Joined: Jul 27, 2016

Post by likeabaus » June 9th, 2017, 12:04 pm

A quick update, I guess I'm rustier than I thought, just killed my PU-23 motherboard, by accidentally ripping off a SMT capacitor XD. Not to worry though, I have a spare console, just no idea what motherboard is in it, as it was apparently refurbished by someone else before I got it (model number sticker has been removed). Time to crack it open and see what I got to work with, RIP overclocked PU-23, you served me well hahahaha

User avatar
Shadow
Verified
Admin / PSXDEV
Admin / PSXDEV
Posts: 2670
Joined: Dec 31, 2012
PlayStation Model: H2000/5502
Discord: Shadow^PSXDEV

Post by Shadow » June 9th, 2017, 1:12 pm

Probably fixable.
Development Console: SCPH-5502 with 8MB RAM, MM3 Modchip, PAL 60 Colour Modification (for NTSC), PSIO Switch Board, DB-9 breakout headers for both RGB and Serial output and an Xplorer with CAETLA 0.34.

PlayStation Development PC: Windows 98 SE, Pentium 3 at 400MHz, 128MB SDRAM, DTL-H2000, DTL-H2010, DTL-H201A, DTL-S2020 (with 4GB SCSI-2 HDD), 21" Sony G420, CD-R burner, 3.25" and 5.25" Floppy Diskette Drives, ZIP 100 Diskette Drive and an IBM Model M keyboard.

rama3
Verified
/// PSXDEV | ELITE ///
/// PSXDEV | ELITE ///
Posts: 510
Joined: Apr 16, 2017

Post by rama3 » June 10th, 2017, 1:24 am

MrPeach wrote:Why are you returning while you are still holding the interrupt lock?

Code: Select all

  if (scpos < 12){
    return;
  }

  interrupts(); // end critical section
I didn't mean to! Thanks, I will fix it with the next update.

rama3
Verified
/// PSXDEV | ELITE ///
/// PSXDEV | ELITE ///
Posts: 510
Joined: Apr 16, 2017

Post by rama3 » June 10th, 2017, 1:28 am

Matt wrote:Probably fixable.
Yep, just find the service manual for SCPH 9000. It has the locations of all parts and their values listed nicely.
Be glad it is a PU-23. Best service manual we have is for it :)

kalymnos77
Curious PSXDEV User
Curious PSXDEV User
Posts: 23
Joined: Jun 06, 2017

Post by kalymnos77 » June 10th, 2017, 2:45 am

Phaltex19 has to send on github, the SCREW inject bitstream from Net Yaroze, I tested it on the last vertion of the code and it is ok on my pm-41, and it works well for me.

Code: Select all

    // This PsNee version is meant for Arduino boards.
    // 16Mhz and 8Mhz variants are supported. "Pro Micro" etc supported and recommended
    // ATtinys should be able to do this as well; requires a bit of porting and testing

    // PAL PU-41 support isn't implemented here yet. Use PsNee v6 for them.

    // By default, this code is multi-region. You can optimize it for your console, if you want to.
    // Choose the correct inject_SCEX() for your console region.
    // e = Europe / PAL
    // a = North America / NTSC-U
    // i = Japan / NTSC-J

    // Uncomment #define PU22_MODE for PU-22, PU-23, PU-41 mainboards.

    #define PU22_MODE

    //Pins
    const int data = 8;         // Arduino pin 8, ATmega PB0 injects SCEX string. point 6 in old modchip Diagrams
    const int SUBQ = 10;     // Arduino pin 10, ATmega PB2 "SUBQ" Mechacon pin 24 (PU-7 and early PU-8 Mechacons: pin 39)
    const int SQCK = 11;    // Arduino pin 11, ATmega PB3 "SQCK" Mechacon pin 26 (PU-7 and early PU-8 Mechacons: pin 41)
    //Timing
    const int delay_between_bits = 4000; // 250 bits/s (microseconds)
    const int delay_between_injections = 74; // 74 original, 72 in oldcrow (milliseconds)

    // for PU-22 mode: specific delay times for the high bit injection. It depends on the MCU speed.
    #if F_CPU == 16000000
    const byte gate_high = 21;
    const byte gate_low = 23;
    #else
    const byte gate_high = 20;
    const byte gate_low = 20;
    #endif

    // SQCK (SUBQ clock) sampling timeout: All PSX will transmit 12 packets of 8 bit / 1 byte each, once CD reading is stable.
    // If the pulses take too much time, we drop the byte and wait for a better chance. 1000 is a good value.
    const int sampling_timeout = 1000;


    //SCEE: 1 00110101 00, 1 00111101 00, 1 01011101 00, 1 01011101 00
    //SCEA: 1 00110101 00, 1 00111101 00, 1 01011101 00, 1 01111101 00
    //SCEI: 1 00110101 00, 1 00111101 00, 1 01011101 00, 1 01101101 00
    const boolean SCEEData[44] = {1,0,0,1,1,0,1,0,1,0,0,1,0,0,1,1,1,1,0,1,0,0,1,0,1,0,1,1,1,0,1,0,0,1,0,1,0,1,1,1,0,1,0,0}; //SCEE
    const boolean SCEAData[44] = {1,0,0,1,1,0,1,0,1,0,0,1,0,0,1,1,1,1,0,1,0,0,1,0,1,0,1,1,1,0,1,0,0,1,0,1,1,1,1,1,0,1,0,0}; //SCEA
    const boolean SCEIData[44] = {1,0,0,1,1,0,1,0,1,0,0,1,0,0,1,1,1,1,0,1,0,0,1,0,1,0,1,1,1,0,1,0,0,1,0,1,1,0,1,1,0,1,0,0}; //SCEI
    const boolean SCEWData[44] = {1,0,0,1,1,0,1,0,1,0,0,1,0,0,1,1,1,1,0,1,0,0,1,0,1,0,1,1,1,0,1,0,0,1,0,0,0,1,0,1,0,1,0,0}; //SCEW

    void inject_SCEX(char region)
    {
      const boolean *SCEXData;
      switch (region){
        case 'e': SCEXData = SCEEData; break;
        case 'a': SCEXData = SCEAData; break;
        case 'i': SCEXData = SCEIData; break;
        case 'W': SCEXData = SCEIData; break;
      }

      digitalWrite(LED_BUILTIN, HIGH); // this is Arduino Pin 13 / PB5

      for (byte bit_counter = 0; bit_counter < 44; bit_counter = bit_counter + 1)
      {
        if (*(SCEXData+bit_counter) == 0)
        {
          bitClear(PORTB,0); // pull data low
          delayMicroseconds(delay_between_bits);
        }
        else
        {
          unsigned long now = micros();
          do {
    #ifdef PU22_MODE
            bitWrite(PORTB,0,1); // output high
            delayMicroseconds(gate_high);
            bitWrite(PORTB,0,0); // output low
            delayMicroseconds(gate_low);
    #else
            bitSet(PORTB,0); // drag data pin high
    #endif
          }
          while ((micros() - now) < delay_between_bits);
          //Serial.println((micros() - now));
        }
      }
      bitClear(PORTB,0); // pull data low
      delay(delay_between_injections);
     
      digitalWrite(LED_BUILTIN, LOW);
    }

    //--------------------------------------------------
    //     Setup
    //--------------------------------------------------
    void setup()
    {
      pinMode(data, INPUT); // Arduino pin 8, ATmega PB0
      pinMode(SUBQ, INPUT); // spi data in Arduino pin 10, ATmega PB2
      pinMode(SQCK, INPUT); // spi clock Arduino pin 11, ATmega PB3
      pinMode(LED_BUILTIN, OUTPUT); // Blink on injection / debug.
      Serial.begin (1000000);
      Serial.println("Start ");
     
      // Power saving
      // Disable the ADC by setting the ADEN bit (bit 7)  of the
      // ADCSRA register to zero.
      ADCSRA = ADCSRA & B01111111;
      // Disable the analog comparator by setting the ACD bit
      // (bit 7) of the ACSR register to one.
      ACSR = B10000000;
      // Disable digital input buffers on all analog input pins
      // by setting bits 0-5 of the DIDR0 register to one.
      DIDR0 = DIDR0 | B00111111;
    }

    void loop()
    {
      static unsigned int num_resets = 0; // debug / testing
      static byte scbuf [12] = { 0 }; // We will be capturing PSX "SUBQ" packets, there are 12 bytes per valid read.
      static byte scpos = 0;          // scbuf position

      static unsigned int timeout_clock_counter = 0;
      static byte bitbuf = 0;         // SUBQ bit storage
      static bool sample = 0;

      // Capture 8 bits per loop run.
      // unstable clock, bootup, reset and disc changes are ignored
      noInterrupts(); // start critical section

    // yes, a goto jump label. This is to avoid a return out of critical code with interrupts disabled.
    // It prevents bad behaviour, for example running the Arduino Serial Event routine without interrupts.
    // Using a function makes shared variables messier.
    // We really want to have an 8 bit packet before doing anything else.
    timedout:

      for (byte bitpos = 0; bitpos<8; bitpos++) {
        do {
          // nothing, reset on timeout
          timeout_clock_counter++;
          if (timeout_clock_counter > sampling_timeout){
            scpos = 0;  // reset SUBQ packet stream
            timeout_clock_counter = 0;
            num_resets++;
            bitpos = 0;
            goto timedout;
          }
        }
        while (bitRead(PINB, 3) == 1); // wait for clock to go low
       
    #if F_CPU == 16000000 // wait a few cpu cycles > better readings in tests
        __asm__("nop\n\t"); __asm__("nop\n\t"); __asm__("nop\n\t");
    #endif

        // sample the bit.
        sample = bitRead(PINB, 2);
        bitbuf |= sample << bitpos;

        do {
          // nothing
        } while ((bitRead(PINB, 3)) == 0); // Note: Even if sampling is bad, it will not get stuck here. There will be clock pulses eventually.

        timeout_clock_counter = 0; // This bit came through fine.
      }
     
      scbuf[scpos] = bitbuf;
      scpos++;
      bitbuf = 0;

      if (scpos < 12){
        return;
      }

      interrupts(); // end critical section
     
      // logging.
      if (!(scbuf[0] == 0 && scbuf[1] == 0 && scbuf[2] == 0 && scbuf[3] == 0)){ // a bad sector read is all 0 except for the CRC fields. Don't log it.
        for (int i = 0; i<12;i++) {
          Serial.print(scbuf[i], HEX);
          Serial.print(" ");
        }
        Serial.print(" resets:  ");
        Serial.println(num_resets);
      }

      num_resets = 0;
      scpos = 0;
     
      // check if this is the wobble area
      // 3 bytes would be enough to recognize it. The extra checks just ensure this isn't a garbage reading.
      if ( (scbuf[0] == 0x41 &&  scbuf[1] == 0x00 &&  scbuf[6] == 0x00) && // 0x41 = psx game, beginning of the disc, sanity check
        ((scbuf[2] == 0xA0 || scbuf[2] == 0xA1 || scbuf[2] == 0xA2) ||
        (scbuf[2] > 0x00 && scbuf[2] <= 0x99)) ){ // lead in / wobble area
       
        Serial.println("INJECT!");

        pinMode(data, OUTPUT); // prepare for SCEX injection

        bitClear(PORTB,0); // pull data low
       
        // HC-05 is waiting for a bit of silence (pin Low) before it begins decoding.
         // minimum 66ms required on SCPH-7000
         // minimum 79ms required on SCPH-7502
         delay(82);
       
        for (int loop_counter = 0; loop_counter < 2; loop_counter++)
        {
           inject_SCEX('e'); // e = SCEE, a = SCEA, i = SCEI, w =SCEW
           inject_SCEX('a'); // injects all 4 regions by default
           inject_SCEX('i'); // makes it easier for people to get working
           inject_SCEX('w');
        }

        pinMode(data, INPUT); // high-z the data line, we're done
      }
    // keep catching SUBQ packets forever
    }

    // Old readme!

    //UPDATED AT MAY 14 2016, CODED BY THE FRIENDLY FRIETMAN :-)

    //PsNee, an open source stealth modchip for the Sony Playstation 1, usable on
    //all platforms supported by Arduino, preferably ATTiny. Finally something modern!


    //--------------------------------------------------
    //                    TL;DR
    //--------------------------------------------------
    //Look for the "Arduino selection!" section and verify the target platform. Hook up your target device and hit Upload!
    //BEWARE: when using ATTiny45, make sure the proper device is selected (Extra=>Board=>ATTiny45 (internal 8MHz clock))
    //and the proper fuses are burnt (use Extra=>Burn bootloader for this), otherwise PsNee will malfunction. A tutorial on
    //uploading Arduino code via an Arduino Uno to an ATTiny device: http://highlowtech.org/?p=1695
    //Look at the pinout for your device and hook PsNee up to the points on your Playstation.

    //The modchip injects after about 1500ms the text strings SCEE SCEA SCEI on the motherboard point and stops
    //with this after about 25 seconds. Because all the possible valid region options are outputted on the
    //motherboard the Playstation gets a bit confused and simply accepts the inserted disc as authentic; after all,
    //one of the codes was the same as that of the Playstation hardware...

    //--------------------------------------------------
    //               New in this version!
    //--------------------------------------------------
    //A lot!
    // - The PAL SCPH-102 NTSC BIOS-patch works flawlessly! For speed reasons this is implemented in bare
    //   AVR C. It is functionally identical to the OneChip modchip, this modchip firmware was disassembled,
    //   documented (available on request, but written in Dutch...) and analyzed with a logic analyzer to
    //   make sure PsNee works just as well.
    // - The code now is segmented in functions which make the program a lot more maintable and readable
    // - Timing is perfected, all discs (both backups and originals of PAL and NTSC games) now work in the
    //   PAL SCPH-102 test machine
    // - It was found out that the gate signal doesn't havbe to be hooked up to a PAL SCPH-102 Playstation
    //   to circumvent the copy protection. This is not tested on other Playstation models so the signal still
    //   is available
    // - The /xlat signal is no longer required to time the PAL SCPH-102 NTSC BIOS-patch
    // - Only AVR PORTB is used for compatibility reasons (almost all the AVR chips available have PORTB)


rama3
Verified
/// PSXDEV | ELITE ///
/// PSXDEV | ELITE ///
Posts: 510
Joined: Apr 16, 2017

Post by rama3 » June 10th, 2017, 3:03 am

Element18592 wrote:Great work rama. Glad I stumbled across this being that assembler has been down for some time. Would you happen to have a diagram for PU18?
Here's one for PU-18. Vcc and Gnd are suggestions. You can use anything, as long as it's 3.5V and a good ground connection.
Image

rama3
Verified
/// PSXDEV | ELITE ///
/// PSXDEV | ELITE ///
Posts: 510
Joined: Apr 16, 2017

Post by rama3 » June 10th, 2017, 3:10 am

kalymnos77:
SCEW does not normally work. If you got it working, it's a random fluke.
There is no code in the HC-05 that accepts the "W" as valid.

Edit:
Okay, it works for you because it is still setup to unlock all 3 valid regions.
The new code is supposed to be triggered by calling

Code: Select all

inject_SCEX('w');
but in the actual function, it does

Code: Select all

case 'W': SCEXData = SCEIData; break;
There are 2 errors in this.
First, it looks for 'W' (will never happen, since it sends 'w')
Second, it still assigns the SCEI code to the supposed SCEW array.

Edit2:
Ah, I get it now! This is meant to unlock Net Yaroze consoles. They probably have a HC-05 in them that looks for "W".
I can add this correctly but someone has got to test it. Or verify such a console even needs a modchip. I don't know if it does.
Last edited by rama3 on June 10th, 2017, 3:47 am, edited 1 time in total.

rama3
Verified
/// PSXDEV | ELITE ///
/// PSXDEV | ELITE ///
Posts: 510
Joined: Apr 16, 2017

Post by rama3 » June 10th, 2017, 3:42 am

New version:
- interrupt bugfix (thanks MrPeach!)
- corrected use of PU-41 (it is PM-41 instead. I always get that wrong :p)

Code: Select all

// This PsNee version is meant for Arduino boards.
// 16Mhz and 8Mhz variants are supported. "Pro Micro" etc supported and recommended
// ATtinys should be able to do this as well; requires a bit of porting and testing

// PAL PM-41 support isn't implemented here yet. Use PsNee v6 for them.
// NTSC-U/J PM-41 are supported with PU22_MODE.

// By default, this code is multi-region. You can optimize it for your console, if you want to.
// Choose the correct inject_SCEX() for your console region. 
// e = Europe / PAL
// a = North America / NTSC-U
// i = Japan / NTSC-J

// Use #define PU22_MODE for PU-22, PU-23, PM-41 mainboards.

#define PU22_MODE

//Pins
const int data = 8;         // Arduino pin 8, ATmega PB0 injects SCEX string. point 6 in old modchip Diagrams
const int SUBQ = 10;     // Arduino pin 10, ATmega PB2 "SUBQ" Mechacon pin 24 (PU-7 and early PU-8 Mechacons: pin 39)
const int SQCK = 11;    // Arduino pin 11, ATmega PB3 "SQCK" Mechacon pin 26 (PU-7 and early PU-8 Mechacons: pin 41)
//Timing
const int delay_between_bits = 4000; // 250 bits/s (microseconds)
const int delay_between_injections = 74; // 74 original, 72 in oldcrow (milliseconds)

// for PU-22 mode: specific delay times for the high bit injection. It depends on the MCU speed.
#if F_CPU == 16000000
const byte gate_high = 21;
const byte gate_low = 23;
#else
const byte gate_high = 20;
const byte gate_low = 20;
#endif

// SQCK (SUBQ clock) sampling timeout: All PSX will transmit 12 packets of 8 bit / 1 byte each, once CD reading is stable.
// If the pulses take too much time, we drop the byte and wait for a better chance. 1000 is a good value.
const int sampling_timeout = 1000;


//SCEE: 1 00110101 00, 1 00111101 00, 1 01011101 00, 1 01011101 00
//SCEA: 1 00110101 00, 1 00111101 00, 1 01011101 00, 1 01111101 00
//SCEI: 1 00110101 00, 1 00111101 00, 1 01011101 00, 1 01101101 00
const boolean SCEEData[44] = {1,0,0,1,1,0,1,0,1,0,0,1,0,0,1,1,1,1,0,1,0,0,1,0,1,0,1,1,1,0,1,0,0,1,0,1,0,1,1,1,0,1,0,0}; //SCEE
const boolean SCEAData[44] = {1,0,0,1,1,0,1,0,1,0,0,1,0,0,1,1,1,1,0,1,0,0,1,0,1,0,1,1,1,0,1,0,0,1,0,1,1,1,1,1,0,1,0,0}; //SCEA
const boolean SCEIData[44] = {1,0,0,1,1,0,1,0,1,0,0,1,0,0,1,1,1,1,0,1,0,0,1,0,1,0,1,1,1,0,1,0,0,1,0,1,1,0,1,1,0,1,0,0}; //SCEI

void inject_SCEX(char region)
{
  const boolean *SCEXData;
  switch (region){
    case 'e': SCEXData = SCEEData; break;
    case 'a': SCEXData = SCEAData; break;
    case 'i': SCEXData = SCEIData; break;
  }

  digitalWrite(LED_BUILTIN, HIGH); // this is Arduino Pin 13 / PB5

  for (byte bit_counter = 0; bit_counter < 44; bit_counter = bit_counter + 1)
  {
    if (*(SCEXData+bit_counter) == 0)
    {
      bitClear(PORTB,0); // pull data low
      delayMicroseconds(delay_between_bits);
    }
    else
    {
      unsigned long now = micros();
      do {
#ifdef PU22_MODE
        bitWrite(PORTB,0,1); // output high
        delayMicroseconds(gate_high);
        bitWrite(PORTB,0,0); // output low
        delayMicroseconds(gate_low);
#else
        bitSet(PORTB,0); // drag data pin high
#endif
      }
      while ((micros() - now) < delay_between_bits);
      //Serial.println((micros() - now));
    }
  }
  bitClear(PORTB,0); // pull data low
  delay(delay_between_injections);
  
  digitalWrite(LED_BUILTIN, LOW);
}

//--------------------------------------------------
//     Setup
//--------------------------------------------------
void setup()
{
  pinMode(data, INPUT); // Arduino pin 8, ATmega PB0
  pinMode(SUBQ, INPUT); // spi data in Arduino pin 10, ATmega PB2
  pinMode(SQCK, INPUT); // spi clock Arduino pin 11, ATmega PB3
  pinMode(LED_BUILTIN, OUTPUT); // Blink on injection / debug.
  Serial.begin (1000000);
  Serial.println("Start ");
  
  // Power saving
  // Disable the ADC by setting the ADEN bit (bit 7)  of the
  // ADCSRA register to zero.
  ADCSRA = ADCSRA & B01111111;
  // Disable the analog comparator by setting the ACD bit
  // (bit 7) of the ACSR register to one.
  ACSR = B10000000;
  // Disable digital input buffers on all analog input pins
  // by setting bits 0-5 of the DIDR0 register to one.
  DIDR0 = DIDR0 | B00111111;
}

void loop()
{
  static unsigned int num_resets = 0; // debug / testing
  static byte scbuf [12] = { 0 }; // We will be capturing PSX "SUBQ" packets, there are 12 bytes per valid read.
  static byte scpos = 0;          // scbuf position

  static unsigned int timeout_clock_counter = 0;
  static byte bitbuf = 0;         // SUBQ bit storage
  static bool sample = 0;

  // Capture 8 bits per loop run. 
  // unstable clock, bootup, reset and disc changes are ignored
  noInterrupts(); // start critical section

// yes, a goto jump label. This is to avoid a return out of critical code with interrupts disabled. 
// It prevents bad behaviour, for example running the Arduino Serial Event routine without interrupts.
// Using a function makes shared variables messier.
// SUBQ sampling is essential for the rest of the functionality. It is okay for this to take as long as it does.
start:

  for (byte bitpos = 0; bitpos<8; bitpos++) {
    do {
      // nothing, reset on timeout
      timeout_clock_counter++;
      if (timeout_clock_counter > sampling_timeout){
        scpos = 0;  // reset SUBQ packet stream
        timeout_clock_counter = 0;
        num_resets++;
        bitpos = 0;
        goto start;
      }
    }
    while (bitRead(PINB, 3) == 1); // wait for clock to go low
    
#if F_CPU == 16000000 // wait a few cpu cycles > better readings in tests
    __asm__("nop\n\t"); __asm__("nop\n\t"); __asm__("nop\n\t");
#endif

    // sample the bit.
    sample = bitRead(PINB, 2);
    bitbuf |= sample << bitpos;

    do {
      // nothing
    } while ((bitRead(PINB, 3)) == 0); // Note: Even if sampling is bad, it will not get stuck here. There will be clock pulses eventually.

    timeout_clock_counter = 0; // This bit came through fine. 
  }
  
  scbuf[scpos] = bitbuf;
  scpos++;
  bitbuf = 0;

  if (scpos < 12){
    goto start;
  }

  interrupts(); // end critical section
  
  // logging. 
  if (!(scbuf[0] == 0 && scbuf[1] == 0 && scbuf[2] == 0 && scbuf[3] == 0)){ // a bad sector read is all 0 except for the CRC fields. Don't log it.
    for (int i = 0; i<12;i++) {
      Serial.print(scbuf[i], HEX);
      Serial.print(" ");
    }
    Serial.print(" resets:  ");
    Serial.println(num_resets);
  }

  num_resets = 0;
  scpos = 0;
  
  // check if this is the wobble area
  // 3 bytes would be enough to recognize it. The extra checks just ensure this isn't a garbage reading.
  if ( (scbuf[0] == 0x41 &&  scbuf[1] == 0x00 &&  scbuf[6] == 0x00) && // 0x41 = psx game, beginning of the disc, sanity check
    ((scbuf[2] == 0xA0 || scbuf[2] == 0xA1 || scbuf[2] == 0xA2) ||
    (scbuf[2] > 0x00 && scbuf[2] <= 0x99)) ){ // lead in / wobble area
    
    Serial.println("INJECT!");

    pinMode(data, OUTPUT); // prepare for SCEX injection

    bitClear(PORTB,0); // pull data low
    
    // HC-05 is waiting for a bit of silence (pin Low) before it begins decoding. 
	  // minimum 66ms required on SCPH-7000
	  // minimum 79ms required on SCPH-7502 // wrong! got to keep the NRZ signal in mind for PU22+ !
	  delay(82); 
    
    for (int loop_counter = 0; loop_counter < 2; loop_counter++)
    {
       inject_SCEX('e'); // e = SCEE, a = SCEA, i = SCEI
       inject_SCEX('a'); // injects all 3 regions by default
       inject_SCEX('i'); // makes it easier for people to get working
    }

    pinMode(data, INPUT); // high-z the data line, we're done
  }
// keep catching SUBQ packets forever
}

// Old readme!

//UPDATED AT MAY 14 2016, CODED BY THE FRIENDLY FRIETMAN :-)

//PsNee, an open source stealth modchip for the Sony Playstation 1, usable on
//all platforms supported by Arduino, preferably ATTiny. Finally something modern!


//--------------------------------------------------
//                    TL;DR
//--------------------------------------------------
//Look for the "Arduino selection!" section and verify the target platform. Hook up your target device and hit Upload!
//BEWARE: when using ATTiny45, make sure the proper device is selected (Extra=>Board=>ATTiny45 (internal 8MHz clock))
//and the proper fuses are burnt (use Extra=>Burn bootloader for this), otherwise PsNee will malfunction. A tutorial on
//uploading Arduino code via an Arduino Uno to an ATTiny device: http://highlowtech.org/?p=1695
//Look at the pinout for your device and hook PsNee up to the points on your Playstation.

//The modchip injects after about 1500ms the text strings SCEE SCEA SCEI on the motherboard point and stops 
//with this after about 25 seconds. Because all the possible valid region options are outputted on the
//motherboard the Playstation gets a bit confused and simply accepts the inserted disc as authentic; after all,
//one of the codes was the same as that of the Playstation hardware...

//--------------------------------------------------
//               New in this version!
//--------------------------------------------------
//A lot!
// - The PAL SCPH-102 NTSC BIOS-patch works flawlessly! For speed reasons this is implemented in bare
//   AVR C. It is functionally identical to the OneChip modchip, this modchip firmware was disassembled,
//   documented (available on request, but written in Dutch...) and analyzed with a logic analyzer to
//   make sure PsNee works just as well.
// - The code now is segmented in functions which make the program a lot more maintable and readable
// - Timing is perfected, all discs (both backups and originals of PAL and NTSC games) now work in the 
//   PAL SCPH-102 test machine
// - It was found out that the gate signal doesn't havbe to be hooked up to a PAL SCPH-102 Playstation 
//   to circumvent the copy protection. This is not tested on other Playstation models so the signal still
//   is available
// - The /xlat signal is no longer required to time the PAL SCPH-102 NTSC BIOS-patch
// - Only AVR PORTB is used for compatibility reasons (almost all the AVR chips available have PORTB)


User avatar
TriMesh
Verified
PSX Aptitude
PSX Aptitude
Posts: 225
Joined: Dec 20, 2013
PlayStation Model: DTL-H1202
Location: Hong Kong

Post by TriMesh » June 10th, 2017, 4:23 am

rama3 wrote: I can add this correctly but someone has got to test it. Or verify such a console even needs a modchip. I don't know if it does.
An unmodifed Yaroze can boot retail discs from any region and the Yaroze boot disc, but it can't boot copies, so you need a modchip for that.

It doesn't need to be anything out of the ordinary, though - since the Yaroze will boot discs from any region, you can use any region mod chip in them too. That "SCEW" region code seems to have been more intended to prevent the Yaroze boot CD from working on retail consoles, although it was a pretty ineffective measure since it works with no problems on both debug consoles and modified retails.

rama3
Verified
/// PSXDEV | ELITE ///
/// PSXDEV | ELITE ///
Posts: 510
Joined: Apr 16, 2017

Post by rama3 » June 10th, 2017, 5:46 am

Okay, that's good to know. I'll leave the W code out then. Less complexity and flash space used.

Element18592
What is PSXDEV?
What is PSXDEV?
Posts: 3
Joined: Jun 09, 2017

Post by Element18592 » June 10th, 2017, 7:38 am

rama3 wrote:
Element18592 wrote:Great work rama. Glad I stumbled across this being that assembler has been down for some time. Would you happen to have a diagram for PU18?
Here's one for PU-18. Vcc and Gnd are suggestions. You can use anything, as long as it's 3.5V and a good ground connection.
Image
Okay so I've tested the 3.5v and opted to go to the larger cap on the same rail and chose a GND rail i was already soldered to. Below is my install edited to show where each wire is going to on my NANO.

Its hard to tell by the image but GND and VCC are wired to the underside of the NANO
Image

I'm using the most recent code you provided today and a US region game and im getting a few different results when powering on the console as explained in the video below.

Edit: For some reason the video won't embed so here's a link.
https://www.youtube.com/watch?v=hZ4gEj7UdP8

rama3
Verified
/// PSXDEV | ELITE ///
/// PSXDEV | ELITE ///
Posts: 510
Joined: Apr 16, 2017

Post by rama3 » June 10th, 2017, 5:54 pm

Have you commented the PU22_MODE define?

Element18592
What is PSXDEV?
What is PSXDEV?
Posts: 3
Joined: Jun 09, 2017

Post by Element18592 » June 10th, 2017, 7:07 pm

rama3 wrote:Have you commented the PU22_MODE define?
Yes. I've tried two different NANOs. No clue what the issue is.

rama3
Verified
/// PSXDEV | ELITE ///
/// PSXDEV | ELITE ///
Posts: 510
Joined: Apr 16, 2017

Post by rama3 » June 10th, 2017, 7:43 pm

Check if the LED on the Nano blinks. It will blink when injecting, meaning it is decoding the SUBQ data correctly.
In the code, try to just inject the SCEA string.
Is this a 16Mhz Nano? I haven't verified that 16Mhz boards work on 3.5V. They're specified to run on 5V but I do hope 3.5V is enough. You will know it works with 3.5V if it blinks the LED for injections.

Edit:
But don't try to hook it up to 5V. The code is sending a signal using Vcc level. It would send 5V into a 3.5V device.

Edit2:
A couple Arduino Nano clones with 16Mhz / 5V arrived and I have tested one in a PU-18. Works nicely at 3.5V, even 3.3V :)

likeabaus
Extreme PSXDEV User
Extreme PSXDEV User
Posts: 133
Joined: Jul 27, 2016

Post by likeabaus » June 11th, 2017, 2:59 am

Matt wrote:Probably fixable.
While you're technically correct, where this was a PU-23 board, the component in question was too small for my expertise or patience and where I have other boards lying around, I decided to chuck it lol.

A quick update: The other "mystery board" ended up being a PU-18. The night, I was plugging away at this, was clearly not going my way. Not sure if I was just over tired or what (it was pretty late where I am at that time). I also broke a SMT resistor off the PU-18 board.This time the component was much larger, so I figured remounting it wouldn't be an issue (I also measured it to see if it was a low enough resistance, to try bypassing it by just bridging the connection, but that went out the window, as the resistance was very high and I wasn't about to fry anything lol). So I got my tweezers and proceeded to attempt to remount it to the board, I struggled with it for a while and during this process, the resistor somehow went flying and is nowhere to be found (great!) Two boards dead in one night for something that should be fairly simple (I've done plenty of psx modchip installs without issue. This leads me with one more console left (another mystery board, now model sticker). A friend gave it to me as he knows I like to refurb and mod old hardware, he just wanted to get rid of it. However, this one has serious issues (he told me upfront when he gave it to me and I confirmed it when I fired it on). Whenever trying to boot any original (this doesn't appear to be modded at all, but I haven't opened it up to double check, as cd-r's result in the "Please Insert A Playstation Disc" screen), I get a really weird graphical mess and the console completely hangs at what is supposed to be the black playstation logo screen. I suspect that the GPU needs a good reflow or reball job, but I won't know for sure until I open it up and take a look. When I get a chance, I will see if I can get this console running at all, if so, I'll try to install the already flashed Uno I have with Rama3's PSNee code.

P.S. if anyone has a 4 leaf clover or a lucky rabbits foot PM me for my address, seeing as the luck I'm having here, I might need it hahahaha jk

User avatar
TriMesh
Verified
PSX Aptitude
PSX Aptitude
Posts: 225
Joined: Dec 20, 2013
PlayStation Model: DTL-H1202
Location: Hong Kong

Post by TriMesh » June 11th, 2017, 3:30 am

Counter-intuitive as is may sound, that problem can be caused by a bad optical pickup. I suspect it was an oversight on Sony's part, but the license data sectors on the CD are written without ECC/EDC, and are only protected by the standard CD Audio C1/C2 error correction. If the error rate is bad enough to overcome that then the license data is corrupted, and since that PSX logo and the "Licensed by" text are stored in the license sectors it's all messed up.

If the white screen is good, but the black boot screen is messed up (bad logo, corrupted text - but the SCEI/SCEA/SCEE bit is right) then this is the first thing to check.

likeabaus
Extreme PSXDEV User
Extreme PSXDEV User
Posts: 133
Joined: Jul 27, 2016

Post by likeabaus » June 11th, 2017, 6:14 am

Thanks! Now that i have an over abundance of spare laser assemblies to work with, i will try that first. I honestly cant remember, if the initial white screen comes up ok, but ill check that.

What you're saying actually makes sense, as i remember "back in the day" one could edit the black screen using some free tools (maybe gridlock did that, as well as region patching?, its been so long, but i digress....) and make it say whatever you want. So if the laser isnt reading those sectors correctly, that could certainly explain those symptoms. Thanks for the tip! I'll let you know how it goes....

User avatar
Shadow
Verified
Admin / PSXDEV
Admin / PSXDEV
Posts: 2670
Joined: Dec 31, 2012
PlayStation Model: H2000/5502
Discord: Shadow^PSXDEV

Post by Shadow » June 11th, 2017, 9:35 am

Development Console: SCPH-5502 with 8MB RAM, MM3 Modchip, PAL 60 Colour Modification (for NTSC), PSIO Switch Board, DB-9 breakout headers for both RGB and Serial output and an Xplorer with CAETLA 0.34.

PlayStation Development PC: Windows 98 SE, Pentium 3 at 400MHz, 128MB SDRAM, DTL-H2000, DTL-H2010, DTL-H201A, DTL-S2020 (with 4GB SCSI-2 HDD), 21" Sony G420, CD-R burner, 3.25" and 5.25" Floppy Diskette Drives, ZIP 100 Diskette Drive and an IBM Model M keyboard.

Post Reply

Who is online

Users browsing this forum: No registered users and 3 guests