CB_COLOR_INFO format 1 with number type 6 (8_SRGB) threw at decode.
It now decodes as R8_SRGB with component swap 0; the other swaps and
8_8_SRGB still throw.
A device that cannot attach and blend R8_SRGB (NVIDIA, lavapipe)
renders a resident 8_SRGB target through an RGBA8_SRGB view of an
RGBA8 copy of its R8 image: the image is blitted in before the pass
and back when the pass ends, and the write mask keeps R only, so the
encode, decode and blend are the device's sRGB attachment rules.
APS5_SRGB_ATTACHMENT_PROXY=1 forces the copy. Linear, mipmapped and
3D 8_SRGB targets throw on such a device.
PPSA26344 renders its G-buffer slot 5 and a multiply-blend pass into
8_SRGB targets.
LEGO Horizon Adventures imports 19 functions that no library exports
and no open pull request adds, so it fails eager binding. They are
declared as throwing stubs. The two libSceAjmWVorbis imports have no
known name and are exported by NID from libSceAjm.native.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A title maps direct memory with protection 0x3f2, which adds bits
0x100 and 0x200 to the CPU, GPU and AMPR bits, and the mapping threw.
They are the audio coprocessor (ACP) read and write bits, as named in
the KytyPS5 and etaHEN headers. The coprocessor work runs on the host
CPU, so they map to host read and read/write access like the GPU bits.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Return the version 0 internal register defaults, the internal
counterpart of sceAgcGetRegisterDefaults.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A stage's user data registers are read for the count in its RSRC2
(COMPUTE_PGM_RSRC2 for compute). A register the title never wrote no
longer refuses the draw or dispatch: it reads 0, as Kyty and SharpEmu
read it and as AMD PAL and Mesa initialize the user data registers.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The mixing stage threw when a mastering voice and its render buffer had different channel counts. A 2-channel voice is now mixed into the first two channels of a 6- or 8-channel buffer; other mismatches still throw.
Driver::RegisterShader required the Shader header at an 8-byte
boundary (alignof(Shader)) and read its fields through the pointer.
PPSA26344 uses its shader packs in place: its compute shader objects
point at headers 4 and 1 bytes past an 8-byte boundary, so the first
sceAgcCreateShader of such a header threw "null or misaligned address".
The header is now checked for null and readable memory at any
address, and its fixed fields and the registers the trace prints are
copied out with memcpy. The code address must still be 256-byte
aligned, and the header and size checks are unchanged. The console's
rule is unknown and is listed in TechnicalDebt.
The call site of PPSA21402 sets only three argument registers, so the function has no size parameter. A data chunk that runs past the buffer or ends inside a frame returns INVALID_WAVEFORM_DATA instead of being shortened. The test no longer writes padding from a string literal.
Write the 2-dword CLEAR_STATE (0x12) packet with a 4-bit command, the
packet the driver already validates and executes by restoring the
initial context registers.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Write SET_CONFIG_REG (0x68) packets like the context, shader and user
config register setters: one register from a ShaderRegister, or a range
of values at an offset.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Patch the mask of a wait packet like sceAgcWaitRegMemPatchReference
patches its reference: a 32-bit value written to the low mask word of a
32- or 64-bit WAIT_REG_MEM, rejected above 32 bits.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The end-of-shader action is written by an inline SDK builder as a
RELEASE_MEM packet, so the size is the 32 bytes that
sceAgcCbReleaseMem writes and that sceAgcAcbQueueEndOfShaderActionGetSize
already returns.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The reverb was a Freeverb-style approximation. It now follows the PS4
firmware 11.00 libSceNgs2.sprx, read and checked against its output: the
input mixed to mono with the library's fixed gains, a 14400-sample buffer
with four reflection taps from the reflection pattern tables and a late
feed, sixteen damped comb filters with a pre-emphasis stage, a signed
selection of combs and four allpasses per output channel, a two-pole room
HF filter, and the library's parameter clamps, crossfades and setup
defaults. The test values are the PS4 library's own output.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
20 of the 31 NIDs have names in shadPS4's aerolib list. They are declared
under those names; POSIX sleep is implemented. The NpPartner001 and Psml
MFSR2 exports stay unnamed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A pixel, vertex or tessellation stage whose wave is wider than the host
subgroup runs one guest lane per invocation, so lanes at or above the
subgroup size have no invocation. v_readlane_b32 still shuffled from
them, which Vulkan leaves undefined; a wave64 pixel minimum loop that
reads lanes 31 and 63 can then wait for a value no live lane holds and
hang the GPU.
At one lane per invocation outside compute, a v_readlane_b32 of a
constant lane at or above the host subgroup size, and v_permlanex16_b32
on a subgroup of 16 lanes or fewer, now fail SPIR-V emission. Lanes in
registers still build, so s_ff1_i32_b64 waterfalls are unaffected,
and neither check applies to compute or to two lanes per invocation.
v_permlane16_b32 and v_permlanex16_b32 take the source lane's EXEC from
a ballot, as DPP does, instead of a shuffle from a possibly inactive
invocation.
GFX10 image format 30 (10_11_11_UNORM: X and Y are unorm11 in bits
0-21, Z is unorm10 in bits 22-31, per Mesa's gfx10 tables) has no
Vulkan format, so its sampled and storage descriptors threw at decode.
Format 30 now takes the R32_UINT route of 10_11_11_UINT: the driver
binds the raw dwords as R32_UINT and the shader extracts each field and
converts it with the buffer format helpers (NormalizeFormatComponent on
loads, EmitFormatStoreComponent on stores); DST_SEL 1 reads 1.0f.
Samples, gathers, LOD queries, 16-bit data and loads or stores whose
DST_SEL names the missing W channel throw.
Converted textures are now viewed with an identity component mapping,
since the shader applies DST_SEL itself: a 10_11_11_UINT view whose X
selector was not X lost the packed dword. DCC clear codes 0001 and 1110
of a converted texture throw instead of filling one R32_UINT channel.
RackGetInfo reports the rack's handles, buffer, id, uid, option limits,
render count and active voices. VoiceGetPortInfo reports a port's matrix,
volume and destination. VoiceQueryInfo answers info id 0x4001 with the
voice channel count and throws for other ids. Assumptions are recorded in
TechnicalDebt.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
sceLoginDialogGetResult zeroed 8 bytes of a result struct of unknown size and reported result 0
with user id 0. It now writes only the leading int32 (USER_CANCELED), like
sceWebBrowserDialogGetResult and like the sign-in dialog, so a title takes its "no user chosen"
path instead of reading an invalid user id. Records the dialog in the silent-stubs list in
docs/dev/TechnicalDebt.md.
Per review: sceUserServiceGetNpAccountId reports success with account id 0 and
sceUserServiceGetUserColor returns blue by default; both are assumptions. Records them under
"Unknown function info" in docs/dev/TechnicalDebt.md.
* feat(libkernel): implement sceKernelReleaseFlexibleMemory
Unmaps the range through sceKernelMunmap, which returns its pages to
the flexible memory budget, as fpPS4 and prosper do.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(libkernel): keep the flexible memory release check apart from the batch map checks
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
sceAgcCbCondWrite writes the 9-dword COND_WRITE packet: poll a memory
dword, compare it masked with the reference, and write a dword to memory
on a match. sceAgcCbCondWriteGetSize returns its 36 bytes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sceAgcAsyncCondExecPatchSetCommandAddress and
sceAgcAsyncCondExecPatchSetEnd patch the COND_EXEC packet like their
graphics counterparts, since sceAgcAcbCondExec writes the same packet
as sceAgcDcbCondExec. Both variants share one implementation, as the
REWIND patches do.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The query writes the maximum resource name length (0xfc) through its
output pointer and returns 0, as prosper does from a title's registration
configuration. The parameter follows the SDK wrapper
sce::Agc::ResourceRegistration::getMaxNameLength(unsigned int*). Resource
registration itself stays unavailable.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rack 0x2001 is created with its option layout and KytyPS5's defaults, takes
the setup (0x20010000) and I3DL2 (0x20010001) voice params and reports the
common voice state. The voice mixes its inputs and runs a Freeverb-style
approximation driven by the I3DL2 parameters: room and room HF, early
reflections and their delay, late reverb and its pre-delay, decay time and
HF ratio, and diffusion. Out-of-range params throw, param changes keep the
tail, a stop or kill clears it, and the tail ends once it decays below
1e-20. The console's algorithm is unknown; the approximation is recorded in
TechnicalDebt. The test context buffer pool grows to 64.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Mastering voice param 0x30000004 sets a full-band and an LFE level. They
scale the mastering voice when it is mixed into the render buffer, the LFE
level on channel 3 of 6- and 8-channel voices. Non-finite levels are
invalid arguments.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The SDK 9 libc.prx heap maps its arenas with flag 0x8000, which threw as
an unsupported flag. The flag is ignored for this function, as sharpemu
does; other unknown flags still throw.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Whether the console's parser rejects 1e309 or stores an infinite real
is unknown, and RFC 8259 allows both. Following the exact-or-throw rule,
sce::Json::Parser::parse now throws with the number text and a note that
the behaviour is unverified, instead of returning JsonErrorParse. The
partially built tree is freed before the exception leaves the parser.
The case is listed under unknown function info in TechnicalDebt.md.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R5WJS4ZdQynAJesCZKH5hb
sceAgcWriteDataPatchSetDst, sceAgcWriteDataPatchSetCachePolicy, their
Async forms and sceAgcAsyncWriteDataPatchSetAddressOrOffset threw. They
now rewrite a WRITE_DATA packet in place: the destination in the
graphics (sceAgcDcbWriteData) or compute (sceAgcAcbWriteData) encoding,
the cache policy in bits 25-26 and the address in dwords 2-3, so the
patched packet equals the one written with those values. A register
destination is rejected when the packet requests write confirmation,
as when the packet is written.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PPSA14632 (Unreal Engine) writes sceAgcCbBranch(mode 1, compare
function 0, mask 0, reference 0) with a then buffer and a null else
buffer of 0 dwords. It leaves the compare address uninitialised, so it
is sometimes only 4-byte aligned. The writer rejected the null else
buffer and the misaligned compare address, and the driver accepted
opcode 0x3f only as the 4-dword INDIRECT_BUFFER, so the 14-dword branch
would have failed at submission.
sceAgcCbBranch no longer checks the compare address of an always-pass
branch, which reads nothing, or the address of a buffer of 0 dwords.
The driver runs the first buffer of an always-pass COND_INDIRECT_BUFFER
in modes 1 and 2 (if-then and if-then-else) in place of the packet. A
comparison, a predicated branch and other modes throw.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The 106-key (Japanese) arrangement threw. Its alphanumeric layer now
follows the JIS layout of the HID usages: the symbol keys right of the
digits and letters, the Ro key (0x87) and the Yen key (0x89). With the
Kana LED set it still throws, as the kana the console returns are
unknown.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sceAjmBatchJobControl threw. It now appends a control job that keeps
the sideband input pointer and runs at sceAjmBatchStart: RESET (bit 13)
clears the context as sceAjmBatchJobClearContext does, INITIALIZE
(bit 14) initializes the codec, and SIDEBAND_GAPLESS_DECODE (bit 45)
overwrites the gapless total and skip counts, in this order.
The sideband input holds the gapless decode first, then the codec's
initialize parameters: 8 bytes for ATRAC9, 12 for Opus, none for MP3.
The output is the 8-byte result. Other flags, INITIALIZE for other
codecs, and other sizes throw. SIDEBAND_GAPLESS_DECODE without RESET
throws too: RPCSX and shadPS4 keep zero counts there. The bits and the
order follow shadPS4 (PS4), the overwrite with RESET follows RPCSX, and
the sizes follow the one title seen.
PPSA14632 calls sceAudioOut2Set3DLatency(0xFF, 1) during its audio
setup (eboot 0x5613e2c) and fails the setup on a nonzero return. Only
latency 2 from PPSA26344 was accepted, so the call threw. Latency 1 and
2 are now accepted for the system user; 0, 3 and other users still
throw.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
scePlayerInvitationDialogGetResult makes the common dialog checks of
sceWebBrowserDialogGetResult: NOT_INITIALIZED before the dialog is
initialized, ARG_NULL for a null result and NOT_FINISHED until the
dialog finishes. The dialog shows no UI and sends no invitation, so the
finished dialog reports USER_CANCELED with error code 0. The 40-byte
result layout (error code, result, 32 reserved bytes) is taken from
SharpProspero.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Report the spacing the writing line applies: the modelled line places
each run at the sum of the previous advances, so every space is 0.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The plain-named twin of std::_Execute_once delegates to that symbol and inherits its call_once semantics; the name-equivalence assumption is recorded in TechnicalDebt. Registers guest_std_execute_once_tests.
A second sceSaveDataInitialize3 returned SAVE_DATA_ERROR_ALREADY_INITIALIZED.
PPSA12544's executable and its Unity SaveData plugin both initialize, and
the plugin raises Unity.SaveData.PS5.Core.SaveDataException on any error,
so the console must accept the second call. Initializations are now
counted; sceSaveDataTerminate ends the session at the last one and only
then checks for mounted slots.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A push mixed the ports' buffers at once and queued the mix on SDL, and
the queue level left out a 40 ms cushion that the SDL queue rarely
exceeded, so titles saw an empty queue. PPSA12544's FMOD output fills a
256-frame buffer after pushing it, reuses it two pushes later, and its
mixer thread can still be writing a buffer when the next push follows
within microseconds: a grain boundary broke about every 5 ms (an audible
crackle).
A push now records the buffers the ports point at and reads the previous
grain at the next push, 100 us after it. The mixed frames are played by
the SDL device callback, which waits for a 40 ms cushion before it plays
(again after running dry), and the queue level counts the unplayed
grains beyond that cushion. Recording the four buffers at every push
showed 27% of boundaries broken when read at the push, 59% when read two
pushes later and none when read at the next push; the title's output
went from 4-9% to none of its grain boundaries broken over 6,000 loud
grains.
AI-assisted: yes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Report the face's glyph count and the glyph index of a character through
the library's driver; the FreeType driver gains its glyphs_count entry.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A title's libc.prx passes the dso address of __cxa_thread_atexit to
_sceKernelRtldThreadAtexitIncrement and fails the registration when it
returns nonzero. Increment takes a reference on the loaded image that
contains the address, so it stays mapped while thread_local destructors
are pending, and Decrement releases one. An address outside every
loaded image and a Decrement without a reference throw.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The resource id array is cleared and given the user. A null array returns
INVALID_ADDRESS and an invalid user INVALID_USER_ID without writing it; a
user whose keyboard is not open gets NOT_OPENED, and an open one gets
CONNECTION_FAILED, as no USB keyboard is reported through the IME, as in
shadPS4. The missing IME keyboard events are recorded in TechnicalDebt.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On a host subgroup narrower than 32 lanes, threadBit reads an EXEC
written with s_mov_b32 or s_mov_b64 at bit LaneId & 31 of EXEC_LO, and
LaneId is the subgroup invocation id. Every lane at or above the host
subgroup size therefore reads the bit of a lower lane, in wave32 and
wave64 alike. An EXEC produced by a compare stays consistent because
its ballot is subgroup-local as well. Found while investigating the
llvmpipe failure of #751.
An S# with FORCE_UNNORMALIZED threw in DecodeSamplerResource. It is now
bound through a Vulkan sampler with unnormalizedCoordinates when every
use stays where the S# and the host select the same texels.
ShaderInfoCollector records the live uses of each sampler after Apply
and dead-code elimination, and the emitter shares its explicit-LOD
predicate. Populate flags a direct S# with the bit that only explicit-LOD
image_sample without offset, comparison, derivatives or _a uses, paired
only with direct 1D or 2D images without a format conversion; anything
else throws. The driver checks the S# filters, clamps, TRUNC_COORD and
MC_COORD_TRUNC, creates the sampler with nearest mips and a zero LOD
range, and requires a single-level, single-layer 1D or 2D view of mip 0.
The shader disk cache format becomes 5.
Returns the CPU mask threads get by default (DEFAULT_THREAD_AFFINITY,
0x1FFF), the value itself rather than an error code.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PPSA21564 and PPSA21567 import std::_Fiopen (NID vYWK2Pz8vGE), the only libc
NID the host libc lacks. Without it the executable fails to load against
the host libc when the title's own libc.prx is left out of the guest
conversion, which is how the Linux runs of PPSA21564 avoid the libc.prx
binding crash. The values of the open mode and the meaning of the
protection argument are unknown, so the export throws when called; it was
never called in a 300 s run of PPSA21567.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014A3UgWDUxE1EeHyVZm6tiN
No additional content is installed, so sceAppContentAddcontMount returns
SCE_APP_CONTENT_ERROR_NOT_FOUND with the mount point untouched, and
sceAppContentAddcontUnmount finds no mount to release. A missing label
or mount point is a parameter error. The library gets its own
CMakeLists for the new guest_appcontent test.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sceHttp2CreateCookieBox hands out an id from the library's handle
counter, sceHttp2SetCookieBox binds one to a template or request, and
sceHttp2CookieFlush succeeds: no request reaches the network, so no
cookie is ever stored. sceHttp2SetRequestNoContentLength is accepted
like sceHttp2SetRequestContentLength. The library gets its own
CMakeLists for the new guest_http2 test.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Registration of owners and resources fails with
RESOURCE_REGISTRATION_UNAVAILABLE, so no handle is ever valid: the owner
and resource getters, sceAgcDriverSetResourceUserData,
sceAgcDriverRegisterGdsResource, sceAgcDriverFindResourcesPublic,
sceAgcDriverUnregisterAllResourcesForOwner and
sceAgcDriverGetDefaultOwner return the same error.
sceAgcDriverUnregisterWorkloadStream mirrors the accepting
RegisterWorkloadStream. No capture, trace or submit validation ever runs,
so their status queries report false.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sceVoiceQoSInit accepted only app type 0x20000000 and threw for every
other value. PPSA26344 v1.008 passes 0x10000000 at both of its call
sites, so its initialization threw.
Accept 0x10000000 as a second known app type. Its meaning is unknown,
so the constant is named after the value, and it is handled like
0x20000000; the block stays unused. A null or empty block, a second
initialization and every other app type still throw.
guest_voice_qos_tests now takes the app type as its argument and runs
in ctest once per accepted value, because sceVoiceQoSEnd still throws
and one process can initialize only once.
sceAudioOut2PortCreate threw for 12-channel ports, which PPSA26344
creates as its two 7.1.4 float beds (data format 0xc00).
Each accepted layout (1, 2, 6, 8 or 12 channels, float or int16) now
folds into the stereo mix through a coefficient table: centre, side,
back and top front channels at -3 dB, top back channels at -6 dB into
the front, LFE dropped. Zero coefficients are skipped, so NaN or Inf on
a dropped channel does not reach the mix. Ports of 3, 4, 5 or 7
channels, which were mixed as L/R, now throw, as do other counts and
formats with any of bits 12-31 set. The assumed format fields,
channel order and coefficients are listed in TechnicalDebt.
The new audio_out2_port_layouts test checks each layout's fold, float
and int16, and the formats that throw.
Create, destroy, clear, write runs, step through them and read the
line metrics, following KytyPS5. Layouts from SharpProspero.
Co-Authored-By: Claude <noreply@anthropic.com>
Wait8 and Wait16 compare the 1- or 2-byte value at the address with the
comparand and share the waiter queue of the other sizes.
sceKernelSyncOnAddressWake accepts any non-null address: libc's
__std_atomic_notify_one/all pass the atomic's own address, which for 8- and
16-bit atomics need not be 4-byte aligned.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DecodeState, the draw precheck and DecodePixelStageInfo rejected every
nonzero CONSERVATIVE_Z_EXPORT (DB_SHADER_CONTROL bits 13-14).
EXPORT_LESS_THAN_Z (1) and EXPORT_GREATER_THAN_Z (2) promise that the
exported Z stays on one side of the interpolated Z. The value now
reaches the recompiler as a pixel stage field, and a pixel shader that
writes FragDepth declares DepthLess or DepthGreater next to
DepthReplacing, the SPIR-V modes RADV maps to these values. Vulkan lets
those modes only add a depth test of the interpolated Z before shading,
so a shader that keeps the promise renders the same. The reserved value
3 still throws.
The field is part of the recompile cache key, the draw key and the
serialized request (version 7), and ValidateShaders accepts both modes.
Initialize, PortOpen/Close, PortSetAttribute, PortGetQueueLevel,
PortAdvance and PortPush. One port, validation order and error codes from
the PS5 module as read by prosper; blocking push paced at granularity
samples per frame at 48 kHz like KytyPS5.
Co-Authored-By: Claude <noreply@anthropic.com>
sceVideoOutRegisterBuffers2 threw "DCC presentation is not implemented"
for category 1 (DCC-compressed) buffers, which PPSA26344 registers. Such
a buffer now needs DCC metadata and the tiled layout, and dcc_control may
only use the CB_DCC_CONTROL block layout bits 0x10026c.
At a flip the keys are read behind their recorded writers, one byte per
256 bytes as in the driver's DCC model. Uncompressed keys present the
stored texels as before; a uniform clear code presents its color with a
GPU clear of the scaler's source image; a pending storage image is used
when it serves the keys. Mixed or unreadable keys, clear codes the
display format has no DCC encoding for, register-clear keys over a
pending image and a clear color wider than 32 bits throw. Buffers
without DCC take the old path.
sceFontOpenFontSet failed for every set type, so PPSA21564 drew no text
in system fonts (the title screen copyright line, credits, button
guides). It now loads the set's primary font file from
ANYPS5_SYSTEM_FONTS, or anyps5-fonts beside the executable: console
files under their own names first, then openly licensed substitutes
(Noto Sans, Noto Sans Mono, Noto Sans Thai, Noto Sans CJK). The
PS5-only JG2 set types are accepted.
System font handles use the system font context. Their faces are
loaded by FreeType in host memory: about 1 MiB per CJK face does not
fit the font memory the title sizes for the console's fonts, and
sceFontCreateRenderer then failed with ALLOCATION_FAILED. Handles of
the same font file share one copy of its bytes.
PPSA12544's Media/Plugins modules (CommonDialog, PSN, Share) import
libSceVrSetupDialog, which no library provided, and Share, NpTrophy2,
WebBrowserDialog and NpEntitlementAccess functions that were not
exported. Add libSceVrSetupDialog and the missing functions as
unimplemented exports, except
sceNpEntitlementAccessRequestConsumeServiceEntitlement, which reports
SCE_NP_ERROR_SIGNED_OUT like
sceNpEntitlementAccessRequestConsumeUnifiedEntitlement. Their other
imports are covered by #734 and #369, and two by #407.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sceAmprAmmCommandBufferMapAsPrt, AllocatePaForPrt, RemapIntoPrt and
UnmapToPrt, with the MapAsPrt and AllocatePaForPrt measures. Signatures,
checks and their order follow ampr_emu.
The executor keeps the PRT pages of the AMM ranges. Unbacked PRT pages
are zero-filled with GPU read access; AllocatePaForPrt backs each
unbacked page with a pool page and changes the type and protection of
backed ones; RemapIntoPrt moves a mapped range into a PRT range; and
UnmapToPrt returns the pages to the pool and zero-fills them again. A
plain map, unmap or remap over a PRT range ends it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sceVideoOutIsOutputSupported threw VIDEO_OUT_ERROR_UNSUPPORTED_OUTPUT_MODE
for every mode other than the default and 119.88 Hz, and
sceVideoOutConfigureOutput threw for an unavailable 119.88 Hz mode. Titles
probe and request modes the display may lack and handle the result:
PPSA12544 asks for 0xd000000a and falls back to 3840 pixels when it is not
supported, and its sceVideoOutConfigureOutput caller switches on the
returned error codes, including VIDEO_OUT_ERROR_UNAVAILABLE_OUTPUT_MODE.
Every mode except the default now reports 0, and configuring one returns
VIDEO_OUT_ERROR_UNAVAILABLE_OUTPUT_MODE.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
libSceAmpr gains sceAmprAmmCommandBufferRemap, MultiMap, ModifyProtect
and ModifyMtypeProtect with their GPU mask forms and the eight measure
functions. Signatures and the protection and mask checks follow ampr_emu.
The executor keeps a page table of the AMM ranges: each page's physical
offset, protection, memory type and whether it came from the pool. A
remap moves the pages of a fully mapped range and leaves the old range
reserved; a multimap maps the same pages again; a pool page returns to
the pool only when its last mapping goes. A protection change applies
the masked bits page by page.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
libSceAmpr gains the AMM command buffer (constructor, destructor, map,
map direct and unmap, with their GPU mask forms and measures),
sceAmprAmmGiveDirectMemory, sceAmprAmmGetVirtualAddressRanges, the three
submit forms and sceAmprAmmWaitCommandBufferCompletion. The APR
MapBegin, MapDirectBegin and MapEnd commands and their measures record
the same map commands.
The libkernel executor now maps: a plain map takes pages from the direct
memory given to the mapper with usage 1, a direct map uses the given
offset, and an unmap returns the pages to that pool and leaves the range
reserved. The AMM ranges are reserved in the guest arena on first use.
Commands are walked by the buffer's byte offset so an AMM submission can
run raw command memory.
Signatures, the protection mask and the APR map rules follow ampr_emu;
the mapper model follows PS5PCEM. While an APR map region is open, a
second begin and every completion write return EPERM.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sceAmprAprCommandBufferReadFileGather, ReadFileScatter,
ReadFileGatherScatter and ResetGatherScatterState, with their measure
functions. Signatures, argument checks and the read cursor follow
ampr_emu: each read leaves the file, the next offset and the next
destination; a gather reads at a new offset into the next destination, a
scatter continues in the file into a new destination, and a
gather-scatter takes both. Recording one needs a file read since the last
reset, tracked in the command buffer object next to its type.
sceAmprAprCommandBufferReadFile now applies the same length, offset and
destination checks and rejects a null command buffer instead of
dereferencing it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sceAmprCommandBufferWaitOnCounter_04_00 and WriteCounter_04_00 take the
counter access size and offset, the wait mask and the write operation,
with their measure functions; ConstructNop records a nop with an optional
leading word and a payload of up to 60 bytes, and ConstructMarker records
the set, push and pop markers by type. Signatures and checks follow
ampr_emu.
The executor now reads and writes counters by access: the 8-byte access
of counter n spans n and n + 1, the 2- and 1-byte accesses a half or a
byte of the counter. Waits compare at the access width, so the signed and
wrapped compares see the field's own sign bit, and the atomic writes wrap
within the field. The legacy counter commands record a 4-byte access.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SET_PREDICATION threw, and packets with the predicate header bit were
rejected. The executor now keeps the queue's predication: operations 3
and 4 read a 64- or 32-bit value and bit 8 selects whether predicated
packets run when it is non-zero or zero; operation 0 clears it. Before
a predicated packet runs while predication is active, queued labels are
recorded and the value is read, as for COND_EXEC; the packet is skipped
when the predicate fails.
Indirect buffers are inlined when a submission is copied, so a
predicated INDIRECT_BUFFER call keeps its header in front of the
inlined commands and records their end like a COND_EXEC range; the
block runs or is skipped on one evaluation, as on the command
processor. Query predication, a predicated COND_EXEC, predicated chains
and flips inside predicated command buffers throw.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A title passes a work memory block and app type 0x20000000, and turns
voice chat off when initialization fails. Initialization now records
the library as initialized and succeeds. A null or empty memory block,
another app type and a second initialization throw, as their error
codes are unknown.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sceKernelInstallExceptionHandler and sceKernelRemoveExceptionHandler threw.
They now keep one handler per allowed signal (SIGHUP, SIGILL, SIGFPE,
SIGBUS, SIGSEGV, SIGUSR1, as in shadPS4): another signal or a null handler
returns EINVAL, a second handler for a signal returns EAGAIN, and removing
clears it. Delivery is not implemented and is recorded in the technical
debt; sceKernelRaiseException still throws.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A title's libc.prx calls it from __cxa_thread_atexit with flags 2 and
stores the returned module id in the destructor record. The 0x1A8-byte
info reports the name, id, TLS block, init and fini procedures,
eh_frame_hdr and eh_frame, and up to four load segments of the image
containing the address. The id is the loader handle when the image was
opened through sceKernelLoadStartModule and otherwise a stable id from
the same range. Unknown flags and st_size values throw.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rename the two unknown libSceSaveData.native stubs to
sceSaveDataTransferringMountPs4 (RjMlsR8EXrw) and
sceSaveDataDirNameSearchPs4 (X4MYzukPc3g). There is no PS4 save area:
the mount returns NOT_FOUND like sceSaveDataTransferringMount, and the
search reports zero hits.
Co-Authored-By: Claude <noreply@anthropic.com>
OQ-dzhlnM28, qBS714-Jr3g and tB59hFLH3SA are _sceLibcInternalThreadDtors,
_sceLibcInternalThreadAtexit and _sceLibcInternalForceTlsDestructor,
implemented in libSceLibcInternal by #641. dbOlWdppb4o is implemented by
#651.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
NH6xARDOVv8 is the NID of sceKernelGetOperationMode. PPSA12544 passes two
int outputs and logs them as mode and submode; both are reported as 0.
B2n8aDorSH4 and PZQhiiLXRFs are sceKernelSyncOnAddressWait32 and
sceKernelSyncOnAddressWait64, implemented by #633, and are no longer added
as unimplemented exports.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Implement scePthreadGetschedparam and scePthreadSetschedparam on top of
the thread priority, POSIX utimes and fsync on top of sceKernelUtimes
and sceKernelFsync, and sceUserServiceGetAccessibilityZoomFollowFocus
like the other accessibility queries. Add the remaining imports of
PPSA12544 as unimplemented exports and record unknown NIDs and
signatures in the technical debt.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Report age level 0 for the initial user and reject other users and a null
output like the other user queries. The meaning of the value is unknown and
recorded in the technical debt; PPSA12544 only stores it for its user
profile.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sceVideoOutRegisterBuffers2 and sceVideoOutSubmitChangeBufferAttribute2
threw for every buffer attribute option other than 0. PPSA26344 builds
its display buffers with option 8 through the libSceAgc helper linked
into it, so its first registration failed.
Option 8, VIDEO_OUT_BUFFER_ATTRIBUTE_OPTION_STRICT_COLORIMETRY (name
and value from KytyPS5), is now accepted and presented as option 0;
every other option still throws. What the console changes for it is
unknown and recorded in TechnicalDebt. The rejection now names the
tiling mode, pitch, aspect ratio and option it was given.
video_out_flip_tests decode checks that option 8 describes the same
buffer as option 0 and that options 1, 32 and 40 are rejected.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Ghost of Yotei (PPSA26344) imports both functions, so its import
resolution failed at startup. Markers only feed an attached Razor
capture. AnyPS5 hosts none and sceRazorCpuIsCapturing reports 0, so,
like the other libSceRazorCpu exports, both do nothing and return 0.
The push signature comes from the title's calls (a string literal,
0x80ffffff, 2). TechnicalDebt lists both functions with the assumed
signatures. guest_razor_cpu covers nested and unbalanced markers.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The export threw, and titles query the system name during startup.
Parameter 6 (the system name) now writes the fixed name "PS5" into a
buffer of at least SYSTEM_SERVICE_MAX_SYSTEM_NAME_LENGTH (65) bytes.
A null buffer or a zero size returns SYSTEM_SERVICE_ERROR_PARAMETER,
as in KytyPS5. Other parameter ids and buffers of 1 to 64 bytes still
throw, because no PS5 source gives their result. guest_system_service
covers the error rows, both throws and the returned name.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
scePsmlMfsrGetContextBufferRequirement1100, scePsmlMfsrCreateContext1100
and scePsmlMfsrGetDispatchMfsrPacket1100 were not exported, so a title
importing them failed to load.
In Sony's libScePsml all three return 0x8A810001 (not initialized)
without writing their outputs until scePsmlMfsrInit has succeeded.
AnyPS5's scePsmlMfsrInit throws, so that is the only state a title can
reach, and the three calls now return that error.
The existing stubs for scePsmlMfsrInit, scePsmlMfsrReleaseContext and
scePsmlMfsrGetDispatchMfsrPacketSizeInDwords get their real names and
still throw. libScePsml_debug gets a CMakeLists.txt for the new
guest_psml test.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Titles set the PS Store icon layout before they show the icon, and a
title that imports the call stops at startup on the unresolved import.
No PS Store icon is drawn, so like the show and hide calls it accepts
every layout and returns 0 without effect. The signature follows
shadPS4 (a PS4 reference), which also returns OK for every layout.
The libSceNpCommerce entry under "Silent stubs" in TechnicalDebt now
names the function.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A title that loads libSceMsgDialog.native without libSceMsgDialog
imports sceMsgDialogClose from it, so without the export it stops at
startup on an unresolved import.
Close turns a running dialog into a finished one and returns
NOT_RUNNING in every other state, as libSceMsgDialog's Close does.
The module keeps its own dialog status, so it cannot reuse that
export. Open in this module finishes the dialog at once, so Close
after Open returns NOT_RUNNING and leaves the result unchanged.
The module is now listed under silent stubs in TechnicalDebt, and a
CMakeLists.txt registers the guest_msg_dialog_native test.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A title's own libc.prx implements __cxa_thread_atexit and the
destructor pass of exit() through _sceLibcInternalThreadAtexit and
_sceLibcInternalThreadDtors. Its __cxa_finalize calls
_sceLibcInternalForceTlsDestructor.
Destructors are kept per thread and run newest first, including those
registered while they run, as FreeBSD's __cxa_thread_call_dtors does.
A null destructor or one outside every loaded image throws instead of
being skipped. The first registration installs the pass as the
libkernel thread exit hook, so it runs on every guest thread before
the thread can be joined. _sceLibcInternalForceTlsDestructor throws.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
libc's __std_atomic_wait_direct_32 and __std_atomic_wait_direct_64
import these functions, so a libc.prx that contains the C++20 atomic
wait wrappers does not load without them. Wait32 compares a 4-byte
value and Wait64 the full 8-byte value. Both share the waiter queue
of sceKernelSyncOnAddressWait, so sceKernelSyncOnAddressWake releases
waiters of every size on the address. A null address, or one not
aligned to the value size, throws. The by-value comparand, the return
values and the 8-byte alignment of Wait64 are assumed and recorded in
TechnicalDebt.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Titles import sceHttpParseStatusLine from libSceHttp to read the
status line of a response; without the export they fail at startup.
Parse the HTTP/x.y version, the three-digit code and the reason phrase
up to the line feed, and return the library's PARSE_HTTP error codes.
The seven-argument signature is the one SharpProspero declares; the
behaviour follows the shadPS4 reimplementation of the PS4 library,
except that no byte past lineLen is read. A consumed count above
INT32_MAX cannot be returned and throws. guest_http covers valid lines
and each error path.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On Windows the guest arena ended at 0x72_0000_0000: #231 kept its
448 GiB size after #153 had moved its start down to 0x2_0000_0000.
Titles map fixed addresses up to the application map area end,
0xFC_0000_0000 (SCE_KERNEL_APP_MAP_AREA_END_ADDR on the PS4), and a
direct memory mapping above the old end threw "shared mapping outside
the guest arena".
The arena is now reserved up to 0xFC_0000_0000. The out-of-arena
errors name the address and length, and a fixed mapping over a used
arena range says whether it hit a host region. guest_memory maps
direct memory at the last two pages below the end, reads it through
an alias and checks that a mapping at the end is refused.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PPSA26344 calls sceAudioOut2Set3DLatency(0xFF, 2) right after
sceAudioOut2Initialize and fails its audio initialization on a negative
return; the export was missing, so the import did not resolve. Its
audio subsystem setup also calls sceAudioOut2MasteringInit(0), which
threw.
sceAudioOut2Set3DLatency accepts a latency of 2 for the system user
(0xFF) and throws for any other user or latency, as the unit and range
are unknown. sceAudioOut2MasteringInit accepts flags 0 and throws for
other flags. There is no 3D rendering or mastering stage, so neither
call changes the output; TechnicalDebt lists this under Functional and
the assumed signatures under Unknown function info.
The new audio_out2_latency test covers the accepted and thrown values.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Validate refused every COND_EXEC, so a submission that uses one was
rejected as a whole. The packet now reads the dword at its address once
the earlier packets of its queue and their GPU writes have completed,
and skips the exec_count dwords after it when the dword is zero.
The command copy that inlines INDIRECT_BUFFERs records where each range
ends, so a range over an INDIRECT_BUFFER skips the whole buffer.
Unaligned addresses, address bits 48 and up, and reserved control and
count bits throw; the cache policy is accepted on compute queues only,
as the MEC defines it. A flip inside a range, a range that ends inside
a packet or past its command buffer, and a chained INDIRECT_BUFFER or
REWIND inside a range throw.
agc_driver_pm4 and agc_driver_flip cover the skips and the rejections.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PPSA26344 imports libSceAgc NID dbOlWdppb4o, whose name is unknown,
and calls it with the (regs, gs, ps) arguments of
sceAgcCreateInterpolantMapping to fill the 32 SPI_PS_INPUT_CNTL
registers. It is exported as sceAgcUnknownCreateInterpolantMapping.
It differs from sceAgcCreateInterpolantMapping only for inputs that
carry the high f16 half alone (is_f16 2): these take the default bit
and DEFAULT_VAL from the high half, as KytyPS5 does.
Both exports share validation and the register loop. More than 32
pixel shader inputs now throw; before, they were written past the
32-register block. agc_interpolant_mapping covers both exports.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The resource materializer refused every atomic image descriptor whose
format was not 32_UINT. RDNA2 image atomics act on the raw dword and
the numeric format only affects addressing, so 32_SINT and 32_FLOAT
surfaces are now accepted with the Uint numeric class and run through
the existing integer atomics and float compare-exchange loops. Other
formats still throw, and the message now names the format.
DescriptorBinding gains imageAtomic, carried through the shader disk
cache (format version 4) and the resource content key. The driver
binds those elements through a cached R32_UINT view of R32_SINT and
R32_SFLOAT storage images.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sceAgcGetIsTrinityMode takes a pointer to a one-byte flag; the only
known caller ignores the return value. The export took no argument and
never wrote the flag. That caller's flag is in zero-initialised .bss,
so this corrects the signature; it does not fix a visible failure.
The function now stores false, as sceKernelIsTrinityMode reports a base
PS5, returns 0 and throws on a null pointer, whose error code is
unknown. It moves from Unimplemented.cpp to Misc/src/Platform.cpp, and
the new agc_platform_tests ctest target covers it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DecodeState and the draw precheck rejected PA_CL_CLIP_CNTL bit 24
(DX_LINEAR_ATTR_CLIP_ENA), so every draw that sets it was skipped.
Vulkan requires clipped NoPerspective outputs to vary linearly in
framebuffer space, and RADV and radeonsi set this bit for every draw
they emit. With the bit set the console therefore clips the way the
host driver already does, and the pipeline needs no extra state.
Clip space, depth clamping and the viewport depth range decode as
with the bit clear. Every other unsupported bit still rejects the
draw, with or without bit 24.
TechnicalDebt records that a clear bit, which was already accepted,
gets the same clipping.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AMD hardware compares a sample_c reference against a color texture's red
channel; Vulkan defines comparison sampling only for depth formats, so the
driver refused any compare-sampled texture that is not R32 float or R16
unorm. PPSA21567 compares the same LESSEQUAL, clamp-to-border (opaque
white) sampler against a shadow map and against a 1x1 RGBA8 texture.
For a compare-sampled image whose format is not natively comparable, the
specialization records the paired sampler's compare function, filter,
addressing and border, and the view's reference clamp kind; the image then
binds as an ordinary color texture. The backend fetches the red channel,
applies wrap, clamp-to-edge or clamp-to-border addressing with the
sampler's texel-centre convention (border taps take the border's red),
compares, and blends four comparisons for bilinear filtering. Real depth
formats keep the native path.
Only sample_c / sample_c_lz on 2D and 2D array views, float/unorm/snorm
formats, wrap, clamp-to-edge or clamp-to-border, point or bilinear at one
level are implemented; half-border, the border color table and everything
else on this path throw. The reference clamp for unorm/snorm color formats
is not documented by AMD and is recorded in the technical debt.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
IntrusivePtr<T> is three pointers: object, deleter, LibContext. The default
constructors zero them, the copy constructors copy them and take a reference
on the object, operator-> and operator* return the object, and the destructors
drop a reference and hand the object to the deleter when it was the last one.
The last-reference release of a pointer without a deleter needs the object's
destructor and the LibContext memory pool and still throws.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The constructor was a silent stub that left the guest object
uninitialised and c_str threw. The constructor now writes the 0x20-byte
object, c_str returns the buffer or an empty string, and the destructor
throws for a non-null buffer, whose release needs the LibContext
allocator.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Report the process time at which sceAudioOutOutput or sceAudioOutOutputs
accepted the port's last block. A port that never output reports 0, and
waiting with a null pointer does not move the time.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The DCB variant threw "not implemented" while the ACB one wrote a
5-dword packet. Both now go through Agc::Command::WritePrimeUtcl2 and
the size query returns 20 bytes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Format through the shared wide formatter, truncate to the buffer and
return the full length, as C11 K.3.9.1.3 specifies. A null buffer or
format, a zero or oversized n, %n and a null %s argument are
runtime-constraint violations that return a negative value.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v_ceil/floor/trunc/rndne/fract/sqrt/rsq/rcp/rcp_iflag/log/exp/sin/cos
(f32 and f16) and v_frexp_mant_f32 left NaN, invalid, zero and infinite
results to the driver: signalling NaNs came back unquieted, lavapipe lost
the NaN sign and payload, invalid results were +NaN instead of -NaN, f32
sin/cos at whole and half cycles returned tiny values instead of +0, and
v_fract_f16 of a tiny negative rounded up to 1.0.
Adds an execution test for the 27 opcodes with expected values from
hardware; approximate ops are compared with tolerances from the Vulkan
precision table.
Co-Authored-By: Claude <noreply@anthropic.com>
A filter_type naming a subset of the PNG filters used only the first
filter of the mask, because stb's writer is either fully adaptive or
forced to one filter. Decoder::Png::Encode now takes the set of allowed
filter types, filters the rows and writes the chunks itself, and keeps
stb for deflate only. Output for the all-filters and single-filter
cases is unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SHA1RNDS4/NEXTE/MSG1/MSG2 with a memory source made `--to-intel` fail
the whole relink. The stub now spills a scratch xmm, loads the operand
into it with the unaligned load already used for SHA-256 and runs the
register-form lowering. The SHA1RNDS4 immediate is read after the SIB
byte and displacement. RIP-relative operands still fail: the stub runs
at a different address.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Return the kerning between two character codes at the render scale of
the font, the one set by sceFontSetupRenderScalePixel and
sceFontSetupRenderScalePoint, and fail with NOT_BOUND_RENDERER when no
renderer is bound. sceFontGetKerning keeps its behaviour and shares the
FreeType lookup.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The WriteAddressFromCounter_04_00 measure checks only the address and the
counter pair measure only the address and an even start, as in ampr_emu.
TechnicalDebt records that AMPR commands are larger than the console
records, which affects titles that pad with Nop to an exact offset, and
that the at-start flag of the 04_00 writes is ignored.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
s_setreg_b32 has no effect, so a read of the MODE round fields after it
wrote another mode still reports round to nearest even, the rounding the
recompiled code uses. The refused HW_ID test row is named as hardware
register 4, which has no name on gfx10.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sceAgcSetPacketPredication sets or clears the predicate bit of a type-3
packet header, and sceAgcSetRangePredication does so for every type-3
packet between two addresses, skipping type-2 fillers. The z-pass, bool
and disable predication size queries return the size of the
SET_PREDICATION packet sceAgcDcbSetPredication writes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
As in ampr_emu, a counter pair starts at an even counter, and the write
commands take a non-null, 8-byte aligned address; others return EINVAL.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sceAmprCommandBufferWaitOnAddress took (address, reference, mask,
compare) and WaitOnCounter (counter, reference, compare), and both read
the compare value as WAIT_REG_MEM (0 always, 1 <, 2 <=, 3 ==, ...).
ampr_emu, which replaces libSceAmpr for retail titles on the console,
has (address, reference, compare, flush) and (counter, reference,
compare, flush) with the SCE compare values (0 ==, 1 > unsigned,
2 < unsigned, 3 !=), so waits were decoded as other comparisons and
could block forever or pass early.
WriteAddressFromCounterPairOnCompletion takes one counter index, not
two, and WriteKernelEventQueueOnCompletion an int id and no user data.
Counter indices above 127, compare values above 3, flush values above 1
and misaligned wait addresses return EINVAL, as in ampr_emu.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Read the MPEG audio frame header and report the frame size, channel
count, samples per channel, bitrate and sample rate. The signature,
the result layout and the rate tables follow shadPS4's reimplementation
of the PS4 library. Requesting the original file length throws: that
lookup is not implemented.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ds_add/sub/rsub/inc/dec_u64, ds_min/max_i64/u64, ds_and/or/xor/mskor_b64,
ds_cmpst_b64/f64, ds_min/max_f64, their _rtn forms and ds_wrxchg_rtn_b64
threw in the decoder.
LDS is a 32-bit workgroup array, so the two dwords are read and written
under a lock dword placed after the guest LDS, which is cleared with a
workgroup barrier at entry. The lock is acquired and released in the same
loop iteration, so lanes of one subgroup cannot deadlock on it. Stages
whose LDS is a function variable update it directly. 64-bit GDS atomics
throw.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds the dialog to the silent-stubs list in docs/dev/TechnicalDebt.md, since it finishes without
showing anything. sceErrorDialogOpen now logs the error code and user id from the parameter
(offsets 4 and 8), like libSceMsgDialog logs its message, so an error a title would have shown
the player stays visible instead of disappearing.
sceAmprCommandBufferPushMarker, PushMarkerWithColor, PopMarker, SetMarker
and SetMarkerWithColor record a marker command, and the matching
sceAmprMeasureCommandSize functions return its size. The APR executor
skips markers, as it does a nop.
Signatures follow the ampr_emu reimplementation of libSceAmpr.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The mix level is a linear gain on the pad speaker port, 32768 being 0 dB.
A pad speaker port opens at 11626 (-9 dB). An unknown handle, a port of
another type and a level above 0 dB return the AudioOut error codes; a
negative level throws, as its effect is unknown.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two diagrams in docs/dev/ARCHITECTURE.md: how the relinker and the NID-patched system libraries produce a native program, and the graphics path from command buffers through the shader recompiler to Vulkan. README only gains a link.
Co-Authored-By: Claude <noreply@anthropic.com>
Any other field or value throws. The existing s_setreg_b32 no-op is
recorded under Functional technical debt instead of silent stubs.
Co-Authored-By: Claude <noreply@anthropic.com>
s_cmovk_i32 writes the sign-extended 16-bit immediate when SCC is set.
s_version is a no-op marker. s_setreg_imm32_b32 takes its value from a
literal dword and is ignored like s_setreg_b32; both are now listed as
silent stubs in TechnicalDebt.
Co-Authored-By: Claude <noreply@anthropic.com>
sceAudioPropagationSourceRender takes the system, an array of RenderInfo
descriptors and their count: PPSA21564 and PPSA21567 pass one RenderInfo
{0x010107d6, 0x30} per call, with the source handle at +0x10, its output
buffer at +0x18, the buffer size in bytes at +0x20 and the word 2 at
+0x28, once per audio grain for each propagated source.
Without acoustic propagation a source contributes nothing, so each
output buffer is zeroed for its size. Every RenderInfo is checked first
(descriptor, a live source of this system, a non-empty output), and a
count of 0 or a format word other than 2 throws, as neither has been
observed.
RSQRTPS and RCPPS are approximations whose low bits differ between Intel
and AMD. Intel returns 0x3F7FF000 for 1/sqrt(1.0), and two Newton-Raphson
steps on it settle on 0.99999994 instead of 1.0. PPSA21564 renormalises
its spring quaternions that way: an identity quaternion keeps w at
0.99999994 with a zero axis, its axis-angle conversion then normalises the
zero axis into NaNs, and the NaN bone poses reach keyframed physics bodies.
A NaN body later moves to an invalid broadphase cell and the game crashes
a few seconds into its hub level.
--to-intel now replaces the VEX.128 register forms with an out-of-line stub
that computes 1/sqrt(x) with SQRTPS and DIVPS (1/x with DIVPS), keeping
the upper half of the destination cleared and the scratch register intact.
A site with no room for the jump, including one followed by a branch
target or a RIP-relative instruction, keeps the native instruction and is
reported as kept instead of failing the relink.
The 22 exports used by PPSA21567 take the call shapes recovered from its
call sites (#481): destroys take the system and the object, attribute
setters take a count, SourceCreate takes only an output handle,
UnregisterMaterial only the material.
The system lives in the title's CPU memory (16-byte header, no GPU memory)
and its handle is that address; rooms, portals, sources and materials are
counter handles. Attributes are validated and have no effect; no rays are
requested and sources report no audio paths. Non-empty ray results, path
calculation and audio paths throw, SourceRender stays unimplemented, and
invalid input throws because no error code is known. Objects left when
their system is destroyed become unusable; their later destroy or
unregister is a no-op.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SHA1RNDS4, SHA1NEXTE, SHA1MSG1 and SHA1MSG2 passed through --to-intel
unchanged, so a relinked title that executes them faults on Intel CPUs
without SHA-NI. Their register forms are now lowered out of line with
SSE2 only through the shared stub builder; short sites share stubs via
MatchSequence. Memory forms fail the relink with the file offset, as for
SHA-256.
Co-Authored-By: Claude <noreply@anthropic.com>
Replace the decoder-less AvPlayer with a player that demuxes MP4 sources
with FFmpeg (opened by path or through the title's file replacement),
decodes H.264 and AAC on their own threads, and hands out NV12 frames and
interleaved 16-bit PCM in buffers from the title's allocators, presented
on a media clock that audio drives when it is enabled.
Both libSceAvPlayer and libSceAvPlayer.native are built from the same
sources and link the shared ffmpeg target. The struct size checks stay,
next to the types in SceTypes.hpp. ChangeStream and GetStreamInfoEx are
implemented; Init without allocators, StartEx, SetAvailableBandwidth,
SetLogCallback and negative trick speeds succeed as before and are listed
in TechnicalDebt. HLS sources throw.
guest_avplayer plays an embedded 6 KB MP4 (H.264 plus two AAC tracks).
pthread_barrier_init threw for any non-null attributes object, and no
function could create one. Add pthread_barrierattr_init, _destroy,
_getpshared and _setpshared after FreeBSD libthr, and let
pthread_barrier_init take the object.
PTHREAD_PROCESS_SHARED still throws in pthread_barrierattr_setpshared:
FreeBSD 9.0 rejects it and 11.0 accepts it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sceKernelSyncOnAddressWait parks the calling thread while the 32-bit word
at the address still holds the expected value, until
sceKernelSyncOnAddressWake releases it or the timeout expires.
sceKernelSyncOnAddressWake releases up to the requested number of threads
parked on the address, in arrival order.
The libc.prx bundled with SDK 9 titles imports both for its once
primitive, so those titles stopped at load with an unresolved import.
# Conflicts:
# docs/dev/TechnicalDebt.md
libkernel did not export sceKernelMapNamedFlexibleMemoryInternal, which
the libc bundled with SDK 9 titles imports. It now forwards to
sceKernelMapNamedFlexibleMemory: the mapping counts against the flexible
budget, gets the range name and is released by sceKernelMunmap. Older
libc builds call the public function at the same sites with the same
arguments and result handling.
The known callers pass flag 0x8000, whose meaning is unknown. It is
still rejected as an unsupported mapping flag and is recorded in
TechnicalDebt.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
and throws for any non-zero word after it. Its layout matches shadPS4's
ServiceThreadParams instead: an unknown first word (16), a set-priority flag
and a priority (256..767), a set-affinity flag and a 64-bit CPU mask at
offset 16. PPSA21564 passes 16, 1, 0x100, 1 and 0x1FFF, so it stops at
startup on main.
sceVideoOutOpen now validates each field and reads the mask only when its
flag is set, so a 16-byte param with both flags clear still works. The
priority and affinity are not applied, since the present and vblank threads
are host threads; this and the unknown first word are listed in the
technical debt.
scePngEncQueryMemorySize, scePngEncCreate, scePngEncEncode and
scePngEncDelete encode R8G8B8A8 and B8G8R8A8 images with a pitch into
RGB or RGBA PNGs using the shared encoder in core/Decoder/Png.
Decoder::Png::Encode takes optional compression level and filter
options so the encode parameters are honoured.
Co-Authored-By: Claude <noreply@anthropic.com>
All six exports are implemented: MP3 and AAC (ADTS or raw blocks) are
decoded with the bundled FFmpeg and ATRAC9 with LibAtrac9, one unit per
call, into interleaved S16 or float PCM, with the libSceAudiodec
validation and error codes. libSceAudiodec.native is built from the same
sources.
Co-Authored-By: Claude <noreply@anthropic.com>
Sign-in, web browser and player dialogs finish cancelled; the message dialog finishes at once;
NpAuth, entitlement consumption, reachability, account age and the NpUtility bandwidth test
report signed out; sceKernelMtypeprotect changes the protection (the memory type has no host
equivalent); the APR ForEach resolvers resolve every path and report each failure in its own
result entry. vswprintf's stub is dropped in favor of the existing wide-formatter
implementation, which already covers it on every platform.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Keyboard input follows libSceMouse: the video out event loop forwards SDL
key and focus events, whose scancodes are USB HID usages, and the library
keeps the pressed keys, modifiers and lock LEDs in a 16-entry history for
sceKeyboardRead and a snapshot for sceKeyboardReadState.
sceKeyboardGetKey2Char translates the 101-key arrangement; the 106-key
one throws and is listed as technical debt.
KeyboardData holds 16 key codes (96 bytes), not 6.
Co-Authored-By: Claude <noreply@anthropic.com>
sceSslGetCaCerts reports that no CA certificates are available and
sceSslFreeCaCerts clears the structure, in line with the library's
no-network behaviour. sceHttp2AbortRequest succeeds like
sceHttpAbortRequest. sceSslClose and sceSslGetSerialNumber keep throwing
and are listed as unknown signatures.
Co-Authored-By: Claude <noreply@anthropic.com>
In 64-bit mode a REX prefix only takes effect when it immediately
precedes the opcode; a REX followed by a legacy prefix or another REX is
ignored. The instruction decoder, the rewriter's reference classifier,
DecodedInstruction and the SSE4a, SHA-256 and CLZERO operand decoders
read legacy prefixes and then at most one REX. `48 F3 0F 2B 00`
(MOVNTSS) was therefore scanned as `[48 F3][0F 2B 00]` and kept, and
`48 67 0F 01 FC` lost its address-size prefix.
All of them now accept REX bytes among the prefixes and keep only one
that directly precedes the opcode. The converter's guard against
prefix-only fragments is removed, since the decoder no longer produces
them, and the TechnicalDebt entry describing the split is dropped.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Lower CLZERO out of line instead of failing the relink: the 64-byte line
containing rAX (EAX with 67h) is cleared with four MOVNTDQ stores of
zero, the same non-temporal, weakly ordered store. The line address is
masked in xmm0 so RFLAGS stays untouched; xmm0 and rcx are spilled below
the red zone. Short sites share stubs through MatchSequence. CLZERO with
LOCK, an FS/GS override, a 66/F2/F3 prefix or longer than 15 bytes fails
the relink.
The decoder splits a REX followed by another prefix into a separate
instruction, which would hide a prefix that changes what CLZERO or the
next instruction does. The converter now fails the relink when such a
prefix-only fragment directly precedes an AMD-only instruction or would
be moved into a stub as a trailing instruction.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replace MONITORX with a NOP and MWAITX with PAUSE in place, padded with
NOPs to the original length, instead of failing the relink. MWAITX may
return before its timer or a store to the monitored line, and without an
armed monitor it does not wait, so callers already re-check their
condition; the replacement takes that path every time.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Lower SHA256RNDS2, SHA256MSG1 and SHA256MSG2 (register forms) out of line
with legacy SSE2 instructions only, so relinked code no longer needs
SHA-NI. Consecutive short SHA-256 and SSE4a sites share one stub. The
SSE4a stub builder moves to StubBodyBuilder for reuse; IsShaNi now also
recognises SHA256RNDS2 (0F 38 CB). Memory operand forms fail the relink.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
feat: export the AMPR command buffer waits and writes, sceAgcFuseShaderHalves, sceAgcSetSubmitMode, sceNpSessionSignalingCreateContext and sceNetEpollAbort
Lower INSERTQ xmm1, xmm2 (F2 0F 79) out of line with SSE2 only instead of
failing the --to-intel relink. Length and index are read from bits 69:64
and 77:72 of the source; dst[127:64] is zeroed as on hardware.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>