pcsx2 icon indicating copy to clipboard operation
pcsx2 copied to clipboard

SIO: Separate SIO2 from SIO0

Open RedPanda4552 opened this issue 3 years ago • 8 comments

Description of Changes

This PR breaks SIO2 and SIO0 out in to two detached systems. Registers and supporting functions are separated into two classes. These two classes are singletons which remain unaware of each other's existence, and simply react to IOP memory reads and writes to their own registers.

That was the original goal. Along the way either because it was convenient to do or was a requirement to repair after making the above changes, the following changes were made:

  • Removal of the "last byte ACK hack". PS1 games use the ACK line of the SIO bus to update SIO0 STAT's acknowledge bit. This is basically how a peripheral tells a PS1 "please don't stop I have more to reply". This is completely useless to PS2 games where everything is managed within SIO2MAN/MCMAN/PADMAN.
  • Interrupts are a bit nicer to look at now but nothing fundamentally changed. PS1 games still have weird behavior with them.
  • Reimplementation of all memory card commands. These were previously full of shortcuts, mixed into SIO code, and commands generally had a flow which was hard to follow. For PS2 games, this implementation is stateless; the function for the target command will consume the PS2's command data all at once and spit out a valid memory card reply. PS1 games on the other hand send one command byte and receive one command byte per frame instead of using DMA to transfer entire commands, and they require some state management, tracked in a struct. Only one struct is required, as it is physically impossible for the PS2 or PS1 to ever address more than one memory card at a time.
  • Reimplementation of all PS2 multitap commands. These are pretty low tech, not much to explain here and nothing really changed except the code is probably easier to follow along.
  • Auto ejection system is replaced with a lower tech system which should be more predictable and still accomplish the job. Honestly I couldn't tell you exactly how the old system worked, but the new one basically allows a memcard to be "auto ejected", which sets a counter to 60. Each memcard command sent to that slot decrements the counter. When the counter hits 0, its treated as inserted again. This seems to do a remarkably good job of alerting a game that its memcard is gone, and then being inserted again pretty quickly after, but may need adjusting.

Rationale behind Changes

For basically its entire life, PCSX2 has been using a derivative of PCSX's original SIO0 implementation. With limited knowledge of the PS2's new SIO2 registers and IOP modules, an attempt was made to adapt SIO0 to behave more like SIO2. However, SIO0 registers were still being used as if they were a part of SIO2, when in fact they are completely separate.

Suggested Testing Steps

I strongly recommend using a copy of your memory card, and not using the one you actually care about while testing.

cracks knuckles

  • MGS3: Check that camos are now saveable/usable
  • MGS3: Check that old "corrupted" save files now suddenly start working again
  • Shining Force EXA: Check that the game can detect its own save files
  • Shining Force EXA: Check that saving after clearing the final boss doesn't torch the game's saves
  • PlayStation Underground Holiday 2004 Demo Disc: Check if Viewtiful Joe 2 demo still fries the memcard. DO NOT ATTEMPT THIS ONE USING A MEMORY CARD YOU REMOTELY CARE ABOUT! It is still fully expected that your memcard will be sent to the shadow realm, but when I ran some tests the memcard actually survived (which isn't even supposed to happen) so I need some help corroborating this one.
  • Jak X: Though this game's memcard problems are present on hardware, PCSX2 seemed to have a REALLY bad go at it in comparison. Check to see if the game is at least somewhat serviceable now, or if it's gotten worse somehow.
  • Tales of Legendia, Resident Evil 4, Dogz, Just Cause: These games were name dropped to me but I was never given any explanation as to what was wrong with them in particular. Some generic tests to make sure memcards are still working would be nice.
  • Any game: Check if you can still access and write to memory cards.
  • Any game: Check if your controller still functions as expected, including basic button presses, analog sticks, and if relevant, button pressures.
  • Multitap games: Check if you can enable a multitap and get a multitap slot controller to show up in-game.
  • Any game: Create savestates in places where memory cards are being read (very important, do not do this while they are being WRITTEN. I do not care about testing while it is being WRITTEN, because this is a flat out idiotic thing to do and guaranteed to fry memcards no matter how many safety nets we try to throw at it.
  • Any game: Load savestates which were created while the memory card was being read. Verify that auto ejection kicks in and ejects the memory card. Then verify a follow-up attempt to read the memory card succeeds.
  • Any game: Check if input recording works. I really have no idea if I bricked this part of the emulator or not, and I think I am too dumb to work out how to get this system working.

This post may be updated as things progress, as I've no doubt missed something. But here's a starting point. Go nuts.

RedPanda4552 avatar Jul 30 '22 07:07 RedPanda4552

Datel Game Studio crashes the emulator using this PR: image

Florin9doi avatar Aug 09 '22 21:08 Florin9doi

Datel Game Studio crashes the emulator using this PR: image

Interesting, an exception in that function suggests the deque is empty when it tries to get the front and pop. Will look into it and see what is going on in more detail.

RedPanda4552 avatar Aug 09 '22 21:08 RedPanda4552

@Florin9doi I did not realize this was an actual hardware device. What happens on current master? I would expect it flops, probably in a different manner, but I don't see how this could function without supporting emulation of the hardware unit itself.

RedPanda4552 avatar Aug 11 '22 20:08 RedPanda4552

On master the device is undetected but the difference is that the emulator doesn't crash.

Florin9doi avatar Aug 11 '22 20:08 Florin9doi

On master the device is undetected but the difference is that the emulator doesn't crash.

Very interesting. Likely what I'll do is just add a condition that if FIFO is empty return zero and warn about empty FIFO access (which would be closer to what the hardware does anyways if there's no device connected and dead air over the line).

As for actually supporting it, well I don't think it will be any time soon but, no doubt this is now burned into my mind so thanks for letting me know this thing exists!

RedPanda4552 avatar Aug 11 '22 20:08 RedPanda4552

Same issue with "Max Memory Online" (they used custom commands for their memory cards?) and "SharkPort - Code and Save Transfer Kit" (why? that's an USB accessory).

It works, the crashes are resolved returning zeros:

diff --git a/pcsx2/Sio.cpp b/pcsx2/Sio.cpp
index 00cdc9688..00b63378b 100644
--- a/pcsx2/Sio.cpp
+++ b/pcsx2/Sio.cpp
@@ -805,7 +805,12 @@ void Sio2::Write(u8 data)
                                this->Memcard();
                                break;
                        default:
-                               Console.Error("%s(%02X) Unhandled SIO mode %02X", __FUNCTION__, data, sioMode);
+                               Console.Error("%s(%02X) Unhandled SIO mode %02X, len=%d", __FUNCTION__, data, sioMode, commandLength);
+                               SetRecv1(Recv1::DISCONNECTED);
+                               while (fifoOut.size() < commandLength)
+                               {
+                                       fifoOut.push_back(0x00);
+                               }
                                break;
                }

Florin9doi avatar Aug 11 '22 23:08 Florin9doi

@Florin9doi Latest commit should resolve it, if you could try again and verify?

RedPanda4552 avatar Aug 12 '22 05:08 RedPanda4552

All 3 are ok now

Florin9doi avatar Aug 12 '22 07:08 Florin9doi

I continued testing PR last night.

PS2:

Silent Hill 2, Siren both save games
Both saves appear in the BIOS
Katamari feels fine to control. Saves with little issue
Both Fatal Frame game engines are fine controls and saves

PS1:

The underground jampak demo has a "download station" Where it'll read card saves from the disk to a card.
Was able to load a Gran Turismo 1 save from the demo in the game. Those saves appear in BIOS as well. So, that worked 
Harry Potter will not respond to controls. The menus barely work and ingame there is no control, the game will save to a card.
Final Fantasy VIII still does the unformatted card thing.
Mr. Driller saves and controls

weirdbeardgame avatar Oct 27 '22 20:10 weirdbeardgame