Advertisement
Guest User

PsNee

a guest
Mar 19th, 2017
7,094
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 14.18 KB | None | 0 0
  1. //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  2. //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  3. //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  4. //||||||MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM|||||
  5. //||||||M*************************************************************M|||||
  6. //||||||M*************************************************************M|||||
  7. //||||||M***QQQQQQQQQ***************Q******Q**************************M|||||
  8. //||||||M***Q********Q**************QQ*****Q**************************M|||||
  9. //||||||M***Q********Q**************QQ*****Q**************************M|||||
  10. //||||||M***Q********Q**************Q*Q****Q**************************M|||||
  11. //||||||M***Q********Q**************Q*Q****Q**************************M|||||
  12. //||||||M***Q********Q**************Q*Q****Q**************************M|||||
  13. //||||||M***Q********Q**************Q**Q***Q**************************M|||||
  14. //||||||M***QQQQQQQQQ***************Q**Q***Q**************************M|||||
  15. //||||||M***Q***********QQQQQQQQ****Q***Q**Q******QQQQ*******QQQQ*****M|||||
  16. //||||||M***Q**********QQ******Q****Q***Q**Q*****QQ**Q******QQ**Q*****M|||||
  17. //||||||M***Q**********Q************Q***Q**Q****QQ***Q*****Q***QQ*****M|||||
  18. //||||||M***Q**********QQQ**********Q****Q*Q***QQ**QQQ****QQQQQQ******M|||||
  19. //||||||M***Q************QQQQQ******Q****Q*Q***QQQQQ******QQ**********M|||||
  20. //||||||M***Q****************QQQ****Q*****QQ**QQ**********Q***********M|||||
  21. //||||||M***Q******************Q****Q*****QQ**Q**********QQ***********M|||||
  22. //||||||M***Q**********Q*******QQ***Q*****QQ**Q******QQ**Q******QQ****M|||||
  23. //||||||M***Q**********QQ******QQ***Q******Q**QQ****QQ***QQ****QQ*****M|||||
  24. //||||||M***Q***********QQQQQQQQ****Q******Q***QQQQQ******QQQQQQ******M|||||
  25. //||||||M*************************************************************M|||||
  26. //||||||M*************************************************************M|||||
  27. //||||||MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM|||||
  28. //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  29. //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  30. //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  31. //
  32. //PsNee, an open source stealth modchip for the Sony Playstation 1, usable on
  33. //all platforms supported by Arduino, preferably ATTiny. Finally something modern!
  34. //
  35. /////////// TO DO: /////////////
  36. // - Find out how the NTSC BIOS patch for SCPH-102 works and integrate it in this sketch
  37. //   (supposedly it forces pin 15 (data 2) on the BIOS chip (IC102) low when something happens on pin 31 (address 18) according to http://problemkaputt.de/psx-spx.htm#cdromprotectionmodchips)
  38. // - Make SCEx-arrays smaller by commoning up the common parts of the arrays and thus use less flash
  39. // - Common up the two big for-loops with an OR-statement
  40. ////////////////////////////////
  41. //
  42. //PLAYSTATION 1 SECURITY - HOW IT DOES IT'S THING:
  43. //Sony didn't really go through great lenghts to protect it's precious Playstation
  44. //from running unauthorised software; the main security is based on a simple ASCII
  45. //string of text that is read from a part of an original Playstation disc that cannot
  46. //be reproduced by an ordinary PC CD burner.
  47. //As most of you will know, a CD is basically a very long rolled up (carrier) string in which very
  48. //little pits and ehm... little not-pits are embedded that represent the data stored on the disc.
  49. //The nifty Sony engineers did not use the pits and stuff to store the security checks for
  50. //Playstation discs but went crazy with the rolled up carrier string. In an ordinary CD, the
  51. //string is rolled up so that the spacing between the tracks is as equal as possible. If that
  52. //namely is not the case, the laser itself needs to move a bit to keep track of the track and
  53. //reliably read the data off the disc.
  54. //If you wonder how the laser knows when it follows the track optimally: four photodiodes, light
  55. //intensity measurement, difference measurements, servo. There.
  56. //To the point: the Sony engineers decidedly "fumbled up" the track of sector 4 on a Playstation
  57. //disc (the track was modulated in nerd-speak) so that the error correction circuit outputs a
  58. //recognisable signal, as the laser needs to be corrected to follow the track optimally.
  59. //This outputted signal actually is a 250bps serial bitstream (with 1 startbit and 2 stopbits) which
  60. //in plain ASCII says SCEA (Sony Computer Entertainment of America), SCEE (Sony Computer Entertainment
  61. //of Europe) or SCEI (Sony Computer Entertainment of Japan), depending on the region of the disc inserted.
  62. //The security thus functions not only as copy protection, but also as region protection.
  63. //The text string from the disc is compared with the text string that is embedded in the Playstation
  64. //hardware. When these text strings are the same, the disc is interpreted to be authentic and from
  65. //the correct region. Bingo!
  66. //
  67. //HOW THE MODCHIP TRICKS THE PLAYSTATION:
  68. //The modchip isn't all that of a complicated device: clever reverse engineers found the point on the
  69. //Playstation motherboard that carried the text string from the disc and found a way to temporarily block
  70. //this signal (by grounding an input of an op-amp buffer) to be able to inject the signal from the modchip
  71. //The modchip injects after about 1500ms the text strings SCEE SCEA SCEI on the motherboard point and stops
  72. //with this after about 25 seconds. Because all the possible valid region options are outputted on the
  73. //motherboard the Playstation gets a bit confused and simply accepts the inserted disc as authentic; after all,
  74. //one of the codes was the same as that of the Playstation hardware...
  75. //Early modchips applied the text strings as long as there was applied power to them, whereby later Playstation
  76. //software could detect whether a modchip was installed. This is circumvented in this application by idling the
  77. //modchip after about 25 seconds. The text strings are only tranmitted again when the CD lid is opened and closed
  78. //again, to enable playing multi-disc games. This is also called a stealth modchip in marketing-speak.
  79. //
  80. //This code is verified on an ATTiny45 with the 8MHz internal oscillator using a Saleae Logic Analyser, timing is
  81. //reasonable important in this application.
  82. //Kindly coded and documented by TheFrietMan, August 20 2015, The Netherlands.
  83. //The Playstation is great but nothing beats our national pride, the Philips CDi! Cheesiness for the win!
  84. //
  85. //PINOUT IC:
  86. //  ATTiny45:
  87. //    Pin 1: Not connected
  88. //    Pin 2: Not connected
  89. //    Pin 3: Not connected
  90. //    Pin 4: Ground
  91. //    Pin 5: OUT - Data
  92. //    Pin 6: OUT - Gate
  93. //    Pin 7: IN - CD lid
  94. //    Pin 8: Vcc
  95. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  96.  
  97. #include <Flash.h>     //Include the Flash library to conveniently store the SCExData-arrays in PROGMEM, see http://arduiniana.org/libraries/flash/
  98.  
  99. //BLOODY GLOBAL VARIABLES
  100. //Pins for the Arduino Uno
  101. int data = 8;        //The pin that outputs the SCEE SCEA SCEI string
  102. int gate = 9;        //The pin that gets pulled low to enable data injection on the Playstation motherboard
  103. int lid = 10;         //The pin that gets connected to the internal CD lid signal; active high
  104.  
  105. //Pins for the ATTiny45 Arduino
  106. //int data = 0;
  107. //int gate = 1;
  108. //int lid = 2;
  109. boolean flagFirstCycle = 0;    //This flag is 1 when the system completes the first cycle of SCEx-string outputting; this is done to stealth the chip up
  110.  
  111. void setup()
  112. {
  113.   pinMode(data, INPUT);    //The pins are high-impedance when configured as inputs so they don't interfere with the Playstation mortherboard circuitry
  114.   pinMode(gate, INPUT);    
  115.   pinMode(lid, INPUT);
  116.    
  117.   delay(1200);            //Wait a second before we're really heading off  
  118. }
  119.  
  120. void loop()
  121. {                                                                                                                                //The bitstreams are reversed (because LSB) and inverted (because the buffer we're injecting our signal after also inverted it's input)
  122.   //VARIABLES                                                                                                                    //      Start            Data     Stop
  123.   FLASH_ARRAY (boolean, SCEEData, 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: 1 00110101 00, 1 00111101 00, 1 01011101 00, 1 01011101 00   44 bits total
  124.   FLASH_ARRAY (boolean, SCEAData, 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: 1 00110101 00, 1 00111101 00, 1 01011101 00, 1 01111101 00
  125.   FLASH_ARRAY (boolean, SCEIData, 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: 1 00110101 00, 1 00111101 00, 1 01011101 00, 1 01101101 00
  126.   int arraycounter;
  127.   int datacounter;
  128.   boolean lidstatus = digitalRead(lid);
  129.  
  130.   if (flagFirstCycle == 0)
  131.   {
  132.     pinMode(gate, OUTPUT);
  133.     digitalWrite(gate, 0);          //Pull to ground to enable data injecting
  134.    
  135.     for (datacounter = 0; datacounter < 31; datacounter = datacounter + 1)        //One cycle of SCEx-string outputting takes approximately 744 ms; we want to go on for about 25 seconds so we output the cycle 30 times
  136.     {
  137.       for (arraycounter = 0; arraycounter < 44; arraycounter = arraycounter + 1)
  138.       {
  139.         if (SCEEData[arraycounter] == 0)
  140.         {
  141.           pinMode(data, OUTPUT);                //We pull the data pin to ground to force a 0
  142.           digitalWrite(data, 0);
  143.           delay(4);                             //Send the signal for 4 ms
  144.         }
  145.         else
  146.         {
  147.           pinMode(data, INPUT);                //We make the data pin high-impedance to let the pull-up of the Playstation motherboard make a 1
  148.           delay(4);
  149.         }
  150.       }
  151.       delay(64);        //According to the logic analyser the time between two bitstreams now approximates 72 ms on an ATTiny45 with built-in 8MHz oscillator, just like the doctor ordered
  152.      
  153.       for (arraycounter = 0; arraycounter < 44; arraycounter = arraycounter + 1)
  154.       {
  155.         if (SCEAData[arraycounter] == 0)
  156.         {
  157.           pinMode(data, OUTPUT);                //We pull the data pin to ground to force a 0
  158.           digitalWrite(data, 0);
  159.           delay(4);
  160.         }
  161.         else
  162.         {
  163.           pinMode(data, INPUT);                //We make the data pin high-impedance to let the pull-up of the Playstation motherboard make a 1
  164.           delay(4);
  165.         }
  166.       }
  167.       delay(64);
  168.      
  169.       for (arraycounter = 0; arraycounter < 44; arraycounter = arraycounter + 1)
  170.       {
  171.         if (SCEIData[arraycounter] == 0)
  172.         {
  173.           pinMode(data, OUTPUT);                //We pull the data pin to ground to force a 0
  174.           digitalWrite(data, 0);
  175.           delay(4);
  176.         }
  177.         else
  178.         {
  179.           pinMode(data, INPUT);                //We make the data pin high-impedance to let the pull-up of the Playstation motherboard make a 1
  180.           delay(4);
  181.         }
  182.       }
  183.       delay(64);
  184.     }
  185.     pinMode(data, INPUT);    //Make all outputting pins high-impedance again when we're finished
  186.     pinMode(gate, INPUT);
  187.     flagFirstCycle = 1;      //We completed the initial round of SCEx-outputting; only do this again when a new CD is inserted while the Playstation is turned on!
  188.   }
  189.  
  190.   //Only force authentication when this isn't the first cycle and the lid has been opened and closed again
  191.   if ((flagFirstCycle != 0) && (lidstatus != 0))
  192.   {
  193.     delay(50);                      //Extra delay to compensate for the state-switching of the CD lid
  194.     if (lidstatus == 0)            //Only do your thing when the lid is closed again
  195.     {
  196.       delay(100);                     //Just wait a second until the coast is clear
  197.       pinMode(gate, OUTPUT);
  198.       digitalWrite(gate, 0);          //Pull to ground to enable data injecting
  199.    
  200.       for (datacounter = 0; datacounter < 31; datacounter = datacounter + 1)        //One cycle of SCEx-string outputting takes approximately 744 ms; we want to go on for about 25 seconds so we output the cycle 30 times
  201.       {
  202.         for (arraycounter = 0; arraycounter < 44; arraycounter = arraycounter + 1)
  203.         {
  204.           if (SCEEData[arraycounter] == 0)
  205.           {
  206.             pinMode(data, OUTPUT);                //We pull the data pin to ground to force a 0d
  207.             digitalWrite(data, 0);
  208.             delay(4);
  209.           }
  210.           else
  211.           {
  212.             pinMode(data, INPUT);                //We make the data pin high-impedance to let the pull-up of the Playstation motherboard make a 1
  213.             delay(4);
  214.           }
  215.         }
  216.         delay(64);        //Volgens de logic analyser is de tijd tussen de twee bitstreams nu precies 72 ms op een ATTiny45 met ingebouwde 8MHz oscillator, zoals het zou moeten zijn
  217.        
  218.         for (arraycounter = 0; arraycounter < 44; arraycounter = arraycounter + 1)
  219.         {
  220.           if (SCEAData[arraycounter] == 0)
  221.           {
  222.             pinMode(data, OUTPUT);                //We pull the data pin to ground to force a 0
  223.             digitalWrite(data, 0);
  224.             delay(4);
  225.           }
  226.           else
  227.           {
  228.             pinMode(data, INPUT);                //We make the data pin high-impedance to let the pull-up of the Playstation motherboard make a 1
  229.             delay(4);
  230.           }
  231.         }
  232.         delay(64);
  233.        
  234.         for (arraycounter = 0; arraycounter < 44; arraycounter = arraycounter + 1)
  235.         {
  236.           if (SCEIData[arraycounter] == 0)
  237.           {
  238.             pinMode(data, OUTPUT);                //We pull the data pin to ground to force a 0
  239.             digitalWrite(data, 0);
  240.             delay(4);
  241.           }
  242.           else
  243.           {
  244.             pinMode(data, INPUT);                //We make the data pin high-impedance to let the pull-up of the Playstation motherboard make a 1
  245.             delay(4);
  246.           }
  247.         }
  248.         delay(64);
  249.       }
  250.     pinMode(data, INPUT);    //Make all outputting pins high-impedance again when we're finished
  251.     pinMode(gate, INPUT);
  252.     }
  253.   }
  254. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement