<feed xmlns='http://www.w3.org/2005/Atom'>
<title>gbos.git/src/osk.asm, branch master</title>
<subtitle>gbos - a tiny Unix-flavored OS for the Game Boy Color (kernel, shell, coreutils in C, RAM filesystem)</subtitle>
<id>https://git.sl0p.foo/gbos.git/atom/src/osk.asm?h=master</id>
<link rel='self' href='https://git.sl0p.foo/gbos.git/atom/src/osk.asm?h=master'/>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/gbos.git/'/>
<updated>2026-07-18T19:50:22Z</updated>
<entry>
<title>term: SCY ring-scroll - scroll writes ONE map row; OSK toggle is 212 cycles</title>
<updated>2026-07-18T19:50:22Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-07-18T19:50:22Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/gbos.git/commit/?id=9b813f2a0eb8626f84489de0f55dc6da2ed22420'/>
<id>urn:sha1:9b813f2a0eb8626f84489de0f55dc6da2ed22420</id>
<content type='text'>
The BG map's 32 rows become a ring: logical row L always lives at map
row (wMapTop + L) &amp; 31, and SCY = (wMapTop + wViewTop)*8 places the
view. Scrolling bumps wMapTop, rebuilds the one new bottom line and
writes its single map row (map_row_one); the other 17 rows move for
free. The whole OSK view dance - shift the cursor above the keys,
restore the backlog on hide - is now term_view_update: one SCY write,
no map rewrite at all.

OSK safety: the keyboard lives on the WINDOW layer, which SCY never
moves. Stale ring rows can only appear under it: wViewTop = max(0,
wCurRow-14) &lt;= 3 is nonzero only while the OSK is visible, and the
window covers exactly those bottom 3 rows (WX=7, WY=120). Verified:
scroll + view shift + scroll-while-OSK-up + backlog restore all
pixel-correct via VRAM screenshots; full README demo passes.

term_scroll: 78.5k -&gt; 35.6k T-cycles (857k pre-optimization: 24x).
OSK toggle: 45k tilemap rewrite -&gt; 212 cycles.
Regenerated demo/gbos-demo.gif on the new renderer.
</content>
</entry>
<entry>
<title>term: 7-color terminal (per-glyph fg+bg) + ANSI escapes; colorize irc</title>
<updated>2026-07-18T18:41:27Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-07-18T18:41:27Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/gbos.git/commit/?id=9e7d5f6e5e01b7473b84bc3449d7f8e0f78e7045'/>
<id>urn:sha1:9e7d5f6e5e01b7473b84bc3449d7f8e0f78e7045</id>
<content type='text'>
Fano-plane palette scheme: the 7 colors map onto 7 CGB BG palettes so
any color pair shares one palette; a tile's palette is picked from the
set of colors its two cells need (tables generated by tools/gencolor.py).
Per cell a packed (bg&lt;&lt;4)|fg byte lives alongside the char shadow, and
the glyph blitter steers glyph/empty pixels to each cell's fg/bg color
slots via plane masks.

An ANSI-ish CSI parser (ESC [ .. m) drives it; usr/ansi.c demos it and
the irc client now renders hashed nick colors, status dimming and a
channel-activity bar.
</content>
</entry>
<entry>
<title>term: dark mode - black background, white text (OSK highlight inverts to match)</title>
<updated>2026-07-17T22:31:27Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-07-17T22:31:27Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/gbos.git/commit/?id=391833f8c611a206ed8d3f8483356a42e9890aa9'/>
<id>urn:sha1:391833f8c611a206ed8d3f8483356a42e9890aa9</id>
<content type='text'>
</content>
</entry>
<entry>
<title>term: compute the OSK view offset from the cursor row (keep input visible)</title>
<updated>2026-07-16T14:46:21Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-07-16T14:46:21Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/gbos.git/commit/?id=0db949c3a3ab07b264c21c3a15efea6b6055be0d'/>
<id>urn:sha1:0db949c3a3ab07b264c21c3a15efea6b6055be0d</id>
<content type='text'>
A fixed offset of OSK_ROWS pushed the cursor off the top of the screen when
there was little backlog (e.g. a fresh terminal: cursor at logical row 0 -&gt;
screen row -3, hidden). Now the offset is max(0, wCurRow - 14): 0 when the
cursor is within the visible area, growing only enough to keep the cursor
line at the bottom visible row (14) once the terminal has filled past it.

compute_offset (from wOskVisible + wCurRow) runs at the top of
term_write_tilemap; cursor_down re-runs the tilemap when the cursor changes
rows while the OSK is up; osk_toggle just re-runs it. Shared OSK_DOCK
constant in gbos.inc keeps term.asm and osk.asm in sync.

Verified: fresh terminal + OSK shows the input at row 0; filling past row 14
shifts the view to hold the input at row 14; full screen + OSK puts it at
row 14; toggle on+off is still lossless.
</content>
</entry>
<entry>
<title>term/osk: view-offset scroll region (lossless backlog on OSK toggle)</title>
<updated>2026-07-16T14:40:45Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-07-16T14:40:45Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/gbos.git/commit/?id=2f43a8851a89661b304edd9396677080dcb3e003'/>
<id>urn:sha1:2f43a8851a89661b304edd9396677080dcb3e003</id>
<content type='text'>
Replace the shrink-and-scroll region with a view offset. The terminal is
always 18 logical rows; term_write_tilemap maps screen row -&gt; logical row +
wViewTop (rows the OSK covers clamp to the cursor line). Showing the OSK
sets the offset to OSK_ROWS so the cursor line lands at row 14 (above the
keyboard) and hiding it sets the offset back to 0 - now purely a remap, so
nothing is scrolled off or destroyed. term_set_view replaces term_set_rows;
term_scroll/cursor_down are back to plain 18-row scrolling.

Result: full 18-row backlog when the OSK is hidden, a shifted 15-row window
when shown, and toggling is lossless (verified: OSK-shown view == baseline
rows 3..17, and toggle on+off == baseline exactly).
</content>
</entry>
<entry>
<title>term/osk: scroll region so the OSK never hides the input line</title>
<updated>2026-07-16T14:30:33Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-07-16T14:30:33Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/gbos.git/commit/?id=fe51f65be393161da81d6db6144418c97a8e0fe7'/>
<id>urn:sha1:fe51f65be393161da81d6db6144418c97a8e0fe7</id>
<content type='text'>
The terminal now has a variable usable height (wTermRows). term_scroll and
cursor_down operate within [0 .. wTermRows-1], and term_set_rows(n) shrinks
or grows that region, scrolling the cursor up into view when it would fall
outside. osk_toggle shrinks the terminal to the rows above the keyboard on
show (18 - OSK_ROWS = 15) and restores full height on hide, so the active
line is always visible just above the docked keyboard, and hiding the OSK
reclaims all 18 rows.

Also add c/count.c ("count [n]", default 25): prints n numbered lines to
observe/debug scrolling and the scroll-region behavior. Registered as
program id 21 / bank 23. Fixed the arg to read argv[0] (getargs returns the
string after the command name).

Verified: filling the screen then opening the OSK scrolls the latest line
to row 14 (visible) with the keyboard at 15-17; closing it restores rows
15-17; count N prints exactly N lines.
</content>
</entry>
<entry>
<title>osk: bind START to Enter (CR)</title>
<updated>2026-07-16T14:19:32Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-07-16T14:19:32Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/gbos.git/commit/?id=ef04a15c8dd3c18968b6fc134cdcf169069c385e'/>
<id>urn:sha1:ef04a15c8dd3c18968b6fc134cdcf169069c385e</id>
<content type='text'>
START now returns $0A regardless of cursor position, so you can submit a
command without navigating to the CR key. The CR key still works too.
</content>
</entry>
<entry>
<title>sh: handle backspace in readline; prompt is now '#'</title>
<updated>2026-07-16T14:17:02Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-07-16T14:17:02Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/gbos.git/commit/?id=30f3a65e2de99cdffd091289b4edb8e14be9032d'/>
<id>urn:sha1:30f3a65e2de99cdffd091289b4edb8e14be9032d</id>
<content type='text'>
readc() returning $08/$7F now drops the last char from the command buffer
(and emits one $08 so the terminal erases it) instead of storing the raw
byte. Previously "lz&lt;bksp&gt;s" left the buffer as "lz\x08s", so the command
"ls" was reported "not found" even though the screen showed "ls".
Also change the shell prompt from '$' to '#'.

osk: B button types the selected key SHIFTED (uppercase a-z). A types the
key as shown (lowercase/digit/symbol); B on a letter subtracts 32 for the
uppercase glyph (the font already has A-Z). Non-letters are unchanged.
</content>
</entry>
<entry>
<title>osk: wrap the cursor around all four edges</title>
<updated>2026-07-16T14:11:06Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-07-16T14:11:06Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/gbos.git/commit/?id=b565577fd371ea0a8d6255e61017e0e4f8f5b9e1'/>
<id>urn:sha1:b565577fd371ea0a8d6255e61017e0e4f8f5b9e1</id>
<content type='text'>
Left at column 0 wraps to the last column (and vice-versa); up at the top
row wraps to the bottom (and vice-versa). Makes reaching far keys quicker
- e.g. the Enter/space area is one UP away from the top row.
</content>
</entry>
<entry>
<title>osk: toggle-able on-screen keyboard on the window layer</title>
<updated>2026-07-16T14:07:01Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-07-16T14:07:01Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/gbos.git/commit/?id=a5557c75767f7201d5df8c6f95c162044072ef10'/>
<id>urn:sha1:a5557c75767f7201d5df8c6f95c162044072ef10</id>
<content type='text'>
A joypad-driven keyboard that costs zero permanent screen space: it lives
on the GB window layer, so SELECT just flips LCDC bit 5 (window enable) and
the terminal's background layer underneath is never disturbed.

- src/joypad.asm: read $FF00 with edge detection (wPadCur/Prev/New).
- src/osk.asm: 3x20 key grid (letters, digits, space, punctuation, plus
  Enter/Backspace) built once into spare bank-1 VRAM tiles (104+) and laid
  out on the $9C00 window map, docked to the bottom 3 rows. The highlighted
  key is a palette swap on its window attribute byte (CGB BG palette 1 =
  inverted), so moving the cursor is 1-2 attribute writes with no tile
  rebuilding. SELECT toggles, d-pad moves, A types.
- KGetc's console poll loop now polls the joypad and osk_handle each
  iteration; a key press returns its byte to the reader exactly like a
  serial byte, so the shell is oblivious to the input source.

Verified in the emulator (via --keys): SELECT shows the keyboard, the
highlight tracks the d-pad, and typing "ls"+Enter runs the command and
lists the files; a second SELECT hides it and reclaims the full 18 rows.

Known limitation: the OSK overlays the bottom 3 terminal rows, so if the
prompt has scrolled to the very bottom the current input line can be
hidden. A follow-up can add a scroll region (terminal uses rows 0-14 while
the OSK is up). Input over serial still works unchanged.
</content>
</entry>
</feed>
