Update time!
As hinted in the last update, I’ve been busy with another project, which will be finished in about a month. Luckily that did not stop me from spending some spare time on the PS2!
Travel case and SD2PSX
I’ve been using the prototype almost daily for 2h during my commutes, probably for more than a month now. It’s great! The battery life is about 4.5h at full brightness and headphones, which is a lot more than I originally intended to implement. I did notice some bugs in the firmware that need fixing in the future (like the gamepad not working after turning the system off and on a couple of times while charging).
To give the portable a bit of protection I designed a little travel case:
(The color is on purpose, so I find the damn thing again)
The original 8MB memory card turned out to be a bit of a bottleneck – I only have one and it’s full already, after finishing about 6 games! But there is hope… luckily, the PS2 scene is innovating at a crazy rate nowadays - I was made aware of the SD2PSX(td) project, which might solve all my storage issues.
I ordered a PSxMemCard Gen2 for testing and it does indeed work great! While the OPL MMCE beta 2 had some game compatibility issues similar to the MX4SIO (actually the same games didn’t work), the load times were a noticably faster and there was slightly less stutter than MX4SIO.
From experience, neutrino offers better compatibility on MX4SIO, so naturally I wanted to try it with MMCE. The only MMCE compatible launcher I could find was NHDDL (apart from XEB+ neutrino launcher). After installing the NHDDL MMCE beta 3 and neutrino 1.5.0 on the SD2PSX boot card, I was impressed to see it working as well as the previous MX4SIO setup I had. All games I tried were running fine and there is finally all the memory card space I ever need on a single device! This might be my new setup of choice!
Just the test setup is very sketchy:
To make this a bit more usable, I was looking for ways to integrate it into my portable. I decided against integrating it internally on the memcard flex early on, as I would like to keep both memory card slots fully functional. With all the advancements recently, who knows what comes next and whether it's compatible to the SD2PSX. If the 2 SD memory card slots will stay, it means that the SD2PSX will need to shrink to the size of an SD card. This enables the use of a SD2PSX, while keeping compatibility to MX4SIO and my SD memory card.
Thankfully the SD2PSX hardware only consists of an RP2040, SPI flash, PSRAM and micro-SD slot, after removing the display and buttons. In the beginning I thought this would be an easy fit, but in the end it was tight with all the signals needing accessible test points at the back. I also had to use smaller packages for the flash and PSRAM to make everything fit & select the smallest micro-SD slot I could find -> this one has no latching mechanism, which would take a lot of space.
This is the current state:
Both the flex PCB and the components were ordered. You see there are no buttons and no display – they are actually not needed for general use. My only concern right now would be the missing I2C display preventing the firmware from functioning (I really don’t want to modify the firmware, but I will if I have to). The whole PCBA will be adhered to a 3D printed frame to create an SD assembly similar to my SD memory card.
Next topic: FPGA
I was refactoring a lot of the video processor implementation and creating a top level block diagram to better plan the integration with the syscon. To get back into the topic, I wanted to replace the hybrid motion adaptive deinterlacer with a proper 4 field motion adaptive deinterlacer.
This however was not trivial, a 4 field motion detector requires 33% more framebuffer bandwidth compared to my previous hybrid implementation. In order to achieve such an increase I had to completely rewrite the framebuffer scheduler, video decoder module and the deinterlacer. There were 2 distinct enhancements to the architecture:
- The video input module is no longer sampling the black borders horizontally (they are now added back by the scaler module when in 4:3 mode) – 33% improvement
- The 3-byte pixel data is now packed into the 4-byte wide SDRAM data bus and gets unpacked by a ringbuffer in the deinterlacer module (before the upper byte of the SDRAM data was unused) – 25-30% improvement
Another issue was the SDRAM itself. Reading and writing from very different addresses in the same bank has a huge hit on bandwidth, because each time an address row must be opened and closed.
The hybrid deinterlacer had no issues, it needs 3 banks to read and 1 bank to write, and the SDRAM has 4 physical banks in total. For the 4 field deinterlacer I need 4 banks to read and 1 bank to write -> 5 banks in total. Luckily, each bank has enough space to fit 2 frames, so I decided to split each bank to create 8 “virtual” banks with the bandwidth limitation above.
In order to reduce the bandwidth impact, I changed how the scheduler handles reads and writes: The scheduler now tries to avoid switching between read and write as much as possible, often reading a full line before it schedules a write to the SDRAM. Before it was alternating between read and write after every burst, which would have resulted in a disastrous bandwidth reduction using the new banking scheme.
These enhancements to the data path made it possible to finally implement a 4 field motion detector! And it works!
The old motion implementation had its weaknesses in 50/60Hz games, due to the reliance on the error-prone 2 field motion detector. This is exactly where the new 4 field deinterlacer shines, the combing artefacts are almost completely gone in 60Hz games compared to before. With some tweaking of the motion thresholds, it could still be improved further. The performance in 25/30Hz games is about the same. The video delay of one field (16-20ms) from GS output to displayed image is also the same.
Flickering on very fine horizontal details (the horizontal lines in OPL are a prominent example) is completely eliminated in the new implementation. This was caused by the vertical averaging performed in the 2 field motion detector, leading erroneous motion detection.
After doing the new deinterlacer I started researching for the scaler, writing down the required calculations and thinking about the state machine. This is the point where I am right now, I should also focus on thinking about how to best implement the hardware sprite module and in general the interface to the syscon.
Boot rom flex
I had another boot rom reverse engineering session and using the information
@wisi provided, together with my notes from previous sessions I finally figured out how to properly decode the CS lines. This enabled me to design a tiny boot rom replacement in the size of the original chip:
The original flash indeed has 3 CS lines – /CS1, /CS2 and /PPCS.
CS2 and PPCS access the same data while CS1 accesses the DVD rom. Using 2 AND gates it’s possible to generate one CS for the new flash. Of course, pre-deckard PS2s are missing the PPCS, so in order to make those compatible I added a pullup to PPCS (in the service manuals I saw that this pin seems to be either connected to VCC or floating). A22 also doesn’t seem to be connected on all PS2 models, so I’m basing it on CS1.
This new 64M chip has the DVD rom in the lower half and the boot rom in the upper half of the flash – it required a python script to combine them in the right order.
Soldering the BGA flash to the flex PCB is a bit tricky, as there is no stiffener which would prevent it from warping during reflow - I had to tape all 4 sides to the tray of the reflow oven. If it wasn't so expensive, I would have ordered the first PCBs already with 0.1mm stainless steel stiffener. Tape works too I guess
So far, I only installed one in a 90k and it performs 1:1 as the original bios chip. Due to it containing the DVD rom, even DVD movies work now!
More testing is needed to figure out the compatibility to other models. Let’s see what else comes up in the future!