From 0ee93d36012cea0da789b8e7afacbb795baa833d Mon Sep 17 00:00:00 2001 From: "NathanNeurotic (Ripto)" <109461996+NathanNeurotic@users.noreply.github.com> Date: Mon, 3 Aug 2026 16:27:34 -0700 Subject: [PATCH 1/2] diag(pad): count read misses for the Debug HUD (#340 test instrumentation) The HUD 'PAD miss:' line has had no writers since the PR #328 revert -- it always rendered miss:0 regardless of hardware behavior. Count ready- state polls that produce no fresh sample so testers can see whether the priority-ceiling sio2man actually drives the miss rate to zero. No behavior change: diagnostics only, repeat handling untouched. Co-Authored-By: Claude Fable 5 --- include/pad.h | 4 ++-- src/pad.c | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/include/pad.h b/include/pad.h index 9be08f108e..5878fd2951 100644 --- a/include/pad.h +++ b/include/pad.h @@ -33,8 +33,8 @@ void unloadPads(); // Colors is on (gui.c / dia.c). Field semantics live with the writers in pad.c. typedef struct { - unsigned int readMisses; // total failed ready-state pad reads - unsigned int missBurst; // current consecutive-miss run, max across pads (polls) + unsigned int readMisses; // polls where at least one ready-state pad produced no fresh sample + unsigned int missBurst; // current consecutive run of such polls (0 when all ready pads read) unsigned int missBurstMax; // session peak of the above unsigned int pollMaxMs; // worst readPads() period this session unsigned int stateFlaps; // DISCONN -> ready reconnect edges seen diff --git a/src/pad.c b/src/pad.c index cdbe6379f2..369cfc9fc3 100644 --- a/src/pad.c +++ b/src/pad.c @@ -137,6 +137,13 @@ static u32 oldpaddata; // are SHOWN only when Settings -> Debug Colors is on. static pad_diag_t padDiag; +// Per-poll read outcome, reset by readPads() and filled in by each readPad(): how many pads were +// in a ready state, and how many produced a fresh sample. A poll where a ready pad produced no +// fresh sample is a read MISS (per-pad accounting: another pad reading fine does not hide it). +// Misses cluster under SIO2 load on real hardware; an emulator's pad never produces one. +static int pollPadsReady; +static int pollPadsRead; + void padGetDiag(pad_diag_t *out) { if (out) @@ -483,6 +490,7 @@ static int readPad(struct pad_data_t *pad) } if (isPadReadyState(pad->state)) { + pollPadsReady++; ret = padRead(pad->port, pad->slot, &pad->buttons); // port, slot, buttons if (ret != 0) { @@ -544,6 +552,7 @@ static int readPad(struct pad_data_t *pad) #endif if (padsRead > 0) { + pollPadsRead++; newpdata = readLeftJoy(pad, newpdata); pad->paddata = newpdata; @@ -817,9 +826,24 @@ int readPads() if (time_since_last > padDiag.pollMaxMs) padDiag.pollMaxMs = time_since_last; + pollPadsReady = 0; + pollPadsRead = 0; for (i = 0; i < pad_count; ++i) result |= readPad(&pad_data[i]); + // Debug-Colors diag: a read MISS is a poll where a ready pad produced no fresh sample -- + // counted per-pad, so another pad (or a PADEMU ds34) reading fine does not hide it. These + // counters feed the HUD "PAD miss:" line; they had no writers between the PR #328 revert + // and this change, so the HUD showed miss:0 regardless of what the hardware did. + if (pollPadsRead < pollPadsReady) { + padDiag.readMisses++; + padDiag.missBurst++; + if (padDiag.missBurst > padDiag.missBurstMax) + padDiag.missBurstMax = padDiag.missBurst; + } else { + padDiag.missBurst = 0; + } + // Stamp input activity AFTER the merge: any held button/stick re-arms the PAD_SELF_HEAL_IDLE_MS gate. if (paddata != 0) lastInputActivityMs = curtime; From 45d5469da52844a975be5bc463590c3725d1898b Mon Sep 17 00:00:00 2001 From: "NathanNeurotic (Ripto)" <109461996+NathanNeurotic@users.noreply.github.com> Date: Mon, 3 Aug 2026 16:36:17 -0700 Subject: [PATCH 2/2] test(sio2man): swap in the pre-rewrite 2023 sio2man -- DIAGNOSTIC ONLY, DO NOT MERGE (#340) Confirmation experiment requested by KrahJohlito: embed the threaded prio-24 sio2man extracted verbatim from uOPL's pinned 2023-09-09 CI container (import fingerprint thbase+thevent, no thsemap) in place of the SDK's current threadless freesio2.irx, everything else stock plus the Debug-HUD miss counters. If the D-pad drop/queue issue disappears on this build, the ps2sdk threadless sio2man rewrite (PR #709) is confirmed as the trigger on real hardware. Expected side effects: MMCE and MX4SIO menu features may break (they require the modern sio2man API) -- USB-boot test rig only. See modules/sio2man-2023/PROVENANCE-TEST.md. Co-Authored-By: Claude Fable 5 --- .gitignore | 2 ++ Makefile | 7 +++++- modules/sio2man-2023/PROVENANCE-TEST.md | 31 ++++++++++++++++++++++++ modules/sio2man-2023/freesio2-2023.irx | Bin 0 -> 5428 bytes 4 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 modules/sio2man-2023/PROVENANCE-TEST.md create mode 100644 modules/sio2man-2023/freesio2-2023.irx diff --git a/.gitignore b/.gitignore index a0571f7f5b..f90eb5399a 100644 --- a/.gitignore +++ b/.gitignore @@ -34,6 +34,8 @@ DETAILED_CHANGELOG !.clang-format !.clang-format-ignore !modules/debug/*.irx +# TEST-ONLY (#340): the vendored 2023-era sio2man diagnostic blob +!modules/sio2man-2023/*.irx # # Generated source files diff --git a/Makefile b/Makefile index 9e7939ce84..b69ed84ce5 100644 --- a/Makefile +++ b/Makefile @@ -836,7 +836,12 @@ $(EE_ASM_DIR)iomanx.c: $(PS2SDK)/iop/irx/iomanX.irx | $(EE_ASM_DIR) $(EE_ASM_DIR)filexio.c: $(PS2SDK)/iop/irx/fileXio.irx | $(EE_ASM_DIR) $(BIN2C) $< $@ $(*F)_irx -$(EE_ASM_DIR)sio2man.c: $(PS2SDK)/iop/irx/freesio2.irx | $(EE_ASM_DIR) +# TEST-ONLY BUILD (#340 diagnosis, DO NOT MERGE): embed the pre-rewrite 2023 sio2man (threaded, +# prio-24 worker) extracted from uOPL's pinned CI container instead of the SDK's current +# threadless freesio2.irx. Confirms/refutes the threadless-sio2man trigger on real hardware. +# EXPECTED side effects: MMCE and MX4SIO menu features may break (they need the new sio2man API). +# See modules/sio2man-2023/PROVENANCE-TEST.md. +$(EE_ASM_DIR)sio2man.c: modules/sio2man-2023/freesio2-2023.irx | $(EE_ASM_DIR) $(BIN2C) $< $@ $(*F)_irx $(EE_ASM_DIR)padman.c: $(PS2SDK)/iop/irx/freepad.irx | $(EE_ASM_DIR) diff --git a/modules/sio2man-2023/PROVENANCE-TEST.md b/modules/sio2man-2023/PROVENANCE-TEST.md new file mode 100644 index 0000000000..a5e2d239b5 --- /dev/null +++ b/modules/sio2man-2023/PROVENANCE-TEST.md @@ -0,0 +1,31 @@ +# modules/sio2man-2023 -- DIAGNOSTIC blob, never to be merged + +`freesio2-2023.irx` (5428 bytes, sha256 +`df200af667a3584a54da5096670ec5c347d3f787a5f47f133a0c29d08ac5eaa9`) is the PS2SDK `sio2man` +extracted VERBATIM from `ghcr.io/ps2dev/ps2dev@sha256:362bcd26b8bd94149c539f41749edb13facbb5b68a8b960e219fc079693cb95f` +-- the exact container digest uOPL's CI pins, image created **2023-09-09**, file dated +2023-09-04 inside the image. This is the PRE-rewrite module: its import table carries +`thbase` + `thevent` (dedicated priority-0x18 worker thread driven by event flags) and no +`thsemap`, unlike the post-PR#709 threadless build. + +## Purpose (issue #340) + +Confirmation experiment requested by KrahJohlito: if the D-pad drop/queue issue disappears +with ONLY this module swapped (everything else stock), the ps2sdk threadless sio2man rewrite +(PR #709, Jan 2025) is confirmed as the trigger on real hardware. This build exists to +produce that pass/fail datum -- it is NOT a fix. + +## Expected breakage -- do not report as bugs of this build + +- MMCE menu features (mmceman hooks the modern sio2man internals). +- MX4SIO menu browsing (post-PR#862 mx4sio_bd requires the modern sio2man). +- MX4SIO game launches (the same embed is loaded game-side for CORE_IRX_MX4SIO). + +Test on a USB-booted, USB-game setup only. + +## The actual fix candidate + +`feat/340-sio2man-priority-ceiling` -- the modern module rebuilt from pinned source with a +priority-ceiling bracket (same API, no feature breakage). If THIS diagnostic build fixes the +D-pad and the ceiling build does too, ship the ceiling; if this fixes it and the ceiling does +not, the ceiling theory is wrong and the delta between the two modules needs a deeper look. diff --git a/modules/sio2man-2023/freesio2-2023.irx b/modules/sio2man-2023/freesio2-2023.irx new file mode 100644 index 0000000000000000000000000000000000000000..a56214b710f45927e75787325d7869bc0a096c07 GIT binary patch literal 5428 zcmb_gO-N+f8U5;2*SsQTnWwTg{wr`#_TdiHPqS;iY zE^1+RStgnoE87=Qqq0_Owu5>R1f))t;+B^!&UK=zuF|8*$5+heOXk%C^|p2ImS^at zYZdll%)B6J2l2Fhd?jHwN^IAGb_ZyawzYc=h!10Ll&*KwWD{tYL|jv`Xi3;<*v&ux zFsOrF2b+UP!ETUU4?8704cnL90DHUA6*T%I*61fZjxS-u!Kam>`r}G&HE-T6YWdbt zU))M$XRXHh-?VZ)$Gjjvu(F%_l3l!2vJ1CTR=zia`PEq>z}Octheg`&dY1Gt$AZP3 zPGfoq>cdMh>kQ0pl=I?WOLy77Dg*WG`>&NStxf3RDeQr{`L=oVQ*`}&;QFZzwd;s~ zR(#Yi^U6M%)4bM#y6A5ed33o7U?Y#t9)&%n{Cvp<>YLJr93RBlV#aPF=Iy1%=HI~k zs2oGCrW|MXTJs3TS9W8L;*T(vqe^G6hjsL^j>WB1Ho#hr&ZWMC-IQIaoiD}gLXfiG zUimfh^%bju{m~-(irF7BU$c%>0vN?EA?CA6P2eFe;!18Gu|=pyEoxG)BSyUspcg)~ zSZC%N&}1~VDxcK^e^I_Jf=`|4>r?dgH#|?GKR#!>NQ>?Nf#+=RyYbXy@78{Z{3NpP zE!dZMM+H+`dX=w=w@Z>umd?@ho`1i})}voo!8+c~d*O#F^oI z!kBO_Zv4-}JWyxYX_);U<0)c1J3Mcmm&N>XcD!uT>kQJgi(Xp;Fl8$^TVBwD^{B^w zy$*dJJbagbjyZ!dbL~9DF`jEjJ;whM@o6CE$gD(j>lu! zSGngmGH*0-|8^U$rKcT-S`xDqJXwUdEFq#W)IqccLL;ph7?2kbVdHw;$ z!nyrOSUtBmo{xd&{34rkd`}#aKIc@%8vX)4^To4^^X~E9U|yMre`8%^mU6M&AG}X_ zk8=NW9MQhy+2Eexe&PP%{Te-chP{V|t1n<+dyJDwtR>;*dH`0Pb}7ha$<1Fm}R^w0J+dnShd z*_eUnF=gf}7sf16yJDRga>eH{E>HBUb<7UlbSoG$%TEsGh9|F$u>A!y?766fF&<*Z zCJNWa2Pa(akq!49sYb{)Y>V$*4qp;}85k*5_m>+V9FDXa6zdBcg_nh|0?%r2Jky2T z*d!jXUykQ&48Lj?Mu!HcN1n%=H@`4;$jnhb@l9e5Qrk6J{KAFNQ<=q+3p?j zJ>sv5$9E1FKOjCQJ}-Vs{H*u|@pyMQ{X62<#czn;6u&EePyD|4L-CKrKaqbd{|Lx& zr?8U52B4c4kn?I5-zL6Ye2@5E@qOa^#plG2iqDH*5ML6%Dt=#hEKFiBZd}3!VIXV~ z_6U1{9CtsE%Z#@w|iZv9kD8@$2F@#NQXcBYs!>zIfg>_}C-yPsAUK=ioX1I{e{$(?G^Ih!4c` zJ|v$J-zL9Zem9Wqd&FNA-!DEVepGy3JnvZQE{HFQ=RHXNws_u&^bh6pex#oQf^v5y z{Wkf$SLyf5=N(IbR6g%p`UUyCd+8VD7jTc_$l8o>R#+6y3m1eX;gWD!cw2Z!SQf4b z?+RCiYr=KmhHz83Exa#$ApDbXN4P886YdKSgb#&}gonb%!Y9Hb;js|^KyrCW2$Mqm z0CIdvST9Tq8-%_v5H<^2gc)I*uw9rHb_lzL?+AN@SB1U8K4HI*??0}qwNC$Ryf8Qf zEL;n5G_uAfr^Y99)_QFu-&z=%DZrY{4HgDNCbWj8r>XL}%GVK9#49oi=KtO->%%xEJf5Qj5jLydE&~e`1=La4(FL|KyL<(@bx8J8zAj(p;GU4RO&oNZGjyX z_RHsQ2=PjA?`~F)a?l*(~EwUe0o*nAZ{+^I}Yv_~n^}d_O)F*N*XZM?t_S?mx1o2d@AC literal 0 HcmV?d00001