PS1 Emulation: Difference between revisions

From PS3 Developer wiki
Jump to navigation Jump to search
 
(46 intermediate revisions by 2 users not shown)
Line 28: Line 28:
}}
}}


== Files ==
== PS1 Emulator Types and Revisions ==
 
<div>
=== Emulator versions ===
<div style="float:top; text-align:center;">'''PS1 Emulator Types and Revisions'''</div>
There is no accurate info in wiki about the different PS1 emulator .self revisions, if you want to collaborate documenting this info see the experimental table on {{talk}} page
<div style="float:left;">
 
{| class="wikitable" style="line-height:100%; font-size:70%; margin-right:5px"
=== Game formats ===
|+ ps1_emu.elf (decrypted)<br><div style="height:5px"></div>
See: [[ISO.BIN.EDAT]] and [[PSISOIMG0000]]
! Firmware !! Size !! MD5 !! Timestamp !! <abbr title="Revision">Rev</abbr> !! style="padding:1px" | <abbr title="Maximun number of supported commands">Comm</abbr>
|-
! [[1.00_AV|1.00 AV]]
| 10 296 408 || style="font-family:monospace" | 981A7428C2A59219FA05861EDEEDBD4A || 06/10/04/12:16 || ? || ?
|-
! [[1.02_CEX|1.02]]
| 10.296.408 || style="font-family:monospace" | C5FE03742A951194C336EE33783F5CD6 || 06/10/21/00:01 || ? || ?
|-
! [[1.10_CEX|1.10]]
| 10.296.408 || style="font-family:monospace" | C9C9D7D2E36F3E3579A5DF713E9ABE1E || 06/11/09/06:09 || ? || ?
|-
! [[1.11_CEX|1.11]]
| 10.296.408 || style="font-family:monospace" | 26271CCA29B77483DC3D7FDDE7B9CC3C || 06/11/21/17:55 || ? || ?
|-
! [[1.30_CEX|1.30]]
| 10.296.496 || style="font-family:monospace" | E7932EC24E72B3005EE152B141A63690 || 06/12/05/05:34 || ? || ?
|-
! [[1.31_CEX|1.31]]
| 10.296.496 || style="font-family:monospace" | 2244DE70C85093D7E37BC3D3F4278BE1 || 06/12/12/18:48 || ? || ?
|-
! [[1.32_CEX|1.32]]
| 10.296.496 || style="font-family:monospace" | 601BCADBBBC0A2D0433C932A2D67C4EF || 06/12/18/05:55 || ? || ?
|-
! [[1.50_CEX|1.50]]
| 10.303.536 || style="font-family:monospace" | F8050B006CDFCC64DF742D7BBDC03130 || 07/01/18/22:53 || ? || ?
|-
! ?
| ? || ? || ? || ? || ?
|-
! [[1.70_CEX|1.70]]
| 6.857.648 || style="font-family:monospace" | EA49942B6789FBE0A1C98BC12E282533 || 07/04/16/16:12 || ? || <abbr title="Highest Command ID used in the configs">0x14?</abbr>
|-
! ?
| ? || ? || ? || ? || ?
|-
! [[1.90_CEX|1.90]]
| 6.974.864 || style="font-family:monospace" | 478CFED0F7EE13C94F01C2A246C83D45 || 07/07/21/06:45 || ? || ?
|-
! ?
| ? || ? || ? || ? || ?
|-
| colspan="6" style="background:#ff8080; text-align:center; line-height:75%" | Stripped/extracted rom/bios
|-
! [[2.10_CEX|2.10]]
| 2.887.152 || style="font-family:monospace" | AEE181B061E586F99E76C033C9DCF726 || 07/12/15/05:30 || ? || 0x15
|-
! ?
| ? || ? || ? || ? || ?
|-
! [[3.40_CEX|3.40]]
| 2.824.576 || style="font-family:monospace" | A6ABFB04739575E2264A4D3FEB2A9CBF || 10/06/23/15:45 || ? || ?
|-
! ?
| ? || ? || ? || ? || ?
|-
! [[3.66_CEX|3.66]]
| 2.824.832 || style="font-family:monospace" | 95399A202003E216794511BD2D2E9DF6 || 11/06/16/03:52 || ? || ?
|-{{cellcolors|#bbbbff}}
! [[3.70_CEX|3.70]]
| rowspan="3" | 2.824.920 || style="font-family:monospace" | 045D81147B9BDFB8C8A416FD5F5A0C56 || 11/08/05/03:42 || rowspan="3" | same || rowspan="3" | ?
|-{{cellcolors|#bbbbff}}
! ~
| colspan="2" style="text-align:center; background-color:#bbbbff;" | ''Any''
|-{{cellcolors|#bbbbff}}
! [[3.72_CEX|3.72]]
| style="font-family:monospace" | C745A30231103B83F04539021E4878FC || 11/09/14/01:17
|-{{cellcolors|#ddddff}}
! [[3.73_CEX|3.73]]
| rowspan="2" | 2.824.920 || style="font-family:monospace" | EB3AFF30B3206CFA6A8962AB393F773E || 11/10/04/12:55 || rowspan="2" | same || rowspan="2" | ?
|-{{cellcolors|#ddddff}}
! [[3.74_CEX|3.74]]
| style="font-family:monospace" | E2A77C3DC9FD5AD4264341196462D096 || 11/10/25/00:38
|-{{cellcolors|#bbbbff}}
! [[4.00_CEX|4.00]]
| rowspan="3" | 2.829.784 || style="font-family:monospace" | 94A8E6A8063C08FAD8CA9B340CCCAE67 || 11/11/22/03:17 || rowspan="3" | same || rowspan="3" | ?
|-{{cellcolors|#bbbbff}}
! ~
| colspan="2" style="text-align:center; background-color:#bbbbff;" | ''Any''
|-{{cellcolors|#bbbbff}}
! [[4.11_CEX|4.11]]
| style="font-family:monospace" | 02B7F6D5F517959161B2154135D4B3BC || 12/02/11/07:13
|-
! [[4.15_CEX|4.15]]
| ? || ? || ? || ? || ?
|-{{cellcolors|#ddddff}}
! [[4.20_CEX|4.20]]
| rowspan="2" | 2.829.912 || style="font-family:monospace" | 3778948C92F5FA12CB0AABE65BEE5465 || 12/06/15/02:09 || rowspan="2" | same || rowspan="2" | ?
|-{{cellcolors|#ddddff}}
! [[4.21_CEX|4.21]]
| style="font-family:monospace" | B7B662397E3FFDD7C11F9617C1B41856 || 12/06/30/01:13
|-
! [[4.23_SEX|4.23 S]]
| 2.829.912 || style="font-family:monospace" | 6E74CC51E0C6462DF1F9278ED9DB9593 || 12/07/31/00:22 || ? || ?
|-
! [[4.25_CEX|4.25]]
| 2.829.912 || style="font-family:monospace" | 03EA65C3EA3F8DB04F236C49C6B6C0E1 || 12/09/07/07:03 || <abbr title="same code than 4.20 CEX and 4.21 CEX.... but different than the 4.23 SEX in between, grrrr">same</abbr> || ?
|-
! ?
| ? || ? || ? || ? || ?
|-
! ?
| ? || ? || ? || ? || ?
|-
! ?
| ? || ? || ? || ? || ?
|-
! [[4.78_CEX|4.78]]
| 2.765.488 || style="font-family:monospace" | 354F1DEEDCA3C4CFA1B49B6B28B1648D || 15/12/17/01:18 || ? || ?
|-
! [[4.80_CEX|4.80]]
| ? || ? || ? || ? || ?
|-
! [[4.81_CEX|4.81]]
| 2.765.616 || style="font-family:monospace" | 2123E3D6A8E81647CB41F51AFEE6CCD6 || 16/10/24/19:23 || ? || ?
|-
! colspan="6" style="background:#80ff80; line-height:75%" | Abandoned (last revision)
|-{{cellcolors|#ddddff}}
! [[4.82_CEX|4.82]]
| rowspan="3" | 2.765.616 || style="font-family:monospace" | 64BFA4DBD595A20E317B2189B54BF673 || 17/08/24/15:42 || rowspan="3" | Last || rowspan="3" | 0x15
|-
! ~
| colspan="2" style="text-align:center; background-color:#ddddff;" | ''Any''
|-
! [[4.89_CEX|4.89]]
| style="background-color:#ddddff; font-family:monospace" | 44F975821FD714E2E810771836178CB3 || style="background-color:#ddddff;" | 22/02/04/14:38
|}
<span style="font-size:small">
{{dot}}'''Decrypted (elf)''': changes <abbr title="When comparing two decrypted files of the same revision from different firmwares the only differences are the build label (1 area with size 0x20) and the target firmware (1 area with size 0x2)">every firmware version</abbr><br>
{{dot}}'''<abbr title="0x20 bytes">Build label</abbr>''': yes, with timestamp, search for '''-sgpu-sspu-sli4'''<br>
{{dot}}'''<abbr title="2 bytes">Target Firmware</abbr>''': yes repeated '''one''' time<br>
{{dot}}'''Revision''': unknown
</span>
</div>
<div style="float:left;">
{| class="wikitable" style="line-height:100%; font-size:70%; margin-left:5px; margin-right:5px"
|+ ps1_netemu.elf (decrypted)<br><div style="height:5px"></div>
! Firmware !! Size !! MD5 !! Timestamp !! <abbr title="Revision">Rev</abbr> !! style="padding:1px" | <abbr title="Maximun number of supported commands">Comm</abbr>
|-
! [[1.70_CEX|1.70]]
| 6.872.592 || style="font-family:monospace" | 5DA8492C4702F94DDDC4530921316789 || 07/04/16/16:13 || ? || <abbr title="Highest Command ID used in the configs">0x16?</abbr>
|-
! ?
| ? || ? || ? || ? || ?
|-
! ?
| ? || ? || ? || ? || ?
|-
! [[1.90_CEX|1.90]]
| 6.853.368 || style="font-family:monospace" | 8A5A3676B461C97A9A467D5651D6EAAD || 07/07/21/06:47 || ? || ?
|-
! ?
| ? || ? || ? || ? || ?
|-
| colspan="6" style="background:#ff8080; text-align:center; line-height:75%" | Stripped/extracted rom/bios
|-
! [[2.10_CEX|2.10]]
| 2.764.288 || style="font-family:monospace" | 7826B1C6799404216D4771C07DE12F53 || 07/12/15/05:31 || ? || <abbr title="Highest Command ID used in the configs">0x18?</abbr>
|-
! ?
| ? || ? || ? || ? || ?
|-
! [[3.40_CEX|3.40]]
| 2.971.288 || style="font-family:monospace" | FD32C7B7CBA2639FC8DB9EB615A16461 || 10/06/23/15:46 || 6520 || <abbr title="Highest Command ID used in the configs">0x2C?</abbr>
|-
! ?
| ? || ? || ? || ? || ?
|-
! [[3.66_CEX|3.66]]
| 2.971.976 || style="font-family:monospace" | 9586FC8B121E59526C31405DCFFB79CA || 11/06/16/03:54 || ? || ?
|-{{cellcolors|#bbbbff}}
! [[3.70_CEX|3.70]]
| rowspan="3" | 2.972.168 || style="font-family:monospace" | AA1DB63461EE0BE021ED45F85A6EECE0 || 11/08/05/03:43 || rowspan="3" | same || rowspan="3" | ?
|-{{cellcolors|#bbbbff}}
! ~
| colspan="2" style="text-align:center; background-color:#bbbbff;" | ''Any''
|-{{cellcolors|#bbbbff}}
! [[3.72_CEX|3.72]]
| style="font-family:monospace" | 32F45129EC2844D419582912E54CEB22 || 11/09/14/01:18
|-{{cellcolors|#ddddff}}
! [[3.73_CEX|3.73]]
| rowspan="2" | 2.972.168 || style="font-family:monospace" | 17063FFAB205B72ABF7F59582B8A7988 || 11/10/04/12:56 || rowspan="2" | same || rowspan="2" | ?
|-{{cellcolors|#ddddff}}
! [[3.74_CEX|3.74]]
| style="font-family:monospace" | 89C03D80ACE7C4FA914DD699621EB4F8 || 11/10/25/00:40
|-{{cellcolors|#bbbbff}}
! [[4.00_CEX|4.00]]
| rowspan="2" | 2.977.128 || style="font-family:monospace" | DBB8FB62BE3F2064D31332FCB7575DF1 || 11/11/22/03:19 || rowspan="2" | same || rowspan="2" | ?
|-{{cellcolors|#bbbbff}}
! [[4.01_CEX|4.01]]
| style="font-family:monospace" | 9E60379FA979B0440C27C6AEE38754AF || 11/12/23/01:10
|-{{cellcolors|#ddddff}}
! [[4.10_CEX|4.10]]
| rowspan="2" | 2.977.208 || style="font-family:monospace" | B3CD41AB8235906AB41D3DA18D04F00E || 12/02/05/23:19 || rowspan="2" | same || rowspan="2" | ?
|-{{cellcolors|#ddddff}}
! [[4.11_CEX|4.11]]
| style="font-family:monospace" | 4DDF2C3289AD9BEDF0719DBE1BDA971C || 12/02/11/07:15
|-
! [[4.15_CEX|4.15]]
| ? || ? || ? || ? || ?
|-{{cellcolors|#bbbbff}}
! [[4.20_CEX|4.20]]
| rowspan="2" | 2.977.432 || style="font-family:monospace" | 363A2D5EE2246E9CEFCBF1078593C771 || 12/06/15/02:10 || rowspan="2" | same || rowspan="2" | ?
|-{{cellcolors|#bbbbff}}
! [[4.21_CEX|4.21]]
| style="font-family:monospace" | 5E08C86EC07E4F227D3591DD9530CC95 || 12/06/30/01:15
|-
! [[4.23_SEX|4.23 S]]
| 2.977.416 || style="font-family:monospace" | 149E5E6AD727B1B37E29D4E8D15D5BB0 || 12/07/31/00:23 || ? || ?
|-
! [[4.25_CEX|4.25]]
| 2.977.432 || style="font-family:monospace" | 295B61D9EEE704077FEC870C8EAC7D35 || 12/09/07/07:04 || <abbr title="same code than 4.20 CEX and 4.21 CEX.... but different than the 4.23 SEX in between, grrrr">same</abbr> || ?
|-
! ?
| ? || ? || ? || ? || ?
|-
! ?
| ? || ? || ? || ? || ?
|-
! ?
| ? || ? || ? || ? || ?
|-
! [[4.78_CEX|4.78]]
| 2.913.480 || style="font-family:monospace" | 398A7CA9F0E8449E15FCB33B87C96194 || 15/12/17/01:19 || ? || ?
|-
! [[4.80_CEX|4.80]]
| ? || ? || ? || ? || ?
|-
! [[4.81_CEX|4.81]]
| 2.913.656 || style="font-family:monospace" | 8765A00EE467B8635A13ECCBB1F85B89 || 16/10/24/19:24 || ? || ?
|-
! [[4.82_CEX|4.82]]
| 2.913.752 || style="font-family:monospace" | FCEB6595F9F8E5C77BA36C73C38397D9 || 17/08/24/15:43 || ? || ?
|-
! colspan="6" style="background:#80ff80; line-height:75%" | Abandoned (last revision)
|-{{cellcolors|#ddddff}}
! [[4.83_CEX|4.83]]
| rowspan="3" | 2.913.992 || style="font-family:monospace" | CA9509623B9885E18D12E14FA1488EEF || 18/09/02/18:03 || rowspan="3" | 11624 || rowspan="3" | 0x3C
|-
! ~
| colspan="2" style="text-align:center; background-color:#ddddff;" | ''Any''
|-
! [[4.89_CEX|4.89]]
| style="background-color:#ddddff; font-family:monospace" | AE51D20A9E9564A135800E0F0AFC3F53 || style="background-color:#ddddff;" | 22/02/04/14:39
|}
<span style="font-size:small">
{{dot}}'''Decrypted (elf)''': changes <abbr title="When comparing two decrypted files of the same revision from different firmwares the only differences are the build label (1 area with size 0x20) and the target firmware (2 areas with size 0x2)">every firmware version</abbr><br>
{{dot}}'''<abbr title="0x20 bytes">Build label</abbr>''': yes, with timestamp, search for '''-sgpu-sli4'''<br>
{{dot}}'''<abbr title="2 bytes">Target Firmware</abbr>''': yes repeated '''two''' times<br>
{{dot}}'''Revision''': <abbr title="ps1_netemu.self from firmware 2.10 (or older) doesnt contains the revision string">sometimes</abbr>, search for '''Revision'''
</span>
</div><div style="float:left;">
{| class="wikitable" style="line-height:100%; font-size:70%; margin-left:5px; margin-right:5px"
|+ ps1_newemu.elf (decrypted)<br><div style="height:5px"></div>
! Firmware !! Size !! MD5 !! Timestamp !! <abbr title="Revision">Rev</abbr> !! style="padding:1px" | <abbr title="Maximun number of supported commands">Comm</abbr>
|-
! [[2.10_CEX|2.10]]
| 2.763.848 || style="font-family:monospace" | C792C72A06B94705374B846B94981B1A || 07/12/15/05:31 || ? || <abbr title="Highest Command ID used in the configs">0x19?</abbr>
|-
! ?
| ? || ? || ? || ? || ?
|-
! [[3.40_CEX|3.40]]
| 2.708.856 || style="font-family:monospace" | C866D54E85BAA06D111C8300F9EA85F1 || 10/06/23/15:51 || ? || <abbr title="Highest Command ID used in the configs">0x18?</abbr>
|-
! ?
| ? || ? || ? || ? || ?
|-
! [[3.66_CEX|3.66]]
| 2.708.864 || style="font-family:monospace" | 9AB86CFAEB12675F3DB08FCAA3541534 || 11/06/16/03:54 || ? || ?
|-{{cellcolors|#bbbbff}}
! [[3.70_CEX|3.70]]
| rowspan="3" | 2.708.880 || style="font-family:monospace" | 7AB7C32901778E3F0C9B8DB45296821B || 11/08/05/03:44 || rowspan="3" | same || rowspan="3" | ?
|-{{cellcolors|#bbbbff}}
! ~
| colspan="2" style="text-align:center; background-color:#bbbbff;" | ''Any''
|-{{cellcolors|#bbbbff}}
! [[3.72_CEX|3.72]]
| style="font-family:monospace" | 2863E9B70B4FB6C5A0938FF508C46057 || 11/09/14/01:18
|-{{cellcolors|#ddddff}}
! [[3.73_CEX|3.73]]
| rowspan="2" | 2.708.880 || style="font-family:monospace" | 871E256771632569D664FF2A1ECE82C3 || 11/10/04/12:57 || rowspan="2" | same || rowspan="2" | ?
|-{{cellcolors|#ddddff}}
! [[3.74_CEX|3.74]]
| style="font-family:monospace" | 8A8AC80CBA58561CC754C6CF66B059AB || 11/10/25/00:40
|-{{cellcolors|#bbbbff}}
! [[4.00_CEX|4.00]]
| rowspan="2" | 2.713.832 || style="font-family:monospace" | F9E840430B2BC982CB1A71B7BDD7FC35 || 11/11/22/03:19 || rowspan="2" | same || rowspan="2" | ?
|-{{cellcolors|#bbbbff}}
! [[4.01_CEX|4.01]]
| style="font-family:monospace" | 953090CBCB96626899731B711B3D5B6A || 11/12/23/01:11
|-{{cellcolors|#ddddff}}
! [[4.10_CEX|4.10]]
| rowspan="2" | 2.713.720 || style="font-family:monospace" | 47E7FA52DB7BDEDF2187EB02D868834D || 12/02/05/23:20 || rowspan="2" | same || rowspan="2" | ?
|-{{cellcolors|#ddddff}}
! [[4.11_CEX|4.11]]
| style="font-family:monospace" | 8A90DB2A206BE79423A99D4CF2458241 || 12/02/11/07:16
|-
! [[4.15_CEX|4.15]]
| ? || ? || ? || ? || ?
|-{{cellcolors|#bbbbff}}
! [[4.20_CEX|4.20]]
| rowspan="2" | 2.713.904 || style="font-family:monospace" | 8AC80356D1EFDDCFF7A7AD82136137D2 || 12/06/15/02:11 || rowspan="2" | same || rowspan="2" | ?
|-{{cellcolors|#bbbbff}}
! [[4.21_CEX|4.21]]
| style="font-family:monospace" | E482927E47B00C1478313E343DD652C4 || 12/06/30/01:15
|-
! [[4.23_SEX|4.23 S]]
| 2.713.888 || style="font-family:monospace" | A2CF9C4C00B40779FB5C529849E0D6A4 || 12/07/31/00:24 || ? || ?
|-
! [[4.25_CEX|4.25]]
| 2.713.904 || style="font-family:monospace" | 24107753F0B02075DAB20492BA67167D || 12/09/07/07:05 || <abbr title="same code than 4.20 CEX and 4.21 CEX.... but different than the 4.23 SEX in between, grrrr">same</abbr> || ?
|-
! ?
| ? || ? || ? || ? || ?
|-
! ?
| ? || ? || ? || ? || ?
|-
! ?
| ? || ? || ? || ? || ?
|-
! [[4.78_CEX|4.78]]
| 2.649.144 || style="font-family:monospace" | BF78A0DC74084B43777A7F8CE6C7B66A || 15/12/17/01:20 || ? || ?
|-
! [[4.80_CEX|4.80]]
| ? || ? || ? || ? || ?
|-
! [[4.81_CEX|4.81]]
| 2.649.272 || style="font-family:monospace" | 0C76DE974439B12546EA494639C8EE9A || 16/10/24/19:25 || ? || ?
|-
! colspan="6" style="background:#80ff80; line-height:75%" | Abandoned (last revision)
|-{{cellcolors|#ddddff}}
! [[4.82_CEX|4.82]]
| rowspan="3" | 2.649.288 || style="font-family:monospace" | C5957F268EE9E1429DE3AF0BC15F1395 || 17/08/24/15:44 || rowspan="3" | Last || rowspan="3" | 0x18
|-
! ~
| colspan="2" style="text-align:center; background-color:#ddddff;" | ''Any''
|-
! [[4.89_CEX|4.89]]
| style="background-color:#ddddff; font-family:monospace" | F3739EB5CB787316B614F0CF244726D2 || style="background-color:#ddddff;" | 22/02/04/14:39
|}
<span style="font-size:small">
{{dot}}'''Decrypted (elf)''': changes <abbr title="When comparing two decrypted files of the same revision from different firmwares the only differences are the build label (1 area with size 0x20) and the target firmware (2 areas with size 0x2)">every firmware version</abbr><br>
{{dot}}'''<abbr title="0x20 bytes">Build label</abbr>''': yes, with timestamp, search for '''-sgpu-sspu-sli4'''<br>
{{dot}}'''<abbr title="2 bytes">Target Firmware</abbr>''': yes repeated '''two''' times<br>
{{dot}}'''Revision''': unknown
</span>
</div>
</div>
<br style="clear: both;" />


=== Savegames ===
== PS1 emulators workload comparison ==
*Location: /dev_hdd0/savedata/vmc
Note: capitalisation of filename is important: name it xxx.VM1 instead of xxxx.vm1 (e.g. Internal Memory Card.VM1 for PSX/PSone, Internal Memory Card.VM2 for PS2/PStwo)
 
The .VMx files appear to be raw memory card data:
* [[PS1_Savedata#Virtual_Memory_Card_PS1_.28.VM1.29 | .VM1 Playstation 1 Memory cards]] can be edited with [[PS1_Savedata#Memory_Card_Tools_PS1 | MemcardRex]]
* [[PS2_Savedata#Virtual_Memory_Card_PS2_.28.VM2.29 | .VM2 Playstation 2 Memory cards]] can be edited with [http://www.csclub.uwaterloo.ca:11068/mymc/ mymc]
 
==PS1 emulators workload comparison==


All emulators seems to use similar workload. Note that SPU 0-4 don't use JOB name per se, so is just info what they do.
All emulators seems to use similar workload. Note that SPU 0-4 don't use JOB name per se, so is just info what they do.
Line 120: Line 461:
| PPU:1 || ? || ? ||
| PPU:1 || ? || ? ||
|}
|}
== PS1 BIOS ==
The PS1 emulators included in between PS3 firmwares [[1.00_AV|1.00]] up to [[2.01_CEX|2.01]] contains a PS1 BIOS embedded inside the emulator .SELF structure<br>
In PS3 firmware [[2.10_CEX|2.10]] (at the same time the ps1_newemu.self was introduced) the PS1 BIOS was extracted from the .SELF and shipped as an independant file named ps1_rom.bin. This BIOS have a size of 4.089.584 bytes (MD5: FBB5F59EC332451DEBCCF1E377017237) and is exactly the same file that was previously embedded in all PS1 emulators<br>
In PS3 firmware [[4.00_CEX|4.00]] the ps1_rom.bin file was reduced in size down to 524.288 bytes (MD5: 81BBE60BA7A3D1CEA1D48C14CBCC647B) by removing the unrelated PS2 functions<br>
The latest version of ps1_rom file is the first 512KB of the 1.90 PS2 rom.<br>
{| class="wikitable" style="line-height:110%; font-size:90%"
|+ ps1_rom.bin<br><div style="height:5px"></div>
! Firmware !! Size !! MD5
|-
! [[2.10_CEX|2.10]] ~ [[3.74_CEX|3.74]]
| 4.089.584 || style="font-family:monospace" | FBB5F59EC332451DEBCCF1E377017237
|-
! [[4.00_CEX|4.00]] ~ [[4.88_CEX|4.88]]
| 524.288 || style="font-family:monospace" | 81BBE60BA7A3D1CEA1D48C14CBCC647B
|}
The PS1 BIOS version can be seen in a string (codenamed VERSTR) with this text, where the last character of the first text row with the suffix "'''A'''" indicates the region (A=America, E=Europe, J=Japan). This character is always located at offset 0x7FF52 in all PS1 and PS2 bios/roms
<pre>System ROM Version 5.0 06/23/03 A
Copyright 1993-1999 (C) Sony Computer Entertainment Inc.
</pre>
On PCSX2 while in PS1 mode the latest versions of the "'''J'''" and "'''E'''" roms/bios are not able to load the games from all regions because was added an additional '''CD licence check''' that only accepts the discs matching the hardcoded region<br>
The  "'''A'''" roms/bios are able to load all regions games because doesnt have this check. It happens the same in the PS2 roms/bios, only the "'''A'''" ones accepts the games from all regions by default (this is why you have to patch the MECHACON for the US DTL region to get true region free playback)<br>
The bios included in the PS3 firmwares is the "'''A'''" version, so it doesnt have this check, and allows the version string to be patched to replace the suffix "'''A'''" by "'''E'''" or "'''J'''" as explained below
=== PS1 BIOS Region patch ===
Inside the emulators there is a string with the characters: <span style="font-familly:monospace; font-weight:bold">JJJJAEJEAEJJEJJA</span> that works as a selector based on the [[Product Code]] (also known as TargetID, and located inside the [[IDPS]])<br>
When the emulators are executed (inmediatly before booting the game) the PS3 does a check to the [[Product Code]], then the PS1 BIOS is loaded into memory and a patch is applyed to the version string to replace the suffix "'''A'''" by one of the characters from the selector string<br>
This patch is related to the region, there are only 3 posible results for it, '''A'''=America, '''E'''=Europe, '''J'''=Japan. It changes the video output, and is unknown if is responsible for anything else, like timings etc...
<div style="overflow-x:auto">
{|class="wikitable" style="line-height:110%; font-size:90%"
|-style="text-align:center"
! Console Type
| {{NOT_IN_USE}} || class="nowrap" | {{TOOL}} {{SD}} || class="nowrap" | {{DEX}} {{DTCP-IP}} {{TEST}} || colspan="13" | {{CEX}} {{SHOP}}
|-style="text-align:center; font-weight:bold"
! [[SKU_Regioning|Release Region]]
| colspan="3" | WorldWide || Japan || US<br>Canada || Europe || Korea || U.K.<br>Ireland || Mexico || Australia<br>New Zealand || Singapore<br>Malaysia || Taiwan || Russia<br>Ukraine<br>India || China || Hong Kong || Brazil
|-style="text-align:center"
! [[SKU_Models|PS3 Models]]
| style="background:lightgrey" | N/A || DECR-xx'''00'''<br>DEH-Zxx'''00''' || DECH-xx'''00'''&nbsp;&nbsp;<br>DECH-Sxx'''00''' || CECHx'''00'''&nbsp;&nbsp;&nbsp;<br>CECH-xx'''00''' || CECHx'''01'''&nbsp;&nbsp;&nbsp;<br>CECH-xx'''01''' || CECHx'''04'''&nbsp;&nbsp;&nbsp;<br>CECH-xx'''04''' || CECHx'''05'''&nbsp;&nbsp;&nbsp;<br>CECH-xx'''05''' || CECHx'''03'''&nbsp;&nbsp;&nbsp;<br>CECH-xx'''03''' || CECHx'''11'''&nbsp;&nbsp;&nbsp;<br>CECH-xx'''11''' || CECHx'''02'''&nbsp;&nbsp;&nbsp;<br>CECH-xx'''02''' || CECHx'''06'''&nbsp;&nbsp;&nbsp;<br>CECH-xx'''06''' || CECHx'''07'''&nbsp;&nbsp;&nbsp;<br>CECH-xx'''07''' || CECHx'''08'''&nbsp;&nbsp;&nbsp;<br>CECH-xx'''08''' || style="background:lightgrey" | N/A || CECHx'''12'''&nbsp;&nbsp;&nbsp;<br>CECH-xx'''12''' || CECHx'''14'''&nbsp;&nbsp;&nbsp;<br>CECH-xx'''14'''
|-style="text-align:center; font-weight:bold"
! [[Product Code]]
| 0x80 || 0x81 || 0x82 || 0x83 || 0x84 || 0x85 || 0x86 || 0x87 || 0x88 || 0x89 || 0x8A || 0x8B || 0x8C || 0x8D || 0x8E || 0x8F
|-style="text-align:center"
! [[SKU_Regioning|PS1 PS2 Region]]
| colspan="3" | NTSC-J || NTSC-J || NTSC-U/C || PAL || NTSC-J || PAL || NTSC-U/C || PAL || NTSC-J || NTSC-J || PAL || NTSC-J || NTSC-J || NTSC-U/C
|-style="text-align:center; font-weight:bold"
! PS1 BIOS patch
! J !! J !! J !! J !! A !! E !! J !! E !! A !! E !! J !! J !! E !! J !! J !! A
|}
</div>
As example, in a retail PS3 model released in Europe (Fat=CECHx'''04''' or Slim/SuperSlim CECH-xx'''04''') the version string inside ps1_rom.bin is patched with the suffix "'''E'''" resulting in:
<pre>
System ROM Version 5.0 06/23/03 E
Copyright 1993-1999 (C) Sony Computer Entertainment Inc.
</pre>
==== PS1 BIOS Cobra Patch ====
Every CFW which use cobra module potentially can be affected by nasty bug that is there probably even before 7.00, example based on ps1_emu:
<pre>
SprxPatch ps1_emu_patches[] =
{
{ ps1_emu_get_region_offset, LI(R29, 0x82), &condition_true }, /* regions 0x80-0x82 bypass region check. */
{ 0 }
};
</pre>
The cobra patch is skipping part of code where the region of the PS3 is stored for later usage, and is setting the whole emulation to Japan region (NTSC U/C) by applying an static hard patch that belongs to [[Product Code]] '''0x82''' (a debug DECH-xx'''00''' PS3 model) potentially leading to PAL games frame pacing issues, desynced audio, and maybe more. While i can't test that i'm 100% sure that better solution here will be read third character of Title ID from SYSTEM.CNF file of disc/iso, and then applying a dynamic patch based on it<br>
If the game Title ID have an "'''E'''" (example: SLES-12345) then patch to ANY EU target ID, similar for US, for titles where U or E isn't found just use default J target ID
<pre>
SprxPatch ps1_emu_patches[] =
{
{ ps1_emu_get_region_offset, LI(R29, title_id_based_region), &condition_true }, /* Dynamic patch based on TitleID. */
{ 0 }
};
</pre>
=== PS1 BIOS Replacements ===
Is worth to note the suffix "'''A'''", "'''E'''", or "'''J'''" in the version string inside the BIOS is always on the same offset in ALL PS1 and PS2 bios images. So in case of replacing the bios the patches mentioned above will be applyed normally<br>
The bios can be replaced by any PS1 rom image (included DTL models), and by most PS2 rom images (maybe by all, deckard models untested). Replacing it by the original PS1 bios restores the Sony logo at start up, and is able to run PS1 menu alone (unmounting disc image with WebMAN during Sony Computer Entertainment logo). Both memory card and CD player are fully accessible. Remounting a disc image (regardless if different than the one started with) will work and boot to PlayStation logo from main menu. Props to Jabu, iirc he figured out running Sony startup screen ages ago<br>
The emulator have a bug (netemu at least) that loads the bios with a fixed size of 4MB file. They probably not changed that size after they reduced the bios file size from 4MB to 512KB. So any PS1/PS2(no deckard) bios image can be used if it have a size of 4MB or smaller. All of them should load games fine.
==PS1 GPU emulation==
That part of all 3 emulators is quite impressive. Task is split between 4 SPE cores, but not in usual way.
Every core is responsible for different part of PS1 GPU command flow, which is done dynamically. All that is linked by so called sli (spu link?), and all SPE cores run exactly same elf file.
SPE program synchronize using sliTick, and sliTock functions with use of channels 16 - 24, and with help of PPU.
That way 4 different PS1 GPU emulators can proceed 4 different PS1 GPU commands at the same time, with synchronization enough to not override other PS1 GPU tasks.
As a example you can remove dithering by patch only on SPU0, and observe that only 1/4 of displayed lines will be missing dither pattern.
== PSone Classic format ==
See: [[ISO.BIN.EDAT]] and [[PSISOIMG0000]]
* Savegames Location: /dev_hdd0/savedata/vmc
Note: capitalisation of filename is important: name it xxx.VM1 instead of xxxx.vm1 (e.g. Internal Memory Card.VM1 for PSX/PSone, Internal Memory Card.VM2 for PS2/PStwo)
The .VMx files appear to be raw memory card data:
* [[PS1_Savedata#Virtual_Memory_Card_PS1_.28.VM1.29 | .VM1 Playstation 1 Memory cards]] can be edited with [[PS1_Savedata#Memory_Card_Tools_PS1 | MemcardRex]]
* [[PS2_Savedata#Virtual_Memory_Card_PS2_.28.VM2.29 | .VM2 Playstation 2 Memory cards]] can be edited with [http://www.csclub.uwaterloo.ca:11068/mymc/ mymc]
=== PSone Classic Tools ===
*Latest psxtract by kozarovv (release date 2022/01/30) adds support to subchannel data extraction for single and multi disc PSone Classic games (used by libcrypt protected PAL games). Based on https://github.com/DeadlySystem/psxtract-2 (Only Windows version is updated, Linux code is not updated). Please mirror or even make pr on github if that's prefered. '''[https://www.mediafire.com/file/ytg875p1a6ph89f/psxtract-2-master.zip/file Download]''' (source plus exe)
*Other psxtract versions commented [https://www.psx-place.com/threads/ive-made-a-new-version-of-xdontnanos-psxtract.35541/#post-314241 here]


== Arguments ==
== Arguments ==
Line 197: Line 643:
|}
|}


==PS1 GPU emulation==
== PS1 games management in multiman ==
=== Manual starting SELF method ===
#Insert PSX/PSone disc (region/pressed doesn't matter)
#Start MultiMAN (e.g. 2.07.01++)
::*Since 02.07.05 the PSX and PS2 discs are properly detected. PSX discs will show in XMB Game Column and you can launch the PS1 game from there. It uses ps1_emu.self default (you can choose Load or Load (Net), latter uses ps1_netemu).
#Switch to filemanager mode
#Browse to /dev_flash/ps1emu
#Select either one of the ps1 emulation SELF files
 
Note: Some games run better with ps1_emu.self (e.g. Mortal Kombat) while others run better with ps1_netemu.self (e.g. Resident Evil 3). If it doesn't work, try another ps1 emulation SELF file.
 
Downside: memory card options are unavailable unless you created a Virtual Memorycard ''before'' starting MultiMAN (XMB::Category Game:: Memory Card Utility (PS/PS2) > Create a PS1 memory card. Set it to Slot 1 (Press Triangle while selecting the Memory Card, then Assign it). Note: naming it "Internal Memory Card" sometimes works better than other names. MultiMAN 02.07.07 seems to solve the savegame issues.
 
=== Changes in MultiMAN 2.07.00/01 for ps1_emu handling ===
These options where needed to make above work:
* Added: LV2 access rights to use LV1 Storage Manager (syscall 864)
* Added: LV1 patch for user access to sys_storage functions (syscalls 600 to 623)
 
=== Arguments handling===
From multiman.cpp source (line 2502) http://code.google.com/p/multiman/source/browse/source/multiman.cpp?r=8c5b662f1c54d4f95f646949cae3d033b15b1a2e
{{Boxcode|code=<syntaxhighlight lang="c">
{
char* launchargv[9];
memset(launchargv, 0, sizeof(launchargv));
launchargv[0] = (char*)malloc(strlen(mc1)+1); strcpy(launchargv[0], mc1);
launchargv[1] = (char*)malloc(strlen(mc2)+1); strcpy(launchargv[1], mc2);
launchargv[2] = (char*)malloc( 5); strcpy(launchargv[2], "0082");
launchargv[3] = (char*)malloc( 5); strcpy(launchargv[3], "1600");
launchargv[4] = (char*)malloc(10); strcpy(launchargv[4], app_path);
launchargv[5] = (char*)malloc( 2); strcpy(launchargv[5], "1");
launchargv[6] = (char*)malloc( 2); strcpy(launchargv[6], "2"); // full screen on/off = 2/1
launchargv[7] = (char*)malloc( 2); strcpy(launchargv[7], "1"); // smoothing on/off = 1/0
launchargv[8] = NULL;
unload_modules();
exitspawn((const char*) "/dev_flash/ps1emu/ps1_netemu.self", (char* const*)launchargv, NULL, NULL, 0, 1001, SYS_PROCESS_PRIMARY_STACK_SIZE_1M);
}


That part of all 3 emulators is quite impressive. Task is split between 4 SPE cores, but not in usual way.
{
Every core is responsible for different part of PS1 GPU command flow, which is done dynamically. All that is linked by so called sli (spu link?), and all SPE cores run exactly same elf file.
char* launchargv[7];
SPE program synchronize using sliTick, and sliTock functions with use of channels 16 - 24, and with help of PPU.
memset(launchargv, 0, sizeof(launchargv));
That way 4 different PS1 GPU emulators can proceed 4 different PS1 GPU commands at the same time, with synchronization enough to not override other PS1 GPU tasks.
launchargv[0] = (char*)malloc(strlen(mc1)+1); strcpy(launchargv[0], mc1);
As a example you can remove dithering by patch only on SPU0, and observe that only 1/4 of displayed lines will be missing dither pattern.
launchargv[1] = (char*)malloc(strlen(mc2)+1); strcpy(launchargv[1], mc2);
launchargv[2] = (char*)malloc( 5); strcpy(launchargv[2], "0082"); // region
launchargv[3] = (char*)malloc( 5); strcpy(launchargv[3], "1200");
launchargv[4] = (char*)malloc( 2); strcpy(launchargv[4], "1"); // full screen on/off = 2/1
launchargv[5] = (char*)malloc( 2); strcpy(launchargv[5], "1"); // smoothing on/off = 1/0
launchargv[6] = NULL;
unload_modules();
exitspawn((const char*) "/dev_flash/ps1emu/ps1_emu.self", (char* const*)launchargv, NULL, NULL, 0, 1001, SYS_PROCESS_PRIMARY_STACK_SIZE_1M);
}
</syntaxhighlight>}}
*Notes:
**The '''''full screen''''' commented argument seems to be the '''Upscaler''' setting available from XMB {{icon category settings}} ⇨ '''[Game Settings]''' ⇨ '''[PS/PS2 Upscaler]''', with values: '''full/normal/off = 2/1/0'''


== Game settings ==
== Game settings ==
Line 251: Line 743:


=== Embedded Game settings ===
=== Embedded Game settings ===
All the PS1 emulators contains a list of game settings embedded inside his .SELF structure inside 3 tables we could name the '''Checksums Table''', the '''Title IDs table''' (is the only in human readable format), and the '''Commands Data Table'''. The offset of this tables differs by emulator revision and by emulator type<br><!-- as far i know there is not a known way to find his offsets programatically, other than doing a search for a well known value, usually the first checksum-->
All the PS1 emulators contain a list of game settings embedded inside his .SELF structure inside 3 tables we could name the '''Checksums Table''', the '''Titles table''', and the '''Commands Table'''. The offsets of this tables differs by emulator revision and type<br><!-- as far i know there is not a known way to find his offsets programatically, other than doing a search for a well known value, usually the first checksum-->
The entry point to read the whole structure of this tables starts by reading the 4 bytes of the first checksum from the checksums table (see below), next 4 bytes are an offset (to read the Title IDs table), next 4 bytes is a '''Command Count''' and next 4 bytes is a '''Command offset''' (to read the Commands Data Table), to load the data in the other tables is needed to substract 0x10000 to this offsets located next to the checksum of a specific game<br>
The entry point to read the whole structure of this tables starts by reading the 4 bytes of the first '''Checksum''' of the first game from the checksums table (see below), next 4 bytes are an offset (to read the Titles table), next 4 bytes is a '''Command Count''' and next 4 bytes is a '''Command offset''' (to read the Commands Table), to load the data in the other tables is needed to <abbr title="Or substract 0xFEB0000 in firmware 1.70 and keep in mind the order of the commands table is inverted">substract 0x10000</abbr> to this offsets located next to the checksum of a specific game<br>
Every command inside the Commands Data Table is composed by 8 bytes, where the first 4 bytes are the '''Command ID''' (see talk page) and the next 4 bytes is the '''Command Data'''<br>
The Title IDs (from inside the '''Titles table''') doesnt seems to be used for any logic check, seems to be mostly identifyers (with typos) intended to be displayed in some kind of debug menu in "human readable format" only for informative purposes. Are text strings null terminated in the format "ABCD_123.45" and aligned to 8 bytes, so most of them have a total size of 0x10 but in old firmwares there are some entries with the text "unknown" with a size of 8 bytes (in other words, the entries with the text "unknown" are half the size of the others)<br>
Every command inside the Commands Table is composed by 8 bytes, where the first 4 bytes are the '''Command ID''' (see talk page) and the next 4 bytes is the '''Command Data'''<br>
All the '''Command Data''' values can be considered the most bottom of this hierarchy... except command ID=0x02(netemu 3.40 up to 4.88) containing an offset to a deeper level of the hierarchy where is stored a list with some of the disc sectors for a few libcrypt protected games
All the '''Command Data''' values can be considered the most bottom of this hierarchy... except command ID=0x02(netemu 3.40 up to 4.88) containing an offset to a deeper level of the hierarchy where is stored a list with some of the disc sectors for a few libcrypt protected games


==== Sector 16 checksum ====
==== Game checksum ====
Checksum is simple Adler32 calculated from 2048 bytes of disc data, starting from 0x9318 offset in raw image. Emulator perform check if that sector have CD001 string, if string is missing "unknown" string is used, and hash calculation is not performed. You can use tools like hashtab to easily calculate checksum for new game.<br>
Checksum is simple Adler32 calculated from 2048 bytes of disc data, starting from 0x9318 offset in raw image. Emulator perform check if that sector have CD001 string, if string is missing "unknown" string is used, and hash calculation is not performed. You can use tools like hashtab to easily calculate checksum for new game.<br>
Is calculated using the data contents only (2048 bytes or 0x800h) of the sector 16 (beginning at the 0x9318 of the RAW/2352 image). Every single byte is used in the process. Calculation code does start at 0xC1658 in the ps1_netemu from 4.88 firmware.
Is calculated using the data contents only (2048 bytes or 0x800h) of the sector 16 (beginning at the 0x9318 of the RAW/2352 image). Every single byte is used in the process. Calculation code does start at 0xC1658 in the ps1_netemu from 4.88 firmware.
Line 320: Line 813:
     print (hex(suma))
     print (hex(suma))
</syntaxhighlight>}}
</syntaxhighlight>}}
==== Game settings access ====
Like mentioned above config is created from 2x u32 values. Lets call first value command, and second value param.<br>
Command is used to calculate address for param, and only param is stored on obtained address.<br>
Emulator then check for params, and if found (usually when not zero) apply settings based on them.<br>
Beside functions that read command params directly, every emulator have function (madeup name) ReadInternalConfigValue(u32 command_id). This function take command_id as only variable, and return param in r3 for selected command. This is used widely to read command params, that include libcrypt commands.
<div class="mw-collapsible mw-collapsed">'''Disassembly of the related function'''<pre class="mw-collapsible-content">
0x10BC8                lwz      r0, 0(r9)      # load HASH
0x10BCC                cmpw      cr7, r0, r27    # compare title HASH with one from DB
0x10BD0                bne      cr7, loc_10BB8  # loop till HASH found
0x10BD4                slwi      r0, r10, 4      # config number << 4 to get offset from first entry in table
0x10BD8                addi      r24, r1, 0xAB0+var_A40
0x10BDC                extsw    r0, r0
0x10BE0                clrldi    r3, r24, 32
0x10BE4                add      r29, r0, r8    # r29 now points to game entry in config table
0x10BE8                lwz      r4, 4(r29)      # load pointer to game ID
0x10BEC                bl        sub_137FF8
0x10BF0                nop
0x10BF4                lwz      r28, 8(r29)
0x10BF8                cmpwi    cr7, r28, 0
0x10BFC                ble      cr7, loc_10C58  # check config count is not 0 or less
0x10C00                lwz      r26, 0xC(r29)  # r26 is now pointer to configs for game
0x10C04                li        r30, 0
0x10C08                li        r29, 0
0x10C0C                lwz      r25, off_17B5D8 # "core.c: CoreCheckTitle: param[%d] = 0x%"...
0x10C10
0x10C10 read_conf_loop:                          # CODE XREF: CoreCheckTitle+2DC↓j
0x10C10                add      r11, r30, r26  # r11 is now pointer to currently read config for game
0x10C14                addi      r29, r29, 1    # count...
0x10C18                clrldi    r11, r11, 32
0x10C1C                mr        r3, r25        # just for print
0x10C20                addi      r30, r30, 8    # add 8 so next time in loop we read new config (4),
0x10C20                                          # and new params (4) if game have more than one config
0x10C24                lwz      r4, 0(r11)      # load command
0x10C28                lwz      r0, 4(r11)      # load params
0x10C2C                slwi      r9, r4, 2      # r9 = r4 << 2 so shift our command to the left by 2, and store in r9
0x10C30                clrldi    r5, r0, 32      # just print again
0x10C34                addi      r9, r9, 0x10    # add 0x10 to shifted command value
0x10C34                                          # to create address where param of config will be stored
0x10C38                extsw    r4, r4
0x10C3C                extsw    r9, r9
0x10C40                add      r9, r9, r31    # r31 is value that change between emu versions.
0x10C40                                          # That way emulator can keep correct config IDs without changes to table.
0x10C40                                          # r31 0x2B0930 + what we currently have in r9 after previous calculations.
0x10C44                stw      r0, 4(r9)      # Store param on finally calculated address + 4. For example for config 04
0x10C44                                          # address will be 0x2B0954.
0x10C48                bl        print_
0x10C4C                nop
0x10C50                cmpw      cr7, r28, r29  # r28 overall config count
0x10C50                                          # r29 currently read count
0x10C54                bne      cr7, read_conf_loop
</pre></div>
Function mentioned above is placed on (in emu memory, 4.86):
* ps1_emu 0x10638
* ps1_newemu 0x12F54
* ps1_netemu 0xB65F0
<!-- strings for printing
CoreCheckTitle: start
CoreCheckTitle: param[%d] = 0x%08xU
CoreCheckTitle: 0x%08xU, "%s" %c
-->


==== Game settings lists ====
==== Game settings lists ====
Line 332: Line 888:
</div></div>{{clear}}
</div></div>{{clear}}


==PS1 rom handling==
Current version of ps1_rom file is first 512KB of 1.90 PS2 rom. Previously it was exactly the same version but whole 4MB were supplied to emulator.<br>
Since firmware 2.10++ all PS1 emulators, ps1_emu.self, ps1_netemu.self, ps1_newemu.self uses the since then added ps1_rom.bin bios file. In earlier firmwares file was embed into every emulator self file. File '''ps1_rom.bin''' is exactly the same file that was previously embed in all PS1 emulators.
{| class="wikitable" style="line-height:110%; font-size:90%"
|+ ps1_rom.bin
! Firmware !! Size !! MD5
|-
! [[2.10_CEX|2.10]] ~ [[3.74_CEX|3.74]]
| 4.089.584 || style="font-family:monospace" | FBB5F59EC332451DEBCCF1E377017237
|-
! [[4.00_CEX|4.00]] ~ [[4.88_CEX|4.88]]
| 524.288 || style="font-family:monospace" | 81BBE60BA7A3D1CEA1D48C14CBCC647B
|}
===Region patch===
All 3 emulators perform bios patching right after file is loaded into memory. Patch is related to region lock, and is unknown that its responsible for anything else, like timings etc.<br>
There is a string in emulator JJJJAEJEAEJJEJJA which is selector for bios/rom region based on target ID ([[Product_Code]]).
<pre>J    J    J    J    A    E    J    E    A    E    J    J    E    J    J    A
0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8A 0x8B 0x8C 0x8D 0x8E 0x8F</pre>
Patch apply to string in VERSTR, '''X''' is replaced with appropriate region:
<pre>System ROM Version 5.0 06/23/03 X
Copyright 1993-1999 (C) Sony Computer Entertainment Inc.
</pre>
Is worth to note that '''X''' is always on the same offset in ALL ps1 bios versions, and all ps2 bios images. So in case of bios swap
([[Talk:PS1_Emulation#ps1_rom.bin]] ) correct region will be still set.<br>
Patched offset is 0x7FF52 in rom file itself. Cobra have region free patch that in the end make X set to A (America) region, which apparently make bios region free. This can be true as similar thing happen on PCSX2 in ps1 mode. US rom is able to run all regions games, while JPN/EU fail to load different regions. It is because later JPN/EU BIOS versions have got an additional CD licence check introduced, accepting only the discs matching the hardcoded region. US BIOSes have never got this check implemented. By the way, it is the same thing with the PS2 BIOSes - only the US one will accept the discs from all over the world by default (that is why you have to patch the MECHACON for the US DTL region to get true region free playback).
==PS1 games management in multiman==
=== Manual starting SELF method ===
#Insert PSX/PSone disc (region/pressed doesn't matter)
#Start MultiMAN (e.g. 2.07.01++)
::*Since 02.07.05 the PSX and PS2 discs are properly detected. PSX discs will show in XMB Game Column and you can launch the PS1 game from there. It uses ps1_emu.self default (you can choose Load or Load (Net), latter uses ps1_netemu).
#Switch to filemanager mode
#Browse to /dev_flash/ps1emu
#Select either one of the ps1 emulation SELF files
Note: Some games run better with ps1_emu.self (e.g. Mortal Kombat) while others run better with ps1_netemu.self (e.g. Resident Evil 3). If it doesn't work, try another ps1 emulation SELF file.
Downside: memory card options are unavailable unless you created a Virtual Memorycard ''before'' starting MultiMAN (XMB::Category Game:: Memory Card Utility (PS/PS2) > Create a PS1 memory card. Set it to Slot 1 (Press Triangle while selecting the Memory Card, then Assign it). Note: naming it "Internal Memory Card" sometimes works better than other names. MultiMAN 02.07.07 seems to solve the savegame issues.
=== Changes in MultiMAN 2.07.00/01 for ps1_emu handling ===
These options where needed to make above work:
* Added: LV2 access rights to use LV1 Storage Manager (syscall 864)
* Added: LV1 patch for user access to sys_storage functions (syscalls 600 to 623)
=== Arguments handling===
From multiman.cpp source (line 2502) http://code.google.com/p/multiman/source/browse/source/multiman.cpp?r=8c5b662f1c54d4f95f646949cae3d033b15b1a2e
{{Boxcode|code=<syntaxhighlight lang="c">
{
char* launchargv[9];
memset(launchargv, 0, sizeof(launchargv));
launchargv[0] = (char*)malloc(strlen(mc1)+1); strcpy(launchargv[0], mc1);
launchargv[1] = (char*)malloc(strlen(mc2)+1); strcpy(launchargv[1], mc2);
launchargv[2] = (char*)malloc( 5); strcpy(launchargv[2], "0082");
launchargv[3] = (char*)malloc( 5); strcpy(launchargv[3], "1600");
launchargv[4] = (char*)malloc(10); strcpy(launchargv[4], app_path);
launchargv[5] = (char*)malloc( 2); strcpy(launchargv[5], "1");
launchargv[6] = (char*)malloc( 2); strcpy(launchargv[6], "2"); // full screen on/off = 2/1
launchargv[7] = (char*)malloc( 2); strcpy(launchargv[7], "1"); // smoothing on/off = 1/0
launchargv[8] = NULL;
unload_modules();
exitspawn((const char*) "/dev_flash/ps1emu/ps1_netemu.self", (char* const*)launchargv, NULL, NULL, 0, 1001, SYS_PROCESS_PRIMARY_STACK_SIZE_1M);
}
{
char* launchargv[7];
memset(launchargv, 0, sizeof(launchargv));
launchargv[0] = (char*)malloc(strlen(mc1)+1); strcpy(launchargv[0], mc1);
launchargv[1] = (char*)malloc(strlen(mc2)+1); strcpy(launchargv[1], mc2);
launchargv[2] = (char*)malloc( 5); strcpy(launchargv[2], "0082"); // region
launchargv[3] = (char*)malloc( 5); strcpy(launchargv[3], "1200");
launchargv[4] = (char*)malloc( 2); strcpy(launchargv[4], "1"); // full screen on/off = 2/1
launchargv[5] = (char*)malloc( 2); strcpy(launchargv[5], "1"); // smoothing on/off = 1/0
launchargv[6] = NULL;
unload_modules();
exitspawn((const char*) "/dev_flash/ps1emu/ps1_emu.self", (char* const*)launchargv, NULL, NULL, 0, 1001, SYS_PROCESS_PRIMARY_STACK_SIZE_1M);
}
</syntaxhighlight>}}
*Notes:
**The '''''full screen''''' commented argument seems to be the '''Upscaler''' setting available from XMB {{icon category settings}} ⇨ '''[Game Settings]''' ⇨ '''[PS/PS2 Upscaler]''', with values: '''full/normal/off = 2/1/0'''
{{Reverse engineering}}<noinclude>[[Category:Main]]</noinclude>
{{Reverse engineering}}<noinclude>[[Category:Main]]</noinclude>

Latest revision as of 14:33, 20 August 2024

Description[edit | edit source]

Note: there are no PS1 emulators available in early Tool/DECR and Debug/DEX firmwares (does not have dev_flash/ps1emu or ps2emu folder. dev_flash/vsh/etc/version.txt & index.dat say: ¨ps1emu:NA@NA: ps2emu:NA@NA: ps2gxemu:NA@NA: emerald:NA@NA: bdp:NA@NA:¨).

Firmware changes related with PS1 emulation
  • Firmware 1.02:
    • Added ps1_emu.self
  • Firmware 1.70:
    • Added ps1_netemu.self
    • Added the ability to play original PlayStation format games downloaded from the PlayStation Store.
    • Added rumble functionality for USB accessories which support it when playing PS2 games.
    • Saved data from PlayStation format software now usable on both PSP and PS3 systems.
    • Backwards compatibility for PS1 and PS2 games was improved.
  • Firmware 1.80:
    • Ability to upscale PS1 and PS2 games
    • Ability to copy PS1/PS2 game saves from PS3 to Memory Cards using a Memory Card adapter.
    • Backwards compatibility for PS1 and PS2 games was improved.
  • Firmware 2.10:
    • Added ps1_newemu.self
    • Added ps1_rom.bin (MD5: FBB5F59EC332451DEBCCF1E377017237)
    • Users can now play PS1 game discs on a PSP with remote play, PSP firmware version 3.50 or newer is required. (this feature was not announced).
    • Backwards compatibility for PS1 and PS2 games was improved (Update was also unannounced but evident in Sony's backwards compatibility search site).
  • Firmware 4.00
    • Updated ps1_rom.bin (MD5: 81BBE60BA7A3D1CEA1D48C14CBCC647B). The new rom is stripped from PS2 related functions. As a result is 3565296 bytes smaller than previous version.

PS1 Emulator Types and Revisions[edit | edit source]

PS1 Emulator Types and Revisions
ps1_emu.elf (decrypted)
Firmware Size MD5 Timestamp Rev Comm
1.00 AV 10 296 408 981A7428C2A59219FA05861EDEEDBD4A 06/10/04/12:16 ? ?
1.02 10.296.408 C5FE03742A951194C336EE33783F5CD6 06/10/21/00:01 ? ?
1.10 10.296.408 C9C9D7D2E36F3E3579A5DF713E9ABE1E 06/11/09/06:09 ? ?
1.11 10.296.408 26271CCA29B77483DC3D7FDDE7B9CC3C 06/11/21/17:55 ? ?
1.30 10.296.496 E7932EC24E72B3005EE152B141A63690 06/12/05/05:34 ? ?
1.31 10.296.496 2244DE70C85093D7E37BC3D3F4278BE1 06/12/12/18:48 ? ?
1.32 10.296.496 601BCADBBBC0A2D0433C932A2D67C4EF 06/12/18/05:55 ? ?
1.50 10.303.536 F8050B006CDFCC64DF742D7BBDC03130 07/01/18/22:53 ? ?
? ? ? ? ? ?
1.70 6.857.648 EA49942B6789FBE0A1C98BC12E282533 07/04/16/16:12 ? 0x14?
? ? ? ? ? ?
1.90 6.974.864 478CFED0F7EE13C94F01C2A246C83D45 07/07/21/06:45 ? ?
? ? ? ? ? ?
Stripped/extracted rom/bios
2.10 2.887.152 AEE181B061E586F99E76C033C9DCF726 07/12/15/05:30 ? 0x15
? ? ? ? ? ?
3.40 2.824.576 A6ABFB04739575E2264A4D3FEB2A9CBF 10/06/23/15:45 ? ?
? ? ? ? ? ?
3.66 2.824.832 95399A202003E216794511BD2D2E9DF6 11/06/16/03:52 ? ?
3.70 2.824.920 045D81147B9BDFB8C8A416FD5F5A0C56 11/08/05/03:42 same ?
~ Any
3.72 C745A30231103B83F04539021E4878FC 11/09/14/01:17
3.73 2.824.920 EB3AFF30B3206CFA6A8962AB393F773E 11/10/04/12:55 same ?
3.74 E2A77C3DC9FD5AD4264341196462D096 11/10/25/00:38
4.00 2.829.784 94A8E6A8063C08FAD8CA9B340CCCAE67 11/11/22/03:17 same ?
~ Any
4.11 02B7F6D5F517959161B2154135D4B3BC 12/02/11/07:13
4.15 ? ? ? ? ?
4.20 2.829.912 3778948C92F5FA12CB0AABE65BEE5465 12/06/15/02:09 same ?
4.21 B7B662397E3FFDD7C11F9617C1B41856 12/06/30/01:13
4.23 S 2.829.912 6E74CC51E0C6462DF1F9278ED9DB9593 12/07/31/00:22 ? ?
4.25 2.829.912 03EA65C3EA3F8DB04F236C49C6B6C0E1 12/09/07/07:03 same ?
? ? ? ? ? ?
? ? ? ? ? ?
? ? ? ? ? ?
4.78 2.765.488 354F1DEEDCA3C4CFA1B49B6B28B1648D 15/12/17/01:18 ? ?
4.80 ? ? ? ? ?
4.81 2.765.616 2123E3D6A8E81647CB41F51AFEE6CCD6 16/10/24/19:23 ? ?
Abandoned (last revision)
4.82 2.765.616 64BFA4DBD595A20E317B2189B54BF673 17/08/24/15:42 Last 0x15
~ Any
4.89 44F975821FD714E2E810771836178CB3 22/02/04/14:38

 · Decrypted (elf): changes every firmware version
 · Build label: yes, with timestamp, search for -sgpu-sspu-sli4
 · Target Firmware: yes repeated one time
 · Revision: unknown

ps1_netemu.elf (decrypted)
Firmware Size MD5 Timestamp Rev Comm
1.70 6.872.592 5DA8492C4702F94DDDC4530921316789 07/04/16/16:13 ? 0x16?
? ? ? ? ? ?
? ? ? ? ? ?
1.90 6.853.368 8A5A3676B461C97A9A467D5651D6EAAD 07/07/21/06:47 ? ?
? ? ? ? ? ?
Stripped/extracted rom/bios
2.10 2.764.288 7826B1C6799404216D4771C07DE12F53 07/12/15/05:31 ? 0x18?
? ? ? ? ? ?
3.40 2.971.288 FD32C7B7CBA2639FC8DB9EB615A16461 10/06/23/15:46 6520 0x2C?
? ? ? ? ? ?
3.66 2.971.976 9586FC8B121E59526C31405DCFFB79CA 11/06/16/03:54 ? ?
3.70 2.972.168 AA1DB63461EE0BE021ED45F85A6EECE0 11/08/05/03:43 same ?
~ Any
3.72 32F45129EC2844D419582912E54CEB22 11/09/14/01:18
3.73 2.972.168 17063FFAB205B72ABF7F59582B8A7988 11/10/04/12:56 same ?
3.74 89C03D80ACE7C4FA914DD699621EB4F8 11/10/25/00:40
4.00 2.977.128 DBB8FB62BE3F2064D31332FCB7575DF1 11/11/22/03:19 same ?
4.01 9E60379FA979B0440C27C6AEE38754AF 11/12/23/01:10
4.10 2.977.208 B3CD41AB8235906AB41D3DA18D04F00E 12/02/05/23:19 same ?
4.11 4DDF2C3289AD9BEDF0719DBE1BDA971C 12/02/11/07:15
4.15 ? ? ? ? ?
4.20 2.977.432 363A2D5EE2246E9CEFCBF1078593C771 12/06/15/02:10 same ?
4.21 5E08C86EC07E4F227D3591DD9530CC95 12/06/30/01:15
4.23 S 2.977.416 149E5E6AD727B1B37E29D4E8D15D5BB0 12/07/31/00:23 ? ?
4.25 2.977.432 295B61D9EEE704077FEC870C8EAC7D35 12/09/07/07:04 same ?
? ? ? ? ? ?
? ? ? ? ? ?
? ? ? ? ? ?
4.78 2.913.480 398A7CA9F0E8449E15FCB33B87C96194 15/12/17/01:19 ? ?
4.80 ? ? ? ? ?
4.81 2.913.656 8765A00EE467B8635A13ECCBB1F85B89 16/10/24/19:24 ? ?
4.82 2.913.752 FCEB6595F9F8E5C77BA36C73C38397D9 17/08/24/15:43 ? ?
Abandoned (last revision)
4.83 2.913.992 CA9509623B9885E18D12E14FA1488EEF 18/09/02/18:03 11624 0x3C
~ Any
4.89 AE51D20A9E9564A135800E0F0AFC3F53 22/02/04/14:39

 · Decrypted (elf): changes every firmware version
 · Build label: yes, with timestamp, search for -sgpu-sli4
 · Target Firmware: yes repeated two times
 · Revision: sometimes, search for Revision

ps1_newemu.elf (decrypted)
Firmware Size MD5 Timestamp Rev Comm
2.10 2.763.848 C792C72A06B94705374B846B94981B1A 07/12/15/05:31 ? 0x19?
? ? ? ? ? ?
3.40 2.708.856 C866D54E85BAA06D111C8300F9EA85F1 10/06/23/15:51 ? 0x18?
? ? ? ? ? ?
3.66 2.708.864 9AB86CFAEB12675F3DB08FCAA3541534 11/06/16/03:54 ? ?
3.70 2.708.880 7AB7C32901778E3F0C9B8DB45296821B 11/08/05/03:44 same ?
~ Any
3.72 2863E9B70B4FB6C5A0938FF508C46057 11/09/14/01:18
3.73 2.708.880 871E256771632569D664FF2A1ECE82C3 11/10/04/12:57 same ?
3.74 8A8AC80CBA58561CC754C6CF66B059AB 11/10/25/00:40
4.00 2.713.832 F9E840430B2BC982CB1A71B7BDD7FC35 11/11/22/03:19 same ?
4.01 953090CBCB96626899731B711B3D5B6A 11/12/23/01:11
4.10 2.713.720 47E7FA52DB7BDEDF2187EB02D868834D 12/02/05/23:20 same ?
4.11 8A90DB2A206BE79423A99D4CF2458241 12/02/11/07:16
4.15 ? ? ? ? ?
4.20 2.713.904 8AC80356D1EFDDCFF7A7AD82136137D2 12/06/15/02:11 same ?
4.21 E482927E47B00C1478313E343DD652C4 12/06/30/01:15
4.23 S 2.713.888 A2CF9C4C00B40779FB5C529849E0D6A4 12/07/31/00:24 ? ?
4.25 2.713.904 24107753F0B02075DAB20492BA67167D 12/09/07/07:05 same ?
? ? ? ? ? ?
? ? ? ? ? ?
? ? ? ? ? ?
4.78 2.649.144 BF78A0DC74084B43777A7F8CE6C7B66A 15/12/17/01:20 ? ?
4.80 ? ? ? ? ?
4.81 2.649.272 0C76DE974439B12546EA494639C8EE9A 16/10/24/19:25 ? ?
Abandoned (last revision)
4.82 2.649.288 C5957F268EE9E1429DE3AF0BC15F1395 17/08/24/15:44 Last 0x18
~ Any
4.89 F3739EB5CB787316B614F0CF244726D2 22/02/04/14:39

 · Decrypted (elf): changes every firmware version
 · Build label: yes, with timestamp, search for -sgpu-sspu-sli4
 · Target Firmware: yes repeated two times
 · Revision: unknown


PS1 emulators workload comparison[edit | edit source]

All emulators seems to use similar workload. Note that SPU 0-4 don't use JOB name per se, so is just info what they do.

ps1_emu.self
Core Job Source Notes
SPU0 PS1 GPU SLI0 SPU ASM PS1 GPU software emulation
SPU1 PS1 GPU SLI1 SPU ASM PS1 GPU software emulation
SPU2 PS1 GPU SLI2 SPU ASM PS1 GPU software emulation
SPU3 PS1 GPU SLI3 SPU ASM PS1 GPU software emulation
SPU4 PS1 SPU SPU ASM PS1 SPU software emulation
SPU5 _libadec_at3CellSpursKernel0 SPU ASM AT library from ps3 firmware
SPU6 Isolation C++ Raw SPU Not PS1 emu specific
SPU7 - - Unavailable: Factory disabled SPU
PPU:0 ? ?
PPU:1 ? ?
ps1_netemu.self
Core Job Source Notes
SPU0 PS1 GPU SLI0 SPU ASM PS1 GPU software emulation
SPU1 PS1 GPU SLI1 SPU ASM PS1 GPU software emulation
SPU2 PS1 GPU SLI2 SPU ASM PS1 GPU software emulation
SPU3 PS1 GPU SLI3 SPU ASM PS1 GPU software emulation
SPU4 PS1 SPU SPU ASM PS1 SPU software emulation
SPU5 _libadec_at3CellSpursKernel0 SPU ASM AT3 library from ps3 firmware
SPU6 Isolation C++ Raw SPU Not PS1 emu specific
SPU7 - - Unavailable: Factory disabled SPU
PPU:0 ? ?
PPU:1 ? ?
ps1_newemu.self
Core Job Source Notes
SPU0 PS1 GPU SLI0 SPU ASM PS1 GPU software emulation
SPU1 PS1 GPU SLI1 SPU ASM PS1 GPU software emulation
SPU2 PS1 GPU SLI2 SPU ASM PS1 GPU software emulation
SPU3 PS1 GPU SLI3 SPU ASM PS1 GPU software emulation
SPU4 PS1 SPU SPU ASM PS1 SPU software emulation
SPU5 _libadec_at3CellSpursKernel0 SPU ASM AT3 library from ps3 firmware
SPU6 Isolation C++ Raw SPU Not PS1 emu specific
SPU7 - - Unavailable: Factory disabled SPU
PPU:0 ? ?
PPU:1 ? ?

PS1 BIOS[edit | edit source]

The PS1 emulators included in between PS3 firmwares 1.00 up to 2.01 contains a PS1 BIOS embedded inside the emulator .SELF structure
In PS3 firmware 2.10 (at the same time the ps1_newemu.self was introduced) the PS1 BIOS was extracted from the .SELF and shipped as an independant file named ps1_rom.bin. This BIOS have a size of 4.089.584 bytes (MD5: FBB5F59EC332451DEBCCF1E377017237) and is exactly the same file that was previously embedded in all PS1 emulators
In PS3 firmware 4.00 the ps1_rom.bin file was reduced in size down to 524.288 bytes (MD5: 81BBE60BA7A3D1CEA1D48C14CBCC647B) by removing the unrelated PS2 functions
The latest version of ps1_rom file is the first 512KB of the 1.90 PS2 rom.

ps1_rom.bin
Firmware Size MD5
2.10 ~ 3.74 4.089.584 FBB5F59EC332451DEBCCF1E377017237
4.00 ~ 4.88 524.288 81BBE60BA7A3D1CEA1D48C14CBCC647B

The PS1 BIOS version can be seen in a string (codenamed VERSTR) with this text, where the last character of the first text row with the suffix "A" indicates the region (A=America, E=Europe, J=Japan). This character is always located at offset 0x7FF52 in all PS1 and PS2 bios/roms

System ROM Version 5.0 06/23/03 A
Copyright 1993-1999 (C) Sony Computer Entertainment Inc.

On PCSX2 while in PS1 mode the latest versions of the "J" and "E" roms/bios are not able to load the games from all regions because was added an additional CD licence check that only accepts the discs matching the hardcoded region
The "A" roms/bios are able to load all regions games because doesnt have this check. It happens the same in the PS2 roms/bios, only the "A" ones accepts the games from all regions by default (this is why you have to patch the MECHACON for the US DTL region to get true region free playback)
The bios included in the PS3 firmwares is the "A" version, so it doesnt have this check, and allows the version string to be patched to replace the suffix "A" by "E" or "J" as explained below

PS1 BIOS Region patch[edit | edit source]

Inside the emulators there is a string with the characters: JJJJAEJEAEJJEJJA that works as a selector based on the Product Code (also known as TargetID, and located inside the IDPS)
When the emulators are executed (inmediatly before booting the game) the PS3 does a check to the Product Code, then the PS1 BIOS is loaded into memory and a patch is applyed to the version string to replace the suffix "A" by one of the characters from the selector string
This patch is related to the region, there are only 3 posible results for it, A=America, E=Europe, J=Japan. It changes the video output, and is unknown if is responsible for anything else, like timings etc...

Console Type  NOT IN USE   TOOL   SD   DEX   DTCP-IP   AV TEST   CEX   SHOP 
Release Region WorldWide Japan US
Canada
Europe Korea U.K.
Ireland
Mexico Australia
New Zealand
Singapore
Malaysia
Taiwan Russia
Ukraine
India
China Hong Kong Brazil
PS3 Models N/A DECR-xx00
DEH-Zxx00
DECH-xx00  
DECH-Sxx00
CECHx00   
CECH-xx00
CECHx01   
CECH-xx01
CECHx04   
CECH-xx04
CECHx05   
CECH-xx05
CECHx03   
CECH-xx03
CECHx11   
CECH-xx11
CECHx02   
CECH-xx02
CECHx06   
CECH-xx06
CECHx07   
CECH-xx07
CECHx08   
CECH-xx08
N/A CECHx12   
CECH-xx12
CECHx14   
CECH-xx14
Product Code 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8A 0x8B 0x8C 0x8D 0x8E 0x8F
PS1 PS2 Region NTSC-J NTSC-J NTSC-U/C PAL NTSC-J PAL NTSC-U/C PAL NTSC-J NTSC-J PAL NTSC-J NTSC-J NTSC-U/C
PS1 BIOS patch J J J J A E J E A E J J E J J A

As example, in a retail PS3 model released in Europe (Fat=CECHx04 or Slim/SuperSlim CECH-xx04) the version string inside ps1_rom.bin is patched with the suffix "E" resulting in:

System ROM Version 5.0 06/23/03 E
Copyright 1993-1999 (C) Sony Computer Entertainment Inc.

PS1 BIOS Cobra Patch[edit | edit source]

Every CFW which use cobra module potentially can be affected by nasty bug that is there probably even before 7.00, example based on ps1_emu:

SprxPatch ps1_emu_patches[] =
{
	{ ps1_emu_get_region_offset, LI(R29, 0x82), &condition_true }, /* regions 0x80-0x82 bypass region check. */
	{ 0 }
};

The cobra patch is skipping part of code where the region of the PS3 is stored for later usage, and is setting the whole emulation to Japan region (NTSC U/C) by applying an static hard patch that belongs to Product Code 0x82 (a debug DECH-xx00 PS3 model) potentially leading to PAL games frame pacing issues, desynced audio, and maybe more. While i can't test that i'm 100% sure that better solution here will be read third character of Title ID from SYSTEM.CNF file of disc/iso, and then applying a dynamic patch based on it
If the game Title ID have an "E" (example: SLES-12345) then patch to ANY EU target ID, similar for US, for titles where U or E isn't found just use default J target ID

SprxPatch ps1_emu_patches[] =
{
	{ ps1_emu_get_region_offset, LI(R29, title_id_based_region), &condition_true }, /* Dynamic patch based on TitleID. */
	{ 0 }
};

PS1 BIOS Replacements[edit | edit source]

Is worth to note the suffix "A", "E", or "J" in the version string inside the BIOS is always on the same offset in ALL PS1 and PS2 bios images. So in case of replacing the bios the patches mentioned above will be applyed normally
The bios can be replaced by any PS1 rom image (included DTL models), and by most PS2 rom images (maybe by all, deckard models untested). Replacing it by the original PS1 bios restores the Sony logo at start up, and is able to run PS1 menu alone (unmounting disc image with WebMAN during Sony Computer Entertainment logo). Both memory card and CD player are fully accessible. Remounting a disc image (regardless if different than the one started with) will work and boot to PlayStation logo from main menu. Props to Jabu, iirc he figured out running Sony startup screen ages ago
The emulator have a bug (netemu at least) that loads the bios with a fixed size of 4MB file. They probably not changed that size after they reduced the bios file size from 4MB to 512KB. So any PS1/PS2(no deckard) bios image can be used if it have a size of 4MB or smaller. All of them should load games fine.

PS1 GPU emulation[edit | edit source]

That part of all 3 emulators is quite impressive. Task is split between 4 SPE cores, but not in usual way. Every core is responsible for different part of PS1 GPU command flow, which is done dynamically. All that is linked by so called sli (spu link?), and all SPE cores run exactly same elf file. SPE program synchronize using sliTick, and sliTock functions with use of channels 16 - 24, and with help of PPU. That way 4 different PS1 GPU emulators can proceed 4 different PS1 GPU commands at the same time, with synchronization enough to not override other PS1 GPU tasks. As a example you can remove dithering by patch only on SPU0, and observe that only 1/4 of displayed lines will be missing dither pattern.

PSone Classic format[edit | edit source]

See: ISO.BIN.EDAT and PSISOIMG0000

  • Savegames Location: /dev_hdd0/savedata/vmc

Note: capitalisation of filename is important: name it xxx.VM1 instead of xxxx.vm1 (e.g. Internal Memory Card.VM1 for PSX/PSone, Internal Memory Card.VM2 for PS2/PStwo)

The .VMx files appear to be raw memory card data:

PSone Classic Tools[edit | edit source]

  • Latest psxtract by kozarovv (release date 2022/01/30) adds support to subchannel data extraction for single and multi disc PSone Classic games (used by libcrypt protected PAL games). Based on https://github.com/DeadlySystem/psxtract-2 (Only Windows version is updated, Linux code is not updated). Please mirror or even make pr on github if that's prefered. Download (source plus exe)
  • Other psxtract versions commented here

Arguments[edit | edit source]

ps1_emu.self[edit | edit source]

ps1_emu.self arguments
7 arguments Name Example Notes
argv[0] self starting location dev_flash/ps1emu/ps1_emu.self
argv[1] VM1-1 location dev_hdd0/savedata/vmc/filename1.VM1
argv[2] VM1-2 location dev_hdd0/savedata/vmc/filename2.VM1
argv[3] Regionnumber/TargetID 0082
argv[4] unknown 1200
argv[5] unknown 1 XRegistry.sys/setting/game/emuUpConvert ? (full/normal/off = 2/1/0)
argv[6] unknown 0 XRegistry.sys/setting/game/emuSmoothing ? (on/off = 1/0)

ps1_netemu.self[edit | edit source]

ps1_netemu.self arguments
9 arguments Name Example Notes
argv[0] Self starting location dev_flash/ps1emu/ps1_netemu.self
argv[1] VM1-1 name (dev_hdd0/savedata/vmc/)argv[1]
argv[2] VM1-2 name (dev_hdd0/savedata/vmc/)argv[2]
argv[3] Regionnumber/TargetID 0084
argv[4] Unknown 1200
argv[5] Path to ps1 game /dev_hdd0/game/NPUJ01324
argv[6] Vibration on/off? 1 Seems to be XRegistry.sys/setting/pad/vibrationEnable
argv[7] Emu UpConvert 0 XRegistry.sys/setting/game/emuUpConvert ? (full/normal/off = 2/1/0)
argv[8] Emu Smoothing 0 XRegistry.sys/setting/game/emuSmoothing ? (on/off = 1/0)

ps1_newemu.self[edit | edit source]

ps1_newemu.self arguments
9 arguments Name Example Notes
argv[0] self starting location dev_flash/ps1emu/ps1_newemu.self
argv[1] VM1-1 name (dev_hdd0/savedata/vmc/)argv[1]
argv[2] VM1-2 name (dev_hdd0/savedata/vmc/)argv[2]
argv[3] Regionnumber/TargetID 0082
argv[4] unknown 600
argv[5] path to ps1 game /dev_hdd0/game/NPUJ01324
argv[6] unknown 1
argv[7] unknown 2
argv[8] unknown 2

PS1 games management in multiman[edit | edit source]

Manual starting SELF method[edit | edit source]

  1. Insert PSX/PSone disc (region/pressed doesn't matter)
  2. Start MultiMAN (e.g. 2.07.01++)
  • Since 02.07.05 the PSX and PS2 discs are properly detected. PSX discs will show in XMB Game Column and you can launch the PS1 game from there. It uses ps1_emu.self default (you can choose Load or Load (Net), latter uses ps1_netemu).
  1. Switch to filemanager mode
  2. Browse to /dev_flash/ps1emu
  3. Select either one of the ps1 emulation SELF files

Note: Some games run better with ps1_emu.self (e.g. Mortal Kombat) while others run better with ps1_netemu.self (e.g. Resident Evil 3). If it doesn't work, try another ps1 emulation SELF file.

Downside: memory card options are unavailable unless you created a Virtual Memorycard before starting MultiMAN (XMB::Category Game:: Memory Card Utility (PS/PS2) > Create a PS1 memory card. Set it to Slot 1 (Press Triangle while selecting the Memory Card, then Assign it). Note: naming it "Internal Memory Card" sometimes works better than other names. MultiMAN 02.07.07 seems to solve the savegame issues.

Changes in MultiMAN 2.07.00/01 for ps1_emu handling[edit | edit source]

These options where needed to make above work:

  • Added: LV2 access rights to use LV1 Storage Manager (syscall 864)
  • Added: LV1 patch for user access to sys_storage functions (syscalls 600 to 623)

Arguments handling[edit | edit source]

From multiman.cpp source (line 2502) http://code.google.com/p/multiman/source/browse/source/multiman.cpp?r=8c5b662f1c54d4f95f646949cae3d033b15b1a2e

{
	char* launchargv[9];
	memset(launchargv, 0, sizeof(launchargv));
	launchargv[0] = (char*)malloc(strlen(mc1)+1); strcpy(launchargv[0], mc1);
	launchargv[1] = (char*)malloc(strlen(mc2)+1); strcpy(launchargv[1], mc2);
	launchargv[2] = (char*)malloc( 5); strcpy(launchargv[2], "0082");
	launchargv[3] = (char*)malloc( 5); strcpy(launchargv[3], "1600");
	launchargv[4] = (char*)malloc(10); strcpy(launchargv[4], app_path);
	launchargv[5] = (char*)malloc( 2); strcpy(launchargv[5], "1");
	launchargv[6] = (char*)malloc( 2); strcpy(launchargv[6], "2");		// full screen	on/off	= 2/1
	launchargv[7] = (char*)malloc( 2); strcpy(launchargv[7], "1");		// smoothing	on/off	= 1/0
	launchargv[8] = NULL;
	unload_modules();
	exitspawn((const char*) "/dev_flash/ps1emu/ps1_netemu.self", (char* const*)launchargv, NULL, NULL, 0, 1001, SYS_PROCESS_PRIMARY_STACK_SIZE_1M);
}

{
	char* launchargv[7];
	memset(launchargv, 0, sizeof(launchargv));
	launchargv[0] = (char*)malloc(strlen(mc1)+1); strcpy(launchargv[0], mc1);
	launchargv[1] = (char*)malloc(strlen(mc2)+1); strcpy(launchargv[1], mc2);
	launchargv[2] = (char*)malloc( 5); strcpy(launchargv[2], "0082");	// region
	launchargv[3] = (char*)malloc( 5); strcpy(launchargv[3], "1200");
	launchargv[4] = (char*)malloc( 2); strcpy(launchargv[4], "1");		// full screen	on/off	= 2/1
	launchargv[5] = (char*)malloc( 2); strcpy(launchargv[5], "1");		// smoothing	on/off	= 1/0
	launchargv[6] = NULL;
	unload_modules();
	exitspawn((const char*) "/dev_flash/ps1emu/ps1_emu.self", (char* const*)launchargv, NULL, NULL, 0, 1001, SYS_PROCESS_PRIMARY_STACK_SIZE_1M);
}
  • Notes:
    • The full screen commented argument seems to be the Upscaler setting available from XMB Settings[Game Settings][PS/PS2 Upscaler], with values: full/normal/off = 2/1/0

Game settings[edit | edit source]

External CONFIG file[edit | edit source]

Created/loaded by ps1_newemu.self and ps1_netemu.self at path: /USRDIR/CONFIG
Example:

00000000 1C 00 00 00 50 53 31 45 6D 75 43 6F 6E 66 69 67 ....PS1EmuConfig
00000010 46 69 6C 65 00 97 0A 54 04 00 00 00 01 00 00 00 File...T........
00000020 0F D4 CC B9 10 00 00 00 64 69 73 63 5F 6E 6F 00 ........disc_no.
00000030 04 00 00 00 00 00 00 00 93 D1 5B F8             ..........[.    
Offset size data notes
0x00 0x04 1C 00 00 00 size of the next 4 values
0x04 0x10 PS1EmuConfigFile name/id
0x14 0x04 00 97 0A 54 ?
0x18 0x04 04 00 00 00 ?
0x1C 0x04 01 00 00 00 ?
0x20 0x04 0F D4 CC B9 crc32 of the previous 4 values
0x24 0x04 10 00 00 00 size of the next 3 values
0x28 0x08 disc_no name/id
0x30 0x04 04 00 00 00 amount of discs
0x34 0x04 00 00 00 00 disc number
0x38 0x04 93 D1 5B F8 crc32 of the previous 3 values
  • Other posible entries/commands/id
    • user_memory_size ? (in both ps1_newemu.elf and ps1_netemu.elf appears next to PS1EmuConfigFile and disc_no)

Embedded Game settings[edit | edit source]

All the PS1 emulators contain a list of game settings embedded inside his .SELF structure inside 3 tables we could name the Checksums Table, the Titles table, and the Commands Table. The offsets of this tables differs by emulator revision and type
The entry point to read the whole structure of this tables starts by reading the 4 bytes of the first Checksum of the first game from the checksums table (see below), next 4 bytes are an offset (to read the Titles table), next 4 bytes is a Command Count and next 4 bytes is a Command offset (to read the Commands Table), to load the data in the other tables is needed to substract 0x10000 to this offsets located next to the checksum of a specific game
The Title IDs (from inside the Titles table) doesnt seems to be used for any logic check, seems to be mostly identifyers (with typos) intended to be displayed in some kind of debug menu in "human readable format" only for informative purposes. Are text strings null terminated in the format "ABCD_123.45" and aligned to 8 bytes, so most of them have a total size of 0x10 but in old firmwares there are some entries with the text "unknown" with a size of 8 bytes (in other words, the entries with the text "unknown" are half the size of the others)
Every command inside the Commands Table is composed by 8 bytes, where the first 4 bytes are the Command ID (see talk page) and the next 4 bytes is the Command Data
All the Command Data values can be considered the most bottom of this hierarchy... except command ID=0x02(netemu 3.40 up to 4.88) containing an offset to a deeper level of the hierarchy where is stored a list with some of the disc sectors for a few libcrypt protected games

Game checksum[edit | edit source]

Checksum is simple Adler32 calculated from 2048 bytes of disc data, starting from 0x9318 offset in raw image. Emulator perform check if that sector have CD001 string, if string is missing "unknown" string is used, and hash calculation is not performed. You can use tools like hashtab to easily calculate checksum for new game.
Is calculated using the data contents only (2048 bytes or 0x800h) of the sector 16 (beginning at the 0x9318 of the RAW/2352 image). Every single byte is used in the process. Calculation code does start at 0xC1658 in the ps1_netemu from 4.88 firmware.

Disassembly of the related function

Super simple python script to calculate checksum, script lack of some checks performed by emu, and is hardcoded to 0x9318 offset, but should be enough.
Usage: edit *your first.bin* to name of your image, run script from CMD. Require python (3?).

Find_checksum.py
Edit-copy purple.svg.png
import zlib

with open('your first.bin', 'rb') as f:
    f.seek(0x9318)
    suma = zlib.adler32(f.read(2048))
    print (hex(suma))

Game settings access[edit | edit source]

Like mentioned above config is created from 2x u32 values. Lets call first value command, and second value param.
Command is used to calculate address for param, and only param is stored on obtained address.
Emulator then check for params, and if found (usually when not zero) apply settings based on them.

Beside functions that read command params directly, every emulator have function (madeup name) ReadInternalConfigValue(u32 command_id). This function take command_id as only variable, and return param in r3 for selected command. This is used widely to read command params, that include libcrypt commands.

Disassembly of the related function

Function mentioned above is placed on (in emu memory, 4.86):

  • ps1_emu 0x10638
  • ps1_newemu 0x12F54
  • ps1_netemu 0xB65F0

Game settings lists[edit | edit source]

TitleID settings hardcoded in ps1_emu.self
 ps1_netemu.self 4.83~4.92  (Icon media data cd.png=349 Japan.png=256 Europe.png=21 United States.png=72)  · 
TitleID settings hardcoded in ps1_newemu.self