mirror of
https://git.k-space.ee/arti/vt1200.git
synced 2026-10-30 12:03:54 +02:00
dwt/screenshot: --field even for the real unit's line-interleaved framebuffer; the capture now matches the glass
This commit is contained in:
1 parent
d6d6a7d44a
commit
71588e5405
3 files changed
+51
No files matched your search
Binary file not shown.
|
After Width: | Height: | Size: 8.2 KiB |
@@ -79,3 +79,31 @@ The emulator forces the **VR150** monitor position (`IP4-IP6` high, `0x70`).
|
||||
The real unit's rear switch selects the mode; if it is at another position the
|
||||
firmware may use a different fetch/pattern. Test: set the switch to position 1
|
||||
(VR150), power-cycle, grab again.
|
||||
|
||||
### Line-interleaved framebuffer — the "line doubled" answer
|
||||
|
||||
The real framebuffer is **line-interleaved**: even rows carry the image, odd
|
||||
rows carry a `0x55` mask in window areas (and `0xff` in the root). The display
|
||||
**doubles the even field**, so the odd rows are never shown. A linear `peek`
|
||||
reads both fields, which is why the first captures looked striped and
|
||||
"line doubled".
|
||||
|
||||
Evidence: in the Messages area every even row is `0xff`/text and every odd row
|
||||
is a uniform `0x55`; the root is `0xff` on both. After the owner set the
|
||||
background to 100% white and rebooted, the root is `0xff` everywhere and the
|
||||
TM's odd rows are still `0x55` — yet the screen is solid white. That proves the
|
||||
odd rows are a non-displayed mask.
|
||||
|
||||
Correct capture:
|
||||
|
||||
```sh
|
||||
python3 dwt/screenshot.py --host 100.103.100.103 \
|
||||
--field even --stretch 1280x1024 --out screen.png
|
||||
```
|
||||
|
||||
`dwt/evidence/real-unit-white2.png` is that capture and matches the glass.
|
||||
|
||||
This is a **display-fetch difference, not a CPU-emulation difference**. MAME's
|
||||
driver models a linear 1bpp framebuffer, so the emulator never shows the
|
||||
interleave; the real TMS34010 display controller is programmed for the doubled
|
||||
even field.
|
||||
@@ -87,6 +87,23 @@ def decode(data: bytes, width: int = WIDTH) -> bytearray:
|
||||
return out
|
||||
|
||||
|
||||
def field_double(gray: bytearray, w: int, h: int, parity: str) -> bytearray:
|
||||
"""Select one row parity and duplicate each row.
|
||||
|
||||
The real unit's framebuffer is line-interleaved: the image is on even rows
|
||||
and the odd rows carry a 0x55 mask; the display doubles the even field.
|
||||
Reading linearly shows both, which looks 'line doubled' and striped.
|
||||
"""
|
||||
off = 0 if parity == "even" else 1
|
||||
out = bytearray(w * h)
|
||||
for y in range(h):
|
||||
sy = (y // 2) * 2 + off
|
||||
if sy >= h:
|
||||
sy = h - 1
|
||||
out[y * w:(y + 1) * w] = gray[sy * w:(sy + 1) * w]
|
||||
return out
|
||||
|
||||
|
||||
def scale_nearest(gray: bytearray, sw: int, sh: int,
|
||||
dw: int, dh: int) -> bytearray:
|
||||
"""Nearest-neighbour scale; used for the real unit's 1024->1280 display."""
|
||||
@@ -165,6 +182,8 @@ def one(rd: exploit.RDebug, a: argparse.Namespace, tag: str) -> None:
|
||||
if a.repeat > 1:
|
||||
root, dot, ext = out.rpartition(".")
|
||||
out = f"{root}-{tag}.{ext}" if dot else f"{out}-{tag}"
|
||||
if a.field:
|
||||
gray = field_double(gray, WIDTH, rows, a.field)
|
||||
if a.stretch:
|
||||
dw, dh = a.stretch
|
||||
scaled = scale_nearest(gray, WIDTH, rows, dw, dh)
|
||||
@@ -205,6 +224,10 @@ def main(argv: list[str]) -> int:
|
||||
ap.add_argument("--stretch", type=parse_size, metavar="WxH", default=None,
|
||||
help="nearest-neighbour scale the raw canvas to WxH "
|
||||
"(the real unit displays 1024x1024 as 1280x1024)")
|
||||
ap.add_argument("--field", choices=("even", "odd"), default=None,
|
||||
help="select one row parity and double it; the real unit "
|
||||
"carries the image on even rows and a 0x55 mask on odd "
|
||||
"rows, and the display doubles the even field")
|
||||
ap.add_argument("--screen-width", type=int, default=SCREEN_W)
|
||||
ap.add_argument("--screen-height", type=int, default=SCREEN_H)
|
||||
ap.add_argument("--offset-x", type=int, default=OFFSET_X)
|
||||
|
||||
Reference in new issue
Block a user