Talk:PS2 Emulation

From PS4 Developer wiki
Revision as of 03:01, 27 February 2023 by Scalerize (talk | contribs) (→‎Regs)
Jump to navigation Jump to search

TODO: Please remove unneeded uppercase letters not at the start of sentences.

  • This Is Not Elon Musk Here :P - Roxanne

Regs

    • 1040000000 VU1 regs, mapping like on VU0.
    • 1050000000 VU1 micro data memory (1100C000 on real ps2 and pcsx2 debugger) size 0x4000.
    • 1050004000 VU1 micro data memory mirror (1100C000 on real ps2 and pcsx2 debugger) size 0x4000. Likely mirrored 2 more times on 8000 and c000
    • 104000C000 emulator place here VU1 constants used in popular operations. Eatan/eexp constants, masks for clamping, etc. Similar array can be found in Pcsx2 (mVU_Globals), Dobiestation (atan_const, etc), Play! (GenerateEATAN, etc.)
    • 1030004000 emulator place here VU0 constants used in popular operations. Like above (vu0 don't have efu so placing there efu constants for eatan/eexp is pointless, but there they are).

--Kozarovv (talk) 09:37, 5 January 2023 (UTC)

Misc info

Some data that eventually need to be posted on main emulation page. All data posted here is obtained from jak tpl (so called v1) emulator. All data is confirmed in code itself, no guessing (unless said otherwise). Time to start releasing that old work to public.

Misc misc info

  • Both settings do the same thing:
--external-hdd-fix
--cdvd-determinism
--ee-kernel-hle
--ee-injection-kernel
  • Setting take unused value:
--ee-cache-breaks-block
No matter which value is used, 1 is set.

Few popular misunderstandings

  • vu-xgkick-delay take integer between 0-31 (confirmed on both emu and compiler side), and not float (0.5 is invalid, will be truncated to 0 probably)
  • Cop2 rounding in pcsx2 is governed by "EE/FPU" rounding setting, not by VU or VU0.
  • Cop2 clamping is hardcodded in pcsx2 as far as i know, if no then is likely also governed by EE/FPU setting not VU/VU0
  • xx-no-clamping setting is not really no clamping known from pcsx2. This is special mode which can be used regardless of other clamp commands. To compare pcsx2 have similar mode only for FPU (Full), to fully mimic that mode we still need fpu-to-double enabled.

ee-native-function

Emulator have set of predefined functions used in popular PS2 SDK libraries. Those function are highly optimized to run natively on x64.
--ee-native-function=name,address under the hood this is hooking selected address, and replace it with jump to predefined function. Functions available in JAK TPL emu:

memset      | fptoui           | ieee754_sinf
memcpy      | fptodp           | ieee754_cosf
strlen      | dptofp           | ieee754_sqrtf
strcmp      | fabs             | asinf
strcasecmp  | fabsf            | acosf
litodp      | ieee754_atan2f   | sinf
dptoli      | ieee754_asinf    | cosf
floatdidf   | ieee754_acosf    | sqrtf

This drastically reduce emitted code size for selected function. Additionally there is no need to recompile that at all, emulator just emit jump to label, and that's all. Additionally emulator advance delta clock to compensate cycles which will be normally took by original function.

Example ee_native_floatdidf

vcvtsi2sd    xmm0, xmm0, rdi
vmovq        rax, xmm0
retn

This is what real floatdidf looks like originally in ps2 mips, you can imagine that recompiled x64 code will be much longer. Every single instruction will be translated/recompiled separately.

addiu        $sp, -0x30
sd           $s0, 0x20+saved_s0($sp)
move         $s0, $a0
sd           $s1, 0x20+saved_s1($sp)
li           $s1, 0x81E0
dsll32       $s1, 15
dsra32       $a0, $s0, 0
sd           $ra, 0x20+saved_ra($sp)
jal          litodp
nop
move         $a1, $s1
jal          dpmul
move         $a0, $v0
move         $a1, $s1
jal          dpmul
move         $a0, $v0
move         $s1, $v0
lui          $v0, 0xFFFF
dsrl32       $v0, 0
and          $s0, $v0
dsll32       $s0, 0
dsra32       $s0, 0
jal          litodp
move         $a0, $s0
bgez         $s0, loc_2F3734
move         $a0, $s1
li           $a1, 0x83E0
dsll32       $a1, 15
jal          dpadd
move         $a0, $v0
move         $a0, $s1
jal          dpadd
move         $a1, $v0
ld           $ra, 0x20+saved_ra($sp)
ld           $s1, 0x20+saved_s1($sp)
ld           $s0, 0x20+saved_s0($sp)
jr           $ra
addiu        $sp, 0x30

This is corner case example as floatdidf convert a 64bit signed integer to IEEE double, and PS2 developers generally had no reason to use doubles (fpu/vu are operating on 32 bit floats). But you can see that whole conversion is practically done in 1 opcode, while ps2 take massive function to do this. Other functions are usually less optimized, but still really worth it.

EE/VU injection

"Injections" are special sets of precompiled functions, idea is known better as HLE emulation. Available injections can vary depend on ps2-compiler.self, because that's where lookup for available functions is done. This literally replace code that normally is recompiler, with optimized version when address and hash match. Probably not many games can use this. Good candidates are games that use the same engine as currently released ps2 classics. Many times VU1 programs are reused by the same developer.
VU1

  • Name + offset in JAK TPL compiler
  • unk1
  • VU1 mpg start address (divided by 8)
  • Some kind of hash to ensure that correct part of microprogram gets replaced
  • Many other unknown values
|______NAME_______|U|_ADDR_|______HASH?_____|U|N|K|N|O|W|N
vu1_inject_1B5680, 0, 0,    354AAD4A5C5F8h, 0, 0,0, 0, 1, 0> ; DATA XREF: vu1_exec_1AD1D0+CC8↑o
vu1_inject_1B5CC0, 0, 10Fh, 31BE7F0B62906DB7h,0, 0, 0, 0, 1, 0>
vu1_inject_1BA950, 0, 0Fh,  0B67E7F1B32B878BDh,0, 0, 0, 0, 1, 0>
vu1_inject_1BF5E0, 0, 754h, 280C4275B1928A12h,0, 0, 0, 0, 1, 0>
vu1_inject_1C0290, 0, 74Ah, 8978033C72E3DCA2h,0, 0, 0, 0, 1, 0>
vu1_inject_1C1080, 0, 58h,  559E11A1D3055656h, 0, 0, 0, 0, 1, 0>
vu1_inject_1C09E0, 0, 49h,  0FF679F42534A3255h,0, 0, 0, 0, 1, 0>
vu1_inject_1C72C0, 0, 17Eh, 52A3C65951B99CF3h,0, 0, 0, 0, 1, 0>
vu1_inject_1C8840, 0, 286h, 0F6B365D47BC423C0h, 0, 0, 0, 0, 1, 0>
vu1_inject_1C8A50, 0, 18Ch, 0D50B071B598E86C1h, 0, 0, 0, 0, 1, 0>
vu1_inject_1C9C70, 0, 18Bh, 0D504FF9B7B8E86CFh, 0, 0, 0, 0, 1, 0>
vu1_inject_1C9D40, 0, 183h, 0D886632A2396F9A4h, 0, 0, 0, 0, 1, 0>
vu1_inject_1CAD20, 0, 3DDh, 36CF5FCB8AAED87Eh,0, 0, 0, 0, 1, 0>
vu1_inject_1CC4F0, 0, 474h, 0D1A1E17DE3811013h, 0, 0, 0, 0, 1, 0>
vu1_inject_1CCF10, 0, 96h,  2B8DB65EE593B395h, 0, 0, 0, 0, 1, 0>
vu1_inject_1CE5E0, 0, 2B2h, 9E7800006C113EE5h,0, 0, 0, 0, 1, 0>
vu1_inject_1CE930, 0, 0B8h, 760E33D4278BEA74h,0, 0, 0, 0, 1, 0>
vu1_inject_1D0830, 0, 112h, 0DCE5CDA96EB6389Bh, 0, 0, 0, 0, 1, 0>
vu1_inject_1D22E0, 0, 538h, 52561DBBF5CF1832h,0, 0, 0, 0, 1, 0>
vu1_inject_1D3D80, 0, 55Ah, 1083419D800001Ch, 0, 0, 0, 0, 2, 0>
vu1_inject_1D4820, 0, 549h, 0C5755531B35CC848h, 0, 0, 0, 0, 2, 0>
vu1_inject_1D5300, 0, 168h, 0CAA8A8936947CFC1h, 0, 0, 0, 0, 2, 0>
vu1_inject_1D8FC0, 0, 24h,  90616BE83F46B0B8h, 0, 0, 0, 0, 1, 0>
vu1_inject_1DA6F0, 0, 7Fh,  3CF37762DE2DC97Ch, 0, 0, 0, 0, 2, 0>
vu1_inject_1DC1B0, 0, 88h,  7004A0F767800h, 0, 0, 0, 0, 1, 0>
vu1_inject_1DC1D0, 0, 0F3h, 2D4BD82E171ACD84h,0, 0, 0, 0, 2, 0>
vu1_inject_1DE5C0, 0, 10Dh, 0BD8855ED4151881Ah, 0, 0, 0, 0, 2, 0>
vu1_inject_1E0410, 0, 0DBh, 0F6B7D7417D0400D7h, 0, 0, 0, 0, 2, 0>
vu1_inject_1E2160, 0, 10Ch, 0CFF00003408100h, 0, 0, 0, 0, 2, 0>
vu1_inject_1E25E0, 0, 7FCh, 500001B028000259h,0, 0, 0, 0, 2, 0>
vu1_inject_1E2A60, 0, 5ECh, 5D40E9B71E6A01A1h,0, 0, 0, 0, 2, 0>
vu1_inject_1E6170, 0, 5A4h, 3917D188F40B9940h,0, 0, 0, 0, 2, 0>
vu1_inject_1E8E30, 0, 16Fh, 95C2C290F7DD248h, 0, 0, 0, 0, 2, 0>
vu1_inject_1ECDA0, 0, 7D3h, 7A00268978312859h,0, 0, 0, 0, 2, 0>
vu1_inject_1EDBE0, 0, 5BDh, 0A9FAF30FCE438D4Bh, 0, 0, 0, 0, 2, 0>
vu1_inject_1EF510, 0, 1C6h, 7C7755083564464Ch,0, 0, 0, 0, 2, 0>

EE Title

  • Name used by emu
  • Address in ps2-compiler memory

Please keep in mind that names can be misleading because if function can be reused for EU release, then US inject is used. This happen in Max Payne2 injects.

                NAME                                     ADDR
Psychonauts_compareFunction_EMeshFrag          CODE    0x12BC80
__Psychonauts_loadVUGeneralConstants_WorldClip CODE    0x12CA00
Psychonauts_loadVUGeneralConstants_WorldClip   CODE    0x12CEB0
Psychonauts_loadVUGeneralConstants_ClipScreen  CODE    0x12CFE0
Psychonauts_loadVUGeneralConstants_Frustrum    CODE    0x12D110
GTALCS_SetMatrix                               CODE    0x12D670
GTALCS_sqrtf                                   CODE    0x12DB80
GTALCS_US_0x2016b4                             CODE    0x12DC80
GTALCS_US_0x201780                             CODE    0x12E0E0
GTALCS_US_0x201c74                             CODE    0x12E160
GTALCS_US_0x201da8                             CODE    0x12E1E0
GTALCS_US_0x202a6c                             CODE    0x12E260
GTALCS_EU_0x2017bc                             CODE    0x12E2E0
GTALCS_EU_0x201888                             CODE    0x12E360
GTALCS_EU_0x201d7c                             CODE    0x12E3E0
GTALCS_EU_0x201eb0                             CODE    0x12E460
GTALCS_EU_0x202b74                             CODE    0x12E4E0
GTALCS_JP_0x21e3fc                             CODE    0x12E560
GTALCS_JP_0x21e4c8                             CODE    0x12E5E0
GTALCS_JP_0x21e9bc                             CODE    0x12E660
GTALCS_JP_0x21eaf0                             CODE    0x12E6E0
GTALCS_JP_0x21f7b4                             CODE    0x12E760
GTALCS_US_0x20138c                             CODE    0x12E7E0
GTALCS_US_0x2018ec                             CODE    0x12E8B0
GTALCS_US_0x201ae8                             CODE    0x12E970
GTALCS_US_0x2021bc                             CODE    0x12EA30
GTALCS_US_0x2023c8                             CODE    0x12EAE0
GTALCS_US_0x2025c4                             CODE    0x12EB90
GTALCS_US_0x202770                             CODE    0x12EC50
GTALCS_US_0x202b3c                             CODE    0x12ED10
GTALCS_EU_0x201494                             CODE    0x12EDD0
GTALCS_EU_0x2019f4                             CODE    0x12EEA0
GTALCS_EU_0x201bf0                             CODE    0x12EF60
GTALCS_EU_0x2022c4                             CODE    0x12F020
GTALCS_EU_0x2024d0                             CODE    0x12F0D0
GTALCS_EU_0x2026cc                             CODE    0x12F180
GTALCS_EU_0x202878                             CODE    0x12F240
GTALCS_EU_0x202c44                             CODE    0x12F300
GTALCS_JP_0x21e0d4                             CODE    0x12F3C0
GTALCS_JP_0x21e634                             CODE    0x12F490
GTALCS_JP_0x21e830                             CODE    0x12F550
GTALCS_JP_0x21ef04                             CODE    0x12F610
GTALCS_JP_0x21f110                             CODE    0x12F6C0
GTALCS_JP_0x21f30c                             CODE    0x12F770
GTALCS_JP_0x21f4b8                             CODE    0x12F830
GTALCS_JP_0x21f884                             CODE    0x12F8F0
GTALCS_US_0x22dd8c                             CODE    0x12F9B0
GTALCS_US_0x22ddd0                             CODE    0x12FCD0
GTALCS_US_0x22e034                             CODE    0x12FD50
GTALCS_US_0x22e078                             CODE    0x12FE30
GTALCS_EU_0x22de8c                             CODE    0x12FEB0
GTALCS_EU_0x22ded0                             CODE    0x12FF30
GTALCS_EU_0x22e178                             CODE    0x12FFB0
GTALCS_JP_0x31ad3c                             CODE    0x130030
GTALCS_JP_0x31ad80                             CODE    0x1300B0
GTALCS_JP_0x31b028                             CODE    0x130130
GTAVCS_US_0x23e5ac                             CODE    0x1301B0
GTAVCS_US_0x23f440                             CODE    0x130230
GTAVCS_US_0x23f558                             CODE    0x1302B0
GTAVCS_US_0x23f8e0                             CODE    0x130330
GTAVCS_US_0x23fa80                             CODE    0x1303B0
GTAVCS_US_0x23ffb8                             CODE    0x130430
GTAVCS_US_0x2f1d64                             CODE    0x1304B0
GTAVCS_US_0x280bbc                             CODE    0x130530
GTAVCS_US_0x280c04                             CODE    0x130610
GTAVCS_US_0x280894                             CODE    0x130690
GTAVCS_US_0x2808e8                             CODE    0x130710
MaxPayne2_assignSubDot                         CODE    0x130800
MaxPayne2_sceVu0MulMatrix3x4Const              CODE    0x130D80
MaxPayne2_setTransformedPos                    CODE    0x132640
MaxPayne2_US_506940                            CODE    0x132E50
MaxPayne2_US_506984                            CODE    0x133460
sce_waitIpuIdle_hook                           CODE    0x133B10
sce_waitIpuIdle64_loop                         CODE    0x133E70
sce_waitIpuIdle64_top                          CODE    0x134300
sceMpeg_ri0_000                                CODE    0x1351A0
sceMpeg_copyAddRefImage                        CODE    0x136B10

Example of one entry in emu.

SCE_RELRO:000000000021A280 stru_21A280     db 'SLES-53830',0       ; game_id ; "Psychonauts_compareFunction_EMeshFrag"
SCE_RELRO:000000000021A280                 db 0
SCE_RELRO:000000000021A280                 dd 18A498h              ; hook_start_pc
SCE_RELRO:000000000021A280                 dd 0                    ; unk
SCE_RELRO:000000000021A280                 dd 18A504h              ; hook_end_pc
SCE_RELRO:000000000021A280                 dd 0A40B81CBh           ; hash
SCE_RELRO:000000000021A280                 dd 0                    ; align1
SCE_RELRO:000000000021A280                 dq offset Psychonauts_compareFunction_EMeshFrag; fnc_ptr
SCE_RELRO:000000000021A280                 dq 0                    ; align2
SCE_RELRO:000000000021A280                 dq offset aPsychonautsCom; hook_name

Same goes for "kernel" injections, they are also based on ID + Hash + address. Generally all "injections" should be safe to be enabled by configs. There is really small chance for hash/address(and id) collision. Not to be confused with "native" / "native-patch" !


RESEARCH TO DO

Name Notes
4-Player Multitap in urban reign Weird why it isn't working.
Locating the gs registers Never gonna happen it seems.
Fully understanding the hook functions
Trying to reverse-engineer any eboot to improve compatibility
Locating the proper CDVD read speed (God of war and Ratchet size matters [Both have affected music]) IOP and CDVD commands help
Fully understand what the vif chunk command thingy does Too low and your game will freeze at the intro
Find the the most GIF accurate emulator there is. Kof98??
Find out what some of the gs commands do and edit their description
Implement a EE memory patch for ratchet up your arsenal (Not trivial obviously)
Fix the two tenchu and harry potter games (eughhh)