<feed xmlns='http://www.w3.org/2005/Atom'>
<title>rs-dos/rsnix/src/vt.rs, branch qemu</title>
<subtitle>Simple, kernel-only, 64bit OS, early stage.
</subtitle>
<id>https://git.2137697.xyz/rs-dos/atom?h=qemu</id>
<link rel='self' href='https://git.2137697.xyz/rs-dos/atom?h=qemu'/>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/rs-dos/'/>
<updated>2026-08-21T01:32:07Z</updated>
<entry>
<title>wm: flush terminal window content on gaining focus</title>
<updated>2026-08-21T01:32:07Z</updated>
<author>
<name>salmonik</name>
<email>salmonik@tuta.io</email>
</author>
<published>2026-08-21T01:32:07Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/rs-dos/commit/?id=956093be4f3b7a0fe86a523e5f9d9e74b9a77e59'/>
<id>urn:sha1:956093be4f3b7a0fe86a523e5f9d9e74b9a77e59</id>
<content type='text'>
focus() only composites the title bar — the window content stays
stale until the next write.  Call term.flush() on Focus(true) so
the full window is re-composited immediately when switching to it.
</content>
</entry>
<entry>
<title>wm: F1 spawns a windowed shell — real shell, not a duplicate</title>
<updated>2026-08-20T11:47:10Z</updated>
<author>
<name>salmonik</name>
<email>salmonik@tuta.io</email>
</author>
<published>2026-08-20T11:47:10Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/rs-dos/commit/?id=cb17c57452ccd2ccca77e99098402d4b9f61c0a5'/>
<id>urn:sha1:cb17c57452ccd2ccca77e99098402d4b9f61c0a5</id>
<content type='text'>
Architecture:
- vt: ACTIVE terminal redirect — when set, all gop_print!/put_char/write_str
  go there instead of HOME.  Terminal::from_buffer() renders into a
  WM-owned pixel buffer.
- tty: read_line_from_queue() — canonical-mode line input from the task's
  own message queue (TaskMsg::Key).  Returns None on Close.
- shell: run_windowed() — same shell as the console but reads from the
  message queue.  Returns on ^D or window close.
- wm: F1 calls SPAWN_TERMINAL_CB (set by rsdos).  No shell logic in the WM.
- rsdos: terminal_task callback + terminal_entry task — creates a 640x400
  chrome window, wires up Terminal::from_buffer, sets ACTIVE, runs
  shell::run_windowed(), cleans up on exit.
- shell: 'term' debug command that invokes the callback directly and
  logs each step to serial.
</content>
</entry>
<entry>
<title>wm: integrate home terminal as window 0 + fix console focus after close</title>
<updated>2026-08-19T16:46:35Z</updated>
<author>
<name>salmonik</name>
<email>salmonik@tuta.io</email>
</author>
<published>2026-08-19T16:46:35Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/rs-dos/commit/?id=09a44f15678f27dd3d07f90e9ed0e71cf0e771ff'/>
<id>urn:sha1:09a44f15678f27dd3d07f90e9ed0e71cf0e771ff</id>
<content type='text'>
- wm rewrite: chrome flag per window, create_home_window for the
  console (window 0, chrome-less, bottom-pinned, never closed),
  composite_rect fills desktop background then blits windows bottom-to-top,
  draw_window_intersect handles chrome-less windows, hit_test returns
  Content for chrome-less, destroy/move_window no-op for id 0.

- vt: add window_params() so main.rs can wire the Terminal to wm window 0.

- main.rs: create home terminal window 0 and attach Terminal after wm::init().

- Focus fix: focus(0) now stores CONSOLE sentinel (not raw 0) so
  focused() returns None when the home terminal has focus. Without this,
  closing a GUI window left FOCUSED=0, which tty::poll_key() interpreted
  as 'a GUI app has focus', spinning forever and swallowing all keyboard
  input.
</content>
</entry>
<entry>
<title>vt → per-instance Terminal rendering into a pixel buffer</title>
<updated>2026-08-17T18:28:48Z</updated>
<author>
<name>salmonik</name>
<email>salmonik@tuta.io</email>
</author>
<published>2026-08-17T18:28:48Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/rs-dos/commit/?id=7bd3459f4f8bae69509202e5aa0dbd04a42c656f'/>
<id>urn:sha1:7bd3459f4f8bae69509202e5aa0dbd04a42c656f</id>
<content type='text'>
- Refactor vt.rs into a per-instance Terminal struct (owned cell/rendered
  grids, cursor, ANSI parser, scroll state), rendering glyphs into a
  caller-owned pixel buffer with dirty-region blitting
- Add gop buffer primitives (buffer_glyph_px, buffer_shift_up) and keep
  the legacy vt:: API as thin wrappers around the home terminal
- Remove the now-obsolete scroll hook and shadow scroll path
- Home terminal renders into its own buffer; window_id stays None until
  the WM integration lands
</content>
</entry>
<entry>
<title>wm: keep windows in place when the console scrolls beneath them</title>
<updated>2026-08-17T17:08:47Z</updated>
<author>
<name>salmonik</name>
<email>salmonik@tuta.io</email>
</author>
<published>2026-08-17T17:08:47Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/rs-dos/commit/?id=f4fab5a2b06c37df08d2d315bcb44d15af1786a4'/>
<id>urn:sha1:f4fab5a2b06c37df08d2d315bcb44d15af1786a4</id>
<content type='text'>
The console's batched scroll (gop::shift_up_n) shifts the whole shared
shadow, which dragged any composited window pixels up with it.  Add a
scroll hook so the window manager re-composites every visible window
after a console scroll, restoring them at their fixed positions.
</content>
</entry>
<entry>
<title>Windowed GUI: wm module, input routing, and the paint app</title>
<updated>2026-08-17T16:56:04Z</updated>
<author>
<name>salmonik</name>
<email>salmonik@tuta.io</email>
</author>
<published>2026-08-17T16:56:04Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/rs-dos/commit/?id=5558e3509d020a0e021a77f0617044497b2f2aee'/>
<id>urn:sha1:5558e3509d020a0e021a77f0617044497b2f2aee</id>
<content type='text'>
- Add the wm window-manager facility per ADR 0004: overlapping
  pixel-surface windows, damage-rectangle compositing, WM-drawn title
  bar, focus/minimize/close, and F1-F4 keybindings
- Add gop shadow compositing primitives and vt::repaint_region so the
  console stays layer 0 beneath windows
- Route mouse (absolute coords, press/release edges) and keyboard
  (focus-aware input pump) to the focused window
- Add the rspaint drawing-program crate (pen, 8 colors, clear) and shell
  draw/windows/restore commands
- Extend TaskMsg with AppMouse/Focus/Close and document the design in
  CONTEXT.md + ADR 0004
</content>
</entry>
<entry>
<title>USB2/1.1 (EHCI/UHCI) drivers + real-hardware bring-up hardening</title>
<updated>2026-08-17T12:53:52Z</updated>
<author>
<name>salmonik</name>
<email>salmonik@tuta.io</email>
</author>
<published>2026-08-17T12:53:52Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/rs-dos/commit/?id=be868a43185826b02bf6d091019bb779678525bb'/>
<id>urn:sha1:be868a43185826b02bf6d091019bb779678525bb</id>
<content type='text'>
- Add polled EHCI (USB2) and UHCI (USB1.1) host-controller drivers with
  HID boot mouse support, wired into cursor polling and the 'usb' shell cmd
- Add USB Legacy ownership handoff (claim_usb_legacy) plus config_write_byte
- Harden boot: verify the PIT/timer ticks before shell entry, EOI stray
  interrupts in the LAPIC to stop interrupt storms, bound PS/2 controller
  waits, and INTx-disable AHCI (polled driver)
- Add boot stage markers, klog screen echo, and QR lock; scheduler
  mark_shell_running; NO_USB stopgap to keep BIOS USB-Legacy input alive
- alloc_pages_above for DMA buffers that must avoid low conventional memory
- Expand DEBUG_NOTES with EHCI/QEMU bring-up findings
</content>
</entry>
<entry>
<title>v0.5.9: fix OptiPlex heap crash — EBS retry must not rebuild the free list</title>
<updated>2026-08-03T23:44:05Z</updated>
<author>
<name>salmonik</name>
<email>salmonik@tuta.io</email>
</author>
<published>2026-08-03T23:44:05Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/rs-dos/commit/?id=3e2261d83176752f3ea21e0c97f330b4c1757437'/>
<id>urn:sha1:3e2261d83176752f3ea21e0c97f330b4c1757437</id>
<content type='text'>
Root cause: on real hardware SetMode can invalidate the pre-captured
ExitBootServices map key, so EBS fails and the retry refreshed the map
via capture_memory_map -&gt; init_heap, which REBUILT the free list from
the raw map and wiped the allocation state of every pre-EBS live object
(the display shadow and the vt grids). Their spans became free while
still live, later allocations carved inside the shadow, and the display
writes clobbered them — zeroed back-pointers (family A ptr=0x404443e0
block=0x0) and gray glyph pixels (family B 0xaaaaaa00aaaaaa = 0x00AAAAAA
= PALETTE[7] fg-7 text colour, not a firmware scrub).

Fix: refresh_and_exit now re-captures the map and returns a fresh EBS
key without rebuilding the free list (refresh_map_key); the free list is
the authoritative live-allocation state. Verified in QEMU under a forced
EBS failure (SIMULATE_EBS_FAILURE test hook): verify ok, probe NOT free,
flhead outside the shadow — identical to a clean boot, and the full
shell sequence is crash-free.

Also: removed the crash-family debug markers from the screen (boot-time
heapdbg lines, vt verify marker, shadow marker) — the vt grid self-check
stays serial-only. Version 0.5.8 -&gt; 0.5.9.
</content>
</entry>
<entry>
<title>v0.5.8: heap-free QR encoder + crash-dump QR on framebuffer</title>
<updated>2026-08-03T00:23:35Z</updated>
<author>
<name>salmonik</name>
<email>salmonik@tuta.io</email>
</author>
<published>2026-08-03T00:23:35Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/rs-dos/commit/?id=9fde94d068f87b34e0bc6bfa48388d89bb54f1e4'/>
<id>urn:sha1:9fde94d068f87b34e0bc6bfa48388d89bb54f1e4</id>
<content type='text'>
Real hardware has no serial console, so a kernel crash only leaves a
frozen screen.  Every dump_lines() report now also renders the crash
text as a scannable QR below the white-on-red band (photograph the
screen instead of relaying text).

- rsnix/src/qr.rs: from-scratch no_std/no_alloc byte-mode QR encoder
  (EC-L, v1..v40, .bss statics only — safe on the fault path):
  RS over GF(256), codeword interleave, zigzag placement, 8 masks with
  N1-N4 penalty auto-selection, format/version info.
- gop.rs: dump_qr() joins dump lines into a static buffer, truncates
  with '...' at the v40-L capacity, encodes, and renders centered
  black-on-white with a 4-module quiet zone.
- tools/qrcheck: host harness (embedds qr.rs) + qrcheck.py cross-check
  against segno's placement primitives.  Verified bit-exact: 12
  versions x 8 masks forced, plus auto-mask choice matches segno's
  penalty evaluation.  Caught 3 encoder bugs (multi-block interleave
  offsets, transposed version info, mask eval ordering).
- QEMU e2e: page-fault dump screendump decodes via zbarimg, content
  matches the serial log line-for-line.
- test-msg.sh and test-fault.sh both PASS; debug+release 0 warnings.
</content>
</entry>
<entry>
<title>v0.5.7: fix vt verify content check — expect BLANK (0x70020), not zero</title>
<updated>2026-08-02T23:34:31Z</updated>
<author>
<name>salmonik</name>
<email>salmonik@tuta.io</email>
</author>
<published>2026-08-02T23:34:31Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/rs-dos/commit/?id=d5f41d6e057300c82b83653b4afadeffb45a9f19'/>
<id>urn:sha1:d5f41d6e057300c82b83653b4afadeffb45a9f19</id>
<content type='text'>
The pre-verify 0x70020 'mystery' was a debug artifact, not corruption:
BLANK = {ch:32, fg:7, bg:0} = raw 0x70020, and vec![BLANK; n] fills both
grids with it at init.  The old check compared cells against 0 and its
probe loop break-ed on the first non-zero cell, so probes 1-3 stayed at
their zero-initialized slots — c=[0x70020,0,0,0] was bogus on every
healthy boot.  A full-grid dump proves QEMU grids are 100% BLANK at
shell entry (nz=3700 blank=3700).

Fix: probes compare against blank_raw (0x70020), record all four values
(no early break), probe both cells and rendered, and add a full-grid
nz/blank summary line.  The OptiPlex firmware 0x00AAAAAA scrub remains
cleanly distinguishable (scrub != blank).

Markers: the shell banner occupies grid rows 0-1 and the prompt row 2
(proven by screendump), and a stale crash.log replays at rows 2+, so the
shadow and vt markers moved to the bottom of the screen via the new
gop::text_rows()/bottom_row(off) helpers instead of rows 1-2.

QEMU verified: verify: ok every boot; test-msg + test-fault PASS; debug
and release builds 0 warnings.
</content>
</entry>
</feed>
