Talk:PS1 Emulation: Difference between revisions
(110 intermediate revisions by 6 users not shown) | |||
Line 1: | Line 1: | ||
== Memory Map == | == Memory Map == | ||
For now here, i will move when finished. | For now here, i will move when finished. | ||
Line 393: | Line 14: | ||
Offset in emu memory (ps1_netemu 4.86) | name | info | Offset in emu memory (ps1_netemu 4.86) | name | info | ||
001B39D0 GP0_commands_table {ParamsCount, OPD} | |||
0x10C5E4 GP1_reset_gpu | 0x10C5E4 GP1_reset_gpu | ||
0x10C88C GP1_reset_command_buffer | 0x10C88C GP1_reset_command_buffer | ||
Line 416: | Line 36: | ||
0xD70C20 GPUSTAT_r (PS1 GPU status register 1F801814 in read mode) | 0xD70C20 GPUSTAT_r (PS1 GPU status register 1F801814 in read mode) | ||
0xD70C24 dma_dir__data_req (from GP1 0x04 cmd) | 0xD70C24 dma_dir__data_req (from GP1 0x04 cmd) | ||
0xD70C28 - 0xD70DA0 UNCONFIRMED seems to be GP0 fifo on PPU side, but need some reversing to confirm. | |||
0xD70DA4 display_enable_request (based on GP1 0x03 cmd) | 0xD70DA4 display_enable_request (based on GP1 0x03 cmd) | ||
0xD70DA8 start_of_display_area_in_VRAM__X (from GP1 0x05 cmd) | 0xD70DA8 start_of_display_area_in_VRAM__X (from GP1 0x05 cmd) | ||
Line 456: | Line 77: | ||
</pre> | </pre> | ||
== | === ps1_emu vs ps1_netemu GPU emulation differences === | ||
In some cracktros (Spyro 3, Sydney 2000, NFS Porsche 2000) the GP0 command E4h (E4080200) draws the image on the wrong coordinates, causing the frozen image of the zoomed PS1 licence screen. According to this [https://psx-spx.consoledev.net/graphicsprocessingunitgpu/#gp0e4h-set-drawing-area-bottom-right-x2y2 info], that command does make use of the newer 2MB VRAM GPU coordinates. Restricting the drawing area to the lower coordinates does fix the image. It looks like a lot of emulators are affected by this, either the Sony ones (ps1_emu on PS3, PS1 on PS2 hardware emulator, POPS on PSP) or the homebrew pSX 1.13. The ps1_netemu is displaying the image correctly. Does it mean the ps1_netemu emulate a different, newer GPU or just increase the emulation accuracy in general (assuming these cracktros work fine even on the oldest PSX released EDIT: I have found reports they are picky even on the original PS1 hardware too.)? | |||
* Yes, this should fail also on old PS1 GPU. I can also confirm that PS1DRV (at least before deckard PS2 models) emulate old GPU model. | |||
As for PS3. ps1_emu, and ps1_newemu emulate old GPU, ps1_netemu emulate new GPU at least partially. Also small tip, all emulators have pair of 2 embed | |||
SPE ELFs. One is SPU emulator, second is GPU emulator. All of them have debug symbols. | |||
ps1_emu | |||
<pre> | |||
.text:000014D0 E4_cmd: | |||
.text:000014D0 il r56, 0x3FF | |||
.text:000014D4 hbrr loc_1504, loc_403C | |||
.text:000014D8 rotmi r54, r12, -10 # r12 = whole 32 bit command | |||
# r54 = is command shifted by 10 to skip | |||
# x-cord. So now first bits are y-cord. | |||
.text:000014DC lqr r51, xmmword_E520 | |||
.text:000014E0 and r55, r12, r56 # x-cord and with whole 10 bits. | |||
.text:000014E4 cwd r53, 0xF0+var_F0(sp) | |||
.text:000014E8 cwd r49, 0xF0+var_F0+8(sp) | |||
.text:000014EC ai r52, r55, 1 | |||
.text:000014F0 andi r50, r54, 0x1FF # y-cord and with 0x1FF, so only 9 bits. | |||
</pre> | |||
ps1_netemu | |||
<pre> | |||
.text:00003338 E4_cmd: | |||
.text:00003338 rotmi r18, r12, -10 # r12 = whole 32 bit command | |||
# r18 = is command shifted by 10 to skip | |||
# x-cord. So now first bits are y-cord. | |||
.text:0000333C hbrr loc_3384, loc_3328 | |||
.text:00003340 il r19, 0x3FF | |||
.text:00003344 lqr r39, xmmword_150D0 | |||
.text:00003348 il r8, 0x200 | |||
.text:0000334C lqr r33, xmmword_150E0 | |||
.text:00003350 and r44, r12, r19 # x-cord and with whole 10 bits. | |||
.text:00003354 cwd r42, arg_0+0xC(sp) | |||
.text:00003358 and r43, r18, r19 # y-cord and with 0x3FF, so whole 10 bits. | |||
</pre> | |||
---kozarovv. | |||
== PS1 I/O handlers == | |||
List of functions that are responsible for interpreting HW registers reads/writes. Based on 4.86 ps1_netemu. | |||
<pre> | |||
timers_hwreg_write_handler 0xC2CC0 | |||
timers_hwreg_read_handler 0xC2F80 | |||
dma_hw_read_handler 0xD09C8 | |||
dma_hw_write_handler 0xD0E18 | |||
spu_hwreg_write_handler 0xD1E68 | |||
spu_hwreg_read_handler 0xD1FF8 | |||
joy_hwreg_write_handler 0xD44A8 | |||
joy_hwreg_read_handler 0xD49F8 | |||
sio_hwreg_write_handler 0xD758C | |||
sio_hwreg_read_handler 0xD7620 | |||
cdr_hwreg_read_handler 0xD80A0 | |||
cdr_hwreg_write_handler 0xE8598 | |||
mdec_hwreg_write_handler 0xE9A18 | |||
mdec_hwreg_read_handler 0xEA2F0 | |||
i_ctrl_hwreg_read_handler 0x10577C | |||
i_ctrl_hwreg_write_handler 0x1063AC | |||
gpu_hwreg_read_handler 0x10BF40 | |||
gpu_hwreg_write_handler 0x10C48C | |||
</pre> | |||
==== | == Experimental Patches == | ||
This patches are intended to be applyed to the PS1 emulators | |||
==== Disable Dithering ==== | |||
Always set bit 9 in GP0 E1 command to 0. Patches apply to SPE PS1 GPU emulation program. Based on 4.86, but should be valid for all firmwares since 4.6x<br><br> | |||
For ps1_emu.elf | |||
<pre> | <pre> | ||
search for: 23 EC A4 04 23 E3 3B 85 33 7E 26 00 32 05 86 00 0F 3D C6 11 | |||
replace to: 23 EC A4 04 23 E3 3B 85 33 7E 26 00 32 05 86 00 40 80 00 11 | |||
</pre> | </pre> | ||
For ps1_netemu.elf | |||
<pre> | <pre> | ||
search for: 7C 38 41 94 20 7F F4 94 0F 3D C6 3C 12 7F F3 8A | |||
replace to: 7C 38 41 94 20 7F F4 94 40 80 00 3C 12 7F F3 8A | |||
</pre> | |||
For ps1_newemu.elf | |||
<pre> | |||
search for: 20 7F FD 4C 23 9D C5 85 32 05 B2 80 12 05 B2 0B 0F 3D C6 58 | |||
replace to: 20 7F FD 4C 23 9D C5 85 32 05 B2 80 12 05 B2 0B 40 80 00 58 | |||
</pre> | </pre> | ||
Patch for rpcs3 (newemu only) for testing purpose. | |||
<pre> | |||
<pre> | Version: 1.2 | ||
SPU-f3d8be702bf4cb8545656e37c29fcc6201a57991: | |||
"Disable Dithering": | |||
Games: | |||
All: | |||
All: [ All ] | |||
Author: "kozarovv" | |||
Patch Version: 1.0 | |||
Patch: | |||
- [ be32, 0xFB0, 0x40800058 ] | |||
</pre> | |||
==== | ==== Allow non encrypted ISO.BIN.EDAT and skip signature check (RPCS3 only) ==== | ||
For easier config testing. Patch allow to use unencrypted ISO.BIN.EDAT so we don't need to mess with klic. Also ECDSA signature at the end of file is no longer required. So we can ftp configs as is, for faster testing. Warning! This patch break official ps1_classics. | |||
<br><br> | |||
ps1_netemu.elf 4.86-4.90 offset in raw hex (for Hxd, etc.) | |||
0xDDD6C replace 48 07 14 21 to 38 60 00 00 | |||
0xE13C4 replace 60 00 00 00 to 38 60 00 00 | |||
== Commands Info == | ==== GTE Automatic Widescreen Hack ==== | ||
Automatic widescreen without per game patches. Work only for 3D elements (like 95% of available widescreen patches).<br> | |||
Tested on both RPCS3 and real PS3 (CFW only, but can be added to hen).<br> | |||
ps1_netemu.elf 4.86 - 4.91 offsets in raw hex (for Hxd, etc.) | |||
0x2BDA4 original code: | |||
7C 69 1B 78 3C 60 80 54 2F 89 00 00 60 63 00 10 | |||
40 9E 00 14 3C 60 80 54 60 63 00 02 7C 63 07 B4 | |||
4E 80 00 20 A0 09 00 02 2F 80 00 00 41 9E FF F0 | |||
C0 02 A3 D8 FF 81 00 00 41 9D FF DC C0 02 A3 DC | |||
38 60 00 00 FF 81 00 00 41 9C FF CC D0 29 00 6C | |||
4B FF FF CC | |||
replace to: | |||
78 C0 F8 42 78 C6 F0 82 7C C6 02 14 7D 08 32 14 | |||
48 0C 47 7E 78 E9 F8 42 78 E7 F0 82 7C E9 3A 14 | |||
7C C6 3A 14 48 0C 65 66 79 00 F8 42 79 08 F0 82 | |||
7D 08 02 14 7C C6 42 14 48 0C 69 0A 79 00 F8 42 | |||
79 08 F0 82 7D 08 02 14 7C C6 42 14 48 0C 6C 6A | |||
60 00 00 00 | |||
0xB4778 original code: 7D 08 32 14 replace to: 48 03 BD A6 | |||
0xB6560 original code: 7C C6 3A 14 replace to: 48 03 BD BA | |||
0xB6904 original code: 7C C6 42 14 replace to: 48 03 BD CE | |||
0xB6C64 original code: 7C C6 42 14 replace to: 48 03 BD E2 | |||
== Ps1_netemu Commands Info == | |||
=== External Configs === | |||
Loading external commands is be possible in ps1_netemu. From this we can also figure out that sony call those configs "ad hoc params" which can be little bit misleading. Emulator expect them inside ISO.BIN.EDAT file. Offset depend if "optional header" exist or not. Values are little endian. | |||
The offsets below are the offsets from the start of the PSISOIMG section. This data starts at absolute file offset 0x424 for single disk games that do not use a PSTITLEIMG section. For games that do have a PSTITLEIMG section, the absolute offset will be shifted by 0x400 bytes, i.e. to offset 0x824 and similar. | |||
* Offset 0x424 Config revision in bcd format, that need to be higher than DB from emu (11624 for 4.86). Safe to use 0x200000. | |||
* Offset 0x42C first config command | |||
* Offset 0x430 param for first command | |||
* This repeats 8 times as only 8 commands is supported. | |||
* Command 2 is unsupported. | |||
* Command 0 is unsupported because $ony made mistake in parser. | |||
* Command 0x17 is supported, but there is different official way to inject it, and it is libcrypt key so there is no point to do it this way. | |||
This probably repeats for multidiscs, but for now let's figure out single discs first. | |||
<br>Function that search for configs look like this: | |||
case 9: | |||
if ( *(&0x161FD80) ) 1570FA0(base) + AEDE0(offset in ISO.BIN.DAT or PSISOIMG? ) = 161FD80 in 4.86 ps1_netemu | |||
{ | |||
cfg_rev = get_cfg_rev_from_PSIMG(); | |||
db_rev = get_titledb_rev(); | |||
decimal_16 = ret_32() >> 1; | |||
tty_print("ad hoc param: %x <%x>\n", cfg_rev, db_rev); | |||
if ( decimal_16 ) | |||
{ | |||
low_rev = cfg_rev < db_rev; // Check is opposite to ps2_netemu, only config version higher than included db will pass. | |||
// Which mean config need to be higher version than emu database. | |||
for ( i = 0; i < decimal_16; i += 2 ) // up to 8 configs supported (8 commands + 8 values) | |||
{ | |||
cfg_command = read_cfg_from_PSIMG(i); | |||
_cfg_value = read_cfg_from_PSIMG(i + 1); | |||
if ( cfg_command - 1 <= 0x3B ) // max cfg nr 0x3C | |||
{ | |||
v245 = cfg_command >> 28; // Most likely check for wrong endianess. Configs are LE and are byte reversed before we end up here. | |||
if ( low_rev || v245 || cfg_command == 2 )// cfg 2 unsupported (replaced in later PSIMG rev with subchannel data), or old config rev, or v245. | |||
{ | |||
tty_print("%x: %2d=0x%08x ***\n", v245 & 0xF, cfg_command, _cfg_value); // Ignore cfg | |||
} | |||
else | |||
{ | |||
cfg_value = _cfg_value; | |||
tty_print("%x: %2d=0x%08x\n", 0LL, cfg_command, _cfg_value); | |||
WriteInternalConfigValue(cfg_command, cfg_value); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
=== Command IDs mapping === | |||
The command IDs differs in between the PS1 emulator types and versions because are an indirect ID, it seems every command ID is mapped to a static ID in a separated table<br> | |||
The command ID's varies in between firmware versions, most probably because new functions was added every few versions, reorganized, etc... and this changes created a "displacement" of the old commands that causes them to increase his ID<br> | The command ID's varies in between firmware versions, most probably because new functions was added every few versions, reorganized, etc... and this changes created a "displacement" of the old commands that causes them to increase his ID<br> | ||
At the time of writing this we dont know how to map that variable ID's to an static ID (that could be valid for all firmware versions), so by now in this list is needed to indicate the firmware version where the command ID was found<br> | At the time of writing this we dont know how to map that variable ID's to an static ID (that could be valid for all firmware versions), so by now in this list is needed to indicate the firmware version where the command ID was found<br> | ||
Coincidentially there are a few commands that preserves his ID in between | Coincidentially there are a few commands that preserves his ID in between emulator types and revisions, most probably is because are the first commands implemented and the variable ID given to them is a very low value, so always was kept at a low position in the commands list and was not disturbed by the modifications made to the other commands. | ||
=== Command 0x00 (netemu 3.40 up to 4.88) === | === Command 0x00 (netemu 3.40 up to 4.88) === | ||
*Valid values found | *Valid values found | ||
**0 = ? (used by SCPS-18011 Um Jammer Lammy, and SLPS-01818 Langrisser IV & V Final Edition [Disc1of2]) | **0 = ? (used by SCPS-18011 Um Jammer Lammy, and SLPS-01818 Langrisser IV & V Final Edition [Disc1of2]) | ||
In Um Jammer Lammy is used together with command 0x13, so it was a bit doubtful if it was a mistake. But Langrisser IV & V Final Edition [Disc1of2] uses it too and is the only command used by this disc, so it "should" do something | In Um Jammer Lammy is used together with command 0x13, so it was a bit doubtful if it was a mistake. But Langrisser IV & V Final Edition [Disc1of2] uses it too and is the only command used by this disc, so it "should" do something. Um Jammer Lammy in netemu 3.40 was fixed only with command 0x0/0x0 (id/data) | ||
*Um Jammer Lammy (SCPS-18011) uses somewhat new external config revision (11580) in official classic's external config, but only uses command 0x13. Keep in mind the game was released Febuary 27, 2008, so package was possibly updated with new config at some point, and then in internal table, so maybe it once had a different config command in config table and 0x00 nullified it. Langrisser IV (SLPS-01818) has old config revision (5713) and uses command 0x03 set to 0x3E8, so just default. Maybe internal config for Langrisser IV is empty config just to also nullify external config? --[[User:Mrjaredbeta|Mrjaredbeta]] ([[User talk:Mrjaredbeta|talk]]) 03:32, 1 September 2023 (CEST) | |||
=== Command 0x01 (netemu 3.40 up to 4.88) === | === Command 0x01 (netemu 3.40 up to 4.88) === | ||
Line 604: | Line 275: | ||
=== Command 0x02 (netemu 3.40 up to 4.88) === | === Command 0x02 (netemu 3.40 up to 4.88) === | ||
The command data contains an offset that points to an area where are stored a list of sectors (4 bytes each), | There are only 3 games using this command and are libcrypt protected games:, Crash Team Racing (SCES-02105), MediEvil (SCES-00311), and Vagrant Story (SLES-02754)<br> | ||
The command data contains an offset that points to an area where are stored a list of sectors (4 bytes each). When the emulator starts reading the list it doesnt knows how long is it so it reads groups of 4 bytes consecutivelly until it finds the value 00000000 that works as a terminator, the presence of this terminator at the end of the sector list is mandatory. Worth to note that list is more extensive than redump libcrypt one, but they match to some extend. Probably redump store only sectors really needed to run game correctly, while Sony decided to keep them all. Command is used only with LC1 games (Redump is wrong about medievil, is LC1).<br> | |||
The libcrypt protection is related with subchannel data stored by sectors, in redump.org this data is managed with the SBI files, displayed in a hexeditor view in each specific game page. If we convert the data from the official format to decimal and we compare it with the sector numbers in the redump.org SBI file it can be seen all the libcrypt protected sectors from the SBI file are included in the official format<br> | The libcrypt protection is related with subchannel data stored by sectors, in redump.org this data is managed with the SBI files, displayed in a hexeditor view in each specific game page. If we convert the data from the official format to decimal and we compare it with the sector numbers in the redump.org SBI file it can be seen all the libcrypt protected sectors from the SBI file are included in the official format<br> | ||
The official format seems to include a lot more sectors which purpose is unknown<br> | The official format seems to include a lot more sectors which purpose is unknown<br> | ||
There seems to be way to supply that data/command from external file. Some research by "Fedor Wearing A Fedora" [https://www.psx-place.com/threads/ps1-libcrypt-support-on-ps3-official-emus-research-thread.35836/page-13#post-318218 here] and [https://www.psx-place.com/threads/ps1-libcrypt-support-on-ps3-official-emus-research-thread.35836/page-13#post-318506 here]<br> | There seems to be way to supply that data/command from external file. Some research by "Fedor Wearing A Fedora" [https://www.psx-place.com/threads/ps1-libcrypt-support-on-ps3-official-emus-research-thread.35836/page-13#post-318218 here] and [https://www.psx-place.com/threads/ps1-libcrypt-support-on-ps3-official-emus-research-thread.35836/page-13#post-318506 here]<br> | ||
<u>Crash Team Racing</u> [http://redump.org/disc/798/ SCES-02105] (at absolute offset 0x1627E4 in ps1_netemu.self 4.88) | <u>Crash Team Racing</u> [http://redump.org/disc/798/ SCES-02105] (at absolute offset 0x1627E4 in ps1_netemu.self 4.83-4.88) | ||
<small><pre style="height:410px"> | <small><pre style="height:410px"> | ||
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | ||
Line 750: | Line 422: | ||
</pre></small> | </pre></small> | ||
<u>MediEvil</u> [http://redump.org/disc/592/ SCES-00311] (at absolute offset 0x16298C in ps1_netemu.self 4.88) | <u>MediEvil</u> [http://redump.org/disc/592/ SCES-00311] (at absolute offset 0x16298C in ps1_netemu.self 4.83-4.88) | ||
<small><pre style="height:275px"> | <small><pre style="height:275px"> | ||
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | ||
Line 839: | Line 511: | ||
</pre></small> | </pre></small> | ||
<u>Vagrant Story</u> [http://redump.org/disc/9978/ SLES-02754] (at absolute offset 0x162A8C in ps1_netemu.self 4.88) | <u>Vagrant Story</u> [http://redump.org/disc/9978/ SLES-02754] (at absolute offset 0x162A8C in ps1_netemu.self 4.83-4.88) | ||
<small><pre style="height:350px"> | <small><pre style="height:350px"> | ||
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | ||
Line 964: | Line 636: | ||
Value is integer that is later converted to double float using fcfid, and truncated to single precision by frsp.<br> | Value is integer that is later converted to double float using fcfid, and truncated to single precision by frsp.<br> | ||
I'm not familiar with CELL floating point unit quirks, but value could be just single precision float from the start, why complicate that so much?<br> | I'm not familiar with CELL floating point unit quirks, but value could be just single precision float from the start, why complicate that so much?<br> | ||
*Possible disc read speed delay or adjustment. Larger value results in slower loading times. --[[User:Mrjaredbeta|Mrjaredbeta]] ([[User talk:Mrjaredbeta|talk]]) 03:21, 1 September 2023 (CEST) | |||
'''Custom Usage:''' | |||
*Param 0x384 (900d) fixes Vampire Hunter D (SLUS-01138) hanging issues. | |||
*Param 0x1F4 (500d) fixes Medievil 2 audio and hanging issues. | |||
=== Command 0x04 (netemu 3.40 up to 4.88) === | === Command 0x04 (netemu 3.40 up to 4.88) === | ||
*Valid values found: 0x4, 0x7, 0x14 (20d), 0x46 (70d), 0x64 (100d), 0xC8 (200d), 0xFFFFFF38 ( | *Valid values found: 0x4, 0x7, 0x14 (20d), 0x46 (70d), 0x64 (100d), 0xC8 (200d), 0xFFFFFF38 (-200d) | ||
*Default value: 0 | *Default value: 0 | ||
*_xcdrom_thread related. | *_xcdrom_thread related. | ||
Possible seek delay/adjustment.<br> | |||
'''Custom Usage:''' | |||
*Param 0x64 and above fixes Transformers: Beast Wars Transmetals (SLUS-01160). 0x14 also gets past initial main menu screen, but hangs when loading into a stage. Param 0xC8 is probably safest. | |||
=== Command 0x05 (netemu 3.40 up to 4.88) === | === Command 0x05 (netemu 3.40 up to 4.88) === | ||
Line 979: | Line 657: | ||
*Default value: 0 | *Default value: 0 | ||
*_xcdrom_thread related. | *_xcdrom_thread related. | ||
'''Custom Usage:''' | |||
*Param 0x01 fixes Shrek Treasure Hunt (SLUS-01463) minigame loading screen hangs. | |||
*Param 0x01 fixes Fear Effect (SLUS-00920) hang when pressing START at menu screen. | |||
=== Command 0x07 (netemu 4.83 up to 4.88) === | === Command 0x07 (netemu 4.83 up to 4.88) === | ||
*Default value: 0 | *Default value: 0 | ||
*_xcdrom_thread related. | *_xcdrom_thread related. | ||
'''Custom Usage:''' | |||
*Param 0x01 fixes Fear Effect (SLUS-00920) other issues in main menu, such as graphical corruption in options screens, and returning to options screen after viewing credits. | |||
=== Command 0x08 (netemu 3.40 up to 4.88) === | === Command 0x08 (netemu 3.40 up to 4.88) === | ||
Line 995: | Line 678: | ||
=== Command 0x0E (netemu 4.83 up to 4.88) === | === Command 0x0E (netemu 4.83 up to 4.88) === | ||
*Or command 0x0C (netemu 3.40) | |||
*Default value: 0x1F4 | *Default value: 0x1F4 | ||
*_xcdrom_thread related. | *_xcdrom_thread related. | ||
=== Command 0x0F (netemu 4.83 up to 4.88) === | === Command 0x0F (netemu 4.83 up to 4.88) === | ||
*Or command 0x0D (netemu 3.40) | |||
*Default value: 0xFA | *Default value: 0xFA | ||
*_xcdrom_thread related. | *_xcdrom_thread related. | ||
Line 1,009: | Line 694: | ||
*Default value: 0x7D | *Default value: 0x7D | ||
*_xcdrom_thread related. | *_xcdrom_thread related. | ||
=== Command 0x12 (netemu 4.83 up to 4.88) === | |||
*Or command 0x10 (netemu 3.40) | |||
Command value are flags/settings to alter cdrom behavior. | |||
*0x800 = Different code path for MotorOn/Pause/SetSession cdrom commands. // Need more work, flag affect more than that. | |||
=== Command 0x13 (netemu 4.83 up to 4.88) === | === Command 0x13 (netemu 4.83 up to 4.88) === | ||
*Default value: 0 | *Default value: 0 | ||
*MDEC related? | |||
'''Custom Usage:''' | |||
*Param 0x01 fixes Roland Garros French Open 2001 (SLES-03449) hang when loading into a match. | |||
*Param 0x01 fixes Fear Effect (SLUS-00920) hang when pressing START at menu screen (sometimes). | |||
=== Command 0x14 (netemu 4.83 up to 4.88) === | === Command 0x14 (netemu 4.83 up to 4.88) === | ||
Line 1,021: | Line 715: | ||
=== Command 0x16 (netemu 4.83 up to 4.88) === | === Command 0x16 (netemu 4.83 up to 4.88) === | ||
*Default value: 0 | *Default value: 0 | ||
*DMA timing related. | |||
'''Custom Usage:''' | |||
*Param 0x32 is enough to fix International Superstar Soccer (SLES-02550) black screen after PlayStation logo. | |||
*Param 0x08 is enough to fix Vampire Hunter D’s main menu flashing. | |||
=== Command 0x17 (netemu 4.83 up to 4.88) === | === Command 0x17 (netemu 4.83 up to 4.88) === | ||
*Or command 0x0B (netemu 1.70) | |||
*Or command 0x0A (netemu 2.10) | |||
*Or command 0x15 (netemu 3.40 up to 3.55) | *Or command 0x15 (netemu 3.40 up to 3.55) | ||
*Or command 0x0B (emu | *Or command 0x0B (emu 1.70 up to 4.88) | ||
*Or command 0x07 (newemu 2.10) | |||
*Or command 0x0A (newemu 3.40 up to 4.88) | *Or command 0x0A (newemu 3.40 up to 4.88) | ||
This is the libcrypt magic word. This command is used only in 3 games (SCES_016.95, SLES_019.07, SLES_013.01). see: [[PS1 Custom Patches]] | This is the libcrypt magic word. This command is used only in 3 games (SCES_016.95, SLES_019.07, SLES_013.01). see: [[PS1 Custom Patches]] | ||
In ps1_netemu there is | In ps1_netemu there is possibility to setup that command from one of ps1 classic files (PSISOIMG0000 / PSTITLEIMG000000 related). | ||
When value is not zero is returned by emulator when game try to read cop0r3 (BPC) register. When value is 0 (default), emulator return real BPC content. | |||
* It seems there is a problem with LC games using the third scheme mentioned [https://problemkaputt.de/psx-spx.htm#cdromprotectionlibcrypt here]. After reading the data contents of subchannel Q, the CRC-16 value is not read at all, but calculated on its own by the driver instead. It does break LC games using this particular scheme (web-found confirmed issues with Ape Escape and Final Fantasy VIII). All three games that are meant to work with this command does use these LC sectors. I think this command was meant to resolve this issue, just a guess.--[[User:Agrippa|Agrippa]] ([[User talk:Agrippa|talk]]) 20:06, 12 June 2022 (UTC) | |||
=== Command 0x18 (netemu 4.83 up to 4.88) === | === Command 0x18 (netemu 4.83 up to 4.88) === | ||
Substrat cycles from mdec_block_copy_out_callback delta. When mdec is decoding blocks, copy out happen on every completed 6th block. This is hardcoded to take 0xB00 (2816) cycles in ps1_netemu. By using this config we can make this value less than default, which in turn "overclock" mdec decoding as every 6xblock will be decoded faster. Duckstation by default use value 0xA80 (2688 (448 x 6 blocks)). So to make config that will replicate this behavior we need set config value to 0x80 (0xB00 - 0x80 = 0xA80). | |||
*Default value: 0 | *Default value: 0 | ||
*Valid values range: 0x000 - 0xB00 | |||
*Higher values are ignored and 0 is set (just like when you use 0xB00 value), making MDEC instant. | |||
=== Command 0x19 (netemu 4.83 up to 4.88) === | === Command 0x19 (netemu 4.83 up to 4.88) === | ||
Line 1,042: | Line 750: | ||
=== Command 0x1B (netemu 4.83 up to 4.88) === | === Command 0x1B (netemu 4.83 up to 4.88) === | ||
*Default value: 0x3E8 | *Default value: 0x3E8 | ||
Multiplier for GTE commands cycles. Value from config is multiplied by 256, and then divided by 1000. | |||
For example Battle Arena Toshinden use 0xC8 which result in 0x33(51) as value that is later used. | |||
Default value 0x3E8 end as 0x100(256). | |||
=== Command 0x1C (netemu 4.83 up to 4.88) === | |||
*Or command 0x18 (netemu 3.40) | |||
*Or command 0x1A (netemu 3.55 ?) | |||
*Or command 0x02 (netemu 1.70) - possibly different command | |||
Param flags: | |||
*1 = unk. | |||
*2 = Set Vibration to Off (menu to set it to On is still accessible, but command seems to also skip initializing of vibration internal struct/settings). | |||
=== Command 0x1D (netemu 4.83 up to 4.88) === | |||
*Default value: 0 | |||
*Correct values 0 / 1 / 2 | |||
Config seems to setup default gamepads layout for multitap. | |||
*0 = <0, 2, 4, 6, 1, 3, 5, 7> | |||
*1 = <0, 2, 3, 4, 1, 5, 6, 7> | |||
*2 = <0, 1, 2, 3, 4, 5, 6, 7> | |||
Sync order of controllers is always the same regardless of parameter set (1/1-A, 2/2-A, 1-B, 2-B, 1-C, 2-C, 1-D). Therefore, change is only reflected internally in emulated game. For example, Crash Bash needs parameter 2 for controllers to be set properly in game, but order in which controllers physically connect is not changed. | |||
=== Command 0x1E (netemu 4.83 up to 4.88) === | === Command 0x1E (netemu 4.83 up to 4.88) === | ||
*Default value: 0x7D0 | *Default value: 0x7D0 | ||
*xPadThread related. | *xPadThread related. | ||
=== Command 0x20 (netemu 4.83 up to 4.88) === | |||
GPU multi command (bifield) | |||
*Default value: 0 | |||
*0x08 = Always set Vertical Interlace bit in GPUSTAT to 0 on GP1 (08h) command. | |||
*0x40 = Is not exactly known what happen under the hood, but this command allow to play 50Hz titles in 60Hz with correct speed. | |||
=== Command 0x21 (netemu 4.83 up to 4.88) === | === Command 0x21 (netemu 4.83 up to 4.88) === | ||
Line 1,054: | Line 790: | ||
*Default value: 0x3E8 | *Default value: 0x3E8 | ||
*PS1 GPU related. | *PS1 GPU related. | ||
Seems to fix slowdown in Rapid Racer (SCPS-10060) with value 0x320. | |||
=== Command 0x23 (netemu 4.83 up to 4.88) === | === Command 0x23 (netemu 4.83 up to 4.88) === | ||
Line 1,071: | Line 808: | ||
*PS1 GPU related. | *PS1 GPU related. | ||
=== Command 0x2B(netemu 4.83 up to 4.88) === | === Command 0x2B (netemu 4.83 up to 4.88) === | ||
*Default value: 0 | *Default value: 0 | ||
*PS1 GPU related. | *PS1 GPU related. | ||
Line 1,082: | Line 819: | ||
*Default value: 0 | *Default value: 0 | ||
*PS1 GPU related. | *PS1 GPU related. | ||
=== Command 0x31 (netemu 4.83 up to 4.88) === | |||
GPU multi command (bitfield) | |||
*0x02 = Enable Vertical Interlace bit in GP1 (08h) command in SPE writes (in renderer only). Emulator by default use hack where VI bit is ALWAYS disabled in spe. | |||
Note from nocash docs about Vertical Interlace: ''"'''Interlace must be enabled to see all lines in 480-lines mode''' (interlace is causing ugly flickering, so a non-interlaced low resolution image is typically having better quality than a high resolution interlaced image, a pretty bad example are the intro screens shown by the BIOS).''"<br> | |||
This suggest that games which eventually need 0x31, 0x02 will be ones that send GP1 commands with active bit 2(Vertical Resolution 1=480) and 5(Vertical Interlace) at the same time. Otherwise image will be cropped, or badly interlaced. FF8 use this on "Published by..." screen, you can notice weird interlacing when subtitles fade-in without command. | |||
=== Command 0x32 (netemu 4.83 up to 4.88) === | === Command 0x32 (netemu 4.83 up to 4.88) === | ||
Line 1,107: | Line 850: | ||
=== Command 0x38 (netemu 4.83 up to 4.88) === | === Command 0x38 (netemu 4.83 up to 4.88) === | ||
*Or command 0x2C in ps1_netemu.self 3.40 | |||
*Or command 0x2E in ps1_netemu.self 3.55 ? | |||
*Valid values found: | *Valid values found: | ||
**1 = | **0/1/2/3 | ||
if (cfg == 0) | |||
stay_netemu | |||
if (boot_not_from_disc_drive) | |||
if (cfg & 2) | |||
boot_newemu | |||
if (boot_from_disc_drive) | |||
if (cfg & 1) | |||
boot_ps1emu | |||
else | |||
stay_netemu | |||
// Boot is considered to be from disc if argv with game path is empty. Which make 0x38 with param 0x01 inaccessible, because there is no way to start disc game with netemu in official way (excluding games that ps1_emu launch with 0x15 cmd to ps1_netemu). | |||
=== Command 0x3B (netemu 4.83 up to 4.88) === | |||
PS1 SPU DMA related config. Seems to change some cycles calculation. | |||
*Default value: 0 | |||
*Valid values: 0/1 | |||
== | == Ps1_emu Commands Info == | ||
=== Command 0x15 (ps1emu 4.83 up to 4.88) === | |||
*Valid values found: | |||
**3 (launch game using ps1_netemu) | |||
**Different values are ignored | |||
== Ps1_newemu Commands Info == | |||
=== Command 0x18 (ps1newemu 4.83 up to 4.88) === | |||
Supposed to launch game using different emulator, but all paths do nothing. | |||
*Valid values found: | |||
**3 (Do nothing, but with print! [https://imgflip.com/i/7x4j2p 1]) | |||
**Different values do nothing | |||
== Known bugs == | |||
=== ps1_netemu.elf === | |||
==== Cdr int reads with nonstandard index ==== | |||
Emulator ignore interrupt flag register and interrupt enable register reads if cdrom index is 2, or 3. Reads like that are undocummented behavior, but confirmed to be successful on real hardware. Also Nocash docs, and Duckstation source handle that correctly, and i remember there are games which used that. | |||
== | 0xD81F0 read_0x1F801803: | ||
0xD81F0 lwz r0, (.1F801800 - 0x2E8480)(r8) | |||
0xD81F4 clrlwi r0, r0, 30 # cdrom.index & 3 | |||
0xD81F8 cmpwi cr7, r0, 0 # cdrom.index = 0 | |||
0xD81FC beq cr7, read_interrupt_enable_register | |||
0xD8200 cmpwi cr7, r0, 1 # cdrom.index = 1 | |||
0xD8204 beq cr7, read_interrupt_flag_register | |||
0xD8208 li r3, 0 # return 0 if index was 2 or 3 | |||
0xD820C lwz r7, off_1BC0D4 | |||
0xD8210 clrldi r3, r3, 32 | |||
0xD8214 dcbt 0, r7 | |||
0xD8218 blr | |||
This can be fixed by simple patch from | |||
0xD81F4 clrlwi r0, r0, 30 #hex 54 00 07 BE | |||
0xD8264 clrlwi r0, r0, 30 #hex 54 00 07 BE | |||
to | |||
0xD81F4 clrlwi r0, r0, 31 #hex 54 00 07 FE | |||
0xD8264 clrlwi r0, r0, 31 #hex 54 00 07 FE | |||
This change cdrom.index & 3, into cdrom.index & 1. This way index 2, and 3 will be respected as 0, and 1. Sadly there is no easy hex pattern, so patch need to be done manually. Memory offsets for 4.86. | |||
==== Bad encoding of malformed conditional branch 0 ==== | |||
Emulator don't ignore few bits, and expect they are 0. While real hardware seems to don't care about them. | |||
<pre> | <pre> | ||
. | 31..26 |25..21|20..16|15..11|10..6 | 5..0 | | ||
. | 6bit | 5bit | 5bit | 5bit | 5bit | 6bit | | ||
. | -------+------+------+------+------+--------+------------ | ||
. | 000001 | rs | 0XXX0| <--immediate16bit--> | bltz | ||
000001 | rs | 0XXX1| <--immediate16bit--> | bgez | |||
000001 | rs | 1XXX0| <--immediate16bit--> | bltzal | |||
. | 000001 | rs | 1XXX1| <--immediate16bit--> | bgezal | ||
. | |||
</pre> | </pre> | ||
Problem start when bits 17,18,19 are not zero. Emulator don't clear those bits, and explicitly check only for 0x0,0x1,0x10,0x11. | |||
<pre> | <pre> | ||
. | r24 hold 20..16 bits extracted from opcode. | ||
. | |||
0x107958 bcondz_107958: # CODE XREF: r3000_opcode_table+12C↑j | |||
0x107958 cmpwi cr7, r24, 1 # jumptable 001067D4 case BcondZ | |||
0x10795C beq cr7, loc_107E98 | |||
0x107960 cmplwi cr7, r24, 1 | |||
0x107964 blt cr7, loc_107E78 | |||
0x107968 cmpwi cr7, r24, 0x10 | |||
0x10796C beq cr7, loc_1082A4 | |||
0x107970 cmpwi cr7, r24, 0x11 | |||
0x107974 beq cr7, loc_10821C | |||
</pre> | </pre> | ||
Correct solution here will be patch to AND r24 with 0x11 first, to clear meaningless bits before comparison. | |||
This is reason why emulator fail this "Branch Advance" CPU test: https://emulation.gametechwiki.com/index.php/PS1_Tests#CPU . Possibly standard "Branch" test is failed for the same reason. | |||
== GTE commands == | |||
List of GTE commands is available at 0x001B345C in ps1_netemu 4.86. List include following data {CommandFunctionOPD, Cycles}. | |||
Emulator handle only commands listed below (CMD, addr in emu). | |||
<pre> | <pre> | ||
.GTE_RTPS 0xC4500 | |||
.GTE_MVMVA 0xC4C00 | |||
.GTE_SQR_sf 0xC5168 | |||
.GTE_NCLIP 0xC527C | |||
.GTE_AVSZ3 0xC5338 | |||
.GTE_AVSZ4 0xC5420 | |||
.GTE_OP_sf 0xC5518 | |||
.GTE_GPF_sf 0xC5678 | |||
.GTE_GPL_sf 0xC58C8 | |||
.GTE_RTPT 0xC6288 | |||
.GTE_NCT 0xC7710 | |||
.GTE_NCS 0xC8AD8 | |||
.GTE_CC 0xC91E8 | |||
.GTE_NCCT 0xC9748 | |||
.GTE_NCCS 0xCADF8 | |||
.GTE_DCPL 0xCB5F8 | |||
.GTE_DPCS 0xCBAD8 | |||
.GTE_CDP 0xCBF80 | |||
.GTE_NCDT 0xCC760 | |||
.GTE_NCDS 0xCE5F8 | |||
.GTE_INTPL 0xCF078 | |||
.GTE_DPCT 0xCF540 | |||
</pre> | </pre> | ||
== | == CD Drive Commands == | ||
List of CD commands is available at 001B365C in ps1_netemu 4.86. List include following data {Respond INT count (minus INT3), CMD_nr, Function OPD}. Emulator handle only commands listed below (CMD, addr in emu). | |||
<pre> | |||
.cdr_cmd_Sync 0xD8290 | |||
.cdr_cmd_Reset 0xD8368 | |||
.cdr_cmd_Test 0xD8478 | |||
.cdr_cmd_Getparam 0xD8798 | |||
.cdr_cmd_Setmode 0xD8918 | |||
.cdr_cmd_Init 0xDBC48 | |||
.cdr_cmd_MotorOn 0xDD0C0 | |||
.cdr_cmd_SeekP 0xDD3D0 | |||
.cdr_cmd_Play 0xDD67C | |||
.cdr_cmd_ReadS 0xDD8E8 | |||
.cdr_cmd_Backward 0xDDBD0 | |||
.cdr_cmd_Pause 0xDDF58 | |||
.cdr_cmd_GetTD 0xDE1F8 | |||
.cdr_cmd_Getstat 0xDE598 | |||
.cdr_cmd_GetlocP 0xDE728 | |||
.cdr_cmd_ReadN 0xDEDD0 | |||
.cdr_cmd_SetSession 0xDF130 | |||
.cdr_cmd_Mute 0xDF970 | |||
.cdr_cmd_SeekL 0xDFBAC | |||
.cdr_cmd_Setloc 0xDFE58 | |||
.cdr_cmd_Demute 0xE03E0 | |||
.cdr_cmd_Setfilter 0xE0618 | |||
.cdr_cmd_Forward 0xE0878 | |||
.cdr_cmd_GetlocL 0xE0B98 | |||
.cdr_cmd_Stop 0xE0FF0 | |||
.cdr_cmd_GetTN 0xE1298 | |||
.cdr_cmd_GetID 0xE1544 | |||
.cdr_cmd_ReadTOC 0xE1C58 | |||
Commands 0x17, 0x18, 0x1D are handled as cmd_Sync. Commands above 0x1E seems to be not supported. | |||
</pre> |
Latest revision as of 22:24, 4 June 2024
Memory Map[edit source]
For now here, i will move when finished. Based on ps1_netemu 4.86.
- emu memory 0x770780 - 0x97077F = PS1 RAM (80000000 - 801FFFFF)
- emu memory 0x970780 - 0x970B7F = PS1 Scratchpad (1F800000 - 1F8003FF)
- emu memory 0x970B80 - 0xD70B80 = PS1 ROM (1FC00000 - 1FFFFFFF) (only 512kb used)
[edit source]
Highly recommended to visit site below to understand this info: http://problemkaputt.de/psx-spx.htm#gpustatusregister http://problemkaputt.de/psx-spx.htm#gpudisplaycontrolcommandsgp1 Offset in emu memory (ps1_netemu 4.86) | name | info 001B39D0 GP0_commands_table {ParamsCount, OPD} 0x10C5E4 GP1_reset_gpu 0x10C88C GP1_reset_command_buffer 0x10C940 GP1_acknowledge_gpu_IRQ1 0x10C968 GP1_display_enable 0x10C9A4 GP1_dma_direction___data_request 0x10CA20 GP1_display_mode 0x10CAEC GP1_get_gpu_info 0x10CB00 GP1_horizontal_display_range 0x10CB30 GP1_vertical_display_range 0x10CB60 GP1_start_of_display_area_in_VRAM 0x10CBD8 dma_dir_GPUREADtoCPU 0x10CD34 dma_dir_Off Emulated GPU important data addresses. 0xD70BE4 E2_REG (used for immediate response by GPUINFO request)\ 0xD70BE8 E3_REG (used for immediate response by GPUINFO request) \ Set by GP0 Ex cmds. 0xD70BEC E4_REG (used for immediate response by GPUINFO request) / 0xD70BF0 E5_REG (used for immediate response by GPUINFO request)/ 0xD70C1C GP1_get_gpu_info_request (data supplied in GP1 0x10-0x1F cmd) 0xD70C20 GPUSTAT_r (PS1 GPU status register 1F801814 in read mode) 0xD70C24 dma_dir__data_req (from GP1 0x04 cmd) 0xD70C28 - 0xD70DA0 UNCONFIRMED seems to be GP0 fifo on PPU side, but need some reversing to confirm. 0xD70DA4 display_enable_request (based on GP1 0x03 cmd) 0xD70DA8 start_of_display_area_in_VRAM__X (from GP1 0x05 cmd) 0xD70DAC start_of_display_area_in_VRAM__Y (from GP1 0x05 cmd) 0xD70DB0 H_display_range_X1 (from GP1 0x06 cmd) 0xD70DB4 H_display_range_X2 (from GP1 0x06 cmd) 0xD70DB8 V_display_range_Y1 (from GP1 0x07 cmd) 0xD70DBC V_display_range_Y2 (from GP1 0x07 cmd) 0xD70DC0 H_resolution_1 (from GP1 0x08 cmd) 0xD70DC4 V_resolution (from GP1 0x08 cmd) 0xD70DC8 video_mode___is_pal (from GP1 0x08 cmd) 0xD70DCC display_area_color_depth (from GP1 0x08 cmd) 0xD70DD0 vertical_interlace (from GP1 0x08 cmd) 0xD70DD4 H_resolution_2 (from GP1 0x08 cmd) 0xD70DD8 reverse_flag (from GP1 0x08 cmd) 0xD70DEC display_enable (from GP1 0x03 cmd) 0xD70DF0 display_params_change_requested (1 when old display_mode != new from cmd 0x08) 0xD70DF4 display_mode (whole 8 bits of GP1 0x08) Config GPU related commands. Some values are not directly from cfg (are shifted before writing here, etc.). 0xD70E14 set_by_cmd_21 0xD70E18 set_by_cmd_22 0xD70E1C set_by_cmd_23 0xD70E20 set_by_cmd_24 0xD70E24 set_by_cmd_25 0xD70E28 set_by_cmd_26 0xD70E2C set_by_cmd_27 0xD70E30 set_by_cmd_28 0xD70E34 set_by_cmd_29 0xD70E38 set_by_cmd_2B 0xD70E3C set_by_cmd_2C 0xD70E40 set_by_cmd_2D 0xD70E44 set_by_cmd_2E 0xD70E48 set_by_cmd_2F 0xD70E4C set_by_cmd_20 0xD70E50 set_by_cmd_31 0xD70E54 set_by_cmd_30
ps1_emu vs ps1_netemu GPU emulation differences[edit source]
In some cracktros (Spyro 3, Sydney 2000, NFS Porsche 2000) the GP0 command E4h (E4080200) draws the image on the wrong coordinates, causing the frozen image of the zoomed PS1 licence screen. According to this info, that command does make use of the newer 2MB VRAM GPU coordinates. Restricting the drawing area to the lower coordinates does fix the image. It looks like a lot of emulators are affected by this, either the Sony ones (ps1_emu on PS3, PS1 on PS2 hardware emulator, POPS on PSP) or the homebrew pSX 1.13. The ps1_netemu is displaying the image correctly. Does it mean the ps1_netemu emulate a different, newer GPU or just increase the emulation accuracy in general (assuming these cracktros work fine even on the oldest PSX released EDIT: I have found reports they are picky even on the original PS1 hardware too.)?
- Yes, this should fail also on old PS1 GPU. I can also confirm that PS1DRV (at least before deckard PS2 models) emulate old GPU model.
As for PS3. ps1_emu, and ps1_newemu emulate old GPU, ps1_netemu emulate new GPU at least partially. Also small tip, all emulators have pair of 2 embed SPE ELFs. One is SPU emulator, second is GPU emulator. All of them have debug symbols.
ps1_emu
.text:000014D0 E4_cmd: .text:000014D0 il r56, 0x3FF .text:000014D4 hbrr loc_1504, loc_403C .text:000014D8 rotmi r54, r12, -10 # r12 = whole 32 bit command # r54 = is command shifted by 10 to skip # x-cord. So now first bits are y-cord. .text:000014DC lqr r51, xmmword_E520 .text:000014E0 and r55, r12, r56 # x-cord and with whole 10 bits. .text:000014E4 cwd r53, 0xF0+var_F0(sp) .text:000014E8 cwd r49, 0xF0+var_F0+8(sp) .text:000014EC ai r52, r55, 1 .text:000014F0 andi r50, r54, 0x1FF # y-cord and with 0x1FF, so only 9 bits.
ps1_netemu
.text:00003338 E4_cmd: .text:00003338 rotmi r18, r12, -10 # r12 = whole 32 bit command # r18 = is command shifted by 10 to skip # x-cord. So now first bits are y-cord. .text:0000333C hbrr loc_3384, loc_3328 .text:00003340 il r19, 0x3FF .text:00003344 lqr r39, xmmword_150D0 .text:00003348 il r8, 0x200 .text:0000334C lqr r33, xmmword_150E0 .text:00003350 and r44, r12, r19 # x-cord and with whole 10 bits. .text:00003354 cwd r42, arg_0+0xC(sp) .text:00003358 and r43, r18, r19 # y-cord and with 0x3FF, so whole 10 bits.
---kozarovv.
PS1 I/O handlers[edit source]
List of functions that are responsible for interpreting HW registers reads/writes. Based on 4.86 ps1_netemu.
timers_hwreg_write_handler 0xC2CC0 timers_hwreg_read_handler 0xC2F80 dma_hw_read_handler 0xD09C8 dma_hw_write_handler 0xD0E18 spu_hwreg_write_handler 0xD1E68 spu_hwreg_read_handler 0xD1FF8 joy_hwreg_write_handler 0xD44A8 joy_hwreg_read_handler 0xD49F8 sio_hwreg_write_handler 0xD758C sio_hwreg_read_handler 0xD7620 cdr_hwreg_read_handler 0xD80A0 cdr_hwreg_write_handler 0xE8598 mdec_hwreg_write_handler 0xE9A18 mdec_hwreg_read_handler 0xEA2F0 i_ctrl_hwreg_read_handler 0x10577C i_ctrl_hwreg_write_handler 0x1063AC gpu_hwreg_read_handler 0x10BF40 gpu_hwreg_write_handler 0x10C48C
Experimental Patches[edit source]
This patches are intended to be applyed to the PS1 emulators
Disable Dithering[edit source]
Always set bit 9 in GP0 E1 command to 0. Patches apply to SPE PS1 GPU emulation program. Based on 4.86, but should be valid for all firmwares since 4.6x
For ps1_emu.elf
search for: 23 EC A4 04 23 E3 3B 85 33 7E 26 00 32 05 86 00 0F 3D C6 11 replace to: 23 EC A4 04 23 E3 3B 85 33 7E 26 00 32 05 86 00 40 80 00 11
For ps1_netemu.elf
search for: 7C 38 41 94 20 7F F4 94 0F 3D C6 3C 12 7F F3 8A replace to: 7C 38 41 94 20 7F F4 94 40 80 00 3C 12 7F F3 8A
For ps1_newemu.elf
search for: 20 7F FD 4C 23 9D C5 85 32 05 B2 80 12 05 B2 0B 0F 3D C6 58 replace to: 20 7F FD 4C 23 9D C5 85 32 05 B2 80 12 05 B2 0B 40 80 00 58
Patch for rpcs3 (newemu only) for testing purpose.
Version: 1.2 SPU-f3d8be702bf4cb8545656e37c29fcc6201a57991: "Disable Dithering": Games: All: All: [ All ] Author: "kozarovv" Patch Version: 1.0 Patch: - [ be32, 0xFB0, 0x40800058 ]
Allow non encrypted ISO.BIN.EDAT and skip signature check (RPCS3 only)[edit source]
For easier config testing. Patch allow to use unencrypted ISO.BIN.EDAT so we don't need to mess with klic. Also ECDSA signature at the end of file is no longer required. So we can ftp configs as is, for faster testing. Warning! This patch break official ps1_classics.
ps1_netemu.elf 4.86-4.90 offset in raw hex (for Hxd, etc.)
0xDDD6C replace 48 07 14 21 to 38 60 00 00 0xE13C4 replace 60 00 00 00 to 38 60 00 00
GTE Automatic Widescreen Hack[edit source]
Automatic widescreen without per game patches. Work only for 3D elements (like 95% of available widescreen patches).
Tested on both RPCS3 and real PS3 (CFW only, but can be added to hen).
ps1_netemu.elf 4.86 - 4.91 offsets in raw hex (for Hxd, etc.)
0x2BDA4 original code: 7C 69 1B 78 3C 60 80 54 2F 89 00 00 60 63 00 10 40 9E 00 14 3C 60 80 54 60 63 00 02 7C 63 07 B4 4E 80 00 20 A0 09 00 02 2F 80 00 00 41 9E FF F0 C0 02 A3 D8 FF 81 00 00 41 9D FF DC C0 02 A3 DC 38 60 00 00 FF 81 00 00 41 9C FF CC D0 29 00 6C 4B FF FF CC replace to: 78 C0 F8 42 78 C6 F0 82 7C C6 02 14 7D 08 32 14 48 0C 47 7E 78 E9 F8 42 78 E7 F0 82 7C E9 3A 14 7C C6 3A 14 48 0C 65 66 79 00 F8 42 79 08 F0 82 7D 08 02 14 7C C6 42 14 48 0C 69 0A 79 00 F8 42 79 08 F0 82 7D 08 02 14 7C C6 42 14 48 0C 6C 6A 60 00 00 00 0xB4778 original code: 7D 08 32 14 replace to: 48 03 BD A6 0xB6560 original code: 7C C6 3A 14 replace to: 48 03 BD BA 0xB6904 original code: 7C C6 42 14 replace to: 48 03 BD CE 0xB6C64 original code: 7C C6 42 14 replace to: 48 03 BD E2
Ps1_netemu Commands Info[edit source]
External Configs[edit source]
Loading external commands is be possible in ps1_netemu. From this we can also figure out that sony call those configs "ad hoc params" which can be little bit misleading. Emulator expect them inside ISO.BIN.EDAT file. Offset depend if "optional header" exist or not. Values are little endian. The offsets below are the offsets from the start of the PSISOIMG section. This data starts at absolute file offset 0x424 for single disk games that do not use a PSTITLEIMG section. For games that do have a PSTITLEIMG section, the absolute offset will be shifted by 0x400 bytes, i.e. to offset 0x824 and similar.
- Offset 0x424 Config revision in bcd format, that need to be higher than DB from emu (11624 for 4.86). Safe to use 0x200000.
- Offset 0x42C first config command
- Offset 0x430 param for first command
- This repeats 8 times as only 8 commands is supported.
- Command 2 is unsupported.
- Command 0 is unsupported because $ony made mistake in parser.
- Command 0x17 is supported, but there is different official way to inject it, and it is libcrypt key so there is no point to do it this way.
This probably repeats for multidiscs, but for now let's figure out single discs first.
Function that search for configs look like this:
case 9: if ( *(&0x161FD80) ) 1570FA0(base) + AEDE0(offset in ISO.BIN.DAT or PSISOIMG? ) = 161FD80 in 4.86 ps1_netemu { cfg_rev = get_cfg_rev_from_PSIMG(); db_rev = get_titledb_rev(); decimal_16 = ret_32() >> 1; tty_print("ad hoc param: %x <%x>\n", cfg_rev, db_rev); if ( decimal_16 ) { low_rev = cfg_rev < db_rev; // Check is opposite to ps2_netemu, only config version higher than included db will pass. // Which mean config need to be higher version than emu database. for ( i = 0; i < decimal_16; i += 2 ) // up to 8 configs supported (8 commands + 8 values) { cfg_command = read_cfg_from_PSIMG(i); _cfg_value = read_cfg_from_PSIMG(i + 1); if ( cfg_command - 1 <= 0x3B ) // max cfg nr 0x3C { v245 = cfg_command >> 28; // Most likely check for wrong endianess. Configs are LE and are byte reversed before we end up here. if ( low_rev || v245 || cfg_command == 2 )// cfg 2 unsupported (replaced in later PSIMG rev with subchannel data), or old config rev, or v245. { tty_print("%x: %2d=0x%08x ***\n", v245 & 0xF, cfg_command, _cfg_value); // Ignore cfg } else { cfg_value = _cfg_value; tty_print("%x: %2d=0x%08x\n", 0LL, cfg_command, _cfg_value); WriteInternalConfigValue(cfg_command, cfg_value); } } } } }
Command IDs mapping[edit source]
The command IDs differs in between the PS1 emulator types and versions because are an indirect ID, it seems every command ID is mapped to a static ID in a separated table
The command ID's varies in between firmware versions, most probably because new functions was added every few versions, reorganized, etc... and this changes created a "displacement" of the old commands that causes them to increase his ID
At the time of writing this we dont know how to map that variable ID's to an static ID (that could be valid for all firmware versions), so by now in this list is needed to indicate the firmware version where the command ID was found
Coincidentially there are a few commands that preserves his ID in between emulator types and revisions, most probably is because are the first commands implemented and the variable ID given to them is a very low value, so always was kept at a low position in the commands list and was not disturbed by the modifications made to the other commands.
Command 0x00 (netemu 3.40 up to 4.88)[edit source]
- Valid values found
- 0 = ? (used by SCPS-18011 Um Jammer Lammy, and SLPS-01818 Langrisser IV & V Final Edition [Disc1of2])
In Um Jammer Lammy is used together with command 0x13, so it was a bit doubtful if it was a mistake. But Langrisser IV & V Final Edition [Disc1of2] uses it too and is the only command used by this disc, so it "should" do something. Um Jammer Lammy in netemu 3.40 was fixed only with command 0x0/0x0 (id/data)
- Um Jammer Lammy (SCPS-18011) uses somewhat new external config revision (11580) in official classic's external config, but only uses command 0x13. Keep in mind the game was released Febuary 27, 2008, so package was possibly updated with new config at some point, and then in internal table, so maybe it once had a different config command in config table and 0x00 nullified it. Langrisser IV (SLPS-01818) has old config revision (5713) and uses command 0x03 set to 0x3E8, so just default. Maybe internal config for Langrisser IV is empty config just to also nullify external config? --Mrjaredbeta (talk) 03:32, 1 September 2023 (CEST)
Command 0x01 (netemu 3.40 up to 4.88)[edit source]
- Valid values found
- 1 = ? (used by SLPS_004.16, SLUS_004.33)
- 2 = ? (used by SLPM_865.49, SLPM_865.50, SLPS_017.16)
Command 0x02 (netemu 3.40 up to 4.88)[edit source]
There are only 3 games using this command and are libcrypt protected games:, Crash Team Racing (SCES-02105), MediEvil (SCES-00311), and Vagrant Story (SLES-02754)
The command data contains an offset that points to an area where are stored a list of sectors (4 bytes each). When the emulator starts reading the list it doesnt knows how long is it so it reads groups of 4 bytes consecutivelly until it finds the value 00000000 that works as a terminator, the presence of this terminator at the end of the sector list is mandatory. Worth to note that list is more extensive than redump libcrypt one, but they match to some extend. Probably redump store only sectors really needed to run game correctly, while Sony decided to keep them all. Command is used only with LC1 games (Redump is wrong about medievil, is LC1).
The libcrypt protection is related with subchannel data stored by sectors, in redump.org this data is managed with the SBI files, displayed in a hexeditor view in each specific game page. If we convert the data from the official format to decimal and we compare it with the sector numbers in the redump.org SBI file it can be seen all the libcrypt protected sectors from the SBI file are included in the official format
The official format seems to include a lot more sectors which purpose is unknown
There seems to be way to supply that data/command from external file. Some research by "Fedor Wearing A Fedora" here and here
Crash Team Racing SCES-02105 (at absolute offset 0x1627E4 in ps1_netemu.self 4.83-4.88)
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 001627E0 00 00 06 A3 00 00 0E 21 00 00 17 79 ...£...!...y 001627F0 00 00 29 CB 00 00 2B 21 00 00 2E 22 00 00 31 31 ..)Ë..+!..."..11 00162800 00 00 37 19 00 00 37 1E 00 00 38 35 00 00 38 95 ..7...7...85..8• 00162810 00 00 38 9A 00 00 3A D0 00 00 3A D5 00 00 3B 1A ..8š..:Ð..:Õ..;. 00162820 00 00 3B 1F 00 00 3B D0 00 00 3B D5 00 00 3C 12 ..;...;Ð..;Õ..<. 00162830 00 00 3C 17 00 00 3D 0C 00 00 3D 11 00 00 3F 27 ..<...=...=...?' 00162840 00 00 3F 2C 00 00 48 91 00 00 55 35 00 00 57 A1 ..?,..H‘..U5..W¡ 00162850 00 00 58 38 00 00 59 38 00 00 5B 67 00 00 62 A9 ..X8..Y8..[g..b© 00162860 00 00 62 C5 00 00 78 4F 00 00 78 CA 00 00 7E 94 ..bÅ..xO..xÊ..~” 00162870 00 00 90 30 00 00 9A D5 00 00 9E 05 00 00 A4 3D ...0..šÕ..ž...¤= 00162880 00 00 A4 42 00 00 A5 C0 00 00 A5 C5 00 00 A8 04 ..¤B..¥À..¥Å..¨. 00162890 00 00 A8 09 00 00 A8 A9 00 00 A8 AE 00 00 A9 5A ..¨...¨©..¨®..©Z 001628A0 00 00 A9 5F 00 00 A9 90 00 00 A9 95 00 00 AA 72 ..©_..©...©•..ªr 001628B0 00 00 AA 77 00 00 AD 18 00 00 AD 1D 00 00 C5 5C ..ªw........Å\ 001628C0 00 00 EC 56 00 00 FB CA 00 01 04 52 00 01 04 7C ..ìV..ûÊ...R...| 001628D0 00 01 08 F4 00 01 22 A3 00 01 26 79 00 01 2F 8B ...ô.."£..&y../‹ 001628E0 00 01 2F A6 00 01 2F CE 00 01 53 A8 00 01 79 10 ../¦../Î..S¨..y. 001628F0 00 01 86 0D 00 01 C3 96 00 01 CD 83 00 01 EA 08 ..†...Ö..̓..ê. 00162900 00 01 F6 92 00 02 02 57 00 02 1C 08 00 02 53 85 ..ö’...W......S… 00162910 00 02 91 5D 00 02 93 8F 00 02 93 A6 00 02 AB 93 ..‘]..“...“¦..«“ 00162920 00 02 AB FB 00 02 BC 8C 00 02 CA 39 00 02 D2 17 ..«û..¼Œ..Ê9..Ò. 00162930 00 02 F1 35 00 03 16 06 00 03 4A 45 00 03 4C B6 ..ñ5......JE..L¶ 00162940 00 03 68 26 00 03 6B 1D 00 03 92 B8 00 03 92 F2 ..h&..k...’¸..’ò 00162950 00 03 9B 5D 00 03 A7 76 00 03 BA 90 00 03 C5 1A ..›]..§v..º...Å. 00162960 00 03 C5 41 00 03 C5 A3 00 03 FC F1 00 03 FD DA ..ÅA..Å£..üñ..ýÚ 00162970 00 04 14 C2 00 04 1F 49 00 04 26 57 00 04 87 5F ...Â...I..&W..‡_ 00162980 00 04 8E 65 00 04 C0 DA 00 00 00 00 ..Že..ÀÚ.... 000006A3 00000E21 00001779 000029CB 00002B21 00002E22 00003131 00003719 --- to decimal ---> 14105 (mentioned in the redump SBI file) 0000371E --- to decimal ---> 14110 (mentioned in the redump SBI file) 00003835 00003895 --- to decimal ---> 14485 (mentioned in the redump SBI file) 0000389A --- to decimal ---> 14490 (mentioned in the redump SBI file) 00003AD0 --- to decimal ---> 15056 (mentioned in the redump SBI file) 00003AD5 --- to decimal ---> 15061 (mentioned in the redump SBI file) 00003B1A --- to decimal ---> 15130 (mentioned in the redump SBI file) 00003B1F --- to decimal ---> 15135 (mentioned in the redump SBI file) 00003BD0 --- to decimal ---> 15312 (mentioned in the redump SBI file) 00003BD5 --- to decimal ---> 15317 (mentioned in the redump SBI file) 00003C12 --- to decimal ---> 15378 (mentioned in the redump SBI file) 00003C17 --- to decimal ---> 15383 (mentioned in the redump SBI file) 00003D0C --- to decimal ---> 15628 (mentioned in the redump SBI file) 00003D11 --- to decimal ---> 15633 (mentioned in the redump SBI file) 00003F27 --- to decimal ---> 16167 (mentioned in the redump SBI file) 00003F2C --- to decimal ---> 16172 (mentioned in the redump SBI file) 00004891 00005535 000057A1 00005838 00005938 00005B67 000062A9 000062C5 0000784F 000078CA 00007E94 00009030 00009AD5 00009E05 0000A43D --- to decimal ---> 42045 (mentioned in the redump SBI file) 0000A442 --- to decimal ---> 42050 (mentioned in the redump SBI file) 0000A5C0 --- to decimal ---> 42432 (mentioned in the redump SBI file) 0000A5C5 --- to decimal ---> 42437 (mentioned in the redump SBI file) 0000A804 --- to decimal ---> 43012 (mentioned in the redump SBI file) 0000A809 --- to decimal ---> 43017 (mentioned in the redump SBI file) 0000A8A9 --- to decimal ---> 43177 (mentioned in the redump SBI file) 0000A8AE --- to decimal ---> 43182 (mentioned in the redump SBI file) 0000A95A --- to decimal ---> 43354 (mentioned in the redump SBI file) 0000A95F --- to decimal ---> 43359 (mentioned in the redump SBI file) 0000A990 --- to decimal ---> 43408 (mentioned in the redump SBI file) 0000A995 --- to decimal ---> 43413 (mentioned in the redump SBI file) 0000AA72 --- to decimal ---> 43634 (mentioned in the redump SBI file) 0000AA77 --- to decimal ---> 43639 (mentioned in the redump SBI file) 0000AD18 --- to decimal ---> 44312 (mentioned in the redump SBI file) 0000AD1D --- to decimal ---> 44317 (mentioned in the redump SBI file) 0000C55C 0000EC56 0000FBCA 00010452 0001047C 000108F4 000122A3 00012679 00012F8B 00012FA6 00012FCE 000153A8 00017910 0001860D 0001C396 0001CD83 0001EA08 0001F692 00020257 00021C08 00025385 0002915D 0002938F 000293A6 0002AB93 0002ABFB 0002BC8C 0002CA39 0002D217 0002F135 00031606 00034A45 00034CB6 00036826 00036B1D 000392B8 000392F2 00039B5D 0003A776 0003BA90 0003C51A 0003C541 0003C5A3 0003FCF1 0003FDDA 000414C2 00041F49 00042657 0004875F 00048E65 0004C0DA 00000000
MediEvil SCES-00311 (at absolute offset 0x16298C in ps1_netemu.self 4.83-4.88)
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00162980 00 00 06 15 .... 00162990 00 00 2A 75 00 00 37 19 00 00 3A 33 00 00 3A D0 ..*u..7...:3..:Ð 001629A0 00 00 3B 1A 00 00 3B 8A 00 00 3C 12 00 00 3E 2F ..;...;Š..<...>/ 001629B0 00 00 3E E5 00 00 5D FC 00 00 71 8E 00 00 7C 17 ..>å..]ü..qŽ..|. 001629C0 00 00 80 35 00 00 A4 3D 00 00 A7 3D 00 00 A8 04 ..€5..¤=..§=..¨. 001629D0 00 00 A8 A9 00 00 A9 19 00 00 A9 90 00 00 AB BB ..¨©..©...©...«» 001629E0 00 00 AC 7F 00 00 BA B2 00 00 BE E3 00 00 C0 AF ..¬...º²..¾ã..À¯ 001629F0 00 00 C1 93 00 00 C1 C4 00 00 C3 A1 00 00 DA DE ..Á“..ÁÄ..á..ÚÞ 00162A00 00 00 E7 C1 00 00 FD 3A 00 01 1A 1C 00 01 1D 6A ..çÁ..ý:.......j 00162A10 00 01 1D CF 00 01 29 EF 00 01 45 E2 00 01 6A 98 ...Ï..)ï..Eâ..j˜ 00162A20 00 01 7F BB 00 01 B7 A0 00 01 BB 05 00 01 BF 12 ...»..· ..»...¿. 00162A30 00 01 EE 64 00 02 02 6E 00 02 0B CA 00 02 10 19 ..îd...n...Ê.... 00162A40 00 02 37 24 00 02 45 EC 00 02 54 06 00 02 55 A1 ..7$..Eì..T...U¡ 00162A50 00 02 5D 48 00 02 62 C8 00 02 81 12 00 02 9B 2D ..]H..bÈ......›- 00162A60 00 02 BD 04 00 02 C2 AF 00 02 D9 2A 00 02 DC 90 ..½...¯..Ù*..Ü. 00162A70 00 02 E1 3A 00 02 F2 18 00 02 FC C8 00 03 51 CF ..á:..ò...üÈ..QÏ 00162A80 00 03 52 AA 00 03 72 3F 00 00 00 00 ..Rª..r?.... 00000615 --- to decimal ---> 1557 00002A75 --- to decimal ---> 10869 00003719 --- to decimal ---> 14105 (mentioned in the redump SBI file) 00003A33 --- to decimal ---> 14899 (mentioned in the redump SBI file) 00003AD0 --- to decimal ---> 15056 (mentioned in the redump SBI file) 00003B1A --- to decimal ---> 15130 (mentioned in the redump SBI file) 00003B8A --- to decimal ---> 15242 (mentioned in the redump SBI file) 00003C12 --- to decimal ---> 15378 (mentioned in the redump SBI file) 00003E2F --- to decimal ---> 15919 (mentioned in the redump SBI file) 00003EE5 --- to decimal ---> 16101 (mentioned in the redump SBI file) 00005DFC --- to decimal ---> 24060 0000718E --- to decimal ---> 29070 00007C17 --- to decimal ---> 31767 00008035 --- to decimal ---> 32821 0000A43D --- to decimal ---> 42045 (mentioned in the redump SBI file) 0000A73D --- to decimal ---> 42813 (mentioned in the redump SBI file) 0000A804 --- to decimal ---> 43012 (mentioned in the redump SBI file) 0000A8A9 --- to decimal ---> 43177 (mentioned in the redump SBI file) 0000A919 --- to decimal ---> 43289 (mentioned in the redump SBI file) 0000A990 --- to decimal ---> 43408 (mentioned in the redump SBI file) 0000ABBB --- to decimal ---> 43963 (mentioned in the redump SBI file) 0000AC7F --- to decimal ---> 44159 (mentioned in the redump SBI file) 0000BAB2 --- to decimal ---> 47794 0000BEE3 --- to decimal ---> 48867 0000C0AF --- to decimal ---> 49327 0000C193 --- to decimal ---> 49555 0000C1C4 --- to decimal ---> 49604 0000C3A1 --- to decimal ---> 50081 0000DADE --- to decimal ---> 56030 0000E7C1 --- to decimal ---> 59329 0000FD3A --- to decimal ---> 64826 00011A1C --- to decimal ---> 72220 00011D6A --- to decimal ---> 73066 00011DCF --- to decimal ---> 73167 000129EF --- to decimal ---> 76271 000145E2 --- to decimal ---> 83426 00016A98 --- to decimal ---> 92824 00017FBB --- to decimal ---> 98235 0001B7A0 --- to decimal ---> 112544 0001BB05 --- to decimal ---> 113413 0001BF12 --- to decimal ---> 114450 0001EE64 --- to decimal ---> 126564 0002026E --- to decimal ---> 131694 00020BCA --- to decimal ---> 134090 00021019 --- to decimal ---> 135193 00023724 --- to decimal ---> 145188 000245EC --- to decimal ---> 148972 00025406 --- to decimal ---> 152582 000255A1 --- to decimal ---> 152993 00025D48 --- to decimal ---> 154952 000262C8 --- to decimal ---> 156360 00028112 --- to decimal ---> 164114 00029B2D --- to decimal ---> 170797 0002BD04 --- to decimal ---> 179460 0002C2AF --- to decimal ---> 180911 0002D92A --- to decimal ---> 186666 0002DC90 --- to decimal ---> 187536 0002E13A --- to decimal ---> 188730 0002F218 --- to decimal ---> 193048 0002FCC8 --- to decimal ---> 195784 000351CF --- to decimal ---> 217551 000352AA --- to decimal ---> 217770 0003723F --- to decimal ---> 225855 00000000
Vagrant Story SLES-02754 (at absolute offset 0x162A8C in ps1_netemu.self 4.83-4.88)
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00162A80 00 00 14 B5 ...µ 00162A90 00 00 38 F3 00 00 38 F8 00 00 39 39 00 00 39 3E ..8ó..8ø..99..9> 00162AA0 00 00 3A 33 00 00 3A 38 00 00 3A D0 00 00 3A D5 ..:3..:8..:Ð..:Õ 00162AB0 00 00 3B 1A 00 00 3B 1F 00 00 3B 8A 00 00 3B 8F ..;...;...;Š..;. 00162AC0 00 00 3B D0 00 00 3B D5 00 00 3F 27 00 00 3F 2C ..;Ð..;Õ..?'..?, 00162AD0 00 00 3F AA 00 00 90 84 00 00 A6 54 00 00 A6 59 ..?ª...„..¦T..¦Y 00162AE0 00 00 A6 AF 00 00 A6 B4 00 00 A7 3D 00 00 A7 42 ..¦¯..¦´..§=..§B 00162AF0 00 00 A8 04 00 00 A8 09 00 00 A8 A9 00 00 A8 AE ..¨...¨...¨©..¨® 00162B00 00 00 A9 19 00 00 A9 1E 00 00 A9 5A 00 00 A9 5F ..©...©...©Z..©_ 00162B10 00 00 AD 18 00 00 AD 1D 00 00 BD D6 00 00 BE B1 ........½Ö..¾± 00162B20 00 00 BF AC 00 00 C9 BC 00 00 E5 11 00 01 07 06 ..¿¬..ɼ..å..... 00162B30 00 01 0C 80 00 01 18 E0 00 01 1E 36 00 01 41 46 ...€...à...6..AF 00162B40 00 01 55 E7 00 01 71 BF 00 01 D2 F5 00 01 D8 B5 ..Uç..q¿..Òõ..ص 00162B50 00 01 E4 5A 00 01 E6 29 00 01 F1 FD 00 01 FE B9 ..äZ..æ)..ñý..þ¹ 00162B60 00 02 40 5D 00 02 59 9A 00 02 59 ED 00 02 5A 2F ...]..Yš..Yí..Z/ 00162B70 00 02 8B F6 00 02 8C A0 00 02 8C C2 00 02 A0 62 ..‹ö..Œ ..ŒÂ.. b 00162B80 00 02 DD 59 00 02 FD F1 00 03 0B FC 00 03 0C 26 ..ÝY..ýñ...ü...& 00162B90 00 03 9A B1 00 03 A9 E1 00 03 BC 7F 00 03 E1 B9 ..š±..©á..¼...á¹ 00162BA0 00 03 E2 08 00 03 F8 8F 00 04 01 72 00 04 05 91 ..â...ø....r...‘ 00162BB0 00 04 13 8F 00 04 3E D8 00 04 40 DC 00 04 48 94 ......>Ø...Ü..H” 00162BC0 00 04 67 FB 00 04 78 2C 00 04 8A CE 00 04 B4 A0 ..gû..x,..ŠÎ..´ 00162BD0 00 04 B9 60 00 04 BE 93 00 04 C3 0C 00 04 CB 0E ..¹`..¾“..Ã...Ë. 00162BE0 00 04 CB C9 00 04 D5 C8 00 00 00 00 ..ËÉ..ÕÈ.... 000014B5 000038F3 --- to decimal ---> 14579 (mentioned in the redump SBI file) 000038F8 --- to decimal ---> 14584 (mentioned in the redump SBI file) 00003939 --- to decimal ---> 14649 (mentioned in the redump SBI file) 0000393E --- to decimal ---> 14654 (mentioned in the redump SBI file) 00003A33 --- to decimal ---> 14899 (mentioned in the redump SBI file) 00003A38 --- to decimal ---> 14904 (mentioned in the redump SBI file) 00003AD0 --- to decimal ---> 15056 (mentioned in the redump SBI file) 00003AD5 --- to decimal ---> 15061 (mentioned in the redump SBI file) 00003B1A --- to decimal ---> 15130 (mentioned in the redump SBI file) 00003B1F --- to decimal ---> 15135 (mentioned in the redump SBI file) 00003B8A --- to decimal ---> 15242 (mentioned in the redump SBI file) 00003B8F --- to decimal ---> 15247 (mentioned in the redump SBI file) 00003BD0 --- to decimal ---> 15312 (mentioned in the redump SBI file) 00003BD5 --- to decimal ---> 15317 (mentioned in the redump SBI file) 00003F27 --- to decimal ---> 16167 (mentioned in the redump SBI file) 00003F2C --- to decimal ---> 16172 (mentioned in the redump SBI file) 00003FAA 00009084 0000A654 --- to decimal ---> 42580 (mentioned in the redump SBI file) 0000A659 --- to decimal ---> 42585 (mentioned in the redump SBI file) 0000A6AF --- to decimal ---> 42671 (mentioned in the redump SBI file) 0000A6B4 --- to decimal ---> 42676 (mentioned in the redump SBI file) 0000A73D --- to decimal ---> 42813 (mentioned in the redump SBI file) 0000A742 --- to decimal ---> 42818 (mentioned in the redump SBI file) 0000A804 --- to decimal ---> 43012 (mentioned in the redump SBI file) 0000A809 --- to decimal ---> 43017 (mentioned in the redump SBI file) 0000A8A9 --- to decimal ---> 43177 (mentioned in the redump SBI file) 0000A8AE --- to decimal ---> 43182 (mentioned in the redump SBI file) 0000A919 --- to decimal ---> 43289 (mentioned in the redump SBI file) 0000A91E --- to decimal ---> 43294 (mentioned in the redump SBI file) 0000A95A --- to decimal ---> 43354 (mentioned in the redump SBI file) 0000A95F --- to decimal ---> 43359 (mentioned in the redump SBI file) 0000AD18 --- to decimal ---> 44312 (mentioned in the redump SBI file) 0000AD1D --- to decimal ---> 44317 (mentioned in the redump SBI file) 0000BDD6 0000BEB1 0000BFAC 0000C9BC 0000E511 00010706 00010C80 000118E0 00011E36 00014146 000155E7 000171BF 0001D2F5 0001D8B5 0001E45A 0001E629 0001F1FD 0001FEB9 0002405D 0002599A 000259ED 00025A2F 00028BF6 00028CA0 00028CC2 0002A062 0002DD59 0002FDF1 00030BFC 00030C26 00039AB1 0003A9E1 0003BC7F 0003E1B9 0003E208 0003F88F 00040172 00040591 0004138F 00043ED8 000440DC 00044894 000467FB 0004782C 00048ACE 0004B4A0 0004B960 0004BE93 0004C30C 0004CB0E 0004CBC9 0004D5C8 00000000
Command 0x03 (netemu 3.40 up to 4.88)[edit source]
- Valid values found: 0x32 (50d), 0xC8 (200d), 0x12C (300d), 0x1F4 (500d), 0x258 (600d), 0x2BC (700d), 0x320 (800d), 0x384 (900d), 0x44C (1100d), 0x4B0 (1200d), 0x578 (1400d), 0x5DC (1500d), 0x708 (1800d)
- Default value: 0x3E8
- _xcdrom_thread related.
Value is integer that is later converted to double float using fcfid, and truncated to single precision by frsp.
I'm not familiar with CELL floating point unit quirks, but value could be just single precision float from the start, why complicate that so much?
- Possible disc read speed delay or adjustment. Larger value results in slower loading times. --Mrjaredbeta (talk) 03:21, 1 September 2023 (CEST)
Custom Usage:
- Param 0x384 (900d) fixes Vampire Hunter D (SLUS-01138) hanging issues.
- Param 0x1F4 (500d) fixes Medievil 2 audio and hanging issues.
Command 0x04 (netemu 3.40 up to 4.88)[edit source]
- Valid values found: 0x4, 0x7, 0x14 (20d), 0x46 (70d), 0x64 (100d), 0xC8 (200d), 0xFFFFFF38 (-200d)
- Default value: 0
- _xcdrom_thread related.
Possible seek delay/adjustment.
Custom Usage:
- Param 0x64 and above fixes Transformers: Beast Wars Transmetals (SLUS-01160). 0x14 also gets past initial main menu screen, but hangs when loading into a stage. Param 0xC8 is probably safest.
Command 0x05 (netemu 3.40 up to 4.88)[edit source]
The game configs inside ps1_netemu.self 3.40 doesnt seems to use this command, so is not posible to see if it matches in between 3.40 and 3.55/4.88 but we can assume is the same ID through netemu 3.40 up to 4.88 because higher command IDs (such 0x08) maintained his ID since 3.40
- Default value: 0
- _xcdrom_thread related.
Command 0x06 (netemu 4.83 up to 4.88)[edit source]
- Default value: 0
- _xcdrom_thread related.
Custom Usage:
- Param 0x01 fixes Shrek Treasure Hunt (SLUS-01463) minigame loading screen hangs.
- Param 0x01 fixes Fear Effect (SLUS-00920) hang when pressing START at menu screen.
Command 0x07 (netemu 4.83 up to 4.88)[edit source]
- Default value: 0
- _xcdrom_thread related.
Custom Usage:
- Param 0x01 fixes Fear Effect (SLUS-00920) other issues in main menu, such as graphical corruption in options screens, and returning to options screen after viewing credits.
Command 0x08 (netemu 3.40 up to 4.88)[edit source]
- Valid values found: 0xC8 (200d), 0x12C (300d), 0x1F4 (500d), 0x2BC (700d), 0x320 (800d). It seems to be an small selection of the same values used by command 0x03
- Default value: 0x3E8
- _xcdrom_thread related.
Command 0x0B (netemu 4.83 up to 4.88)[edit source]
- Or command 0x09 (netemu 3.40)
- Valid values found: 0x27104E95 (in netemu 3.40 and 4.88). It seems to be composed by 2 values of 2 bytes size: 0x2710(hex)=10000(dec). And 0x4E95(hex)=20117(dec)
The command data seems to be a bit special, is a value higher than any other command, but is the same value along different ps1_netemu.self revisions, so is not an offset. There is only one game using this command: SLPS_030.12
Command 0x0E (netemu 4.83 up to 4.88)[edit source]
- Or command 0x0C (netemu 3.40)
- Default value: 0x1F4
- _xcdrom_thread related.
Command 0x0F (netemu 4.83 up to 4.88)[edit source]
- Or command 0x0D (netemu 3.40)
- Default value: 0xFA
- _xcdrom_thread related.
Command 0x10 (netemu 4.83 up to 4.88)[edit source]
- Default value: 0xFA
- _xcdrom_thread related.
Command 0x11 (netemu 4.83 up to 4.88)[edit source]
- Default value: 0x7D
- _xcdrom_thread related.
Command 0x12 (netemu 4.83 up to 4.88)[edit source]
- Or command 0x10 (netemu 3.40)
Command value are flags/settings to alter cdrom behavior.
- 0x800 = Different code path for MotorOn/Pause/SetSession cdrom commands. // Need more work, flag affect more than that.
Command 0x13 (netemu 4.83 up to 4.88)[edit source]
- Default value: 0
- MDEC related?
Custom Usage:
- Param 0x01 fixes Roland Garros French Open 2001 (SLES-03449) hang when loading into a match.
- Param 0x01 fixes Fear Effect (SLUS-00920) hang when pressing START at menu screen (sometimes).
Command 0x14 (netemu 4.83 up to 4.88)[edit source]
- Default value: 4
Command 0x15 (netemu 4.83 up to 4.88)[edit source]
- Default value: 4
Command 0x16 (netemu 4.83 up to 4.88)[edit source]
- Default value: 0
- DMA timing related.
Custom Usage:
- Param 0x32 is enough to fix International Superstar Soccer (SLES-02550) black screen after PlayStation logo.
- Param 0x08 is enough to fix Vampire Hunter D’s main menu flashing.
Command 0x17 (netemu 4.83 up to 4.88)[edit source]
- Or command 0x0B (netemu 1.70)
- Or command 0x0A (netemu 2.10)
- Or command 0x15 (netemu 3.40 up to 3.55)
- Or command 0x0B (emu 1.70 up to 4.88)
- Or command 0x07 (newemu 2.10)
- Or command 0x0A (newemu 3.40 up to 4.88)
This is the libcrypt magic word. This command is used only in 3 games (SCES_016.95, SLES_019.07, SLES_013.01). see: PS1 Custom Patches In ps1_netemu there is possibility to setup that command from one of ps1 classic files (PSISOIMG0000 / PSTITLEIMG000000 related).
When value is not zero is returned by emulator when game try to read cop0r3 (BPC) register. When value is 0 (default), emulator return real BPC content.
- It seems there is a problem with LC games using the third scheme mentioned here. After reading the data contents of subchannel Q, the CRC-16 value is not read at all, but calculated on its own by the driver instead. It does break LC games using this particular scheme (web-found confirmed issues with Ape Escape and Final Fantasy VIII). All three games that are meant to work with this command does use these LC sectors. I think this command was meant to resolve this issue, just a guess.--Agrippa (talk) 20:06, 12 June 2022 (UTC)
Command 0x18 (netemu 4.83 up to 4.88)[edit source]
Substrat cycles from mdec_block_copy_out_callback delta. When mdec is decoding blocks, copy out happen on every completed 6th block. This is hardcoded to take 0xB00 (2816) cycles in ps1_netemu. By using this config we can make this value less than default, which in turn "overclock" mdec decoding as every 6xblock will be decoded faster. Duckstation by default use value 0xA80 (2688 (448 x 6 blocks)). So to make config that will replicate this behavior we need set config value to 0x80 (0xB00 - 0x80 = 0xA80).
- Default value: 0
- Valid values range: 0x000 - 0xB00
- Higher values are ignored and 0 is set (just like when you use 0xB00 value), making MDEC instant.
Command 0x19 (netemu 4.83 up to 4.88)[edit source]
- Default value: 4
- Set in same place where bios image is loaded, and region check/patch is performed.
Command 0x1A (netemu 4.83 up to 4.88)[edit source]
Set PS1 PS1 Scratchpad address 0x1F800000 - 0x1F8003FF to given 4 bytes value. Only one game use this, game seems to expect memory initialized to 0xFFFFFFFF, while never do this.
- Default value: 0
Command 0x1B (netemu 4.83 up to 4.88)[edit source]
- Default value: 0x3E8
Multiplier for GTE commands cycles. Value from config is multiplied by 256, and then divided by 1000. For example Battle Arena Toshinden use 0xC8 which result in 0x33(51) as value that is later used. Default value 0x3E8 end as 0x100(256).
Command 0x1C (netemu 4.83 up to 4.88)[edit source]
- Or command 0x18 (netemu 3.40)
- Or command 0x1A (netemu 3.55 ?)
- Or command 0x02 (netemu 1.70) - possibly different command
Param flags:
- 1 = unk.
- 2 = Set Vibration to Off (menu to set it to On is still accessible, but command seems to also skip initializing of vibration internal struct/settings).
Command 0x1D (netemu 4.83 up to 4.88)[edit source]
- Default value: 0
- Correct values 0 / 1 / 2
Config seems to setup default gamepads layout for multitap.
- 0 = <0, 2, 4, 6, 1, 3, 5, 7>
- 1 = <0, 2, 3, 4, 1, 5, 6, 7>
- 2 = <0, 1, 2, 3, 4, 5, 6, 7>
Sync order of controllers is always the same regardless of parameter set (1/1-A, 2/2-A, 1-B, 2-B, 1-C, 2-C, 1-D). Therefore, change is only reflected internally in emulated game. For example, Crash Bash needs parameter 2 for controllers to be set properly in game, but order in which controllers physically connect is not changed.
Command 0x1E (netemu 4.83 up to 4.88)[edit source]
- Default value: 0x7D0
- xPadThread related.
Command 0x20 (netemu 4.83 up to 4.88)[edit source]
GPU multi command (bifield)
- Default value: 0
- 0x08 = Always set Vertical Interlace bit in GPUSTAT to 0 on GP1 (08h) command.
- 0x40 = Is not exactly known what happen under the hood, but this command allow to play 50Hz titles in 60Hz with correct speed.
Command 0x21 (netemu 4.83 up to 4.88)[edit source]
- Default value: 0x3E8
- PS1 GPU related.
Command 0x22 (netemu 4.83 up to 4.88)[edit source]
- Default value: 0x3E8
- PS1 GPU related.
Seems to fix slowdown in Rapid Racer (SCPS-10060) with value 0x320.
Command 0x23 (netemu 4.83 up to 4.88)[edit source]
- Default value: 0x3E8
- PS1 GPU related.
Command 0x24 (netemu 4.83 up to 4.88)[edit source]
- Default value: 7
- PS1 GPU related.
Command 0x25 (netemu 4.83 up to 4.88)[edit source]
- Default value: 0
- PS1 GPU related.
Command 0x2A (netemu 4.83 up to 4.88)[edit source]
- Default value: 0
- PS1 GPU related.
Command 0x2B (netemu 4.83 up to 4.88)[edit source]
- Default value: 0
- PS1 GPU related.
Command 0x2C (netemu 4.83 up to 4.88)[edit source]
- Default value: 0
- PS1 GPU related.
Command 0x2D (netemu 4.83 up to 4.88)[edit source]
- Default value: 0
- PS1 GPU related.
Command 0x31 (netemu 4.83 up to 4.88)[edit source]
GPU multi command (bitfield)
- 0x02 = Enable Vertical Interlace bit in GP1 (08h) command in SPE writes (in renderer only). Emulator by default use hack where VI bit is ALWAYS disabled in spe.
Note from nocash docs about Vertical Interlace: "Interlace must be enabled to see all lines in 480-lines mode (interlace is causing ugly flickering, so a non-interlaced low resolution image is typically having better quality than a high resolution interlaced image, a pretty bad example are the intro screens shown by the BIOS)."
This suggest that games which eventually need 0x31, 0x02 will be ones that send GP1 commands with active bit 2(Vertical Resolution 1=480) and 5(Vertical Interlace) at the same time. Otherwise image will be cropped, or badly interlaced. FF8 use this on "Published by..." screen, you can notice weird interlacing when subtitles fade-in without command.
Command 0x32 (netemu 4.83 up to 4.88)[edit source]
Pad vibration related, seems to be big motor strength used in cellPadSetActDirect if value is less than one of function arguments. Default value set in xPadThread Init is 0x40(64).
Command 0x33 (netemu 4.83 up to 4.88)[edit source]
Value is integer that is later converted to double float using fcfid, and truncated to single precision by frsp.
Pad vibration related, seems to be used to calculate big motor strength used later in cellPadSetActDirect, if other conditions are met. Default value set in xPadThread Init is 0x4B0(1200).
Command 0x36 (netemu 4.83 up to 4.88)[edit source]
- Maximum value 7
- PSX HW regs access related
- Valid values found:
- 1 = ?
- 2 = ?
- 4 = ?
Multiple instances accepted, and not overwrite itself.
Command 0x37 (netemu 4.83 up to 4.88)[edit source]
- Default value: 1
- Valid values found:
- 2 = ?
- 4 = ?
Something related to I_STAT (PSX Interrupt status register).
Command 0x38 (netemu 4.83 up to 4.88)[edit source]
- Or command 0x2C in ps1_netemu.self 3.40
- Or command 0x2E in ps1_netemu.self 3.55 ?
- Valid values found:
- 0/1/2/3
if (cfg == 0) stay_netemu if (boot_not_from_disc_drive) if (cfg & 2) boot_newemu if (boot_from_disc_drive) if (cfg & 1) boot_ps1emu else stay_netemu // Boot is considered to be from disc if argv with game path is empty. Which make 0x38 with param 0x01 inaccessible, because there is no way to start disc game with netemu in official way (excluding games that ps1_emu launch with 0x15 cmd to ps1_netemu).
Command 0x3B (netemu 4.83 up to 4.88)[edit source]
PS1 SPU DMA related config. Seems to change some cycles calculation.
- Default value: 0
- Valid values: 0/1
Ps1_emu Commands Info[edit source]
Command 0x15 (ps1emu 4.83 up to 4.88)[edit source]
- Valid values found:
- 3 (launch game using ps1_netemu)
- Different values are ignored
Ps1_newemu Commands Info[edit source]
Command 0x18 (ps1newemu 4.83 up to 4.88)[edit source]
Supposed to launch game using different emulator, but all paths do nothing.
- Valid values found:
- 3 (Do nothing, but with print! 1)
- Different values do nothing
Known bugs[edit source]
ps1_netemu.elf[edit source]
Cdr int reads with nonstandard index[edit source]
Emulator ignore interrupt flag register and interrupt enable register reads if cdrom index is 2, or 3. Reads like that are undocummented behavior, but confirmed to be successful on real hardware. Also Nocash docs, and Duckstation source handle that correctly, and i remember there are games which used that.
0xD81F0 read_0x1F801803: 0xD81F0 lwz r0, (.1F801800 - 0x2E8480)(r8) 0xD81F4 clrlwi r0, r0, 30 # cdrom.index & 3 0xD81F8 cmpwi cr7, r0, 0 # cdrom.index = 0 0xD81FC beq cr7, read_interrupt_enable_register 0xD8200 cmpwi cr7, r0, 1 # cdrom.index = 1 0xD8204 beq cr7, read_interrupt_flag_register 0xD8208 li r3, 0 # return 0 if index was 2 or 3 0xD820C lwz r7, off_1BC0D4 0xD8210 clrldi r3, r3, 32 0xD8214 dcbt 0, r7 0xD8218 blr
This can be fixed by simple patch from
0xD81F4 clrlwi r0, r0, 30 #hex 54 00 07 BE 0xD8264 clrlwi r0, r0, 30 #hex 54 00 07 BE
to
0xD81F4 clrlwi r0, r0, 31 #hex 54 00 07 FE 0xD8264 clrlwi r0, r0, 31 #hex 54 00 07 FE
This change cdrom.index & 3, into cdrom.index & 1. This way index 2, and 3 will be respected as 0, and 1. Sadly there is no easy hex pattern, so patch need to be done manually. Memory offsets for 4.86.
Bad encoding of malformed conditional branch 0[edit source]
Emulator don't ignore few bits, and expect they are 0. While real hardware seems to don't care about them.
31..26 |25..21|20..16|15..11|10..6 | 5..0 | 6bit | 5bit | 5bit | 5bit | 5bit | 6bit | -------+------+------+------+------+--------+------------ 000001 | rs | 0XXX0| <--immediate16bit--> | bltz 000001 | rs | 0XXX1| <--immediate16bit--> | bgez 000001 | rs | 1XXX0| <--immediate16bit--> | bltzal 000001 | rs | 1XXX1| <--immediate16bit--> | bgezal
Problem start when bits 17,18,19 are not zero. Emulator don't clear those bits, and explicitly check only for 0x0,0x1,0x10,0x11.
r24 hold 20..16 bits extracted from opcode. 0x107958 bcondz_107958: # CODE XREF: r3000_opcode_table+12C↑j 0x107958 cmpwi cr7, r24, 1 # jumptable 001067D4 case BcondZ 0x10795C beq cr7, loc_107E98 0x107960 cmplwi cr7, r24, 1 0x107964 blt cr7, loc_107E78 0x107968 cmpwi cr7, r24, 0x10 0x10796C beq cr7, loc_1082A4 0x107970 cmpwi cr7, r24, 0x11 0x107974 beq cr7, loc_10821C
Correct solution here will be patch to AND r24 with 0x11 first, to clear meaningless bits before comparison. This is reason why emulator fail this "Branch Advance" CPU test: https://emulation.gametechwiki.com/index.php/PS1_Tests#CPU . Possibly standard "Branch" test is failed for the same reason.
GTE commands[edit source]
List of GTE commands is available at 0x001B345C in ps1_netemu 4.86. List include following data {CommandFunctionOPD, Cycles}. Emulator handle only commands listed below (CMD, addr in emu).
.GTE_RTPS 0xC4500 .GTE_MVMVA 0xC4C00 .GTE_SQR_sf 0xC5168 .GTE_NCLIP 0xC527C .GTE_AVSZ3 0xC5338 .GTE_AVSZ4 0xC5420 .GTE_OP_sf 0xC5518 .GTE_GPF_sf 0xC5678 .GTE_GPL_sf 0xC58C8 .GTE_RTPT 0xC6288 .GTE_NCT 0xC7710 .GTE_NCS 0xC8AD8 .GTE_CC 0xC91E8 .GTE_NCCT 0xC9748 .GTE_NCCS 0xCADF8 .GTE_DCPL 0xCB5F8 .GTE_DPCS 0xCBAD8 .GTE_CDP 0xCBF80 .GTE_NCDT 0xCC760 .GTE_NCDS 0xCE5F8 .GTE_INTPL 0xCF078 .GTE_DPCT 0xCF540
CD Drive Commands[edit source]
List of CD commands is available at 001B365C in ps1_netemu 4.86. List include following data {Respond INT count (minus INT3), CMD_nr, Function OPD}. Emulator handle only commands listed below (CMD, addr in emu).
.cdr_cmd_Sync 0xD8290 .cdr_cmd_Reset 0xD8368 .cdr_cmd_Test 0xD8478 .cdr_cmd_Getparam 0xD8798 .cdr_cmd_Setmode 0xD8918 .cdr_cmd_Init 0xDBC48 .cdr_cmd_MotorOn 0xDD0C0 .cdr_cmd_SeekP 0xDD3D0 .cdr_cmd_Play 0xDD67C .cdr_cmd_ReadS 0xDD8E8 .cdr_cmd_Backward 0xDDBD0 .cdr_cmd_Pause 0xDDF58 .cdr_cmd_GetTD 0xDE1F8 .cdr_cmd_Getstat 0xDE598 .cdr_cmd_GetlocP 0xDE728 .cdr_cmd_ReadN 0xDEDD0 .cdr_cmd_SetSession 0xDF130 .cdr_cmd_Mute 0xDF970 .cdr_cmd_SeekL 0xDFBAC .cdr_cmd_Setloc 0xDFE58 .cdr_cmd_Demute 0xE03E0 .cdr_cmd_Setfilter 0xE0618 .cdr_cmd_Forward 0xE0878 .cdr_cmd_GetlocL 0xE0B98 .cdr_cmd_Stop 0xE0FF0 .cdr_cmd_GetTN 0xE1298 .cdr_cmd_GetID 0xE1544 .cdr_cmd_ReadTOC 0xE1C58 Commands 0x17, 0x18, 0x1D are handled as cmd_Sync. Commands above 0x1E seems to be not supported.