PSNee further development

General information to do with the PlayStation 1 Hardware. Including modchips, pinouts, rare or obscure development equipment, etc.
rama3
Verified
/// PSXDEV | ELITE ///
/// PSXDEV | ELITE ///
Posts: 510
Joined: Apr 16, 2017

Post by rama3 » January 14th, 2020, 3:18 am

Dark-Show:
No, I doubt this particular problem is a carry over.
The code simply has to open-drain the data pin to fix the problem. This is obvious to a modchip developer, so I think it was just an oversight.

From what I remember, the laser fix is required because the Mechacon in these PS2s tends to crash.
It's not known what causes it to crash, but we know that later versions are stable again.

bugmenot:
This isn't a modchip problem. Your TV simply doesn't work with PAL timings.
A PAL game will set the console's output to 50Hz, which many NTSC region TV don't recognize.

bugmenot
Interested PSXDEV User
Interested PSXDEV User
Posts: 6
Joined: Oct 17, 2019

Post by bugmenot » January 18th, 2020, 6:43 am

rama3 wrote: January 14th, 2020, 3:18 am bugmenot:
This isn't a modchip problem. Your TV simply doesn't work with PAL timings.
A PAL game will set the console's output to 50Hz, which many NTSC region TV don't recognize.
i'm playing on a PAL PSone and a PAL tv (not CRT). I also changed the scart svideo cable to a scart RGB cable. The picture is so much sharper. But the vertical offset remains there...

PS: the forum still uses http instead of https on an IIS 8 instead of IIS 10 (windows 2012). Just pointing this out as an IT guy ;-)

chriz2600
What is PSXDEV?
What is PSXDEV?
Posts: 1
Joined: Feb 12, 2020

Post by chriz2600 » February 12th, 2020, 8:47 pm

rama3 wrote: December 28th, 2019, 12:36 am As said in pm, the original license is a free for all. Feel free to use it and good luck! :)
Just wanted to share the ESP32 port of PsNee as used on PS1HDMI.

https://github.com/chriz2600/PsNee-ESP32

The repository contains a demo project based on esp-idf v3.3.1.

Thanks again!

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

Post by rama3 » February 14th, 2020, 4:20 am

Awesome, thanks for sharing back! :)

I'd just like to mention that, since you have the ESP32, you should be far less pin constrained.
With more available inputs, you can use some other signals to simplify things.
There is a signal called XSLOW or similar, for example, which is just the drive speed (either x1 or x2).
Using that, you may be able to remove all the hysteresis stuff, as unlock symbols must only appear at x1 speed ;)

zoinknoise
Interested PSXDEV User
Interested PSXDEV User
Posts: 5
Joined: Feb 01, 2020

Post by zoinknoise » February 29th, 2020, 7:59 am

rama3 wrote: April 15th, 2019, 5:52 am Nextria:
Search this forum or Google for PSX color oscillator mod. This is what your board needs.
But it is a difficult mod and the result looks pretty bad. I recommend you use a later revision PSX.
hi rama3, remember me from 2 years ago on github? i found those 3 non-working Konami games and you patched the code so quickly :praise

anyway i just want to point out there is one single PS1 model that can be TRUE dual region, 100% correct PAL and NTSC, and that is the PU-8(2) board. this is actually the Net Yaroze board, but you can find it easily and cheaply inside SCPH-1001 consoles. as a bonus, you get the NTSC-U BIOS so it will boot anything easily.

if you get the board from a 1001, all you have to do is add this 53.2mhz oscillator:

https://www.mouser.com/ProductDetail/Re ... ntAw%3D%3D

and you have to add a resistor and a ferrite.

i used a lot of information from this thread and adapted it for my purposes:

http://www.psxdev.net/forum/viewtopic.php?t=628

you also have to remove the capacitor from the bottom of the board which shorts the PAL oscillator input to ground once you do this mod. so that's 3 components added, 1 removed.

Image

at the end, basically you will have two oscillators in there just like the Yaroze, no hacking or rewiring. you are just adding some missing parts. i have added TRUE PAL to both of my PU-8(2) boards with this mod and it works perfectly, much more satisfying than spending $$$ on a Yaroze.

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

Post by rama3 » February 29th, 2020, 3:36 pm

Yea, these are the nicest consoles for multi region.
It's rare for NTSC people to look for one, but here in PAL land, they're occasionally asked for :)

I think I made a couple of these.
As you say, you need a PU-8 board for the easiest install (though it works on every PSX if you bodge it!).
Applicable boards are (from memory) PU-8-21, PU-8-22 and PU-8-23.
In PAL regions, these are in most "SCPH-1002" consoles sold.

Oh, and one thing:
If you followed a guide, please check whether the resistor and ferrite bead are not swapped by accident.
The configuration should be the same as with the originally installed oscillator.
One guide I saw has them swapped.

zoinknoise
Interested PSXDEV User
Interested PSXDEV User
Posts: 5
Joined: Feb 01, 2020

Post by zoinknoise » March 9th, 2020, 2:21 am

rama3 wrote: February 29th, 2020, 3:36 pm If you followed a guide, please check whether the resistor and ferrite bead are not swapped by accident.
The configuration should be the same as with the originally installed oscillator.
One guide I saw has them swapped.
hehe yes, that did trip me up for a minute. but i think by the time i took that photo, i had them installed correctly.

wyatt8740
What is PSXDEV?
What is PSXDEV?
Posts: 3
Joined: May 16, 2020
I am a: Programmer, wannabe EE
Motto: Who taught him to solder?
PlayStation Model: 1001,5501
Location: Indiana, United States
Contact:

Post by wyatt8740 » May 21st, 2020, 6:45 am

Mine's a PU-8(1) board (meaning it has the dual-ported VRAM and old GPU), so I'm out of luck with the easy dual-oscillator mod I guess. Also the case is incredibly brittle and all the screw posts are gone so it's held together with hot glue so I try to avoid re-opening it (requires prying on brittle plastic).

Anyway, more on-topic: would it be helpful for me to write a little guide on flashing ATTinys using avrdude? It's probably something most people here have figured out, but setting the fuses is kind of tricky if you aren't used to it, and I've found it easier to use avrdude than try to make the IDE work with them on ATTiny's, personally. I'd be happy to write a little guide if there's a chance it'd get put in the git or on the project wiki or something.

Also, I have an ATTiny85 working in my SCPH-9001 (PU-23) board. So does that count as a 'tested' verification? The source code lists it as 'untested'.

I've also made it work with an ATMega32U4 Pro Micro (for my early PU-8 1001) by remapping some pins; shouldn't it be possible to support the 32U4 officially by just using another preprocessor define?

Also, I've noticed PsNee.ino has a singular "carriage return" byte on the last line of the file. The file is otherwise using Unix line endings. Shouldn't that be fixed?

As an aside, interestingly, on my PU-18 (5501), I did not have to erase the bootloader on my Uno in order to make it work. I've even played "Year of the Dragon" on it. It might take at most a second longer to start games than the -9001 using an ATTiny85 which has no bootloader, though.

Also note that I think the README.md is wrong; I had to connect 3.5V to my Uno's """5V""" line to power it, since VIN actually passes through the on-board regulator (which is being under-driven). The """5V""" line, meanwhile, is just directly connected to the ATMega328's Vcc pin.

I made a pull request for most of these issues just now (I did not change the ATTiny85's "untested" designation in the PR though).
SCPH-1001 (early PU-8 with old GPU/dual-ported VRAM) (the "please let me die" unit) (November 1995)
SCPH-5501 (PU-18) (Ol' Reliable, featuring the mega-modchip but otherwise in original condition) (October 1997)
SCPH-9001 (PU-23) (Assembled from my whatever I had lying around; featuring the parallel port to nowhere) (Jan. 2000)
Believe it or not, they're all working fine now.

nicr4wks
What is PSXDEV?
What is PSXDEV?
Posts: 2
Joined: May 22, 2020

Post by nicr4wks » May 22nd, 2020, 10:21 am

Hi guys, is anyone aware of problems with replacement (china) CD drives and psnee?

I've flashed an Arduino NANO ATMega128p via spi, wired up to a PU-20 scph-7002 PAL console and the arduino light is flashing away like it's injecting but the disc sounds like it's continuously seeking and after ~15 seconds the PS ends up at "Please insert original playstation cd-rom" using original and backup discs.

If i disconnect power to the arduino so it's disabled original discs boot perfectly fine, i'm out of troubleshooting ideas.

I used these resources to workout the pinout and have checked solder points with a microscope to ensure no bad joints, bridges etc.

https://quade.co/ps1-modchip-guide/psnee/pu-20/
https://www.youtube.com/watch?v=mhMCT63-h08
and the psnee readme.

Thanks.

nicr4wks
What is PSXDEV?
What is PSXDEV?
Posts: 2
Joined: May 22, 2020

Post by nicr4wks » May 22nd, 2020, 8:56 pm

Just commented out other strings so it only injects my region SCEE (PAL).
► Show Spoiler
Original game: boots to music CD screen.
Backup game: 'please insert playstation cd-rom' screen.
Music CD: works OK.

wyatt8740
What is PSXDEV?
What is PSXDEV?
Posts: 3
Joined: May 16, 2020
I am a: Programmer, wannabe EE
Motto: Who taught him to solder?
PlayStation Model: 1001,5501
Location: Indiana, United States
Contact:

Post by wyatt8740 » June 5th, 2020, 3:57 am

nicr4wks wrote: May 22nd, 2020, 10:21 am Hi guys, is anyone aware of problems with replacement (china) CD drives and psnee?
I've used it fine with PSnee on a launch PSX that had a chinese clone drive for a while. Then I got a -9001 with a stripped gear that I replaced and I moved its drive into it.
nicr4wks wrote: May 22nd, 2020, 10:21 am I've flashed an Arduino NANO ATMega128p via spi, wired up to a PU-20 scph-7002 PAL console and the arduino light is flashing away like it's injecting but the disc sounds like it's continuously seeking and after ~15 seconds the PS ends up at "Please insert original playstation cd-rom" using original and backup discs.
What kind of media did you burn? If you burned CD-RW there's a fair chance it would have trouble reading it. You probably already knew this of course, but CD-R's preferred and you didn't specify so just making sure.
nicr4wks wrote: May 22nd, 2020, 10:21 amIf i disconnect power to the arduino so it's disabled original discs boot perfectly fine, i'm out of troubleshooting ideas.
I remember having that issue with one of my installs, just resoldering everything fixed it for me, IIRC. Don't forget to use flux, it really helps to make good connections. At worst, remove everything and try wiring it again if you're having trouble keeping track of the connections.
nicr4wks wrote: May 22nd, 2020, 10:21 amI used these resources to workout the pinout and have checked solder points with a microscope to ensure no bad joints, bridges etc.
Just try to reflow (with rosin flux); I've missed points even under a microscope before.
Also, make sure it's not shorting to the shield or anything.
nicr4wks wrote: May 22nd, 2020, 8:56 pm Just commented out other strings so it only injects my region SCEE (PAL).

Code: Select all

    for (byte 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'); // optimize boot time by sending only your console region letter (all 3 times per loop)
    }
Original game: boots to music CD screen.
Backup game: 'please insert playstation cd-rom' screen.
Music CD: works OK.
You're doing it wrong.
You need to send the 'e' code three times or it throws off the timing (iirc that's the problem anyway). Do this instead:

Code: Select all

    for (byte loop_counter = 0; loop_counter < 2; loop_counter++)
    {
      inject_SCEX('e'); // e = SCEE, a = SCEA, i = SCEI
      inject_SCEX('e'); // injects all 3 regions by default
      inject_SCEX('e'); // optimize boot time by sending only your console region letter (all 3 times per loop)
    }
I did this (but with the 'a' code) on all three of my PSNee installs.
The results you gave lead me to believe your installation is likely wired correctly, but I'm not quite familiar enough to be able to guarantee it. It just matches behavior I've seen before.
SCPH-1001 (early PU-8 with old GPU/dual-ported VRAM) (the "please let me die" unit) (November 1995)
SCPH-5501 (PU-18) (Ol' Reliable, featuring the mega-modchip but otherwise in original condition) (October 1997)
SCPH-9001 (PU-23) (Assembled from my whatever I had lying around; featuring the parallel port to nowhere) (Jan. 2000)
Believe it or not, they're all working fine now.

Raz0r029
What is PSXDEV?
What is PSXDEV?
Posts: 1
Joined: Jul 16, 2020

Post by Raz0r029 » July 17th, 2020, 11:03 pm

I have an SCPH-1001 model with PU-8 board later revision (-22). I have successfully installed PSNee in my ps1 and it reads any originals and backups in different regions but my original japanese dance dance revolution disc won't read it as a game but goes to the cd player instead. I even tried playing the audio tracks in the cd player and every tracks plays fine so I know the disc and my laser is fine.

I also knew that ddr has one of the anti mod protection that will show up a red slashed circle with japanese texts and it stays like that forever. Since PSNee is an open source stealth modchip, any anti mod ps1 games will get past the error and will read the game fine. I even tried my japanese Silent Hill disc which also has the anti mod protection and it reads it fine and it doesn't show up the error so I knew that the stealth feature is working.

I also discovered that doing the swap trick method even with the modchip installed works with my dance dance revolution disc and it even get past the error and plays fine also so I'm really confused and wondering why loading my ddr disc normally doesn't read it as a game but goes to the cd player instead thinking it's an audio cd but doing the swap trick method seems to load it fine without the error also? Does it have something to do with the code of PSNee or maybe just my installation? But every game I load except ddr works fine so I really don't know at this point. :( Hoping someone can help me with this. Thanks in advance! :D

leafy
Active PSXDEV User
Active PSXDEV User
Posts: 53
Joined: Aug 29, 2020

Post by leafy » October 11th, 2020, 9:55 am

Raz0r029 wrote: July 17th, 2020, 11:03 pm I have an SCPH-1001 model with PU-8 board later revision (-22). I have successfully installed PSNee in my ps1 and it reads any originals and backups in different regions but my original japanese dance dance revolution disc won't read it as a game but goes to the cd player instead.

Does it have something to do with the code of PSNee or maybe just my installation? But every game I load except ddr works fine so I really don't know at this point. :( Hoping someone can help me with this. Thanks in advance! :D
Yeah, it might be how the PSNee handles detection of game disks.

Read here: https://github.com/kalymos/PsNee

PsNee captures and buffers CD subchannel Q data, and then based on this data, decides if it is an audio CD or a game disk.

How did you install? Compile it with /debug on and monitor with a USB to UART adapter 3.3V, use a terminal emulator program (Putty in Windows) and save the session as a log file. Also just watch it. The PsNee should report information over the serial line, see the PsNee source code for the details, and read this entire thread for more information on debug and how PsNee works. There is also some playing around with the hysteresis values that you can try. Again read back a few pages in this thread for hints to try.

Code: Select all

// hysteresis value "optimized" using very worn but working drive on ATmega328 @ 16Mhz
  // should be fine on other MCUs and speeds, as the PSX dictates SUBQ rate
  if (hysteresis >= 14) {
    // If the read head is still here after injection, resending should be quick.
    // Hysteresis naturally goes to 0 otherwise (the read head moved).
    hysteresis = 11;
The detection of CD-DA (music CD) is done here, I think? Maybe try to remove this if/else:

Code: Select all

 else if ( hysteresis > 0 &&
            ((scbuf[0] == 0x01 || isDataSector) && (scbuf[1] == 0x00 /*|| scbuf[1] == 0x01*/) &&  scbuf[6] == 0x00)
        ) {  // This CD has the wobble into CD-DA space. (started at 0x41, then went into 0x01)
    hysteresis++;
  }
But basically you should see lines that start with 41 for game disk, then after a bit of those lines, you should see the report of injection. The exact message differs from the Arduino branch to the ATtinyx5 branch.

Which microcontroller did you use?

zoinknoise
Interested PSXDEV User
Interested PSXDEV User
Posts: 5
Joined: Feb 01, 2020

Post by zoinknoise » October 17th, 2020, 5:59 am

leafy wrote: October 11th, 2020, 9:55 am
Raz0r029 wrote: July 17th, 2020, 11:03 pm I have successfully installed PSNee in my ps1 and it reads any originals and backups in different regions but my original japanese dance dance revolution disc won't read it as a game but goes to the cd player instead.
Yeah, it might be how the PSNee handles detection of game disks.
actually, i am almost sure this is the exact bug i found over 2 years ago in PsNee. early Konami PS1 games are not mastered correctly; i found three games that would not boot out of dozens of games i tried from all regions and publishers. (Tokimeki Memorial: Forever with You, Henry Explorers, and Sexy Parodius) i'm not equipped right now to check for myself, but i bet that DDR disc is another Konami title with the same issue.

i helped to fix the bug when i spent hours wiring up a full-size Arduino to my PS1 motherboard to capture PsNee's debug logs for rama3, and sure enough, those early Konami games do not have the subcode flags set correctly. PsNee at that time was very strict about that. i submitted the logs, and rama3 quickly made a patch:

https://github.com/kalymos/PsNee/issues/11

he branched it off into a new GitHub, and left the old one up, i am not sure why. so i think that is the confusion, maybe you are using the old, stricter version of the code. make sure you use THIS version below, it's been patched for those screwball Konami games!! 8-)

this should work! https://github.com/ramapcsx2/PsNee/commits/master

leafy
Active PSXDEV User
Active PSXDEV User
Posts: 53
Joined: Aug 29, 2020

Post by leafy » October 17th, 2020, 1:45 pm

Ah interesting. I read this entire thread, and rama3 did say at one point that he decided not to unlock disks with many audio tracks. The PsNee algorithm detects CD-DA disks, but also falsely unlocks the many audio track disks, yes? The PsNee method decided to do this to not unlock audio disks, but it has the side effect that if a TOC has a lot of audio tracks it goes to the cd player menu.

However, in this case it might be that Konami bug.

I set up a SCPH-9001 with 2 sockets and I can now test PsNee vs. MM3. So, I'm looking to try whatever titles in this head to head face off!

I can also pop the old 4-wire in there, but so far I have not experienced any anti-modchip screens. I kind of want to see it in action for fun.

Maybe also, I will test the DDR Japan with the 2 mod chips. What else should I test? I only have about 20 Taiyo Yuden CD-R left though (from 10 years ago). They work very well, but need labels to preserve the upper layer from scratches...

zoinknoise
Interested PSXDEV User
Interested PSXDEV User
Posts: 5
Joined: Feb 01, 2020

Post by zoinknoise » October 17th, 2020, 3:48 pm

leafy wrote: October 17th, 2020, 1:45 pm The PsNee algorithm detects CD-DA disks, but also falsely unlocks the many audio track disks, yes? The PsNee method decided to do this to not unlock audio disks, but it has the side effect that if a TOC has a lot of audio tracks it goes to the cd player menu.
i personally never experienced that, either before or after the Konami patch, on my PU-8(2) using CMC Pro discs burned from Redump. and i spent a lot of time torturing PsNee with lots of obscure games to see how good it really was. for example, i think i tried True Pinball, a game with 50 redbook audio tracks, and i don't remember an issue with that one. nothing actually gave me problems except those three Konami games, and Crash Bash (the antimod kept going off, but at least i could patch it easily myself. for the Konami games, i have no clue how to edit CD subcode data :lol: ).
leafy wrote: October 17th, 2020, 1:45 pmI only have about 20 Taiyo Yuden CD-R left though (from 10 years ago). They work very well, but need labels to preserve the upper layer from scratches...
don't label them! just handle them carefully and you'll be fine. putting a label on a CD-R usually throws it off-balance and makes it harder to read even in a PC optical drive, never mind a persnickety PS1 drive.

leafy
Active PSXDEV User
Active PSXDEV User
Posts: 53
Joined: Aug 29, 2020

Post by leafy » October 20th, 2020, 9:48 am

OK, nice. I won't label them. I just had these lose their top layer before.

Oh, I have Crash Bash original disk. Except I don't have a Plextor for dumping. I will try the original though.

Here is what I wired up. I don't actually run 2 chips at once because CMOS chips are power parasitic, and these share a common ground. I should have put that on a switch, but I only have the switch on the +3.4 volts line. One slot takes a ATtiny45 for PsNee, the other a PIC12F508 for MM3. The 2 pin is for serial monitor of PsNee.
20201010_112408z.jpg
You do not have the required permissions to view the files attached to this post.

Neophyte
What is PSXDEV?
What is PSXDEV?
Posts: 1
Joined: Nov 06, 2020

Post by Neophyte » November 6th, 2020, 4:18 am

Hi.

I´m trying to get PSnee up and running on a PAL PSOne SCPH-102 with PM-41 (2) Board.

I wired it up like this:

Image

This is the Code I´m using:

Code: Select all

// PsNee / psxdev.net version
// For Arduino and ATtiny
//
// Quick start: Select your hardware via the #defines, compile + upload the code, install in PSX.
// There are some pictures in the development thread ( http://www.psxdev.net/forum/viewtopic.php?f=47&t=1262&start=120 )
// Beware to use the PSX 3.5V / 3.3V power, *NOT* 5V! The installation pictures include an example.
//
// Arduinos:
//  Use #define ARDUINO_328_BOARD for the following:
//  - Arduino Pro Mini @8Mhz and @16Mhz (supported, tested)
//  - Arduino Uno @8Mhz and @16Mhz (supported, tested)
//  Use #define ARDUINO_32UX_BOARD for the following:
//  - Pro Micro (supported, tested)
//  - Arduino Leonardo (supported, untested)

// ATtiny:
//  - ATtiny85: Should work the same as ATtiny45 (supported, untested)
//  - ATtiny45: LFUSE 0xE2  HFUSE 0xDF > internal oscillator, full 8Mhz speed (supported, tested)
//  - ATtiny25: Should work the same as ATtiny45 but doesn't have enough Flash nor RAM for PSNEEDEBUG (supported, untested)
//  - Use #define ATTINY_X5
//
// To use ATtiny with the Arduino environment, an ATtiny core has to be installed.
//
// PAL PM-41 consoles are supported with #define APPLY_PSONE_PAL_BIOS_PATCH,
// but only on boards with ATmega chips (Arduinos).
// Also, the Arduino must be flashed using SPI (deleting the bootloader), since I expect a signal ~1 second after power on.
//
// This code defaults to multi-region, meaning it will unlock PAL, NTSC-U and NTSC-J machines.
// You can optimize boot times for your console further. See "// inject symbols now" in the main loop.

//+-------------------------------------------------------------------------------------------+
//|                                  Choose your hardware!                                    |
//+-------------------------------------------------------------------------------------------+
// 2 main branches available:
//  - ATmega based > easy to use, fast and nice features for development, recommended
//  - ATtiny based > for minimal installs

// ATmega32U4/32U2 boards (as in the Pro Micro) have to use different pinouts than the 'regular'
// Arduino ATMega328's. For these, a different define must be used.

#define ARDUINO_328_BOARD
//#define ARDUINO_32UX_BOARD
//#define ATTINY_X5

#define APPLY_PSONE_PAL_BIOS_PATCH

//#define PSNEEDEBUG

#include <avr/pgmspace.h>

#if defined(ARDUINO_328_BOARD)
// board pins (code requires porting to reflect any changes)
#if defined(APPLY_PSONE_PAL_BIOS_PATCH)
#define BIOS_A18 4          // connect to PSOne BIOS A18 (pin 31 on that chip)
#define BIOS_D2  5          // connect to PSOne BIOS D2 (pin 15 on that chip)
#endif
#define sqck 6          // connect to PSX HC-05 SQCK pin
#define subq 7          // connect to PSX HC-05 SUBQ pin
#define data 8          // connect to point 6 in old modchip diagrams
#define gate_wfck 9     // connect to point 5 in old modchip diagrams
// MCU I/O definitions
#define SUBQPORT PIND       // MCU port for the 2 SUBQ sampling inputs
#define SQCKBIT 6           // PD6 "SQCK" < Mechacon pin 26 (PU-7 and early PU-8 Mechacons: pin 41)
#define SUBQBIT 7           // PD7 "SUBQ" < Mechacon pin 24 (PU-7 and early PU-8 Mechacons: pin 39)
#define GATEWFCKPORT PINB   // MCU port for the gate input (used for WFCK)
#define DATAPORT PORTB      // MCU port for the gate input (used for WFCK)
#define GATEWFCKBIT 1       // PB1
#define DATABIT 0           // PB0
#if defined(APPLY_PSONE_PAL_BIOS_PATCH)
#define BIOSPATCHPORTIN  PIND
#define BIOSPATCHPORTOUT PORTD
#define BIOSPATCHDDR     DDRD
#define BIOS_A18_BIT 4
#define BIOS_D2_BIT  5
#endif
#elif defined(ARDUINO_32UX_BOARD) // ATMega32U2/ATMega32U4
#if defined(APPLY_PSONE_PAL_BIOS_PATCH)
#define BIOS_A18 8
#define BIOS_D2  9
#endif
#define sqck 2
#define subq 3
#define data 14
#define gate_wfck 15
// MCU I/O definitions
#define SUBQPORT PIND
#define SQCKBIT 1           // PD1
#define SUBQBIT 0           // PD0
#define GATEWFCKPORT PINB
#define DATAPORT PORTB
#define GATEWFCKBIT 1       // PB1
#define DATABIT 3           // PB3
#if defined(APPLY_PSONE_PAL_BIOS_PATCH)
#define BIOSPATCHPORTIN  PINB
#define BIOSPATCHPORTOUT PORTB
#define BIOSPATCHDDR     DDRB
#define BIOS_A18_BIT 4      //PB4
#define BIOS_D2_BIT  5      //PB5
#endif
#elif defined(ATTINY_X5) // ATtiny 25/45/85
// extras
#define USINGSOFTWARESERIAL
// board pins (Do not change. Changing pins requires adjustments to MCU I/O definitions)
#define sqck 0
#define subq 1
#define data 2
#define gate_wfck 4
#define debugtx 3
// MCU I/O definitions
#define SUBQPORT PINB
#define SQCKBIT 0
#define SUBQBIT 1
#define GATEWFCKPORT PINB
#define DATAPORT PORTB
#define GATEWFCKBIT 4
#define DATABIT 2
#if defined(APPLY_PSONE_PAL_BIOS_PATCH)
#error "ATtiny does not support PAL PSOne patch yet!"
#endif
#else
#error "Select a board!"
#endif

#if defined(PSNEEDEBUG) && defined(USINGSOFTWARESERIAL)
#include <SoftwareSerial.h>
SoftwareSerial mySerial(-1, 3); // RX, TX. (RX -1 = off)
#define DEBUG_PRINT(x)     mySerial.print(x)
#define DEBUG_PRINTHEX(x)  mySerial.print(x, HEX)
#define DEBUG_PRINTLN(x)   mySerial.println(x)
#define DEBUG_FLUSH        mySerial.flush()
#elif defined(PSNEEDEBUG) && !defined(USINGSOFTWARESERIAL)
#define DEBUG_PRINT(x)     Serial.print(x)
#define DEBUG_PRINTHEX(x)  Serial.print(x, HEX)
#define DEBUG_PRINTLN(x)   Serial.println(x)
#define DEBUG_FLUSH        Serial.flush()
#else
#define DEBUG_PRINT(x)
#define DEBUG_PRINTHEX(x)
#define DEBUG_PRINTLN(x)
#define DEBUG_FLUSH
#endif

#define NOP __asm__ __volatile__ ("nop\n\t")

// Setup() detects which (of 2) injection methods this PSX board requires, then stores it in pu22mode.
boolean pu22mode;

//Timing
const int delay_between_bits = 4000;      // 250 bits/s (microseconds) (ATtiny 8Mhz works from 3950 to 4100)
const int delay_between_injections = 90;  // 72 in oldcrow. PU-22+ work best with 80 to 100 (milliseconds)

// borrowed from AttyNee. Bitmagic to get to the SCEX strings stored in flash (because Harvard architecture)
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 inject_SCEX(char region)
{
  //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};
  //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,0,1,1,1,0,1,0,0};
  //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,0,1,1,1,0,1,0,0};
  static const PROGMEM unsigned char SCEEData[] = {0b01011001, 0b11001001, 0b01001011, 0b01011101, 0b11101010, 0b00000010};
  static const PROGMEM unsigned char SCEAData[] = {0b01011001, 0b11001001, 0b01001011, 0b01011101, 0b11111010, 0b00000010};
  static const PROGMEM unsigned char SCEIData[] = {0b01011001, 0b11001001, 0b01001011, 0b01011101, 0b11011010, 0b00000010};

  // pinMode(data, OUTPUT) is used more than it has to be but that's fine.
  for (byte bit_counter = 0; bit_counter < 44; bit_counter++)
  {
    if (readBit(bit_counter, region == 'e' ? SCEEData : region == 'a' ? SCEAData : SCEIData) == 0)
    {
      pinMode(data, OUTPUT);
      bitClear(GATEWFCKPORT, DATABIT); // data low
      delayMicroseconds(delay_between_bits);
    }
    else
    {
      if (pu22mode) {
        pinMode(data, OUTPUT);
        unsigned long now = micros();
        do {
          bool wfck_sample = bitRead(GATEWFCKPORT, GATEWFCKBIT);
          bitWrite(DATAPORT, DATABIT, wfck_sample); // output wfck signal on data pin
        }
        while ((micros() - now) < delay_between_bits);
      }
      else { // PU-18 or lower mode
        pinMode(data, INPUT);
        delayMicroseconds(delay_between_bits);
      }
    }
  }

  pinMode(data, OUTPUT);
  bitClear(GATEWFCKPORT, DATABIT); // pull data low
  delay(delay_between_injections);
}

void NTSC_fix() {
#if defined(APPLY_PSONE_PAL_BIOS_PATCH)
  pinMode(BIOS_A18, INPUT);
  pinMode(BIOS_D2, INPUT);

  delay(100); // this is right after SQCK appeared. wait a little to avoid noise
  while (!bitRead(BIOSPATCHPORTIN, BIOS_A18_BIT))
  {
    ;  //wait for stage 1 A18 pulse
  }
  delay(1350); //wait through stage 1 of A18 activity

  noInterrupts(); // start critical section
  while (!bitRead(BIOSPATCHPORTIN, BIOS_A18_BIT))
  {
    ;  //wait for priming A18 pulse
  }
  delayMicroseconds(17); // max 17us for 16Mhz ATmega (maximize this when tuning!)
  bitClear(BIOSPATCHPORTOUT, BIOS_D2_BIT); // store a low
  bitSet(BIOSPATCHDDR, BIOS_D2_BIT); // D2 = output. drags line low now
  delayMicroseconds(4); // min 2us for 16Mhz ATmega, 8Mhz requires 3us (minimize this when tuning, after maximizing first us delay!)
  bitClear(DDRD, BIOS_D2_BIT); // D2 = input / high-z
  interrupts(); // end critical section

  // not necessary but I want to make sure these pins are now high-z again
  pinMode(BIOS_A18, INPUT);
  pinMode(BIOS_D2, INPUT);
#endif
}

//--------------------------------------------------
//     Setup
//--------------------------------------------------

void setup()
{
  pinMode(data, INPUT);
  pinMode(gate_wfck, INPUT);
  pinMode(subq, INPUT); // PSX subchannel bits
  pinMode(sqck, INPUT); // PSX subchannel clock

#if defined(PSNEEDEBUG) && defined(USINGSOFTWARESERIAL)
  pinMode(debugtx, OUTPUT); // software serial tx pin
  mySerial.begin(115200); // 13,82 bytes in 12ms, max for softwareserial. (expected data: ~13 bytes / 12ms) // update: this is actually quicker
#elif defined(PSNEEDEBUG) && !defined(USINGSOFTWARESERIAL)
  Serial.begin(500000); // 60 bytes in 12ms (expected data: ~26 bytes / 12ms) // update: this is actually quicker
  DEBUG_PRINT("MCU frequency: "); DEBUG_PRINT(F_CPU); DEBUG_PRINTLN(" Hz");
  DEBUG_PRINTLN("Waiting for SQCK..");
#endif

#if defined(ARDUINO_328_BOARD) || defined(ARDUINO_32UX_BOARD)
  pinMode(LED_BUILTIN, OUTPUT); // Blink on injection / debug.
  digitalWrite(LED_BUILTIN, HIGH); // mark begin of setup
#endif

  // wait for console power on and stable signals
  while (!digitalRead(sqck));
  while (!digitalRead(gate_wfck));

  // if enabled: patches PAL PSOne consoles so they start all region games
  NTSC_fix();

  // Board detection
  //
  // GATE: __-----------------------  // this is a PU-7 .. PU-20 board!
  //
  // WFCK: __-_-_-_-_-_-_-_-_-_-_-_-  // this is a PU-22 or newer board!

  unsigned int highs = 0, lows = 0;
  unsigned long now = millis();
  do {
    if (digitalRead(gate_wfck) == 1) highs++;
    if (digitalRead(gate_wfck) == 0) lows++;
    delayMicroseconds(200);   // good for ~5000 reads in 1s
  }
  while ((millis() - now) < 1000); // sample 1s

  // typical readouts
  // PU-22: highs: 2449 lows: 2377
  if (lows > 100) {
    pu22mode = 1;
  }
  else {
    pu22mode = 0;
  }

#ifdef ATTINY_X5
  DEBUG_PRINT("m "); DEBUG_PRINTLN(pu22mode);
#else
  DEBUG_PRINT("highs: "); DEBUG_PRINT(highs); DEBUG_PRINT(" lows: "); DEBUG_PRINTLN(lows);
  DEBUG_PRINT("pu22mode: "); DEBUG_PRINTLN(pu22mode);
  // 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;
#endif

#if defined(ARDUINO_328_BOARD) || defined(ARDUINO_32UX_BOARD)
  digitalWrite(LED_BUILTIN, LOW); // setup complete
#endif

  DEBUG_FLUSH; // empty serial transmit buffer
}

void loop()
{
  static byte scbuf [12] = { 0 }; // We will be capturing PSX "SUBQ" packets, there are 12 bytes per valid read.
  static unsigned int timeout_clock_counter = 0;
  static byte bitbuf = 0;   // SUBQ bit storage
  static bool sample = 0;
  static byte bitpos = 0;
  byte scpos = 0;           // scbuf position

  // start with a small delay, which can be necessary in cases where the MCU loops too quickly
  // and picks up the laster SUBQ trailing end
  delay(1); 
  
  noInterrupts(); // start critical section
start:
  // Capture 8 bits for 12 runs > complete SUBQ transmission
  bitpos = 0;
  for (; bitpos < 8; bitpos++) {
    while (bitRead(SUBQPORT, SQCKBIT) == 1) {
      // wait for clock to go low..
      // a timeout resets the 12 byte stream in case the PSX sends malformatted clock pulses, as happens on bootup
      timeout_clock_counter++;
      if (timeout_clock_counter > 1000) {
        scpos = 0;  // reset SUBQ packet stream
        timeout_clock_counter = 0;
        bitbuf = 0;
        goto start;
      }
    }

    // wait for clock to go high..
    while ((bitRead(SUBQPORT, SQCKBIT)) == 0);

    sample = bitRead(SUBQPORT, SUBQBIT);
    bitbuf |= sample << bitpos;

    timeout_clock_counter = 0; // no problem with this bit
  }

  // one byte done
  scbuf[scpos] = bitbuf;
  scpos++;
  bitbuf = 0;

  // repeat for all 12 bytes
  if (scpos < 12) {
    goto start;
  }
  interrupts(); // end critical section

  // log SUBQ packets. We only have 12ms to get the logs written out. Slower MCUs get less formatting.
#ifdef ATTINY_X5
  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++) {
      if (scbuf[i] < 0x10) {
        DEBUG_PRINT("0"); // padding
      }
      DEBUG_PRINTHEX(scbuf[i]);
    }
    DEBUG_PRINTLN("");
  }
#else
  if (!(scbuf[0] == 0 && scbuf[1] == 0 && scbuf[2] == 0 && scbuf[3] == 0)) {
    for (int i = 0; i < 12; i++) {
      if (scbuf[i] < 0x10) {
        DEBUG_PRINT("0"); // padding
      }
      DEBUG_PRINTHEX(scbuf[i]);
      DEBUG_PRINT(" ");
    }
    DEBUG_PRINTLN("");
  }
#endif

  // check if read head is in wobble area
  // We only want to unlock game discs (0x41) and only if the read head is in the outer TOC area.
  // We want to see a TOC sector repeatedly before injecting (helps with timing and marginal lasers).
  // All this logic is because we don't know if the HC-05 is actually processing a getSCEX() command.
  // Hysteresis is used because older drives exhibit more variation in read head positioning.
  // While the laser lens moves to correct for the error, they can pick up a few TOC sectors.
  static byte hysteresis  = 0;
  boolean 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)
          ) {  // This CD has the wobble into CD-DA space. (started at 0x41, then went into 0x01)
    hysteresis++;
  }
  else if (hysteresis > 0) {
    hysteresis--; // None of the above. Initial detection was noise. Decrease the counter.
  }

  // hysteresis value "optimized" using very worn but working drive on ATmega328 @ 16Mhz
  // should be fine on other MCUs and speeds, as the PSX dictates SUBQ rate
  if (hysteresis >= 14) {
    // If the read head is still here after injection, resending should be quick.
    // Hysteresis naturally goes to 0 otherwise (the read head moved).
    hysteresis = 11;

#ifdef ATTINY_X5
    DEBUG_PRINTLN("!");
#else
    DEBUG_PRINTLN("INJECT!INJECT!INJECT!INJECT!INJECT!INJECT!");
#endif
#if defined(ARDUINO_328_BOARD) || defined(ARDUINO_32UX_BOARD)
    digitalWrite(LED_BUILTIN, HIGH);
#endif

    pinMode(data, OUTPUT);
    digitalWrite(data, 0); // pull data low
    if (!pu22mode) {
      pinMode(gate_wfck, OUTPUT);
      digitalWrite(gate_wfck, 0);
    }

    // HC-05 waits for a bit of silence (pin low) before it begins decoding.
    delay(delay_between_injections);
    // inject symbols now. 2 x 3 runs seems optimal to cover all boards
    for (byte loop_counter = 0; loop_counter < 2; loop_counter++)
    {
      inject_SCEX('e'); // e = SCEE, a = SCEA, i = SCEI
      inject_SCEX('e'); // injects all 3 regions by default
      inject_SCEX('e'); // optimize boot time by sending only your console region letter (all 3 times per loop)
    }

    if (!pu22mode) {
      pinMode(gate_wfck, INPUT); // high-z the line, we're done
    }
    pinMode(data, INPUT); // high-z the line, we're done
#if defined(ARDUINO_328_BOARD) || defined(ARDUINO_32UX_BOARD)
    digitalWrite(LED_BUILTIN, LOW);
#endif
  }
  // keep catching SUBQ packets forever
}
Original Disks work, but Backups show either the CD Player Menu ("Frontschweine") or the red "Insert Playstation Disk" Screen (Resident Evil). I tried different CD-Rs and different drives to burn, but non is working.

Anybody knows what I can do?

cstomi
What is PSXDEV?
What is PSXDEV?
Posts: 1
Joined: Dec 20, 2020

Post by cstomi » December 20th, 2020, 1:49 am

Hi,

I've installed an Arduino Pro Mini (m328p,5V/16Mhz) to an SCPH-102 [ PM-41(2) ]. Modchip is working, can play NTSC games as well, but there are some graphical glitches during games and even the boot screens. I use an RGB (scart) cable.

Without modchip:


With modchip:


I used the latest PsNee version (v7.01) with enabled PSone PAL bios patch. The boot screen is bad in case of PAL and NTSC games as well, but after boot, PAL games working good, no graphical glitches. The graphics in NTSC games are still bad after boot.

What could be the problem?

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

Post by Shadow » December 26th, 2020, 2:43 am

Possible clock interference or interference in general from the modchip since that data (IE: the PlayStation logo) is pulled from the CD-ROM from sector 12.
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 2 guests