docs(inventory): decompiled (Ghidra) read path; bottoms out at int 0x84/0xd2 services

This commit is contained in:
2026-07-06 23:20:56 +01:00
parent 961526b545
commit 038c38f029
+31
View File
@@ -183,6 +183,37 @@ explain why every raw `WL2:D` read returned no data — wrong paradigm.
trigger the laser and a good decode (green LED). Only *retrieving* the decoded
bytes is unsolved.
### Decompilation (Ghidra) — the read path
`SCANNER.DYL`/`SCANAPP` decompile cleanly in Ghidra (16-bit real-mode x86). The
app-level read routine (`FUN_858d`) is:
```c
obj->flags |= 8;
obj->[0x190] = 0;
FUN_8ce8(); FUN_8cd3(); FUN_8cd3(); // pre-read setup
obj->[0x194] = FUN_8d8e(); // acquire a read handle (int 0x84)
obj->[0x192] = FUN_8c8b(0,2,1,obj); // set up the read buffer (int 0x84; int 0xd2)
swi(0xcf)(); swi(0xcf)(); // config / enable ops on the channel
if (obj->[0x196] == 0)
obj->[0x196] = swi(0xcf)(); // P_FREAD -> decoded result stored at +0x196
else
swi(0xcf)(); // P_FCANCEL
```
The decoder-side helpers also decompile clearly: `FUN_7ae3` is the per-decoder
init (dispatch on `[channel+10]`; case 4 = the Symbol path, which calls
`FUN_6dc4` to build the `0xff 0xee …` command frame and writes the 11-byte param
block); `FUN_7aa4` is the trigger (two `int 0xCF` ops = the `6`/`7` we use).
**Remaining dependency:** the read acquires its handle and buffer through two
further OS services — **`int 0x84`** (handle/manager service, sub-function in
`AH`) and **`int 0xd2`** — and is woven into the app's object layout
(`obj+0x190..0x196`). Reproducing it in C needs those two services mapped (their
C wrappers / semantics) and the object fields understood. That is the next RE
target; Ghidra makes it tractable but it is still several layers, and any result
must be validated on the physical device (MAME cannot inject a scan).
To close it, one of:
1. The **Workabout MX C SDK** `SCANNER.DYL` header / OO category definition (what
`SCANAPP` was built against) — the clean answer, and likely the only practical