Editing PS1 Emulation
Jump to navigation
Jump to search
The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.
Latest revision | Your text | ||
Line 33: | Line 33: | ||
<div style="float:left;"> | <div style="float:left;"> | ||
{| class="wikitable" style="line-height:100%; font-size:70%; margin-right:5px" | {| class="wikitable" style="line-height:100%; font-size:70%; margin-right:5px" | ||
|+ ps1_emu.elf (decrypted) | |+ ps1_emu.elf (decrypted) | ||
! Firmware !! Size !! MD5 !! Timestamp !! <abbr title="Revision">Rev</abbr> !! style="padding:1px" | <abbr title="Maximun number of supported commands">Comm</abbr> | ! Firmware !! Size !! MD5 !! Timestamp !! <abbr title="Revision">Rev</abbr> !! style="padding:1px" | <abbr title="Maximun number of supported commands">Comm</abbr> | ||
|- | |- | ||
Line 63: | Line 63: | ||
| ? || ? || ? || ? || ? | | ? || ? || ? || ? || ? | ||
|- | |- | ||
! | ! ? | ||
| | | ? || ? || ? || ? || ? | ||
|- | |- | ||
! ? | ! ? | ||
Line 78: | Line 78: | ||
|- | |- | ||
! [[2.10_CEX|2.10]] | ! [[2.10_CEX|2.10]] | ||
| 2.887.152 || style="font-family:monospace" | AEE181B061E586F99E76C033C9DCF726 || 07/12/15/05:30 || ? || | | 2.887.152 || style="font-family:monospace" | AEE181B061E586F99E76C033C9DCF726 || 07/12/15/05:30 || ? || ? | ||
|- | |- | ||
! ? | ! ? | ||
Line 157: | Line 157: | ||
| colspan="2" style="text-align:center; background-color:#ddddff;" | ''Any'' | | colspan="2" style="text-align:center; background-color:#ddddff;" | ''Any'' | ||
|- | |- | ||
! [[4. | ! [[4.88_CEX|4.88]] | ||
| style="background-color:#ddddff; font-family:monospace" | | | style="background-color:#ddddff; font-family:monospace" | 0C553CE93A2A6322E16636DD76D75E32 || style="background-color:#ddddff;" | 21/04/12/11:34 | ||
|} | |} | ||
<span style="font-size:small"> | <span style="font-size:small"> | ||
{{ | {{widedot}}'''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> | ||
{{ | {{widedot}}'''<abbr title="0x20 bytes">Build label</abbr>''': yes, with timestamp, search for '''-sgpu-sspu-sli4'''<br> | ||
{{ | {{widedot}}'''<abbr title="2 bytes">Target Firmware</abbr>''': yes repeated '''one''' time<br> | ||
{{ | {{widedot}}'''Revision''': unknown | ||
</span> | </span> | ||
</div> | </div> | ||
<div style="float:left;"> | <div style="float:left;"> | ||
{| class="wikitable" style="line-height:100%; font-size:70%; margin-left:5px; margin-right:5px" | {| class="wikitable" style="line-height:100%; font-size:70%; margin-left:5px; margin-right:5px" | ||
|+ ps1_netemu.elf (decrypted) | |+ ps1_netemu.elf (decrypted) | ||
! Firmware !! Size !! MD5 !! Timestamp !! <abbr title="Revision">Rev</abbr> !! style="padding:1px" | <abbr title="Maximun number of supported commands">Comm</abbr> | ! 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]] | ! [[1.70_CEX|1.70]] | ||
| | | ? || ? || ? || ? || ? | ||
|- | |- | ||
! ? | ! ? | ||
Line 190: | Line 190: | ||
|- | |- | ||
! [[2.10_CEX|2.10]] | ! [[2.10_CEX|2.10]] | ||
| 2.764.288 || style="font-family:monospace" | 7826B1C6799404216D4771C07DE12F53 || 07/12/15/05:31 || ? || | | 2.764.288 || style="font-family:monospace" | 7826B1C6799404216D4771C07DE12F53 || 07/12/15/05:31 || ? || ? | ||
|- | |- | ||
! ? | ! ? | ||
Line 196: | Line 196: | ||
|- | |- | ||
! [[3.40_CEX|3.40]] | ! [[3.40_CEX|3.40]] | ||
| 2.971.288 || style="font-family:monospace" | FD32C7B7CBA2639FC8DB9EB615A16461 || 10/06/23/15:46 || 6520 || | | 2.971.288 || style="font-family:monospace" | FD32C7B7CBA2639FC8DB9EB615A16461 || 10/06/23/15:46 || 6520 || ? | ||
|- | |- | ||
! ? | ! ? | ||
Line 275: | Line 275: | ||
| colspan="2" style="text-align:center; background-color:#ddddff;" | ''Any'' | | colspan="2" style="text-align:center; background-color:#ddddff;" | ''Any'' | ||
|- | |- | ||
! [[4. | ! [[4.88_CEX|4.88]] | ||
| style="background-color:#ddddff; font-family:monospace" | | | style="background-color:#ddddff; font-family:monospace" | D3283D3F3B5CDF68113560829530E7B3 || style="background-color:#ddddff;" | 21/04/12/11:34 | ||
|} | |} | ||
<span style="font-size:small"> | <span style="font-size:small"> | ||
{{ | {{widedot}}'''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> | ||
{{ | {{widedot}}'''<abbr title="0x20 bytes">Build label</abbr>''': yes, with timestamp, search for '''-sgpu-sli4'''<br> | ||
{{ | {{widedot}}'''<abbr title="2 bytes">Target Firmware</abbr>''': yes repeated '''two''' times<br> | ||
{{ | {{widedot}}'''Revision''': <abbr title="ps1_netemu.self from firmware 2.10 (or older) doesnt contains the revision string">sometimes</abbr>, search for '''Revision''' | ||
</span> | </span> | ||
</div><div style="float:left;"> | </div><div style="float:left;"> | ||
{| class="wikitable" style="line-height:100%; font-size:70%; margin-left:5px; margin-right:5px" | {| class="wikitable" style="line-height:100%; font-size:70%; margin-left:5px; margin-right:5px" | ||
|+ ps1_newemu.elf (decrypted) | |+ ps1_newemu.elf (decrypted) | ||
! Firmware !! Size !! MD5 !! Timestamp !! <abbr title="Revision">Rev</abbr> !! style="padding:1px" | <abbr title="Maximun number of supported commands">Comm</abbr> | ! 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.10_CEX|2.10]] | ||
| 2.763.848 || style="font-family:monospace" | C792C72A06B94705374B846B94981B1A || 07/12/15/05:31 || ? || | | 2.763.848 || style="font-family:monospace" | C792C72A06B94705374B846B94981B1A || 07/12/15/05:31 || ? || ? | ||
|- | |- | ||
! ? | ! ? | ||
Line 296: | Line 296: | ||
|- | |- | ||
! [[3.40_CEX|3.40]] | ! [[3.40_CEX|3.40]] | ||
| 2.708.856 || style="font-family:monospace" | C866D54E85BAA06D111C8300F9EA85F1 || 10/06/23/15:51 || ? || | | 2.708.856 || style="font-family:monospace" | C866D54E85BAA06D111C8300F9EA85F1 || 10/06/23/15:51 || ? || ? | ||
|- | |- | ||
! ? | ! ? | ||
Line 372: | Line 372: | ||
| colspan="2" style="text-align:center; background-color:#ddddff;" | ''Any'' | | colspan="2" style="text-align:center; background-color:#ddddff;" | ''Any'' | ||
|- | |- | ||
! [[4. | ! [[4.88_CEX|4.88]] | ||
| style="background-color:#ddddff; font-family:monospace" | | | style="background-color:#ddddff; font-family:monospace" | 4002EC6CB88F5D2D5E7DF0B0F80A6A0A || style="background-color:#ddddff;" | 21/04/12/11:35 | ||
|} | |} | ||
<span style="font-size:small"> | <span style="font-size:small"> | ||
{{ | {{widedot}}'''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> | ||
{{ | {{widedot}}'''<abbr title="0x20 bytes">Build label</abbr>''': yes, with timestamp, search for '''-sgpu-sspu-sli4'''<br> | ||
{{ | {{widedot}}'''<abbr title="2 bytes">Target Firmware</abbr>''': yes repeated '''two''' times<br> | ||
{{ | {{widedot}}'''Revision''': unknown | ||
</span> | </span> | ||
</div> | </div> | ||
Line 385: | Line 385: | ||
<br style="clear: both;" /> | <br style="clear: both;" /> | ||
== PS1 emulators workload comparison == | |||
== 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] | |||
==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 461: | Line 472: | ||
| PPU:1 || ? || ? || | | PPU:1 || ? || ? || | ||
|} | |} | ||
== Arguments == | == Arguments == | ||
Line 643: | Line 549: | ||
|} | |} | ||
== PS1 | ==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. | |||
== Game settings == | == Game settings == | ||
Line 743: | Line 603: | ||
=== Embedded Game settings === | === Embedded Game settings === | ||
All the PS1 emulators | 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 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--> | ||
The entry point to read the whole structure of this tables starts by reading the 4 bytes of the first | 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 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> | ||
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> | 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 | ||
Line 871: | Line 730: | ||
* ps1_newemu 0x12F54 | * ps1_newemu 0x12F54 | ||
* ps1_netemu 0xB65F0 | * ps1_netemu 0xB65F0 | ||
==== Game settings lists ==== | ==== Game settings lists ==== | ||
Line 888: | Line 742: | ||
</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> |