diff --git a/docs/re/data/splash-dwell-presents-vs-hostclock.txt b/docs/re/data/splash-dwell-presents-vs-hostclock.txt new file mode 100644 index 00000000..cd24bb67 --- /dev/null +++ b/docs/re/data/splash-dwell-presents-vs-hostclock.txt @@ -0,0 +1,16 @@ +# The splash dwell, measured as a COUNT of presents and separately as a +# host-clock duration, in ONE capture. Same run, same game, both numbers. + +segment 0: presents 1..219 n= 219 host= 4.263s 51.4 presents/host-s -> 102.7 units/host-s +segment 1: presents 224..409 n= 186 host= 3.457s 53.8 presents/host-s -> 107.6 units/host-s + +# The corpus's three COLD BOOTS of the same two splashes, wall clock: +# publisher 4.297 / 4.604 / 4.370 s developer 3.508 / 3.503 / 3.366 s +# (boot-order-and-splash-dwell.md) +# THIS run, both splashes end to end: 409 presents in 7.831 s + +# A 30 fps guest presents at most 30 times per second of guest time, and +# Xenia's vsync limiter caps presents at 60/s. Any measured rate ABOVE 30 +# per host-second is therefore impossible for a vblank-paced 30 fps guest +# unless the emulator runs the guest faster than real time, which a +# 60 Hz-limited emulator cannot do. diff --git a/docs/re/dwell-corpus-does-not-falsify-120.md b/docs/re/dwell-corpus-does-not-falsify-120.md new file mode 100644 index 00000000..adb389d3 --- /dev/null +++ b/docs/re/dwell-corpus-does-not-falsify-120.md @@ -0,0 +1,96 @@ +# The dwell corpus does not falsify 120 units/s — it measures a different quantity + +**Status: ✅ the objection is answered, and NOT by a speed factor.** 2026-09-01. +Instrument: ⟨capture⟩, the hash capture, re-read for presents and host clock +together. Data: +[`data/splash-dwell-presents-vs-hostclock.txt`](data/splash-dwell-presents-vs-hostclock.txt). + +The port raised the right objection and named it load-bearing: + +> *"At 120 the publisher splash runs **2.125 s** and the developer **1.750 s**. +> Your own three cold boots measured them at 4.30 / 4.60 / 4.37 and 3.51 / 3.50 / +> 3.37. **120 and the dwell corpus cannot both be right in wall-clock seconds.**"* + +**They can, because they are not measuring the same thing.** + +--- + +## 1 — the dwell corpus is REPRODUCED, not contaminated + +I expected to find those runs slow and to argue they were contaminated the way +the 2.13 s route is. **They are not.** My capture reproduces them: + +| | this capture | `boot-order-and-splash-dwell.md`, three cold boots | +|---|---|---| +| publisher splash | **4.263 s** | 4.297 / 4.604 / 4.370 s | +| developer splash | **3.457 s** | 3.508 / 3.503 / 3.366 s | + +⚠️ **So the "they carry the emulator's speed factor" defence is NOT available and I +am not using it.** Four runs agree. Whatever those seconds are, they are stable. + +## 2 — the flaw is in the comparison, not in either measurement + +**`2.125 s` is the length of the publisher's declared ANIMATION. `4.3 s` is how +long the SCREEN is up.** They are different quantities and the screen is up longer +than its animation runs — it holds after the timeline ends. + +Measured in the same capture, as counts: + +| | presents | declared animation | animation in presents at 2 u/present | +|---|---|---|---| +| publisher | **219** | 255 units | 127.5 | +| developer | **186** | 210 units | 105.0 | + +The publisher is on screen for **219** presents and animates for about **128** of +them. The remaining ~91 are hold. At 120 units/s that is 2.13 s of animation +inside a 3.65 s screen — **consistent**, with the hold accounting for the rest. + +📌 So the falsifier compares a declared animation length against a measured screen +dwell. It would have found a "contradiction" at any units-per-second. + +## 3 — the decisive number, and it needs no speed factor at all + +> **51.4 presents per host-second** on the publisher splash, **53.8** on the +> developer. + +Xenia's frame limiter marks vblank at **60 Hz** and caps presents there +(`graphics_system.cc`, quoted in `guest-frame-rate-WITHDRAWN.md`). A guest paced +at 30 fps presents **every second vblank — at most 30 per second** — and no +emulator that is itself limited to 60 Hz can make it exceed that, because a slow +emulator can only make intervals *longer*. + +**51.4 > 30.** A 30 fps guest cannot produce this observation. A 60 fps guest can: +51.4 is 86 % of 60, i.e. dropping ~14 % of frames, which is exactly the vblank +histogram already measured (one vblank 71.7 %, two 24.6 %). + +**This is a count against a hard limit, not a duration against a fitted factor.** +It is the argument the 2.13 s reconciliation could not make, and it is why I am no +longer leaning on that one. + +## What this settles and what it does not + +✅ **60 units/s is refuted** — it requires a 30 fps guest, and the present rate +exceeds what a 30 fps guest can produce. +✅ **The dwell corpus stands**, in its own terms: those seconds are the screen's +dwell on this emulator, and they are reproducible. They were never a statement +about units per second and should not be read as one. +❔ **Whether Canary's cadence equals a real console's** is still an inference. The +present rate here is bounded by *Xenia's* limiter. A 360 also vblanks at 60 Hz, +which is why the inference is a short one, but it is an inference. +❔ **The clock origin.** Untouched. Every quantity on this page is a count or a +ratio, so a common offset survives all of it. + +⚠️ **Reach: still one boot for the hash ratio.** This page removes an objection to +120; it does not add a second observation of it. The port is right that a second +independent boot is what should move a shipped timeline, and I have not run one. + +## Refutation attempt, recorded per the adversarial duty + +**Target:** the port's falsifier above. **Result: REFUTED**, on the comparison +rather than on either measurement — both of which survive. Recorded with the part +I got wrong first: I initially segmented the capture's atlas eras as "both +splashes then the title" and briefly had a 2× discrepancy that would have let me +declare the dwell corpus contaminated. It was **my segmentation** that was wrong, +and the durations matching the corpus to 1 % is what exposed it. A convenient +answer that arrives from a segmentation you have not checked is the same trap as a +clean answer from an unguarded assumption.