hrydgard/ppsspp — pull request #939 by unknownbrackets (2013-03-11 03:28:30+00:00)
Title: Handle async IO more correctly (testing/review)

This is a larger change and probably could use more testing. I recommend merging only after 0.7, but it'd be great to know if this helps or hurts any games I don't have / haven't tested yet.

It's still not entirely accurate, but it's much better. This is sorta a first step, not wanting to make it too huge. I still need to finish writing better tests also, and there's always more to do, but I'm quite optimistic so far.

Practical affects:
* Can't find any games this breaks (but there is one "hack", see below.)
* Tales of Destiny 2 -> menu
* Unchained Blades -> ingame
* Patapon 2 -> intro
* Patapon -> menu (but black)
* Final Fantasy 4 -> less errors, tiny bit farther (still nowhere)
* Shadow of Destiny -> now loading (slightly farther)
* Likely others?
* Less error messages in console even for games that do work.

Changes:
* sceIo funcs now delay/resched like on the PSP, but I kept all the delays low to be on the safe side (many were 10x or more, but often varied by a wide degree in my testing.)
* The async functions (including sceIoOpen now) call the callback with a proper delay.
* The async wait functions now actually wait.
* The async result is now properly sign extended (e.g. 0xffffffff80020325 not 0x0000000080020325)
* Unfortunately, this change caused regressions. Some games were sceIoReadAsync()'ing into a NULL pointer, but not failing because they thought it worked. Afterward, they crashed.
* For now, I'm making it return 0, and everything seems okay with that.
* Ultimately this is caused by some other HLE func not returning an address, etc., or else timing/scheduling issues.
* I made hleDelayResult() support 64-bit. As a side-effect, it overwrites v1 even when returning 32-bit, but I think this is safe within the ABI?
* It now closes files properly under async, which fixes a lot of spurious logged errors.
* Fixes and adds some sceIoDevctl methods I found along the way (these match tests.) Some were used in the games that got farther with async.
* Avoids overwriting the async result for non-async calls (real firmware doesn't seem to.)

There's still more - for example errors when you try to do an async twice, or wait on no async, etc. But I wanted to create this so others can see my code and report any games it breaks.

-[Unknown]