From cad35e85dddde3a1e1cac8293b21987ccd27a46a Mon Sep 17 00:00:00 2001 From: QIU SHENGMING Date: Fri, 2 Oct 2026 11:54:33 +0800 Subject: [PATCH] Round 27: a correctly placed first action still does not run; the fitting variable is code size The game's app_main was given a fill-every-byte-and-blit first act. Inserted before A = api; it dereferenced an unset pointer and faulted (my own bug, that run is void); moved after the assignment (source +199 B, app 2508 B) the panel still never leaves 43 over 48 s, so the blit never happens, while a 300-byte app doing the same fill-and-blit paints 596 non-zero bytes. The variable that fits every measurement is the app's code size rather than its blob size: a 3028-byte blob with a few dozen bytes of code runs and can call print_tiny, display_clear and get_key; Phases at 372 bytes of code runs; Ladder at 544 dies; Minesweeper at 2400+ dies with its first instruction having no effect. Next: sweep a trivial app at 400, 512, 600, 800 and 1200 bytes of code through the handover to find where the panel stops changing. --- AGENTS.md | 23 +++++++++++++++++++++++ AGENTS.zh-CN.md | 19 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index 30bb6a2..7b2bc57 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1060,6 +1060,29 @@ whoever clicks through the page: whatever row the cursor lands on, MENU starts t launching the game and getting out of it -- are now the things to measure next, along with why the app returns instead of staying up (round 17 saw it paint a full frame from this same artifact). +**Round 27: an app's first action, placed correctly, still does not run -- and the pattern that fits is code size.** + +The user's screenshot is the state this file already describes: the app menu's title (drawn in the 8-bit font, +so F4HWN reads as F4HHH) over one blank white box, which is the launcher's own frame with nothing of the app +on the glass. + +To separate "the app is not entered" from "the app draws nothing", the game's app_main was given an +unmistakable first act: fill every framebuffer byte with 0xFF and blit. The first attempt inserted it before +`A = api;`, so it dereferenced an unset pointer and faulted -- my own bug, and it invalidated that run. Moved +after the assignment (source +199 bytes, app 2508 bytes) the panel still never leaves 43 over 48 s, so the +probe's blit never happens. A 300-byte app doing exactly that fill-and-blit does paint (596 non-zero bytes), +and the loader has been seen reading the header and exactly code_size bytes. + +Taking every measurement together, the variable that fits is the app's **code** size rather than its blob +size: a 3028-byte blob whose code is a few dozen bytes runs and can call print_tiny, display_clear and +get_key; Phases at 372 bytes of code runs; Ladder at 544 bytes dies; Minesweeper at 2400+ bytes dies with +its first instruction having no effect. Round 8's ladder said the same thing and was set aside because a +big blob that calls nothing survived -- which only shows that blob size alone is not the limit. + +So the next round has a quantitative target: build the same trivial app with a code body of 400, 512, 600, +800 and 1200 bytes, drive each through the handover, and find where the panel stops changing. That is a +ladder in the one variable that has not been swept. + That is where the next round starts: the same alternating-spin shape, one call at a time. trace. That is a much better place to be than the emulator mystery this started as. diff --git a/AGENTS.zh-CN.md b/AGENTS.zh-CN.md index b7848a9..a8788a2 100644 --- a/AGENTS.zh-CN.md +++ b/AGENTS.zh-CN.md @@ -858,6 +858,25 @@ PC 追踪**跨过交接点**采样,而不是在它之后。 启动游戏。接下来要量的两件事是「启动游戏」与「从游戏里出来」,以及**它为什么退回来而不是留在上面**(第 17 轮用同一份产物 量到过它画出完整一帧)。 +**第 27 轮:把应用的第一个动作放对位置之后它仍然不执行 —— 而能解释一切的模式是「代码量」。** + +用户那张截图正是本文件已经描述过的状态:应用菜单的标题(8 位像素字体,于是 F4HWN 看起来像 F4HHH)下面是一整块 +空白白框 —— 那是启动器自己的画面,玻璃上没有任何属于应用的东西。 + +为了把「应用没被进入」与「应用什么都没画」分开,给游戏的 app_main 加了一个无法误认的第一个动作:把每个帧缓冲 +字节填成 0xFF 再 blit。第一次插在了 `A = api;` **之前**,于是解引用了一个未设置的指针并崩溃 —— 这是我自己的 +bug,也让那次运行作废。改到赋值之后(源码 +199 字节、应用 2508 字节),面板在 48 秒里始终停在 43,说明探针的 +blit **从未发生**。而一个 300 字节的应用做**同样**的填满加 blit 是能画的(596 个非零字节),加载器也已被看到读出 +头部与恰好 code_size 字节。 + +把所有测量放在一起,能对上的变量是应用的**代码量**,而不是 blob 大小:一个 3028 字节、代码只有几十字节的 blob +能跑、还能调用 print_tiny、display_clear、get_key;Phases 的代码 372 字节能跑;Ladder 的 544 字节死;Minesweeper +的 2400+ 字节死,而且它的第一条指令毫无效果。第 8 轮那份阶梯说的也是同一件事,当时因为「一个很大的、什么都不调用 +的 blob 活着」而被搁置 —— 而那只能说明**blob 大小本身不是限制**。 + +所以下一轮有了一个定量的目标:用同一个平凡应用做出代码体 400、512、600、800、1200 字节的版本,一个个走过交接点, +找出屏幕在哪一档开始不再变化。这是在**唯一还没被扫过的那个变量**上做阶梯。 + 下一轮就从这里开始:同样的「自旋 + 单调用」形状,一次只放一个调用。 进去、读同一份 trace。比起一开始那个模拟器悬案,这是好得多的处境。