From 2f43a8851a89661b304edd9396677080dcb3e003 Mon Sep 17 00:00:00 2001 From: user Date: Thu, 16 Jul 2026 16:40:45 +0200 Subject: term/osk: view-offset scroll region (lossless backlog on OSK toggle) Replace the shrink-and-scroll region with a view offset. The terminal is always 18 logical rows; term_write_tilemap maps screen row -> 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). --- src/osk.asm | 10 +++---- src/term.asm | 87 +++++++++++++++++++++--------------------------------------- 2 files changed, 35 insertions(+), 62 deletions(-) (limited to 'src') diff --git a/src/osk.asm b/src/osk.asm index a34a863..5e316e3 100644 --- a/src/osk.asm +++ b/src/osk.asm @@ -236,9 +236,9 @@ osk_toggle:: ld [wOskVisible], a or a jr z, .hide - ; show: shrink the terminal to the rows above the keyboard, then enable window - ld a, 18 - OSK_ROWS - call term_set_rows + ; show: shift the view up so the cursor line clears the keyboard + ld a, OSK_ROWS + call term_set_view ld a, [rLCDC] or %00100000 ld [rLCDC], a @@ -247,8 +247,8 @@ osk_toggle:: ld a, [rLCDC] and %11011111 ld [rLCDC], a - ld a, 18 ; restore full-height terminal - call term_set_rows + xor a ; view unshifted -> full 18-row backlog + call term_set_view ret ; movement with wrap-around; each moves the highlight diff --git a/src/term.asm b/src/term.asm index 8105285..fb6e870 100644 --- a/src/term.asm +++ b/src/term.asm @@ -36,7 +36,7 @@ DEF wRT_tcol EQU $D58B DEF wRT_cL EQU $D58C DEF wRT_cR EQU $D58D DEF wScratch EQU $D58E -DEF wTermRows EQU $D58F ; usable terminal rows (18 normally, fewer under the OSK) +DEF wViewTop EQU $D58F ; view offset: screen row maps to logical row + this DEF wAssign EQU $D590 ; assign[18]: screen row -> line-slot ($D590-$D5A1) DEF CUR_L EQU $E0 ; cursor underline, left cell (3px) @@ -82,8 +82,8 @@ term_init:: ld [wCurCol], a ld a, 1 ld [wCursorOn], a - ld a, TROWS - ld [wTermRows], a ; full height until the OSK shrinks it + xor a + ld [wViewTop], a ; view starts unshifted (all 18 rows) ; clear the buffer (all slots) to spaces ld hl, TERM_BUF @@ -153,13 +153,18 @@ term_write_tilemap:: ret ; helper: C = screen row -> DE = assign[C]*20, HL = $9800 + C*32 .slot20 - ld a, c + ld a, [wViewTop] + add c ; logical row = screen row + view offset + cp TROWS + jr c, .lok + ld a, TROWS-1 ; rows the OSK covers clamp to the cursor line +.lok add LOW(wAssign) ld l, a ld a, HIGH(wAssign) adc 0 ld h, a - ld a, [hl] ; L = assign[row] + ld a, [hl] ; L = assign[logical row] ld l, a ld h, 0 add hl, hl @@ -435,38 +440,24 @@ term_redraw:: ; term_scroll - scroll up one line: rotate assign[], blank+build the new bottom ; line, rewrite the tilemap. ; ----------------------------------------------------------------------------- -; term_scroll scrolls only within the active region [0 .. wTermRows-1], so the -; rows the OSK covers are left alone. +; term_scroll - scroll all 18 logical rows up one; the new line becomes logical +; row 17. The view offset decides where that lands on screen, so toggling the +; OSK never destroys backlog. term_scroll:: - ld a, [wTermRows] - dec a - ld [wScratch], a ; wScratch = bottom row of the region ld a, [wAssign] - ld b, a ; B = freed line-slot (assign[0]) - ; rotate assign[1..bottom] down into assign[0..bottom-1] - ld a, [wScratch] - or a - jr z, .norot - ld c, a ; count = bottom + ld [wScratch], a ; freed line-slot ld hl, wAssign+1 ld de, wAssign + ld b, TROWS-1 .rot ld a, [hl+] ld [de], a inc de - dec c + dec b jr nz, .rot -.norot - ; assign[bottom] = freed ld a, [wScratch] - add LOW(wAssign) - ld l, a - ld a, HIGH(wAssign) - adc 0 - ld h, a - ld [hl], b + ld [wAssign + TROWS-1], a ; clear buffer[freed] to spaces - ld a, b ld l, a ld h, 0 add hl, hl @@ -483,12 +474,11 @@ term_scroll:: ld [hl+], a dec b jr nz, .clr - ; rebuild the region's bottom line + ; rebuild logical row 17 ld c, 0 .build push bc - ld a, [wScratch] - ld b, a + ld b, TROWS-1 call render_tile pop bc inc c @@ -498,41 +488,24 @@ term_scroll:: call term_write_tilemap ret -; cursor_down - advance the cursor row, scrolling the region if it overflows. +; cursor_down - advance the cursor row, scrolling when it runs past the bottom. cursor_down: ld a, [wCurRow] inc a - ld b, a - ld a, [wTermRows] - cp b - jr z, .scroll - jr c, .scroll ; candidate >= wTermRows - ld a, b - ld [wCurRow], a - ret -.scroll + cp TROWS + jr c, .ok call term_scroll - ld a, [wTermRows] - dec a + ld a, TROWS-1 +.ok ld [wCurRow], a ret -; term_set_rows - A = new usable row count. Scrolls the cursor up into the new -; region if it would fall outside, then applies the new height. -term_set_rows:: - ld e, a -.loop - ld a, [wCurRow] - cp e - jr c, .done ; cursor already inside the new region - call term_scroll ; scroll (old wTermRows still in effect) - ld hl, wCurRow - dec [hl] - jr .loop -.done - ld a, e - ld [wTermRows], a - ret +; term_set_view - A = view-top offset. screen row -> logical row + A. 0 shows all +; 18 rows; OSK_ROWS shifts the view up so the cursor line clears the keyboard. +; No content is scrolled/lost - just remapped. +term_set_view:: + ld [wViewTop], a + jp term_write_tilemap ; ----------------------------------------------------------------------------- ; term_putc - A = character. Print at the cursor, advance, handle \n \r \b. -- cgit v1.3.1-sl0p