AnyPS5/docs/dev/TechnicalDebt.md

141 KiB

Project technical debt

Build

  • Building on Windows requires a specific version of mingw - MinGW-w64 GCC 15.2.0 (winlibs-gcc15, x86_64-ucrt-posix-seh)
  • Even compiled prx libraries on Windows require nearby (static linking of these dependencies causes conflicts):
    • libgcc_s_seh-1.dll
    • libstdc++-6.dll
    • libwinpthread-1.dll

Silent stubs

Throughout the project, every function at every stage either does exactly what it's supposed to or throws an exception. Everywhere... except:

  • libSceSaveDataDialog.native shows no UI and ignores progress values. Progress-bar mode (5) stays running until the caller closes it, matching Skyrim PPSA03747's save sequence; other modes still finish immediately and return button 1 and the first nonempty directory name. Console dialog timing and selection behavior remain unverified.
  • libSceMsgDialog.native - dialogs finish at sceMsgDialogOpen without UI and answer with button 1, so sceMsgDialogClose returns NOT_RUNNING; its result before sceMsgDialogInitialize follows libSceMsgDialog
  • libSceCommonDialog
  • libSceErrorDialog - the error dialog runs the state machine but shows nothing; the error code passed to sceErrorDialogOpen is only logged
  • libSceLoginDialog - the login dialog runs the common-dialog state machine but shows nothing and reports the user as having cancelled
  • libSceHmd implements only the disconnected-headset path: initialization succeeds, device queries report NotDetected, and opening a device returns DeviceDisconnected. Headset support, tracking, rendering and additional HMD exports are not implemented; SDK-level ABI compatibility and in-game behaviour remain unverified.
  • libSceHmd2 has no PS VR2 runtime: sceHmd2Initialize fails, and every other export it has (and every libSceVrTracker2 export) throws. PPSA01317 skips its whole VR set-up when initialization fails
  • libSceMbus implements only the no-device path: initialization and termination succeed, no device events are reported and device queries return no entries
  • libSceAudioPropagation implements only the no-acoustic-propagation path: the system keeps a 16-byte header in the title's CPU memory (no GPU memory), rooms, portals, sources and materials are tracked handles, attributes are validated and have no effect, no rays are requested and sources report no audio paths. Ray results, path calculation and audio paths are accepted only when empty and throw otherwise; sceAudioPropagationSourceRender writes silence (zeroes) to each source's output buffer for the given size, without a dry signal. Objects still alive when their system is destroyed become unusable, and their later destroy or unregister is a no-op: PPSA21567 releases its reference-counted room, portal and source owners just before sceAudioPropagationSystemDestroy, so the order for every object is not proven. Occlusion, reflections and reverb from level geometry are absent; in-game behaviour remains unverified.
  • libSceNpCommerce - the PS Store icon show/hide calls and sceNpCommerceSetPsStoreIconLayout do nothing
  • libSceUsbd implements only the no-device path: sceUsbdInit and sceUsbdExit succeed without a host USB context, the device list is always empty and event handling waits for its timeout; calls that need a device throw
  • libSceSystemService - sceSystemServicePowerTick, sceSystemServiceReportAbnormalTermination, sceSystemServiceDisableMusicPlayer, sceSystemServiceReenableMusicPlayer, sceSystemServiceDisableMediaPlay and sceSystemServiceReenableMediaPlay return success and do nothing: the host has no auto power-off timer to reset, no system crash reporter to notify, no system music player to pause or resume and no system media playback to disable. PPSA01521 calls sceSystemServiceDisableMediaPlay during start-up, and its wrappers for both pass no arguments
  • libSceBluetoothHid implements only the no-device path: initialization and callback and device registration succeed, the callback is never called because no device connects, and calls that need a connected device throw
  • sceVideoOutOpen validates the priority and CPU affinity that the open param requests for the VideoOut service thread but does not apply them: the port's present and vblank threads are host threads, and guest priorities and affinities do not reach host scheduling
  • Without VK_KHR_fragment_shader_barycentric the shader recompiler does not load the barycentric VGPRs: v_interp_p1_f32 is dropped and v_interp_p2_f32 reads the attribute Vulkan interpolated, so pixel shaders that use the barycentrics for anything other than v_interp get wrong values.
  • libSceAudio3d - the port produces no sound: objects can be reserved but the library has no bed exports or sceAudio3dObjectSetAttributes to give them audio, so sceAudio3dPortPush only paces the queue at granularity samples per frame at 48 kHz. sceAudio3dPortSetAttribute accepts the late reverb level and the downmix spread attributes and ignores them
  • libSceTextToSpeech2 has no speech engine: sceTextToSpeech2Initialize fails and the other exports throw. PPSA01317 skips its narration set-up when initialization fails
  • libSceAvPlayer: sceAvPlayerSetLogCallback accepts a callback that is never called, as the player produces no log messages, and sceAvPlayerSetAvailableBandwidth has no effect, as it governs HLS sources, which sceAvPlayerAddSource does not implement.
  • libSceHttp2 - no request reaches the network, so sceHttp2SetMinSslVersion has no TLS connection to restrict and returns success for any id, like sceHttp2SslEnableOption (prosper returns the invalid-id error for an unknown one)
  • libSceNpTrophy2: sceNpTrophy2RegisterUnlockCallback accepts a callback that is never called, as no trophy is ever unlocked, and sceNpTrophy2UnregisterUnlockCallback only returns success.
  • sceAvPlayerSetTrickSpeed (libSceAvPlayer) with a negative speed runs the clock backwards but delivers no frames; when a forward speed is set again, playback resumes from the rewound time.
  • ulobjmgr registers no object: _sceUlobjmgrRegisterObject always hands out id 0 and _sceUlobjmgrUnregisterObject releases nothing, as shadPS4 does
  • libSceHttp - no request reaches the network, so sceHttpSetResponseHeaderMaxSize has no response header to limit and sceHttpRedirectCacheFlush no redirect to forget; sceHttpsUnloadCert returns success like sceHttpsLoadCert, which keeps no certificate; sceHttpSetRedirectCallback and sceHttpSetCookieRecvCallback accept callbacks that are never called, sceHttpsSetSslVersion has no TLS connection to configure and sceHttpsGetSslError reports error 0 with detail 0; sceHttpSetAuthInfoCallback accepts a callback that is never called, as no server asks for authentication
  • sceFontGlyphDefineAttribute (libSceFont) checks the glyph and ignores the attribute and its value, whose meaning is unknown. PPSA01325 sets attribute 0x11 to 0 on a glyph from sceFontGenerateCharGlyph that it deletes unused, and draws the character with sceFontRenderCharGlyphImageHorizontal

Unknown function info

  • sceNpEntitlementAccessGetEntitlementKey - the three-argument signature, 16-byte key and errors 0x817D0002/0x817D0007 follow KytyPS5; PPSA01521 passes a service label, entitlement label and output pointer. Only the no-key path is implemented: local entitlement labels carry no keys, and the output is untouched on failure. Console error precedence and key provisioning are unverified

  • sceNpEntitlementAccess{Request,Poll}{Unified,Service}EntitlementInfoList - signatures unknown; no reference implements them, so they are declared without parameters. Like the consume requests in the same library, they report the signed-out NP state with SCE_NP_ERROR_SIGNED_OUT (0x80550006) and write nothing. PPSA15657 calls the unified request during start-up and continues past the error. Whether the console fails at the request or at the poll when signed out is unverified

  • sceRudpGetStatus - PPSA01521 passes an output pointer and byte count 0xF8; the status layout, size rules and error behavior are unknown. The export throws without writing output, including after initialization. shadPS4 declares it without arguments and returns success without writing status

  • sceHttpSetCookieEnabled - the two-argument signature and 0/1 enable values follow VitaSDK and shadPS4; PPSA01521 passes 0 to disable cookies. Disabling succeeds because the offline HTTP backend has no cookie engine; enabling throws. Invalid enable values use the same error as sceHttpSetInflateGZIPEnabled. Like the existing offline HTTP setters, the handle is not validated; requests still fail with the network error. Console behavior is unverified

  • sceHmd2Initialize (libSceHmd2) - the error the console returns when the PS VR2 runtime is unavailable is unknown; it returns libSceHmd's UNSUPPORTED_FEATURE (0x81110016). PPSA01317 passes a pointer to 16 zeroed bytes and only tests the result for non-zero

  • PPSA01317 imports declared without parameters, signatures unknown: the remaining libSceHmd2 and libSceVrTracker2 exports. Names from the aerolib NID list

  • libSceMbus (libSceDeviceService) - signatures taken from PPSA01317, which calls sceDeviceServiceInitialize(3, 0), polls sceDeviceServiceGetEventState(1) and queries again when bit 0 or 1 is set, and calls sceDeviceServiceQueryDeviceInfo_(0x7001, 0, 0, infos, 1, &count, &unknown, 0x70), treating a negative result as an error and count as the number of entries. The host has no devices: the event state is 0 and a query returns 0 with count 0

  • NGS2 ATRAC9 waveform loops accepts one integer forward smpl loop. Inclusive RIFF endpoints and encoder-delay adjustment follow vgmstream riff.c. PPSA03747 supplies a 60-byte sampler chunk with one loop, samplerData 24, start 256, inclusive end 299224 and delay 256 for 298969 audible samples. The chunk size and loop count bound the records; samplerData is not interpreted. Output positions are assumed to use audible samples and an exclusive end. Blocks split into an optional intro, a repeated range and an optional tail; zero play count means infinite repeats, positive play count includes the first pass. ATRAC9 ranges include a preceding codec frame for decoder history. The output block layout, repeat-count mapping and error codes are unverified on hardware. Multiple, reverse, alternating and fractional loops throw.

  • NGS2 submixer UserFx (control 0x20000004) invokes the title's callback after input mixing on every playing grain, including silence. The 40-byte control and 48-byte process context follow shadPS4. PPSA03747 installs a peak-meter callback; its code confirms the channel pointers, user data 0, channel count, grain size and sample-rate offsets and returns 0. Other user data words are preserved. Flags are assumed to be 1 after registration/restart and 0 thereafter, following UserFx2's first-process convention; this callback does not inspect them. Null handlers disable the effect, setup clears it, and nonzero callback results throw. These lifecycle and error semantics are unverified on console hardware.

  • PPSA01341 imports declared without parameters, signatures unknown: sceAgcSetSemaphoreMemory, sceAgcDriverRegisterMultipleResources. Names from the shadPS4 aerolib NID list

  • sceAppContentDownloadDataGetAvailableSpaceKb (libSceAppContent) - a title whose param.json declares downloadDataSize 0 gets 0 KB and OK; the console's behaviour for a title without a download data area is unverified (it may return an error instead). KytyPS5 does not special-case it, and shadPS4 stubs 1048576 KB

  • 7CxI50-xlCk, pMxXhNozUX8 (libSceNpPartner001) - unknown names and signatures, imported by PPSA23566; declared without parameters

  • libSceBluetoothHid (libSceBluetoothHid) - signatures taken from PPSA01317: sceBluetoothHidInit() and sceBluetoothHidUnregisterCallback() without arguments, sceBluetoothHidRegisterCallback(callback, 0, param) with a 16-byte param, and sceBluetoothHidRegisterDevice / sceBluetoothHidUnregisterDevice(vendorId, productId); the report and device name exports are declared without parameters

  • sceAgcWaitRegMemPatchMask (libSceAgc) - follows sceAgcWaitRegMemPatchReference: the mask is taken as a 32-bit value and written to the low mask word of a 32- or 64-bit wait, as OpenAGC does; sharpemu writes both words of a 64-bit wait's mask. A mask above 32 bits throws

  • scePsmlMfsr2CreateContext, scePsmlMfsr2CreateSharedResources, scePsmlMfsr2GetContextInitRequirement, scePsmlMfsr2GetDispatchPackets, scePsmlMfsr2GetDispatchPacketsSizeInDwords, scePsmlMfsr2GetSharedResourcesInitRequirement, scePsmlMfsr2Init, scePsmlMfsr2ReleaseContext, scePsmlMfsr2ReleaseSharedResources (libScePsml_mfsr2) - unknown signatures, imported by PPSA23566; declared without parameters

  • sceAgcDcbSetCfRegisterDirect, sceAgcDcbSetCfRegisterRangeDirect (libSceAgc) - signatures follow OpenAGC and SharpProspero, which agree; the SET_CONFIG_REG (0x68) packet is OpenAGC's. The driver does not execute SET_CONFIG_REG, so a submitted packet throws

  • scePadOpenExt (libScePad) - only special ports (type 2) are handled, and they return DEVICE_NOT_CONNECTED (0x80920007) because the host has no special controller; whether the console opens a handle and reports the device as disconnected later is unknown. PPSA01317 passes a 16-byte param that names the device by vendor and product id (b7 0e 04 0e ... for 0x0eb7:0x0e04) and skips the user on any negative result. Other port types throw

  • PPSA23566 imports declared without parameters, signatures unknown: sceAudioOut2UserGetSupportedAttributes, sceConvertKeycodeGetCharacterFromKeyboardData, sce::Json::MemAllocator::notifyError, sceNetResolverAbort, sceNpCommerceDialogOpen2, sceNpEntitlementAccessGetPftFlag, sceProprietaryVoiceChatHelper{Initialize,Terminate,SetVoiceChatState,GetVoiceChatUsageState}, sceVoice{GetResourceInfo,ResetPort,EnableChat,DisableChat}. Names from the shadPS4 aerolib NID list

  • PPSA01325 imports declared without parameters, signature unknown: sceRudpActivate. Name from the shadPS4 aerolib NID list

  • sceVoiceChatRequestCreateVoiceChatGroup, sceVoiceChatRequestJoinVoiceChatGroup, sceVoiceChatRequestLeaveVoiceChatGroup, sceVoiceChatRequestDeleteVoiceChatGroup (libSceVoiceChat) - assumed to take a request id and two pointers like the other sceVoiceChatRequest* calls; offline, every argument is ignored and SIGNED_OUT is returned, as for those

  • sceAvPlayerAddSource (libSceAvPlayer) - requests up to 4 additional decode-ahead video framebuffers from the memory replacement beyond num_output_video_framebuffers when memory is available; the console's internal buffering behaviour is unknown

  • sceTextToSpeech2Initialize (libSceTextToSpeech2) - the console's error for an unavailable speech engine is unknown; it returns the kernel's EOPNOTSUPP (0x8002002D). PPSA01317 passes a param that starts with 0x2000000 and only tests the result for non-zero; the other exports it imports are declared without parameters

  • sceAgcDcbClearState (libSceAgc) - the (buffer, command) signature follows SharpProspero and OpenAGC, and the 2-dword CLEAR_STATE (0x12) packet is OpenAGC's; OpenAGC masks the command to 4 bits, here a command above 0xf throws, as the driver rejects that payload

  • Command buffer cursors (libSceAgc) - a null cursor_down is taken as a buffer without downward allocations, whose limit is top. PPSA16064 builds one-packet buffers of 8 dwords that way; the console's handling is unconfirmed

  • sceVideoOutRegisterBuffers2 (libSceVideoOut) - buffer option 8 (STRICT_COLORIMETRY) is presented as option 0, with the stored values unchanged; what the console changes for it is unknown. Only options 0 and 8 are accepted

  • sceAgcGetRegisterDefaultsInternal (libSceAgc) - returns the version 0 internal table, as sceAgcGetRegisterDefaults returns the version 0 public one; OpenAGC returns the table of the version passed to sceAgcInit instead, and null before it

  • sceVideoOutRegisterBuffers2 (libSceVideoOut) - DCC buffers (category 1): dcc_control is taken as the CB_DCC_CONTROL block layout, only bits 0x10026c are accepted; dcc_cb_register_clear_color as the register-clear texel, only 32-bit values are presented

  • sceVideoOutIsOutputSupported (libSceVideoOut) - output mode encoding unknown: every mode except the default reports not supported (0), and sceVideoOutConfigureOutput returns VIDEO_OUT_ERROR_UNAVAILABLE_OUTPUT_MODE for it, instead of returning VIDEO_OUT_ERROR_UNSUPPORTED_OUTPUT_MODE for values the console does not define. PPSA12544 probes 0xd000000a and selects 7680 pixels when it is supported, 3840 otherwise

  • sceVideoOutOpen (libSceVideoOut) - the open param's first word is unknown (PPSA21564 passes 16; it is not the byte size, since the affinity mask is at offset 16); only 16 is accepted. Whether the param continues past offset 24 is also unknown

  • s_setkill (core/shader/recompiler) - decoded as s_endpgm for any immediate: measured on RDNA2 hardware (gfx1035), a store before it is visible and nothing after it runs (#771); whether the KILL status bit it sets is observable differently from s_endpgm is unverified

  • sceRtcParseDateTime (libSceRtc) - the console's zone name table is only known from the names measured on a PS5 (firmware 13.60); any other name is assumed to take the military letter offset of its first character, as every measured name outside the table does (HST, MSK, XYZ), so a name the console's table holds but nobody measured gets the wrong offset

  • sceAudio3dPortOpen (libSceAudio3d) - buffer modes 0 and 1 (also selected by the 0x10 and 0x18 parameter sizes) and 3 beds depend on an SDK version check in the module (prosper) and throw. A repeated sceAudio3dInitialize (NOT_READY in shadPS4, 0 in prosper) and sceAudio3dPortAdvance on a full queue (NOT_READY in shadPS4, unhandled in KytyPS5) throw too

  • sceAudio3dObjectReserve (libSceAudio3d) - object ids, the max_objects limit and the checks of sceAudio3dObjectReserve and sceAudio3dObjectUnreserve follow shadPS4 (PS4), the only reference with a body: ids count up from 1 per port, skipping 0, 0xFFFFFFFF and ids in use, and a failed reserve writes 0xFFFFFFFF

  • s_sethalt (core/shader/recompiler) - with SIMM16[0] clear it is a no-op: the RDNA 2 ISA guide describes that value as resuming a halted wave, and a wave that executes it is not halted; measured on a gfx1035 (RDNA 2) wave: s_sethalt 0 followed by a VALU op completes and gives the normal result. Only SIMM16[0] is read; with it set the instruction throws

  • AMPR WriteAddressFromCounterPairOnCompletion (libSceAmpr) - the pair of an even counter n is assumed to give counter n in the low 32 bits and n + 1 in the high 32 bits. Wait compare values, wait flush and counter index ranges follow the ampr_emu reimplementation; the flush is accepted and has no effect, as commands run in order

  • AMPR command sizes (libSceAmpr) - commands use the emulator's own encoding with an 8-byte header, so Nop(n) takes 8 + 4n bytes where the console record is n dwords including its header (NopWithData(n): (n + 1) dwords). The measure functions agree with the appended sizes, but a title that pads to an exact offset or the end of the buffer with Nop(remaining / 4) gets SCE_AMPR_ERROR_BUFFER_FULL or a shifted offset. The at-start flag of the _04_00 writes is ignored; commands run in order, each after the previous one completes

  • AMPR counter access (libSceAmpr) - signatures and checks of WaitOnCounter_04_00, WriteCounter_04_00, ConstructNop and ConstructMarker taken from the ampr_emu reimplementation, which hands counter commands to the console and does not show their effect. The counters are taken as 32 bits each: the 8-byte access of counter n spans n (low) and n + 1 (high), the 2- and 1-byte accesses select a half or a byte of the counter by its offset, waits compare at the access width (signed and wrapped compares included), the AND mask applies to both sides and the atomic writes wrap within the access. The ConstructNop type is not recorded

  • APR gather and scatter reads (libSceAmpr) - signatures, argument checks and the read cursor taken from the ampr_emu reimplementation, not confirmed on a title: each read leaves the file, the next file offset and the next destination; a gather reads that file at a new offset into the next destination, a scatter continues in the file into a new destination, a gather-scatter takes both. Recording one needs a read file since the last ResetGatherScatterState; like ampr_emu, sceAmprCommandBufferReset keeps that state, and a gather or scatter with no read before it in the submitted buffer throws instead of returning SCE_AMPR_ERROR_APR_INVALIDGATHERSCATTERSTATE

  • AMM map, map direct and unmap (libSceAmpr) - signatures and the protection mask (CPU, GPU, AMPR and ACP read and write) taken from the ampr_emu reimplementation, which hands the remaining checks and the mapping to the console kernel; the mapper model taken from PS5PCEM: sceAmprAmmGiveDirectMemory usage 1 gives the allocated direct memory to the pool plain maps take pages from, usage 0 only allocates it. Not confirmed on a title. The AMM virtual address ranges are a 32 GiB range and a 32 GiB multimap range reserved in the guest arena on first use, not the console's; maps outside them throw. Addresses, sizes and direct offsets must be 16 KiB aligned. The memory type and the GPU mask are ignored, AMPR and ACP access maps as CPU access, unmapped pages go back to the pool and stay reserved. Submission runs the buffer before returning, the submit result is always 0 and a failing command throws; the AMM measures return errors sign-extended, as ampr_emu does. sceAmprAmmGetVirtualAddressRanges throws for a null output

  • AMM remap, multimap and protection changes (libSceAmpr) - signatures and the protection and mask checks taken from ampr_emu; the effects are inferred from the names, not confirmed on a title. A remap moves every page of a fully mapped range to the new address with the given protection and leaves the old range reserved; a multimap maps the same pages at a second address, anywhere in the AMM ranges, and a pool page goes back to the pool once its last mapping is unmapped; a multimap onto its own source range throws. A protection change sets the masked bits on every page of a fully mapped range; the memory type is recorded and ignored. A command on a range that is not fully mapped throws

  • sceVideodec2GetAvcPictureInfo (libSceVideodec2) - runs the sceVideodec2GetPictureInfo body (KytyPS5 binds both NIDs to one function; SharpProspero gives both the same outputInfo, first, second signature); the second (bottom field) picture info is never written, since only progressive H.264 output is modelled. prosper calls the AVC layout unestablished (no title observed calling it)

  • AMM PRT ranges (libSceAmpr) - signatures, checks and their order taken from ampr_emu, where MapAsPrt is a map with the PRT flag and protection 0 and AllocatePaForPrt a memory type and protection change with mask 1019, both checking the buffer memory after its size; the effects are inferred from the names, not confirmed on a title. Unbacked PRT pages are zero-filled pages with GPU read access, so CPU reads see zeros instead of faulting and GPU writes fault instead of being dropped. AllocatePaForPrt backs each unbacked page with a pool page and sets the type and protection of backed ones; RemapIntoPrt moves a fully mapped range into a PRT range, its opcode argument (1011 when 0, as in ampr_emu) is recorded and ignored; UnmapToPrt returns the pages to the pool and zero-fills them again. A plain map, unmap or remap over a PRT range ends it; AllocatePaForPrt, RemapIntoPrt or UnmapToPrt outside a PRT range throws

  • APR map begin and end (libSceAmpr) - as in ampr_emu, MapBegin/MapDirectBegin map when they run and MapEnd only closes the region; while a region is open a second begin and every completion write return EPERM, the at-start _04_00 writes are accepted

  • AMPR markers (libSceAmpr) - signatures taken from the ampr_emu reimplementation, not confirmed on a title: sceAmprCommandBufferSetMarkerWithColor takes the color by pointer, the push and measure variants by value. Colors are not recorded

  • sceFontGetRenderScaledKerning (libSceFont) - arguments, the cleared output and the bound renderer check taken from cellFontGetRenderScaledKerning in RPCS3 (PS3 predecessor of the library), not confirmed on a title. The kerning is the sceFontGetKerning one at the render scale

  • sceFontGetPixelResolution (libSceFont) - signature taken from the IDA type database of Orbital, not confirmed on a title. The value is the one the library's driver reports (64 for FreeType); the argument checks and the cleared output follow sceFontGetLibrary

  • sceFontDettachDeviceCacheBuffer (libSceFont) - signature taken from the IDA type database of Orbital, not confirmed on a title. It detaches the cache buffer attached by sceFontAttachDeviceCacheBuffer, returns the buffer and its size, and reports SCE_FONT_ERROR_NOT_ATTACHED_CACHE_BUFFER when no cache buffer is attached

  • sceFontGetFontGlyphsCount, sceFontGetCharGlyphCode (libSceFont) - signatures taken from the IDA type database of Orbital and matching the SharpProspero bindings, not confirmed on a title. The count is the face's glyph count and the glyph code its glyph index, as the library's driver reports them; a code with no glyph returns NO_SUPPORT_GLYPH and code 0 NO_SUPPORT_CODE, as sceFontRenderCharGlyphImage does. The argument checks and the cleared output follow sceFontGetPixelResolution

  • sceFontGetFontResolution (libSceFont) - signature taken from the IDA type database of Orbital, not confirmed on a title; the outputs are inferred from the names. The resolution is the face's units per EM and the scale pixel the driver's face scale (units per EM / 64 for FreeType), the pixel scale a font has when opened. Either output may be null, as in sceFontGetResolutionDpi

  • sceFontCreateWritingLine, sceFontWritingLineWritesOrder (libSceFont) - signatures and the SceFontWritingLineStep/SceFontCreateWritingLineDetail layouts (detail id 0x0FD5) taken from SharpProspero, not confirmed on a title; the meaning of the 64-bit writing attribute is unknown

  • sceFontWritingLineGetOrderingSpace (libSceFont) - signature taken from the IDA type database of Orbital and the SharpProspero bindings, not confirmed on a title. The modelled line applies no spacing, so the head, inline, tail and advance spaces are 0; what spacing the console applies is unknown. A null output throws

  • sceSaveDataTransferringMountPs4, sceSaveDataDirNameSearchPs4 (libSceSaveData.native) - arguments assumed to be those of sceSaveDataTransferringMount and sceSaveDataDirNameSearch: KytyPS5 binds both NIDs to the PS5 functions, and prosper captured the same result layout on a title for the search. There is no PS4 save area, so the mount returns NOT_FOUND and the search reports zero hits

  • sceCoredumpWriteUserString and sceSaveDataConvert, sceSaveDataGetConvertProgress - imported by PPSA16064, not called during its start-up and added without an implementation; unknown signatures

  • sce::Json::Parser::parse (libSceJson2) - a number that overflows a double (e.g. 1e309) throws: whether the console rejects the document or stores an infinite real is unknown

  • sceUserServiceGetNpAccountId (libSceUserService) - the account id for a user with no linked PSN account is assumed to be 0 with success; libSceNpManager's sceNpGetAccountIdA answers the same question with SCE_NP_ERROR_SIGNED_OUT

  • sceUserServiceGetUserColor (libSceUserService) - the default profile colour is assumed to be blue (0)

  • kP2L8t3j-aM (libSceVideoOut) - unknown name, signature

  • LibwuIonIBw (libSceVideoOut) - unknown name, signature

  • sceAgcDriverGetEqContextId (libSceAgcDriver) - returns ident: an end-of-pipe interrupt is delivered only to the registration whose id equals the raising queue, so ident is that context's id (titles register 0 or 1 for graphics and 0x20 + 8 * pipe + queue for compute). The console's value is not known; KytyPS5 returns the event's data, which it fills with the interrupt's context id, whereas data here is the EV_CLEAR trigger count. Other event filters throw

  • sceAgcSetSubmitMode (libSceAgc) - mode values unknown; only 0 is accepted

  • User data registers (AGC driver) - a SPI_SHADER_USER_DATA_* or COMPUTE_USER_DATA_* register the title never wrote reads as 0 when a stage's RSRC2 count covers it, as Kyty (zeroed UserSgprInfo) and SharpEmu (missing registers read 0) do, and as AMD PAL and Mesa initialize them; the console's value is not confirmed

  • SET_PREDICATION (AGC driver) - boolean predication follows the AMD PM4 encoding Mesa uses: operation 3 reads 64 bits and 4 reads 32 bits, and bit 8 runs predicated packets when the value is non-zero (clear: when it is zero); the bit 12 hint is ignored. The address must have its low 4 bits clear, as sceAgcDcbSetPredication writes it. Query predication (Z-pass, primitive count), a predicated COND_EXEC, predicated command buffer chains and flips in predicated command buffers throw

  • sceAgcGetGsOversubscription (libSceAgc) - signature and occupancy formula (base and expanded vertex/export capacities, budget shift, GE_PC_ALLOC / SPI_SHADER_PGM_RSRC4_GS encoding) follow KytyPS5 only, not confirmed on hardware or a title; a negative or NaN factor that gives a negative target, a missing GS context register or a zero GE_MAX_OUTPUT_PER_SUBGROUP throws

  • Vertex entry merged wave info (recompiler) - s3 of every vertex-path shader is set to waveSize | waveSize << 8 (vertex and primitive count of a full wave, wave index 0). Layout taken from the prologue Mesa's ACO emits for NGG vertex shaders (s_bfe_u64 exec from s3), not measured on hardware. The driver gives every graphics program user data from s8, so the condition does not tell NGG from legacy vertex shaders: they just never read s3. A draw whose last wave is partial still reports a full wave.

  • sceAgcCbCondWrite (libSceAgc) - argument order and the 9-dword COND_WRITE layout follow the clean-room OpenAGC and sharpemu, which agree on them; SharpProspero lists another order. The write space is accepted only as 1 (memory), the one value both encode the same way, and other values throw.

  • sceAgcGetIsTrinityMode (libSceAgc) - signature from the only PPSA26344 call (a pointer to a one-byte flag, result ignored); a null pointer throws because its error code is unknown

  • zARR5aCmkoY (libSceAgc) - unknown name, signature

  • sceAgcDcbContextStateOpGetSize (libSceAgc) - sizes from KytyPS5 only (5, 27, 27 and 32 dwords), equal to what sceAgcDcbContextStateOp_0100 writes; KytyPS5 returns 0 for an operation above 3, here it throws

  • sceAgcBranchPatchSetThenTarget_0300, sceAgcBranchPatchSetElseTarget_0300 (libSceAgc) - names from their NIDs (7Wa3aeJgeVU, rP5xLdOf26k), signatures unknown

  • sceAgcUpdateInterpolantMapping_0100 (libSceAgc) - name from its NID (k0E7vkgqAuE); the (regs, vs, ps) arguments are the declared ones, behaviour unknown

  • sceAgcWriteDataPatchSetDst, sceAgcWriteDataPatchSetCachePolicy and their Async forms (libSceAgc) - the signatures (packet, uint8 value) are inferred from the other patch functions, as no public declaration was found; the value is taken in the encoding of the dst and cachePolicy arguments of sceAgcDcbWriteData (graphics) and sceAgcAcbWriteData (Async, compute), and the patched packet is the one those calls would write. sceAgcAsyncWriteDataPatchSetAddressOrOffset is assumed to patch the address like sceAgcWriteDataPatchSetAddressOrOffset, as the compute WRITE_DATA packet keeps it in the same dwords

  • dbOlWdppb4o (libSceAgc) - unknown name; same arguments as sceAgcCreateInterpolantMapping; the SPI_PS_INPUT_CNTL bits for is_f16 2 inputs follow KytyPS5, not confirmed on hardware

  • sceAgcGetDataPacketPayloadRange (libSceAgc) - signature, the {base, size in bytes} output and the type 0 range (header + 1, one dword longer than the type 1 payload) from KytyPS5 only, matching sceAgcGetDataPacketPayloadAddress_0090; prosper returns header + 2 for both types from that address function

  • sceAgcAsyncCondExecPatchSetCommandAddress, sceAgcAsyncCondExecPatchSetEnd (libSceAgc) - no reference has a body for them; they are assumed to patch the COND_EXEC packet like sceAgcCondExecPatchSetCommandAddress and sceAgcCondExecPatchSetEnd, since sceAgcAcbCondExec writes the same packet as sceAgcDcbCondExec, as sceAgcAsyncRewindPatchSetRewindState does for REWIND

  • sceAgcAcbAtomicGds_0900 (libSceAgc) - name from its NID (gQkqkLttcpw), signature unknown

  • sceAgcDcbPrimeUtcl2 (libSceAgc) - assumed to write the packet sceAgcAcbPrimeUtcl2 writes: PRIME_UTCL2 has the same 5 dwords on the graphics and compute rings. Not confirmed on a title. Both write a NOP of that size, as there is no TLB to prime

  • sceAgcDcbQueueEndOfShaderActionGetSize (libSceAgc) - the builder is inline in the SDK and not exported; the size is assumed to be that of the RELEASE_MEM packet sceAgcCbReleaseMem writes (32 bytes), the same as sceAgcAcbQueueEndOfShaderActionGetSize, as in OpenAGC and REmu

  • sceKernelInternalMemoryGetModuleSegmentInfo (libkernel) - unknown signature

  • sceKernelGetModuleInfoForUnwind (libkernel) - eh_frame_size is assumed to cover the records up to, not including, the zero terminator. LLVM libunwind's CFI_Parser::findFDE stops at the terminator or the length, whichever comes first, so it finds the same FDEs either way; what the console reports is not known.

  • sceKernelGetModuleInfoFromAddr (libkernel) - the 0x1A8-byte info layout follows the shadPS4 reimplementation; a title's libc.prx reads only id (PPSA14632). The meaning of flags is unknown; only 2 is accepted, as is only the full st_size. The id is the sceKernelLoadStartModule handle of an image opened through the loader and otherwise a stable id from the same range. The name is the host file name without .guest.prx. An image with more than 4 load segments (the converted executable has 7) reports its first 4. tls_offset is 0 and ref_count is 1, as the host loader exposes neither. Not implemented on Windows

  • sceKernelReleaseFlexibleMemory (libkernel) - unmaps the range like sceKernelMunmap, as fpPS4 and prosper do; whether the console keeps the virtual range reserved after releasing its pages is unverified

  • Memory protection bits 0x100 and 0x200 (libkernel) - taken as audio coprocessor (ACP) read and write, as in the KytyPS5 and etaHEN headers; the coprocessor work runs on the host CPU, so they grant host read and read/write access like the GPU bits

  • sceKernelSyncOnAddressWait (libkernel) - the only known caller passes a null timeout and a name string as the fourth argument; the timeout is assumed to point to microseconds like the other kernel waits, and the name is ignored

  • sceKernelSyncOnAddressWait8 / sceKernelSyncOnAddressWait16 / sceKernelSyncOnAddressWait32 / sceKernelSyncOnAddressWait64 (libkernel) - libc's __std_atomic_wait_direct_8/16/32/64 pass a microsecond timeout or null and ignore the result; the by-value comparand, return values and the 2- and 8-byte alignment of Wait16 and Wait64 are assumed

  • sceKernelAioSubmitReadCommandsMultiple / sceKernelAioSubmitWriteCommandsMultiple / sceKernelAioWaitRequests / sceKernelAioCancelRequest / sceKernelAioCancelRequests / sceKernelAioDeleteRequests (libkernel) - behaviour from shadPS4 (one id per request for the Multiple submits, cancel turns any request aborted and id 0 reports processing, wait mode 2 returns once one request completed); the 128 requests or ids per batch limit is from SharpProspero, with an unknown error, so larger batches throw; wait modes other than 1 (and) and 2 (or) throw; null pointers, negative counts and invalid ids return the codes the single-request siblings use, checked before any state is written

  • sceKernelGetAvailableCpumask (libkernel) - returns the default thread affinity, 0x1FFF (CPUs 0 to 12), as KytyPS5 does. Titles pin threads within it (PPSA02664 passes 0x1FFB, Hades II PPSA36082 0x3 and 0x3F); whether CPU 13 is available to a title is not confirmed

  • sceKernelMapNamedFlexibleMemoryInternal (libkernel) - flag 0x8000 is accepted and ignored; its meaning is not established. KytyPS5 (GUEST_MAP_UNKNOWN_8000) and sharpemu accept it without reading it. Every known caller is the SDK 9 libc.prx heap (Astro Bot PPSA21564, PPSA22520), which passes it with read/write protection and uses the mapping as an older libc.prx uses sceKernelMapNamedFlexibleMemory with flags 0

  • sceKernelMtypeprotect (libkernel) - sets the memory type of the direct mappings in the page-rounded range and of the direct memory behind them, as shadPS4 and prosper do (KytyPS5 ignores the type); the type is not validated, flexible pages in the range only get the protection, and a later map of the retyped direct memory reports the type it was allocated with. sceKernelBatchMap2 operation 4 takes the same path with the entry type

  • Guest arena (libc) - the application map area is assumed to end at 0xFC_0000_0000, as SCE_KERNEL_APP_MAP_AREA_END_ADDR does on the PS4. On Windows, host allocations made in the arena before libc loads stay, and a fixed guest mapping over one throws

  • sceLibcInternalBacktraceForGame (libSceLibcInternal, implemented in libc) - unknown signature

  • sceLibcInternalHeapErrorReportForGame (libSceLibcInternal, implemented in libc) - unknown signature

  • _sceLibcInternalThreadAtexit, _sceLibcInternalThreadDtors (libSceLibcInternal) - FreeBSD __cxa_thread_atexit semantics assumed; a null or non-image destructor and an allocation failure throw

  • _sceKernelRtldThreadAtexitIncrement, _sceKernelRtldThreadAtexitDecrement (libkernel) - the argument is the dso address a title's libc.prx passes to __cxa_thread_atexit (PPSA14632), which fails when Increment returns nonzero. As in the fpPS4 reimplementation, Increment takes a reference on the loaded image containing the address and Decrement releases one; the variants without the leading underscore are assumed to match

  • _sceLibcInternalForceTlsDestructor (libSceLibcInternal) - behaviour follows sceLibcForceTlsDestructor(int) in a title's libc.prx (disassembly): the calling thread's destructors whose dso belongs to the module run newest first, only if the dso's module is loaded and the dso points to itself, in up to 4 passes. The return type is unknown (that function returns nothing), 0 is returned. The module of each dso is looked up when the destructors are forced, not when they are registered as libc.prx does, and the lookup is Linux only, so on Windows the call throws when the thread has destructors

  • std_execute_once (libc) - assumed to be the plain-named twin of std::_Execute_once (_ZSt13_Execute_onceRSt9once_flagPFiPvS1_PS1_ES1_, the callee of Dinkumware call_once): it delegates there and gets the [thread.once.callonce] semantics already verified for that symbol (one invocation per flag, concurrent callers block until it completes, and a failing or throwing invocation leaves the flag unready so the next caller runs it). The name equivalence is not confirmed on a title, and the callback convention (called with (null, arg, null), non-zero return meaning success) is the twin's, unverified for this symbol

  • __progname (libkernel) - unknown data export

  • pthread_barrierattr_setpshared (libkernel) - PTHREAD_PROCESS_SHARED is accepted on the assumption that the console follows FreeBSD 11.0 libthr, which accepts it (9.0 rejects it with EINVAL); unverified on hardware. Guest code runs in one process, so a shared barrier behaves as a private one

  • sceSslClose (libSceSsl) - unknown signature

  • sceSslGetSerialNumber (libSceSsl) - unknown signature

  • X+4jdIS75P0 (libSceAudioIn) - unknown name, signature

  • sceAudioOut2Set3DLatency (libSceAudioOut) - assumed to take (user_id, latency): KytyPS5 reads (user_id, output, latency_us), but the known calls set just edi and esi; only (0xFF, 2) (PPSA26344) and (0xFF, 1) (PPSA14632) are accepted

  • sceAudioOut2MasteringInit (libSceAudioOut) - flag values unknown; only 0 is accepted. Whether the console reports an error for a repeated sceAudioOut2MasteringInit or for sceAudioOut2MasteringTerm without a matching initialization is unknown; both return 0. PPSA01289 creates the audio device of its next world before it destroys the previous one, so it calls Init twice before Term twice, and only logs a non-zero result

  • sceAudioOutSetMixLevelPadSpk (libSceAudioOut) - effect of a negative mix level unknown; only 0 to 32768 (0 dB) is accepted

  • sceAudioOutSetMixLevelPadSpk (libSceAudioOut) - no source applies the level (shadPS4 only stores it); it is assumed to be a linear gain on the port's own output, and the -9 dB default (11626) is applied to every pad speaker port, including those of titles that never call the function

  • sceAudioOutGetLastOutputTime (libSceAudioOut) - signature and behaviour taken from the shadPS4 and fpPS4 reimplementations of the PS4 library, not confirmed on a PS5 title: the time is the process time at which sceAudioOutOutput or sceAudioOutOutputs accepted the port's last block, not the time the block reached the device

  • sceAudioOut2PortCreate (libSceAudioOut) - MAIN (type 0) format validation follows PS5 firmware 13.60 measurements: bits 8-11 accept 1, 2, 8 or 12, bits 0-6 accept 0 or 1, bit 7 requires 8 channels, and bits 12-31 do not affect validation. The sample types are still read as float and int16; bit 7's layout, the PCM effect of bits 12-31 and the port flags are unverified. Other port types retain unverified format validation, including 6 channels and rejection of bits 12-31

  • sceAudioOut2PortCreate (libSceAudioOut) - 12 channels are assumed to be L R C LFE Ls Rs Lb Rb Ltf Rtf Ltb Rtb as in KytyPS5's 12-to-8 fold, and 6 and 8 channels to be its first 6 and 8; no title or SDK header confirms the order

  • sceAudioOut2PortCreate (libSceAudioOut) - the stereo fold is assumed, not the console's downmix: C at -3 dB into both sides, Ls/Rs, Lb/Rb and Ltf/Rtf at -3 dB and Ltb/Rtb at -6 dB into their own side, LFE dropped

  • scePsmlMfsrGetContextBufferRequirement1100, scePsmlMfsrCreateContext1100, scePsmlMfsrGetDispatchMfsrPacket1100 (libScePsml_debug) - argument layouts unknown; only 0x8A810001 (not initialized) is returned

  • scePngEncEncode (libScePngEnc) - whether rows may stay unfiltered when filter_type names a subset of the filters is unknown; as in shadPS4, they may only for 0 and for the all-filters mask

  • sceJpegEncEncode (libSceJpegEnc) - restart_interval follows SharpProspero's field doc (0 none, -1 every row of blocks, positive a block count); a positive value is taken as the JPEG DRI interval in MCUs and -1 as one restart per MCU row, which no reference confirms. Other negative values throw

  • sceVoiceQoSInit (libSceVoiceQoS) - 0x804E0905 for a second initialization comes from prosper's reading of the module and was not measured: on a PS5 a valid call blocks inside a homebrew payload, so it never returns there. The app type and the block are not used, as no endpoint is implemented

  • AudioIn and NpSessionSignaling exports added without an implementation have assumed signatures

  • sceNpSessionSignalingGetConnectionFromPeerAddress (libSceNpSessionSignaling) - imported by PPSA01289 and added without an implementation; unknown signature

  • libSceCdlgG2P - sceG2PDialogInitialize, Terminate, Open, GetStatus, UpdateStatus and GetResult, imported by PPSA01289, are added without an implementation and declared without parameters

  • vieBRwlh1Lw (libSceAgc) - unknown name, signature

  • scePadIsRemoteController (libScePad) - the name hashes to NID fCWdlnmB1Ks; the signature (int handle, bool* remote) comes from PPSA16064, which zeroes a byte, passes its address after scePadGetControllerInformation and ignores the result. The error codes follow the other pad calls. Controllers are local devices, so the answer is always false

  • scePadSetAngularVelocityBiasCorrectionState (libScePad) - imported by PPSA16064 and not called during its start-up; unknown signature

  • sceKernelGetOperationMode (libkernel) - the signature (int* mode, int* submode) comes from PPSA12544, which logs both values after the call; the values are unknown and 0 is reported for both, as in the prosper reimplementation. Null outputs throw

  • Font, Http2, Net, Ssl, SystemService and libkernel exports imported by PPSA12544 and added without an implementation have unknown signatures

  • sceHttp2GetMemoryPoolStats, sceSslGetMemoryPoolStats, sceNetGetMemoryPoolStats (libSceHttp2, libSceSsl, libSceNet) - signatures (int id, stats*) and the statistics layouts (pool size, peak and current use, and for Http2 and Ssl a 32-bit reserved field) follow the PS4 SDK's SceHttp2MemoryPoolStats, SceSslMemoryPoolStats and SceNetMemoryPoolStats, not confirmed for the PS5. The pool size is the one given at init or pool creation; nothing is allocated from these pools, so the peak and current use are 0. Net returns EBADF for an unknown pool and EINVAL for a null output, as its other pool calls do; for Http2 and Ssl the error codes are unknown, so both cases throw

  • sceHttp2SetResolveRetry (libSceHttp2) - signature (int id, int32_t retry) from libSceHttp's sceHttpSetResolveRetry; the value is accepted and ignored like the other Http2 settings, since no request reaches the network

  • sceHttp2WebSocketCreateRequest, sceHttp2WebSocketCloseAsync, sceHttp2WebSocketSendTextMessageAsync, sceHttp2WebSocketSendDataMessageAsync (libSceHttp2) - imported by PPSA16064 and not called during its start-up; unknown signatures

  • libSceVrSetupDialog, and the Share, NpTrophy2, NpEntitlementAccess and WebBrowserDialog exports imported by PPSA12544's Unity plugins and added without an implementation, have unknown signatures

  • sceAjmDecWVorbisCreateHeaderPacket, sceAjmDecWVorbisCreateSetupPacket (libSceAjmWVorbis, implemented in libSceAjm.native) - unknown signatures

  • Acm, GameLiveStreaming, Net, NpEntitlementAccess, NpManager, NpWebApi2, VoiceQoS, WebBrowserDialog and libkernel exports imported by PPSA14632 and added without an implementation are declared without parameters

  • libSceAudioPropagation (libSceAudioPropagation) - signatures and struct descriptors recovered from PPSA21567's calls (#481), not from documentation. The system options layout is unknown (only checked for non-null); the fourth argument of sceAudioPropagationSourceCalculateAudioPaths is unknown; sceAudioPropagationSourceGetAudioPath is assumed to output an 8-byte path handle. The meaning of the RenderInfo word at +0x28 is unknown (PPSA21567 and PPSA21564 pass 2); only 2 is accepted. Both titles pass one RenderInfo per call: a count of 0 throws, and larger counts are handled element by element without proof. No error code is known, so invalid input throws instead of returning one

  • NGS2 mastering voice gain (libSceNgs2.native) - the param id 0x30000004 is taken from PPSA22520 and the layout from shadPS4's OrbisNgs2MasteringVoiceGainParam; no reference gives the units or range. The levels are assumed to be linear factors applied when the mastering voice is mixed into the render buffer, so the voice's own samples stay unscaled; the LFE level applies to channel 3 of 6- and 8-channel voices, assuming the L R C LFE order of the AudioOut2 entries above, and the full-band level to the rest. Negative levels are accepted, and a new setup resets both levels to 1

  • NGS2 stereo mastering voice into a surround buffer (libSceNgs2.native) - PPSA21402 renders a 2-channel mastering voice into a 6- or 8-channel render buffer, which the mixing stage rejected. The console's conversion is unknown: the left and right channels are assumed to go to the first two buffer channels (front left and right) and the remaining channels stay silent, with no centre, LFE or surround content. Any other channel count mismatch still throws

  • NGS2 streaming PCM waveforms (libSceNgs2.native) - PPSA21402 streams its music by adding one block whose num_samples is the whole track and whose data_size is a 16 KiB first piece, with CONTINUE, and then adds each following piece with flag 0x2 (called APPEND here) and the same num_samples. No reference describes flag 0x2. A 16-bit PCM block without skipped samples or repeats whose num_samples exceed its data is assumed to start such a stream; flag 0x2 is assumed to append the block's data to the last streaming block, ignoring its num_samples; the voice is assumed to output silence without advancing while it has played all appended data and CONTINUE is set; and the waveform is assumed to end at num_samples or, once CONTINUE is cleared, at the end of the appended data. sceNgs2VoiceGetState reports the bytes played as decoded_data_size, which the title uses to release its queued data, and the read position as waveform_data. Appending to a block that is not a stream, or other formats, skipped samples, repeats and partial frames, throw

  • sceAvPlayerStartEx (libSceAvPlayer) - start info layout unknown; it is ignored and playback starts as with sceAvPlayerStart

  • sceAvPlayerInit / sceAvPlayerInitEx (libSceAvPlayer) - behaviour without a memory replacement unknown; frame and sample buffers then come from the guest heap

  • SceAvPlayerVideoEx (libSceAvPlayer) - frame rate field and encoding unknown; it is left zero in frame and stream info

  • sceRazorCpuFlushOccurred (libSceRazorCpu) - signature and return values (1 = flush since the last call, 0 = none) from SharpProspero; without a capture nothing is flushed, so it returns 0 and writes 0 cycles to the optional out pointer (whether the real library writes it when nothing was flushed is unknown)

  • sceRazorCpuPushMarkerStatic, sceRazorCpuPopMarker (libSceRazorCpu) - signatures from PPSA26344's calls; (name, color, flags) assumed for the push; both do nothing without a capture

  • sceRazorCpuPlotValue, sceRazorCpuWriteBookmark (libSceRazorCpu) - signatures (series, float value) and (label, optional description) from SharpProspero, matching PPSA06320's calls; both do nothing without a capture and return 0

  • sceAjmBatchJobGetInfo (libSceAjm.native) - writes the result and format sideband of a run job without buffers with the SIDEBAND_FORMAT flag (0x400000000000), as KytyPS5 does, not confirmed on a PS5 title; the format reports bitrate 0 for ATRAC9 as in KytyPS5, while shadPS4 derives it from the superframe size; before the instance is initialized it returns the not-initialized result (1) and no format, like the other run jobs here, while KytyPS5 returns result 0 with the format of the uninitialized decoder

  • sceAjmDecMp3ParseFrame (libSceAjm.native) - signature, result layout and rate tables taken from the shadPS4 reimplementation of the PS4 library, not confirmed on a PS5 title: the layer field is not checked and MPEG-2.5 stops at 64 kbps; the original file length (parse_ofl) layout (Xing/Info + LAME tag, VBRI, Fraunhofer 0xB4 block with its CRC, encoder delay = samples per frame + LAME delay + 529) also comes from shadPS4 only, and the Fraunhofer block has no other public description

  • sceAjmBatchJobGetCodecInfo, sceAjmBatchJobGetGaplessDecode (libSceAjm.native) - the RUN_GET_CODEC_INFO flag (0x800), the ATRAC9 codec info layout and its next frame size are taken from the shadPS4 and RPCSX reimplementations, not confirmed on a PS5 title; a run job without buffers returns result 0, as in shadPS4. The gapless sideband reports the total and skip counts the title set and does not count them down: RPCSX does the same, shadPS4 counts them down and BryKytyPS5 returns its current counts

  • AJM Opus decoder (libSceAjm.native, codec 24) - the initialize parameter layout (u32 channels, u32 sample rate, u32, seen as 2, 48000, 0) and the little-endian u16 byte count before each packet come from one title (The Smurfs Dreams); only 48000 Hz and a zero third word are accepted

  • sceAjmBatchJobControl (libSceAjm.native) - RESET (bit 13), INITIALIZE (bit 14) and the sideband input order (gapless decode, then initialize parameters) come from shadPS4 (PS4); other flags throw

  • sceAjmBatchJobControl (libSceAjm.native) - RESET is assumed to clear the context as sceAjmBatchJobClearContext does

  • sceAjmBatchJobControl (libSceAjm.native) - initialize parameters are 8 bytes for ATRAC9, 12 for Opus and none for MP3, as one title passes them; other codecs and sizes, and an output other than the 8-byte result, throw

  • sceAjmBatchJobControl (libSceAjm.native) - SIDEBAND_GAPLESS_DECODE with RESET overwrites both counts as in RPCSX; shadPS4 ignores a zero count when the other is nonzero. Without RESET they differ, so it throws

  • NGS2 custom submixer rack (libSceNgs2.native, rack 0x4002) - structure layouts from shadPS4's ngs2_custom.h; module id 0x1f for UserFx2, the voice parameter id 0x40001f00 | module index, the process flags (1 on the first process call after setup, 2 after a parameter change, 0 otherwise) and the call order (setup per voice at rack creation, process after the inputs are mixed, cleanup at destruction) come only from KytyPS5. Only UserFx2 modules on a single buffer are accepted: other module ids, more buffers, a module control handler, different input and output channel counts, setup flags and default rack options throw. Each module's state is a separate buffer, not the state_offset slice of the voice state, and sceNgs2VoiceGetState still throws for this rack. As in KytyPS5, process runs only on grains where an input produced samples, so an effect tail stops with the input and a pending flag 2 waits for the next audible grain

  • sceHttpParseResponseHeader (libSceHttp) - signature follows SharpProspero; parsing and error codes follow shadPS4's reverse-engineered PS4 library, not confirmed on a PS5 title or hardware. Folded values retain their line breaks and whitespace; an empty first line starts the value scan after its line feed. A consumed byte count above INT_MAX throws instead of wrapping.

  • sceHttpParseStatusLine (libSceHttp) - behaviour and error codes follow the shadPS4 reimplementation of the PS4 library, not confirmed on a PS5 title; unlike it, no byte past lineLen is read

  • sceHttpUriMerge (libSceHttp) - signature follows SharpProspero; validation, size formula, absolute/relative split and path join follow the disassembly-like body in shadPS4, not confirmed on a PS5 title or hardware. The base URL goes through our sceHttpUriParse, which removes dot segments from the base path, while the relative part is appended unswept; base query and fragment are dropped. The relative reference is only classified by its scheme and a leading //, and only references with // are validated; as in shadPS4, //host/x is returned unchanged instead of taking the base scheme, a reference with a scheme but no // (mailto:x) is joined onto the base directory, and ?q and #f are appended to the base directory instead of the base path.

  • sceHttpUriUnescape (libSceHttp) - signature follows SharpProspero; percent decoding, invalid sequences and error codes follow shadPS4, not confirmed on a PS5 title or hardware. Size includes the final NUL; malformed escapes and + remain unchanged, and decoding runs once.

  • sceHttpUriSweepPath (libSceHttp) - behaviour follows the shadPS4 reimplementation of the PS4 library and its tests (including the PS4 SDK example), not confirmed on a PS5 title or hardware. It is not RFC 3986 5.2.4: a path that doesn't start with / is copied unchanged and a trailing . or .. without a slash is kept. Unlike shadPS4, nothing at or past srcSize - 1 is read, and srcSize == 1 writes only the terminator

  • sceHttpSetResponseHeaderMaxSize, sceHttpRedirectCacheFlush, sceHttpsUnloadCert (libSceHttp) - signatures follow shadPS4 (PS4); no PS5 reference has them

  • sceHttpSetRedirectCallback, sceHttpSetCookieRecvCallback, sceHttpsSetSslVersion, sceHttpsGetSslError (libSceHttp) - signatures follow shadPS4 (PS4), which only logs and returns 0; a null errNum or detail in sceHttpsGetSslError is assumed to return SCE_HTTP_ERROR_INVALID_VALUE like sceHttpGetLastErrno

  • sceHttpSetAuthInfoCallback (libSceHttp) - signature and callback type follow shadPS4 (PS4); no PS5 reference has them. The id is not checked, as in the other libSceHttp setters

  • sceHttp2GetMemoryPoolStats (libSceHttp2) - unknown signature

  • libSceHttp2 cookie boxes (libSceHttp2) - sceHttp2CreateCookieBox is taken to take the library context id first, as in the prosper reimplementation; further arguments are unknown and ignored. sceHttp2SetRequestNoContentLength is assumed to take only the request id. Cookies are never stored, so sceHttp2CookieFlush has nothing to discard

  • sceNetGetMemoryPoolStats (libSceNet) - unknown signature

  • sceHttpSetRequestStatusCallback (libSceHttp) - no reference implements it (shadPS4 only logs and returns 0); when the callback runs and what status it gets is unknown

  • sceNpSessionSignalingGetMemoryInfo (libSceNpSessionSignaling) - unknown signature

  • sceNpSessionSignalingGetConnectionStatistics (libSceNpSessionSignaling) - unknown signature

  • sceUserServiceGetAgeLevel (libSceUserService) - the meaning of the value is unknown; 0 is reported, as for the unset game presets. PPSA12544 (Unity) only stores it for its user profile

  • sceGameUpdateGetAddcontLatestVersion (libSceGameUpdate) - a null entitlement_label throws: KytyPS5 accepts it, prosper returns 0x80412803. Bytes after found are zeroed as in KytyPS5; prosper leaves them untouched

  • sceSystemServiceParamGetString (libSceSystemService) - the system name (parameter 6) is the fixed PS5, not the console's name; other parameters and buffers of 1 to 64 bytes throw

  • sceNgs2SystemSetSampleRate, sceNgs2SystemSetUserData, sceNgs2SystemGetUserData, sceNgs2SystemLock, sceNgs2SystemUnlock (libSceNgs2.native) - shadPS4 only checks the system handle (INVALID_SYSTEM_HANDLE) and SharpProspero names what each call does; neither gives the other limits. A sample rate of 0 and a null user data pointer throw, any other rate is accepted, and changing the rate while a sampler filter is enabled throws because the filter coefficients were computed for the old rate. Lock and unlock take the same lock as sceNgs2RackLock

  • sceNgs2RackGetInfo (libSceNgs2.native) - field order from shadPS4's OrbisNgs2RackInfo with the 64-byte name of the other info structures (216 bytes); type is assumed to be the rack id divided by 0x1000, min_grain_samples 64 (the system minimum) and state_flags 1; uid comes from a per-process rack counter, render_count is the owning system's render count and active_voice_count counts voices that are not empty (paused and stopped voices included). The last process ratio and tick and active_channel_work_count are left zero

  • sceNgs2VoiceQueryInfo (libSceNgs2.native) - only info id 0x4001 is known: PPSA22520 passes an 8-byte buffer and branches on the first word being 1 or 2, so it is assumed to be the voice channel count (0 before the voice is set up); the second word is zeroed and other ids throw

  • sceNgs2VoiceGetPortInfo (libSceNgs2.native) - layout from shadPS4; the delay and destination input are zero because ports have neither yet

  • sceNgs2ParseWaveformFile (libSceNgs2.native) - the signature (path, offset, info) is taken from the call site of PPSA21402, which sets only three argument registers; the file is read from offset to its end, the data and block offsets are taken to be relative to the start of the file, not of offset, and an unreadable file throws. The audio unit fields of a 16-bit PCM waveform are assumed to be one sample frame per unit and per frame; INVALID_WAVEFORM_DATA for a data chunk that runs past the buffer or ends inside a frame is assumed, and looped PCM and other PCM formats throw

  • sceSaveDataInitialize3 (libSceSaveData.native) - a repeated initialize succeeds: PPSA12544's executable and its Unity SaveData plugin both initialize, and the plugin fails on any error. Initializations are counted and sceSaveDataTerminate ends the session at the last one; how the console pairs them is unknown

  • sceVoiceSetMuteFlag (libSceVoice) - unknown signature

  • sceTextToSpeech2GetSystemStatus (libSceTextToSpeech2) - unknown signature

  • sceVdecswQueryComputeMemoryInfo (libSceVdecsw) - unknown signature

  • sceVdecswFinalizeDecodeSequence (libSceVdecsw) - unknown signature

  • sceVdecswQueryDecoderMemoryInfo (libSceVdecsw) - unknown signature

  • sceVdecswSetDecodeInput (libSceVdecsw) - unknown signature

  • sceVdecswReleaseComputeQueue (libSceVdecsw) - unknown signature

  • sceVdecswAllocateComputeQueue (libSceVdecsw) - unknown signature

  • sceVdecswGetAvcPictureInfo (libSceVdecsw) - unknown signature

  • sceVdecswTrySyncDecodeOutput (libSceVdecsw) - unknown signature

  • sceVdecswTrySyncDecodeInput (libSceVdecsw) - unknown signature

  • sceVdecswSetDecodeOutput (libSceVdecsw) - unknown signature

  • sceVdecswResetDecoder (libSceVdecsw) - unknown signature

  • sceCoredumpAttachUserMemoryFile (libkernel) - unknown signature

  • sceCoredumpAttachMemoryRegion (libkernel) - unknown signature

  • sceKernelAddTimerEvent (libkernel) - usec is taken as the period in microseconds; re-adding an existing timer keeps its pending expiration count and restarts the period from the time of the call, where FreeBSD 12+ filt_timertouch clears pending expirations on EV_ADD; usec == 0 fires on every wait. None of this is confirmed on a PS5 title

  • sceRtcFormatRFC2822, sceRtcFormatRFC2822LocalTime, sceRtcFormatRFC3339LocalTime (libSceRtc) - only shadPS4 (PS4) has bodies. A null tick returns INVALID_POINTER like the existing sceRtcFormatRFC3339, where shadPS4 formats the current time instead; offsets outside ±1439 minutes return INVALID_VALUE like sceRtcFormatRFC3339; the local-time variants use the host's offset at the given instant (shadPS4 uses sceKernelGettimezone, the current offset)

  • snwprintf_s (libc) - follows C11 K.3.9.1.3 with RSIZE_MAX assumed to be SIZE_MAX >> 1. A runtime-constraint violation only returns a negative value: set_constraint_handler_s is not exported and the console's default handler is unknown. An invalid multibyte %s argument is copied byte by byte instead of being reported as an encoding error, as in vswprintf

  • libSceUlt queues - the added sceUltQueuePop, sceUltQueueTryPush, sceUltQueueDestroy and sceUltQueueDataResourcePoolDestroy signatures are inferred from the existing push/pop and object APIs. Queue destruction is assumed to reject blocked callers with ULT_ERROR_BUSY and otherwise discard queued data; pool exhaustion returns ULT_ERROR_AGAIN. These rules, alignment checks and shared slot limits have not been confirmed on PS5 hardware or a title. Non-null queue and data-pool option parameters throw because their layouts are unknown.

  • LinuxProtFromSce (libkernel) - protection bits 0x100 and 0x200 are accepted and assumed not to affect host CPU access; host protection is derived only from the read, write and execute bits

  • _sceUlobjmgrRegisterObject (ulobjmgr) - parameters taken from shadPS4 (PS4): a nonzero 64-bit object, a nonzero 32-bit kind and a 32-bit id output; the meaning of the first two and the PS5 signature are unverified. The id bound of _sceUlobjmgrUnregisterObject (below 0x4000) and the raw EINVAL (22) return also come from shadPS4

  • sceShareGetCurrentStatus (libSceShare) - validation (feature flag non-zero, status non-null) and the all-zero 16-byte status taken from the KytyPS5 reimplementation, not confirmed on a PS5 title; the meaning of the recording status values is unknown

  • sceShareGetRunningStatus (libSceShare) - only the first 32-bit word of the status is known: PPSA01317 treats bits 0x3c of it as a running share feature and gives the call a 40-byte buffer. The host never records or broadcasts, so it stores 0 in that word and leaves the rest untouched; a null status returns INVALID_PARAM by analogy with sceShareGetCurrentStatus

  • sceAgcDcbSetZPassPredicationEnableGetSize, sceAgcDcbSetPredicationDisableGetSize, sceAgcDcbSetBoolPredicationEnableGetSize (libSceAgc) - the builders are inline in the SDK and not exported; the size is assumed to be that of the SET_PREDICATION packet sceAgcDcbSetPredication writes (16 bytes)

  • Resource registration (libSceAgcDriver) - registration always fails with RESOURCE_REGISTRATION_UNAVAILABLE, so the owner and resource queries, sceAgcDriverSetResourceUserData, sceAgcDriverFindResourcesPublic and sceAgcDriverUnregisterAllResourcesForOwner return the same error without reading their arguments. Their parameter lists follow the libSceGnmDriver counterparts and are unverified. sceAgcDriverGetResourceRegistrationMaxNameLength writes 0xfc and returns 0, as prosper does from a title's registration configuration; the uint32_t* parameter matches the SDK wrapper sce::Agc::ResourceRegistration::getMaxNameLength(unsigned int*). sharpemu writes 256 and KytyPS5 returns RESOURCE_REGISTRATION_UNAVAILABLE, so the value is unverified; a null output throws

  • Shader registration (libSceAgcDriver) - a shader header is accepted at any address: PPSA26344 passes headers 4 and 1 bytes past an 8-byte boundary; whether the console refuses an alignment is unknown

  • sceNgs2VoiceControl sampler filter (libSceNgs2.native) - param 0x1000000a, its layout and meaning follow KytyPS5 only: location 1 type 1 is an RBJ low-pass biquad at the system sample rate after resampling, scaled by level, a set channel_mask bit bypasses that channel, type 0 turns the filter off. Other locations and types throw. The voice keeps playing a filter tail after its last block until the history is zero, with outputs below 1e-20 flushed to zero (a KytyPS5 choice); the console's tail length is unknown

  • sceRtcGetDosTime, sceRtcSetDosTime (libSceRtc) - bit layout from shadPS4 (PS4, the standard FAT date/time). A year outside 1980-2107 makes GetDosTime return INVALID_YEAR after writing 0 for an earlier one and 0xff9fbf7d (2107-12-31 23:59:58, the largest encodable time) for a later one, and SetDosTime decodes the year as the unsigned 7-bit FAT field (1980-2107) without validating the fields, as the disassembly-derived fpPS4 reimplementation of the PS4 library does; not confirmed on a PS5 title, and shadPS4 instead masks out-of-range years into the packed value and sign-extends the 16-bit date

  • sce::Json::InitParameter2 (libSceJson2) - layout inferred, not known: assumed to start with the allocator, its user data and the file buffer size, in that order, and the whole struct is assumed to fit in 40 bytes; Initializer::initialize(InitParameter2) ignores them as initialize(InitParameter) does

  • sceAjmBatchJobSetResampleParameters, sceAjmBatchJobGetResampleInfo (libSceAjm) - the ratio is taken as decoded samples per output sample and num_samples as the decoded samples the resampler holds, both inferred from FMOD (Hades II); the console's interpolation is unknown, a 4-point Catmull-Rom is used. The flags argument is ignored, as in shadPS4 and Kyty

  • scePlayerReviewDialogOpen, scePlayerReviewDialogGetResult (libSceCdlgPlayerReview) - the PS5-only dialog has no public reference: the parameter is not read and the result is assumed to start with the 32-bit common dialog result, as sceWebBrowserDialogGetResult assumes

  • sceHttpWaitRequest (libSceHttp) - the timeout is assumed to be in microseconds and a negative timeout to wait without limit; the invalid-value error for a null handle or event array or a non-positive event count is assumed, not measured. No request is ever pending, so the call waits for the timeout and returns 0 events, and a wait without limit throws

Functional

  • libSceHttp2 asynchronous requests (libSceHttp2) never reach the network: sceHttp2SendRequestAsync accepts the request, queues a completion whose result is the library's network error and triggers the user event named by the kqueue option (equeue at offset 0, event id at 8, user data at 16, layout inferred from PPSA17221); sceHttp2WaitAsync returns that completion. The completion's event_type value is unknown and left 0. PPSA17221 completes its request object only after sceHttp2SendRequestAsync returns, and its handler for a synchronous failure calls shared_from_this before that, so a send must not fail synchronously. A kqueue option or user event that is missing, an extra option, and a wait with no completed operation throw
  • sceKernelWriteThrottlingStatus (libkernel) reports no write throttling: the host SSD has no write budget, so the first qword of the 32-byte status is set to UINT32_MAX and the rest is zeroed. PPSA17221 reads only that qword: it multiplies it by 64 KiB and compares the product with byte thresholds up to 0x4AF00000 to pick one of five tiers. When the call fails the title assumes 0x4B000001 bytes, which selects the same top tier as UINT32_MAX. What the value measures on hardware (a remaining budget or a rate) and the meaning of the other three qwords are unknown
  • Wide-character conversions (libc) - wcsrtombs and swprintf still pass guest strings to the host's wchar_t functions. The guest's wchar_t is 16 bits, so on Linux, where the host's is 32 bits, they misread and miswrite guest strings. The wide wcsto* functions parse the ASCII prefix of the guest string, as the C locale accepts only ASCII white space and digits
  • SPIRV-Tools optimization skips CCP and Simplification for modules with storage-only 8- or 16-bit types because the pinned folder produces illegal narrow constants. This also disables unrelated constant folding; the restricted full pipeline mirrors the pinned performance recipe.
  • Windows host-pointer imports are compared instead of write-watched: a driver can mark imported pages dirty after the synchronous import window. GuestMemory excludes every overlapping 64 KiB tracker block while its backing is retained. A full block replaced by fresh private backing regains tracking and gets a new generation; protection changes, partial replacements and shared remappings do not restore it. This preserves CPU edits through byte comparisons but disables snapshot reuse and unit shadows for excluded blocks; restoring tracking on import retirement without replacing the backing and measuring the comparison cost remain unimplemented.
  • sceNetSendmsg and sceNetRecvmsg (libSceNet) copy the scatter/gather list through one host buffer and accept only the flags sceNetSend/sceNetRecv accept. Sending control data throws; a receive never returns control data (msg_controllen 0), since no socket option that queues it is supported
  • Additional content (libSceAppContent) is not installed or mounted: sceAppContentAddcontMount answers NOT_FOUND for every entitlement label and sceAppContentAddcontUnmount for every mount point, as no add-content mount is ever handed out; sceAppContentGetAddcontInfo answers DRM_NO_ENTITLEMENT for every label and sceAppContentGetAddcontInfoList reports 0 entries
  • sceKernelPread, sceKernelPwrite, sceKernelPreadv, sceKernelPwritev (libkernel) on Windows transfer at the given offset with an overlapped ReadFile/WriteFile and restore the descriptor's file pointer afterwards, so a concurrent read/write on the same descriptor can see the moved pointer in between, unlike on the console. Handles that are not disk files return ESPIPE. readv on a pipe or console handle stops after the first iovec read, a short read the console is assumed to allow; each iovec is transferred separately, so a failure after the first transfer returns the bytes already done
  • sceKernelSync (libkernel) on Windows flushes only the host files and directories recorded through RecordWrittenPath_nid_no_patch (the libc, libkernel, save data and app content file functions) and their changed parent directories. A host write in a library that does not record its path is not flushed by sceKernelSync
  • sceKernelSync (libkernel) on Windows skips a recorded file it cannot open for writing (read-only, or held open by a handle that denies write sharing), since FlushFileBuffers needs a writable handle. Such a file's data may not reach the disk before a host crash; the guest reads the same data either way
  • sceKernelInstallExceptionHandler records the handler, but a host fault still ends the process: only signals raised with sceKernelRaiseException are delivered. Unity's PS5Util module installs a SIGUSR1 handler that reads uc_mcontext.mc_rsp (offset 0xf8 of the context) and raises SIGUSR1 on other threads to stop them for garbage collection
  • sceKernelRaiseException delivers on Windows only and throws on Linux
  • sceKernelRaiseException builds the handler's ucontext with FreeBSD's amd64 layout (16-byte sigmask, mcontext at 0x40, mc_rsp at 0xf8); the console's layout is not verified beyond the fields PS5Util reads
  • sceKernelRaiseException does not consult the target thread's signal mask
  • sceKernelRaiseException saves and restores only CONTEXT_FULL | CONTEXT_FLOATING_POINT on Windows, so the upper halves of the YMM registers are not preserved if the handler or the entry uses AVX
  • sceKernelRaiseException reaches a thread that waits in an alertable TimedWait wait through an APC. A thread blocked anywhere else, including all waits under APS5_COARSE_TIMED_WAITS and host waits inside the emulator, is redirected and runs the handler only when that wait returns
  • libSceUlt queues use preallocated host storage instead of the supplied guest work area; its existing size formula and the 512-byte object layouts remain unverified. Waiting-queue pool thread limits and waiter priority ordering are not implemented. Finalization wakes blocked queue callers with ULT_ERROR_STATE.
  • Thread cancellation (libkernel) is not modelled: scePthreadCancel throws, so no cancel request is ever pending and scePthreadTestcancel and pthread_testcancel return without acting; the cancel state and type set by scePthreadSetcancelstate and scePthreadSetcanceltype are stored and not used
  • MIMG tfe and lwe never write the status VGPR after the data. On hardware it is written only when a texel fetch hits an unmapped page of a partially resident texture, or, for lwe on sample/gather, when the LOD is below the T# MIN_LOD_WARN; texture memory is always resident here, the LOD warning (texture-streaming feedback, like the T# MIN_LOD_WARN itself) is never reported, and lwe on image_get_lod throws.
  • Packed horizontal gathers (image_gather4h_pck, MIMG opcode 98): the four window texels are read raw and concatenated into a little-endian bitstream, with DMASK bit i writing stream word i to the next destination register; measured on RDNA2 (gfx1031) at every edge: the anchor is floor(x-0.5) with elements at -1, 0, +1 and +2 clamped horizontally into the width, the row is floor(y), negative rows clamp to row 0, rows at or past the height return zeros, sampler addressing modes do not affect the window, and formats wider than 32 bits per texel write zeros in every register. The emitter fetches each window texel at LOD 0 and packs its bits like image_load_pck, so the sampler's filter, addressing and LOD state are not used; formats whose bits are not recoverable from the view and D16 data throw. The anchor and row multiply the normalized coordinate by the image size without contraction. The stream rule was measured for R8_UNORM, RG8_UNORM and RGBA8; only RGBA8 has an execution test. image_gather8h_pck (opcode 99) never returns texel data on this hardware - across dmasks 0x1 to 0xFF including the upper nibble, RGBA8, RGBA16 and RGBA32 formats, 1D, 2D and 3D descriptors and normalized and unnormalized sampling it only zero-fills popcount(dmask) registers (sentinel-prefilled destinations) - so it decodes but throws at translation; its eight-texel semantics remain unmeasured.
  • MIMG BY2/BY4 loads (image_load[_mip]_by2/by4, opcodes 0x42, 0x43, 0x4a and 0x4b) were measured on RDNA2 (gfx1035) with the hardware oracle for 2D images with identity swizzle. They read N texels (BY2: 2, BY4: 4) from x & ~(N - 1) on row y, texel by texel and component by component within each texel, with each texel converted like image_load. Every register is zero when the mip level is past the last level, x + N - 1 is outside the level's width (unaligned x, unsigned), or y is outside its height. Data only comes back when the N texels fit in one dword: R8 and R16 (DMASK 0x3) or RG8 (0xf) for BY2, and R8 (0xf) for BY4. With 32-bit texels (R32, RG32, RG16, RGBA8) the hardware returns zeros. Other formats, masks, dimensions, swizzles, D16/A16 and indirect descriptors throw. The stores (0x52, 0x53, 0x5a and 0x5b) decode but throw at translation. Measured on hardware, they write from the unaligned x up to the end of its dword, which is not implemented.
  • MIMG PCK2/PCK4 loads (image_load[_mip]_pck2/pck4, opcodes 0x70, 0x71, 0x73 and 0x74) were measured on RDNA2 (gfx1035) with the hardware oracle for 2D images with identity swizzle. With data mask 0x1, they write one dword: the raw bits of the N texels (PCK2: 2, PCK4: 4) from x & ~(N - 1) on row y, concatenated (element k at bit k * texel bits) and zero-extended. The dword is zero when the mip level is past the last level, x + N - 1 is outside the level's width (unaligned x, unsigned), or y is outside its height. Data only comes back when N texels fit in 32 bits: R8, R16 or RG8 for PCK2, R8 for PCK4. Wider texels (R32, RG16, RGBA8) and masks other than 0x1 write zeros on hardware. Those masks throw at decode, and formats outside UNORM/UINT/SINT R8, R16 and RG8 throw. #1314's earlier measurement saw only zeros because it used masks 0x3 and 0xf. The stores (0x76, 0x77, 0x79 and 0x7a) decode but throw at translation. They are not measured, and opcode 0x76 on 32_32_32_32_FLOAT hung the GPU (#1314).
  • Unnormalized S# coordinates (libSceAgcDriver) - FORCE_UNNORMALIZED uses a Vulkan unnormalizedCoordinates sampler, so the S# LOD range, LOD bias and mip filter are not applied, which is exact only on a one-level view.
  • Unnormalized S#s are accepted only when direct and used only by explicit-LOD image_sample without offset, comparison, derivatives or _a, on a single-level, single-layer 1D or 2D view of mip 0, even when the image is also sampled through a normalized S#.
  • An unnormalized S# (libSceAgcDriver) throws with unequal minification and magnification filters, anisotropy, TRUNC_COORD, MC_COORD_TRUNC or X/Y clamping other than last-texel or border.
  • Image atomics on 32_SINT and 32_FLOAT surfaces act on the raw dword through an R32_UINT storage view; their float results are assumed to match those measured on 32_UINT surfaces. Other formats throw.
  • s_memtime on RADV with a GFX10.3 to GFX11.7 GPU (RDNA 2, RDNA 3, RDNA 3.5) reads the Vulkan device clock instead of the subgroup clock, which ACO reads from the 20-bit SHADER_CYCLES register there and which wraps every 2^20 cycles. The device clock is a monotonic 64-bit counter, but it counts the 100 MHz reference clock (the same one as s_memrealtime), not shader cycles, so s_memtime deltas are about 20 times smaller than on hardware. The families are matched by the name RADV reports (NarrowSubgroupClock); a family added to Mesa later reads the subgroup clock until it is listed
  • ds_wrxchg2_rtn_b32, ds_wrxchg2st64_rtn_b32, ds_wrxchg2_rtn_b64 and ds_wrxchg2st64_rtn_b64 are translated as two separate 32-bit or 64-bit atomic swaps per invocation. RDNA2 hardware (measured on gfx1035) performs every lane's first exchange before any lane's second one, so when lanes of the same wave or of different waves overlap addresses, the result can differ from hardware. offset0 == offset1 throws, although on hardware it is two exchanges in order.
  • ds_condxchg32_rtn_b64 uses two 32-bit atomic conditional exchanges. RDNA2 (gfx1035) measurements confirmed aligned return values, conditional bit clearing and 16-bit offsets; out-of-range accesses return zero without modifying LDS. Misaligned accesses fault the wave on gfx1035; the recompiler does not model this fault. Radeon 780M (gfx1103, RDNA3) measurements confirmed aligned return values, conditional bit clearing, EXEC masking and operand overlap in wave32 and wave64; contended cases passed per-dword conservation checks. Contended lane ordering and gfx1013 remain unmeasured; pair-wide indivisibility is not assumed, and concurrent 64-bit LDS atomics use a separate lock. GDS throws. VGPR pairs extending beyond v255 throw; allocated-VGPR EXEC nullification is not emulated.
  • 64-bit image atomics (image_atomic_* with a two-dword data mask) need VK_EXT_shader_image_atomic_int64 and act on 32_32 UINT, SINT and FLOAT surfaces through an R64_UINT storage view. 64-bit image_atomic_inc, image_atomic_dec and the float atomics throw, as does any other access in the same shader to an image it updates with 64-bit atomics.
  • 8_SRGB and 8_8_SRGB loads on a device that cannot sample R8_SRGB or R8G8_SRGB return the sRGB EOTF rounded to nearest even at bf16 precision, as adriadam10 measured on RDNA2 (gfx1035) in #866; the PS5's gfx1013 is not measured.
  • 8_SRGB and 8_8_SRGB textures (libSceAgcDriver) that the device samples as R8_SRGB or R8G8_SRGB use its own decode, which need not match gfx1035: NVIDIA's R8_SRGB is one bf16 step off in 29 of 256 codes.
  • Samples and gathers of 8_SRGB and 8_8_SRGB textures throw on a device that cannot sample R8_SRGB or R8G8_SRGB.
  • Bindless image table entries of 8_SRGB and 8_8_SRGB textures read zeros, like converted formats, on a device that cannot sample R8_SRGB or R8G8_SRGB.
  • The shader recompiler ignores s_setreg_b32: writes to MODE (float rounding and denormal controls) and the other hardware registers have no effect, and s_getreg_b32 reads of the MODE round fields report round to nearest even even after s_setreg_b32 wrote another mode. The initial round mode from the shader's program registers is not read either.
  • On a host subgroup narrower than 32 lanes, threadBit reads an EXEC written as a value (s_mov_b32/s_mov_b64) at bit (subgroup invocation id) of EXEC_LO, so lanes at or above the subgroup size read a lower lane's bit.
  • EXEC read as a value (s_mov_b64 sN, exec, the s_*_saveexec copy, ALU sources) holds only lanes with a host invocation; the console's also holds the wave's other lanes, e.g. 32-63 of a wave64 on 32 host lanes.
  • v_readlane_b32 and fetch-inactive v_permlane16_b32/v_permlanex16_b32 read undefined data from a lane that the host subgroup does not hold or whose host invocation is inactive; the console reads the lane's VGPR.
  • Without fetch-inactive, v_permlane16_b32 and v_permlanex16_b32 take a source lane that the host subgroup does not hold as inactive and keep the old value (0 with bound_ctrl); the console reads that lane's VGPR.
  • On a host subgroup narrower than the wave, v_readlane_b32 of a constant lane outside it builds only as lane 63 of a half-wave scan (DPP row_shr 1/2/4/8, v_permlanex16_b32, EXEC -1); other such reads throw.
  • Shader recompilation currently occurs right before it was transferred to Vulkan with caching, but should be moved to the relinker stage. For this purpose, shader/recompiler was written completely independently from libs/prx.
  • v_interp_p1ll_f16, v_interp_p1lv_f16 and v_interp_p2_f16 read the 16-bit halves of each vertex's parameter through VK_KHR_fragment_shader_barycentric and throw without it, as fixed-function interpolation cannot split a 32-bit attribute. P10 and P20 are the vertex differences rounded to f16 to nearest even, which is not confirmed on hardware. v_interp_p1ll_f16 and v_interp_p1lv_f16 round the exact P10 * I + P0 once to f32 and v_interp_p2_f16 rounds the exact P20 * J + S2 once to f16, as measured on RDNA2 (#697); the exact sums are computed in f64, so these instructions need the Float64 capability. They follow the shader's float mode, measured on RDNA2 (gfx1035) in all eight combinations of IEEE_MODE and kept/flushed f32 and f16 denormals over 768 special and 1,024 random rows. With IEEE=1 a NaN operand is returned quieted; with IEEE=0 it is returned unquieted, except that v_interp_p2_f16's f16 result is always quiet. Flushed f32 denormals flush I/J, v_interp_p2_f16's f32 S2 and the f32 result; flushed f16 denormals flush P0, P10/P20, v_interp_p1lv_f16's f16 S2 and the f16 result. Denormal modes 1 and 2 (flush only inputs or only outputs) and rounding other than to nearest even are not measured and throw. An unknown mode follows IEEE=0 with denormals kept. Lavapipe has no barycentrics, so the draw test is skipped in CI; agc_driver_interpolation_modes checks the arithmetic in every mode against the hardware rows on any device with Float64.
  • v_fma_f64 is fused exactly only for normal inputs: with a subnormal input it is a separate multiply and add, which rounds twice.
  • SINT storage images of 8- and 16-bit components saturate each stored 32-bit value to the component range, as adriadam10 measured for image stores on RDNA2 (gfx1035) in #944 (448 rows match); the PS5's gfx1013 is not measured.
  • StoreTexel writes channel 1 of a two-channel format from the data slot whose DST_SEL is Y, for SINT and UINT alike. With DST_SEL X,Y,Z,W, gfx1035 writes it from the W slot, as adriadam10 measured in #944.
  • COND_EXEC reads its condition after the earlier packets of its queue complete. Without PFP_SYNC_ME the console's graphics PFP reads it ahead of the ME, so a title that races the read sees a later value here.
  • A flip inside a COND_EXEC range throws: the flip is reserved with the video output when the buffer is submitted, and how the console withdraws a skipped one is unknown.
  • A COND_EXEC range must hold whole packets and end inside its command buffer. A chained INDIRECT_BUFFER or a REWIND inside a range throws, as what the CP does with the skipped dwords then is unknown.
  • A COND_INDIRECT_BUFFER (sceAgcCbBranch) runs only with the always-pass compare function; a comparison or a predicated packet throws. Modes 1 and 2 run the first buffer, assumed to be the if-then and if-then-else modes of AMD's PM4 packet. sceAgcCbBranch does not check the compare address of an always-pass branch or the address of an empty buffer, as PPSA14632 passes an uninitialised compare address and a null else buffer of 0 dwords.
  • SET_*_REG_INDIRECT (libSceAgcDriver) reads its register list when the command buffer is submitted, with the packets. The console's graphics PFP reads it when it reaches the packet, so a list written after the submission (by the CPU, or by GPU work ahead of the packet behind PFP_SYNC_ME) is read here before that write.
  • The shader float mode (FLOAT_MODE, DX10_CLAMP, IEEE_MODE and FP16_OVFL of COMPUTE_PGM_RSRC1 and SPI_SHADER_PGM_RSRC1_PS/GS/HS, bit positions from Mesa's gfx10.json and gfx103.json) is decoded into GuestContext::floatMode and is part of the shader cache keys and the serialized request (#981). IEEE_MODE is read by v_min_f32, v_max_f32, v_min3_f32, v_max3_f32 and v_med3_f32, IEEE_MODE and the FLOAT_MODE output denormal bits by the output modifier, DX10_CLAMP by the clamp modifier, and the whole mode by the 16-bit interpolation instructions (see their entries). With IEEE=1 a signaling NaN operand returns that NaN quieted (the first operand checked first, min3/max3 as two nested pairs, med3 as min3 when any operand is NaN), measured on RDNA2 (gfx1035) over every combination of ±0, ±1, ±inf, denormals, quiet and signaling NaNs with f32 denormals kept and flushed. IEEE=0 and unknown modes keep the previous lowering, which matches IEEE=0. The f16 and f64 min/max/med3, NaN quieting in f16 arithmetic (the unary instructions and the f32 arithmetic follow it, see below), FP16_OVFL and FLOAT_MODE (f32 denormals flushed before the min/max compare in Astro's Playroom's 0xc0) still follow a single mode, as the entries below record. The mode comes from the registered shader header's sh_registers, the same source at registration and at draw/dispatch so the prepared artifact keys match. A title that rewrites RSRC1 at run time, or a raw compute program with no header, compiles with that mode or none.
  • v_mullit_f32 follows the hardware measured with the MODE register at IEEE=1 and denormals kept (a signaling NaN src0 is quieted only with IEEE=1, as measured at IEEE=0 too; a positive denormal src2 counts as positive): other denormal settings are not modelled.
  • v_fma_legacy_f32 (VOP3 0x140) is assumed to be fused, which has not been measured on hardware. LLVM decodes this encoding as v_mad_legacy_f32 for gfx1013, and v_mac_legacy_f32 (VOP2 0x06) was measured to round its product before the add, so 0x140 may do the same.
  • v_fma_f16, v_pk_fma_f16 and v_pk_fmac_f16 are an f32 FMA rounded to f16, which rounds twice: 0x62e9 * 0xd159 + 0x23ec gives 0xf89e, the hardware 0xf89f.
  • Signaling NaN inputs of the f32 and f16 unary instructions (v_sqrt/rcp/rsq/log/exp/sin/cos/fract/floor/ceil/trunc/rndne/rcp_iflag/frexp_mant), v_ldexp_f32/f16, v_frexp_mant_f16, v_div_fixup_f32/f16 and v_mullit_f32 are returned quieted only with IEEE=1 and unchanged with IEEE=0, measured on RDNA2 (gfx1035) in both modes; shaders without a known float mode follow IEEE=0. v_add/sub/subrev/mul/fma/fmac/fmamk/fmaak/mul_legacy/fma_legacy_f32 and v_fma_mix_f32 with f32 sources choose their NaN result on the bits, measured over 1000 operand triples in both modes: the first NaN source in operand order after its modifiers (the subtrahend negated, as the hardware adds its negation), quieted only with IEEE=1, or the default NaN 0xffc00000 for an invalid operation; in the fma forms an invalid product (inf * 0) gives the default NaN even when src2 is a NaN, and in the legacy forms a zero factor makes the product 0 even when the other factor is a NaN (a NaN src2 of v_fma_legacy_f32 still wins). The f16 arithmetic, v_fma_mix_f32 with f16 sources, v_cubema, v_mac_legacy_f32 and the separately rounded mad/mac forms (not measurable on RDNA2) follow the same rule on hardware but their NaN bits are left to the driver. v_cvt_f16_f32 and v_dot2_f32_f16 always quiet and v_div_scale_f32 never does.
  • Packed f16 NaN results (v_pk_add/mul/fma/min/max_f16) follow the hardware measured on RDNA2 (gfx1035) at IEEE=0 and IEEE=1 with f16 round-to-nearest-even and f16 denormals kept: with IEEE=1 a signaling NaN input is quieted and min/max return the other operand only for a quiet NaN; with IEEE=0 NaN inputs pass through unquieted and min/max ignore signaling. In v_pk_fma_f16 an invalid product (inf * 0) gives the default NaN even when src2 is a NaN. A shader without a known float mode is translated as IEEE=0, the mode titles use; a mode with another f16 rounding or that flushes f16 denormals throws.
  • f32 denormals follow the shader's FLOAT_MODE f32 denormal field (bits 5:4) when it flushes them (0, and shaders without a known float mode, as in the 0xc0 most titles use), measured on RDNA2 (gfx1035) over 1444 rows per instruction at IEEE=0 and IEEE=1. v_add/sub/subrev/mul/mul_legacy/fma/fmac/fmamk/fmaak/min/max/min3/max3/med3/fract/floor/ceil/frexp_mant/sin/cos_f32 flush their f32 inputs and their result to a zero of the same sign; the f32 compares, v_cvt_i32/u32/rpi_i32/flr_i32_f32, v_frexp_exp_i32_f32, v_cvt_f64_f32, v_cvt_f16_f32, v_cvt_pkrtz_f16_f32, v_cvt_pknorm_i16/u16_f32 and v_cvt_pk_u8_f32 flush their f32 inputs. Tininess is detected before rounding: a product whose exact value is below 2^-126 gives zero even when it rounds to 2^-126, computed exactly from the significands for v_mul_f32, v_mul_legacy_f32, and for v_fma_f32, v_fmac_f32, v_fmamk_f32, v_fmaak_f32 and v_fma_mix_f32 when the addend is zero; with a nonzero addend the fused result is kept, so an exact result just below 2^-126 that rounds to it is not flushed. v_fma_mix_f32 was measured with f32 sources only; its f16 sources are not flushed. Denormal modes 1 and 2 throw. Not covered, and not measurable on RDNA2 (no such opcodes) or not measured: v_mac_f32, v_mad_f32, v_madak_f32 and v_madmk_f32 (rounded separately), v_mac_legacy_f32, v_dot2_f32_f16, the division steps (on hardware v_div_fixup_f32 flushes only src1 and src2, v_div_fmas_f32 only its result), f32 interpolation and LDS float atomics keep the previous lowering. With f32 denormals kept (3) the results depend on the driver's default denormal behaviour, as no DenormPreserve execution mode is requested, and v_ldexp_f32 flushes in every mode.
  • The executable file that relinker generates opens the console when launched, which is inconvenient for playability.
  • PA_CL_CLIP_CNTL (libSceAgcDriver) - DX_LINEAR_ATTR_CLIP_ENA (bit 24) clear is drawn like bit 24 set, with Vulkan's clipping of NoPerspective outputs; what a clear bit changes on the console is undocumented.
  • Per-stage descriptor count (libSceAgcDriver) - a pixel shader's colour attachments are not counted against maxPerStageResources, so its buffers and images can fit the limit while the pipeline exceeds it
  • v_rcp, v_rsq, v_sqrt, v_log, v_exp, v_sin and v_cos (f32 and f16) use the driver's approximation for finite results, not the console's: the low bits can differ. Only NaN, invalid, zero and infinite results and the exact sin/cos zeros are chosen on the bits. v_sin_f32/v_cos_f32 with inputs beyond ±256 cycles were not compared with the console.
  • --to-intel does not lower RDPRU/MCOMMIT; the matcher fails the relink instead.
  • The length-changing path of the instruction rewriter is not used by the converter: it does not adjust data-to-code references (relocations, FDEs, jump tables) or segment sizes, so every substitution keeps the instruction length.
  • DB_SHADER_CONTROL.CONSERVATIVE_Z_EXPORT (libSceAgcDriver) becomes DepthLess/DepthGreater. For a pixel shader that breaks the promise, the host driver decides whether its interpolated Z is depth-tested before shading; what the console does then was not measured.
  • DB_SHADER_CONTROL.PRIMITIVE_ORDERED_PIXEL_SHADER (shader recompiler) - the host pixel interlock spans the whole shader, not only up to s_sendmsg ORDERED_PS_DONE.
  • POPS collision SGPRs (shader recompiler) - the collision wave ID and intrawave collision mask read 0, so a title skips its POPS wait and runs its per-collision loop once.
  • Image loads (shader recompiler) - an image_load reads a sampled binding, also of an image the shader stores to, so in a primitive-ordered pixel shader it misses an earlier overlapping primitive's image_store in the same draw.
  • PA_SC_CONSERVATIVE_RASTERIZATION_CNTL (libSceAgcDriver) - 0x6001 uses Vulkan overestimation on devices that add at most 1/256 pixel and keep degenerate triangles; the console's uncertainty region and degenerate handling are unmeasured.
  • The Linux placement of the --to-intel stubs in the ELF patcher is covered only by a synthetic test.
  • The libc SSE4a trap emulation on Windows is superseded by --to-intel and remains only until the relinked title has been verified without it.
  • Descriptor pool chain (libSceAgcDriver) - each pool holds two storage buffer descriptors more than a set can take, as a workaround: RADV (Mesa 26.0 and later) lets a FREE_DESCRIPTOR_SET pool place a set up to 32 bytes past the pool's buffer (util_vma_heap_init is given bo_size + RADV_POOL_HEAP_OFFSET as a size), and with a page-multiple pool size those bytes are an unmapped page
  • CMASK fast clears (libSceAgcDriver) - only a CMASK whose nibbles are all fast-cleared (0) or all expanded (0xF) is modeled, checked over the target's whole CMASK, 4 KiB per 1024x512-pixel metablock (the size PS5 titles clear, for every color format seen); the addressing within a metablock is not decoded. The first draw or fast-clear eliminate over a fast-cleared CMASK fills the whole target with CB_COLOR_CLEAR_WORD and stores those bytes as expanded, so a draw that covers only part of the target reads the clear value in the rest as the eliminate would leave it. On a DCC target the clear is in the DCC keys, so its CMASK must be all expanded. A mixed CMASK throws, as does a DCC target's CMASK that is not all expanded and a fast clear of a mipmapped, 3D or array color target
  • Host imports (libSceAgcDriver) on Linux skip ranges that are not mapped read-write, which are copied instead. The NVIDIA driver (595.91.07) refuses VK_EXT_external_memory_host imports of read-only or executable mappings (and shared mappings of regular files) with VK_ERROR_OUT_OF_DEVICE_MEMORY, after which every vkAllocateMemory on the device fails the same way. Read-only ranges are never imported, even on drivers that accept them. Shared mappings of regular files are not checked for.
  • Cube texture descriptors with equal BASE_ARRAY and DEPTH expose six faces starting at BASE_ARRAY. Measured with image_load, image_sample and image_get_resinfo on RX 6600 (gfx1032), using 64x64 R32_UINT faces and base slices 0, 5 and 6. Other ranges containing fewer than six faces or incomplete cube arrays still throw: hardware load bounds and filtered-sample addressing differ. Seamless cube filtering and out-of-range cube-array sampling remain unimplemented. PS5 equivalence has not been measured on console hardware.
  • DCC display buffers are presented only when all keys of the console's DCC extent agree on uncompressed or a fast-clear code, padding keys included; other keys, and register-clear keys over a pending image, throw.
  • DCC key stores cover the console's DCC extent only for pipe-aligned DCC of single-level, single-layer 4-byte SW_64KB_R_X surfaces; other surfaces, and every texture and color target key read, cover one byte per 256 bytes.
  • 8_SRGB color targets (libSceAgcDriver) on a device that cannot attach and blend R8_SRGB render into an RGBA8_SRGB copy of the target, so the sRGB encode, decode and blend rounding are the device's; the console's are not measured.
  • 8_SRGB color targets (libSceAgcDriver) on such a device throw unless they are single-mip 2D surfaces with a resident image; linear targets have none.
  • COPY_DATA from the GPU clock (libSceAgcDriver, SRC_SEL 9) writes the host steady clock in 10 ns ticks when the packet runs, the same counter as the RELEASE_MEM timestamp, not the console's GPU clock. The COPY_DATA cache policy fields are accepted and have no effect.
  • --to-intel guest module trampolines are covered only by a synthetic relinker test; no game title has been verified with them on Linux or Windows.
  • --to-intel replaces the approximate VEX.128 register forms of VRSQRTPS and VRCPPS with correctly rounded 1/sqrt(x) and 1/x, not with the AMD approximation: its tables are not public. Intel's approximation of 1/sqrt(1.0) is 0x3F7FF000, and two Newton-Raphson steps on it settle on 0.99999994 instead of 1.0; a renormalised identity quaternion then turns into a NaN axis in PPSA21564, which the console does not show. Refined results now reach the exact value; unrefined ones can still differ from the console in the low bits. Each site costs an out-of-line stub (two jumps, a spill below the red zone, SQRTPS/DIVPS). The 256-bit, scalar, legacy and memory forms keep the native instruction, as does a 4-byte site with no movable instruction after it for the jump (5 sites in PPSA21564, counted before a following RIP-relative instruction could move into the stub; not recounted).
  • sceKeyboardGetKey2Char (libSceKeyboard) translates the 101-key (US) arrangement and the alphanumeric layer of the 106-key (Japanese) one, which follows the JIS layout of the HID usages: the Yen (0x89) and Ro (0x87) keys return \ (0x5C) unshifted, as JIS X 0201 places the yen sign there; whether the console returns U+00A5 instead is unverified. With the Kana LED (bit 4, the HID position) set the 106-key arrangement throws, as the kana the console returns are unknown. Ctrl and Alt do not change the character.
  • sceAudioOut2Set3DLatency and sceAudioOut2MasteringInit, sceAudioOut2MasteringTerm and sceAudioOut2MasteringSetParam (libSceAudioOut) have no effect: there is no 3D rendering or mastering stage.
  • sceImeKeyboardGetInfo (libSceIme) returns 0x80bc0023 (no resource id) for every id while a keyboard is open, since the IME keyboard never reports a connected device. sceImeKeyboardSetMode validates the mode bits but the mode has no effect, as no IME keyboard events are delivered.
  • AudioOut2 contexts (libSceAudioOut) with an SDL device read a grain's port buffers at the next push, at least 100 us after the grain was pushed, and play the mix behind a 40 ms cushion that the queue level leaves out. When the hardware reads the buffers is not known. The timing follows a title whose mixer fills a buffer after pushing it, reuses it two pushes later, and may still be writing it when the next push follows within microseconds. The last grain pushed before a title stops pushing is never read or played.
  • libSceAudiodec throws for the 24-bit PCM word size (iBwPcm 0): its sample layout is unknown. ATRAC9 decoding is covered only by configuration and error tests, as no ATRAC9 encoder is available for a fixture.
  • sceAjmDecMp3ParseFrame (libSceAjm.native) throws when the original file length is requested (parse_ofl non-zero) for a layer other than III, for a CRC-protected frame, or for a VBRI header outside MPEG-1 stereo: shadPS4 looks for the tag after the CRC and after the side information, while LAME and FFmpeg place it without the CRC and VBRI always at byte 36.
  • The output modifier (mul:2, mul:4, div:2) follows the shader's float mode as measured on RDNA2 (gfx1035): the hardware applies it only with IEEE mode off and output denormals of the result's precision flushed (bit 1 of the FLOAT_MODE denormal field clear), and ignores it otherwise. On f32 results it is applied as the hardware does with f32 denormals flushed; a shader without a known float mode is translated with IEEE mode off and f32 denormals flushed, the mode titles use. On f16 and f64 results it is ignored, and it throws in the modes where the hardware applies it.
  • The clamp modifier follows DX10_CLAMP, measured on RDNA2 (gfx1035) for f32, f16, packed f16 and f64 results at IEEE=0 and IEEE=1: with DX10_CLAMP=1 (and in shaders without a known float mode) a NaN result clamps to +0; with DX10_CLAMP=0 a NaN result is written unchanged and every other value clamps to [0, 1] as before. f64 results follow the same rule on hardware, but a clamped f64 result with DX10_CLAMP=0 throws until it has an execution test. With DX10_CLAMP=0 the NaN's bits are those the translation already produces for the instruction without clamp, so where those are left to the driver (f32 and scalar f16 arithmetic) the payload is the driver's, not the hardware's input propagation. v_dot2_f32_f16 and the integer clamps are unchanged.
  • Comparison sampling of a color texture (image_sample_c/image_sample_c_lz on a texture that is not R32 float or R16 unorm) is emulated in the shader, since Vulkan compares only depth formats: the red channel is fetched, compared and, for bilinear filtering, blended (compare, then filter). Only 2D and 2D array views, float/unorm/snorm formats, wrap, clamp-to-edge and clamp-to-border addressing (border red 0 for the black borders, 1 for opaque white) and point or bilinear filtering at one level are implemented, with texel offsets added to the texel indices; LOD biases and clamps are accepted, as they cannot select another level of a single-level sample. Half-border addressing, the border color table, gradients, gathers, other dimensions, anisotropy and mip filtering throw. Under bilinear filtering, taps past a clamp-to-border edge compare the border value and blend with the texel taps, so results near the edge depend on the filter weights. AMD documentation does not say how a color format's reference is handled: it is clamped to [0, 1] for unorm and [-1, 1] for snorm, as Vulkan does for unorm depth, and not clamped for float. Bilinear weights are full float, not the hardware's fixed-point subtexel weights
  • libScePlayerInvitationDialog simulates dialog completion without displaying UI or sending invitations, so scePlayerInvitationDialogGetResult reports USER_CANCELED; its parameter ABI remains unverified. The 40-byte result layout (error code, result, 32 reserved bytes) is taken from SharpProspero and the error codes from the other common dialogs, not confirmed on a title.
  • Converted unorm images (10_11_11_UNORM, read and written through an R32_UINT view): samples, gathers, LOD queries, 16-bit data and a DST_SEL of the missing W channel throw.
  • Converted unorm image loads divide by 2^n - 1 with the buffer format path's OpFDiv, which Vulkan allows to be up to 2.5 ULP off, so some drivers are not bit-exact.
  • 64-bit LDS atomics (ds_*_u64, ds_*_b64, ds_*_f64) read and write the two dwords under a workgroup lock stored after the guest LDS, as LDS is a 32-bit array without 64-bit atomics. They are atomic with respect to each other only: 32-bit accesses to the same dwords issued concurrently are not ordered by the lock. 64-bit GDS atomics throw. ds_min/max(_rtn)_f64 and ds_cmpst(_rtn)_f64 follow the NaN and signed-zero rules measured for the f32 forms; the f64 forms were not measured on hardware.
  • V# bases off a DWORD boundary (shader recompiler) - raw accesses use the exact bytes and s_buffer_load reads (base & ~3) + (offset & ~3), as measured on gfx1035 (Linux, alignment mode UNALIGNED; the console's mode is unknown). Formatted accesses off their element's alignment and atomics throw.
  • Vector buffer offsets that are not a multiple of 4 (shader recompiler) - dword accesses count whole dwords from the V# base, where the hardware reads the exact bytes at base + offset.
  • Min/max S# reduction (libSceAgcDriver) - FILTER_MODE 1 and 2 use Vulkan's min and max reduction (the same SQ_IMG_FILTER_MODE values RADV programs). Measured on RDNA2 (gfx1035), not on the console: only texels of non-zero weight are reduced, and the weight is taken after rounding to the 8-bit subtexel grid (a sample within 1/512 texel of a centre reduces that texel alone); a driver with other subTexelPrecisionBits reduces a different set there. Gathers ignore the mode.
  • Min/max S# (libSceAgcDriver, shader recompiler) - throws with anisotropy, a linear mip filter, depth or color-texture compare, or bilinear filtering of an image the recompiler point-samples (sint, converted, depth-bits).
  • Raw buffer_load_dwordx2 is one 64-bit access on the hardware (with or without glc), so it never sees half of a buffer_atomic_swap_x2. Only a glc load that is 8-byte aligned and in bounds, in a program that has the 64-bit storage view (it uses 64-bit buffer atomics), is read with one 64-bit atomic load; every other dwordx2 load is two dword loads and can tear against a concurrent 64-bit write: loads without glc, and loads in a program without 64-bit buffer atomics while another shader writes the pair with swap_x2.
  • DS src2 operations (ds_*_src2_*, GFX10.1 only) read DS[B], with B = A + 4 * sext(offset1[6:0]:offset0), and then update DS[A] with the matching 32-bit atomic, so the read of B is not atomic with the update of A. The form that takes the offset from the address (offset1[7] set), the 64-bit forms and GDS throw: whether the LDS address keeps A[31:17] in that form, and whether the 64-bit forms scale the offset by 4 or 8, is not documented. ds_min_src2_f32, ds_max_src2_f32 and ds_add_src2_f32 throw: on RDNA2 (gfx1035, the oracle's hardware, which has no src2 opcodes) ds_min_f32, ds_max_f32 and ds_add_f32 ignore IEEE_MODE but depend on whether f32 denormals are flushed (28, 28 and 12 of 196 special rows differ), and that is not modelled for LDS float atomics yet (#981).
  • wcsrtombs_s (libc) follows the console's libc.prx, but a runtime-constraint violation only returns its error: the default handler there writes the message and a newline to stderr before returning, which is not done here. Conversion uses the C locale of wcrtomb (MB_CUR_MAX 1), so the path where a multibyte character does not fit the remaining space is not reached
  • The narrow printf family (libc) passes %ls and %S to glibc on Linux, which reads them as strings of 32-bit wchar_t; the guest's wchar_t is 16 bits (UTF-16), so these conversions fail with -1. The Windows path converts them to UTF-8, and guest_formatting checks wide conversions on Windows only
  • collate::_Getcat (libc) builds the facet for the C locale only and throws for any other locale name. The console's libc.prx stores pointers to its collation state tables at offsets 0x10 and 0x18 of the facet; ours leaves them null, as only the facet's own functions read them. do_transform throws for input with embedded null characters, which the console drops depending on the output buffer size, and for results of 4095 characters or more, whose string storage uses the guest's over-aligned large allocation.
  • poll (libkernel) waits only on guest sockets, through WSAPoll on Windows and poll on Linux; the pollfd layout and flag values are FreeBSD's. A descriptor below the socket range (files, pipes, stdio) throws, as do event bits other than POLLIN, POLLPRI, POLLOUT, POLLRDNORM, POLLRDBAND and POLLWRBAND (the POLLERR, POLLHUP and POLLNVAL bits are ignored in events), POLLPRI on Windows, which WSAPoll rejects, and an infinite timeout with no socket to wait on. A closed socket descriptor reports POLLNVAL; the console's limit on the descriptor count is unknown and not checked
  • Thread exit destructors (libSceLibcInternal) run when a libkernel thread finishes; on the main or a host thread only _sceLibcInternalThreadDtors runs them, as exit does, else they are dropped
  • sceFontOpenFontSet (libSceFont) opens only the primary file of a system font set. Characters the console takes from the set's other files (Hangul, Thai and Arabic in Japanese and Chinese sets, Arabic in European sets) are reported as unsupported glyphs. The console file names are those of the PS4 firmware; the names of the PS5-only JG2 sets (0x1A......) are unknown, so they use the SSTJpPro files. When a console file is missing, an openly licensed substitute (Noto Sans, Noto Sans Mono, Noto Sans Thai, Noto Sans CJK) is loaded instead. It is not the system font: its metrics differ, so text width, line height and wrapping differ from the console. System font faces are loaded by FreeType in host memory, not in the font memory the title passes to the library: FreeType needs about 1 MiB per CJK face, which the title's font memory is not sized for.
  • Font writing lines (libSceFont) - sceFontCreateWritingLine, sceFontWritingLineWritesOrder, sceFontWritingLineRefersRenderStep, sceFontWritingLineGetRenderMetrics and sceFontWritingLineClear follow KytyPS5: runs are placed left to right, each at the line's advance so far, with no spacing or adjustment. Only horizontal and left-to-right lines, writing attribute 0 and non-null run metrics are modelled; other values, the metrics of an empty line and unknown or null handles throw, since no reference gives their result or error code. sceFontWritingLineGetOrderingSpace still throws (KytyPS5's values are placeholders). Lines are allocated on the host, not in the font memory the title passes to the library: FreeType needs about 1 MiB per CJK face, which the title's font memory is not sized for.
  • s_swappc_b64 writes the link pair with the same model as s_getpc_b64: the guest return address pc + 4 as a byte offset over GetShaderBase. Any other use of the link pair (arithmetic, compare, hash, store, or a second s_swappc_b64 sharing it) throws; constant-offset folding over the link is not modeled. The special encoding s_swappc_b64 with SDST 125 still decodes as s_setpc_b64, keeping the existing decode quirk.
  • The s_swappc_b64 fetch-shader call at vertex/local/tessellation/mesh entry assumes the called fetch-shader blob ends in s_setpc_b64 to the link pair (the GNM fetch-shader shape shadPS4's EmitFetch copies); the blob is not part of the shader program, so its return closes the pairing by assumption and any in-program reader of the link pair throws. Attribute fetches are inlined from the request's parsed fetch-shader plan through the same GetAttribute path as the embedded fetch analyzer, honoring the buffer resource dst_sel; an attribute writing more than four registers, or an entry call without a parsed plan, throws. The vertex/instance offset accumulator inside the fetch blob is not replayed for external blobs.
  • sceImeKeyboardGetResourceId (libSceIme) reports that no USB keyboard is connected (0x80bc0004, as shadPS4 does) because IME keyboard events are not delivered to the handler, although libSceKeyboard exposes the host keyboard
  • Player review dialog (libSceCdlgPlayerReview) shows nothing: scePlayerReviewDialogOpen finishes at once and the result reports that the user canceled, as sceWebBrowserDialogOpen does
  • NP reachability callbacks retain one callback and its user data; duplicate registration and unregistering an absent callback return the errors used by shadPS4. No callback is delivered because the existing NP model remains signed out with reachability unavailable.
  • Running application ID (libSceSystemService) - sceSystemServiceGetAppIdOfRunningBigApp reports 1 as the running title's app ID. The value is AnyPS5's own: the console's shell assigns app IDs and their values are not known here, so other calls that take an app ID must use the same one. sceSystemServiceKillApp with that ID and the arguments -1, 0 and 0, which SwanStationPS5 passes to close itself and ps5-payload-dev's hbldr passes to close the running game, ends the title as its own exit(0) would: the guest's shutdown and atexit handlers run and the process exits with status 0. On the console the call returns and the shell then ends the title, and whether those handlers run there is unknown; here there is no shell, so the call does not return. Another app ID or other arguments throw.
  • Temporary app-content storage tracks one /temp0 mount, preserves its files on unmount, and rejects new path resolutions until remount. Mount, format, space-query and unmount errors follow fpPS4; the pointer ABI is also declared by SharpProspero. Existing open host descriptors remain usable after unmount; console behaviour with open files is unverified. Host filesystem failures still throw.
  • Guest path resolution falls back to ASCII case-insensitive component lookup, following shadPS4's host filesystem. PPSA03747 requests Skyrim.INI, Data/Video and lowercase archive/plugin names that differ from the dump's filenames. Exact host names take precedence; multiple fallback matches throw instead of selecting an arbitrary file. Existing parent names are resolved when creating a new file, and guest mount aliases use the same ASCII comparison. Results are not cached, so renames and newly created files remain visible. Unicode case folding and PS5 behaviour for case-colliding host entries are unverified; host roots are used as supplied.
  • Static scalar calls (s_call_b64 and s_swappc_b64) require one call per ordinary even-aligned SGPR link pair (s0:s1 through s104:s105) and one later s_setpc_b64 return reading that exact pair. Regions must nest or be disjoint; recursion, shared links, escaping link values (including overlapping tuples and resource descriptors), invalid targets, interleaved regions, cross-region branches or fall-through, relative SGPR reads and dynamic s_setpc_b64 in a program with calls throw. The analysis checks all decoded instructions, including unreachable code. Arbitrary indirect calls and general call frames are not implemented.
  • s_call_b64 saves PC + 4 over GetShaderBase and branches to PC + 4 + signext(SIMM16) * 4, following AMD RDNA2 ISA sections 3.6.3, 12.2 and 12.3. Forward callees after s_endpgm are decoded. Native RDNA2/PS5 execution and title compatibility for these bounded scalar calls remain unverified; s_rfe_b64 still throws in translation.
  • sceVideodec2CreateDecoder (libSceVideodec2) decodes HEVC (codec type 974921) and VP9 (2382845) through FFmpeg, besides H.264. The tags come from SharpProspero's Videodec2CodecType and EVO-PLAYER-PS5's sce_videodec2.h, which records them from hardware runs. HEVC input is converted from length-prefixed NAL units to Annex B as for H.264, and VP9 frames are passed through. Output is the same 8-bit NV12 for every codec; a decoder for HEVC Main10 or VP9 Profile 2 is created, but a frame deeper than 8 bits throws, since the console's 10-bit output layout is unknown, and QueryDecoderMemoryInfo reports the 8-bit frame size for it. sceVideodec2GetPictureInfo and sceVideodec2GetAvcPictureInfo throw for HEVC and VP9 pictures, which use other layouts (SceVideodec2HevcPictureInfo, SceVideodec2Vp9PictureInfo), and sceVideodec2GetHevcPictureInfo and sceVideodec2GetVp9PictureInfo are not exported