diff options
| author | user <user@clank> | 2026-07-16 16:30:33 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-07-16 16:30:33 +0200 |
| commit | fe51f65be393161da81d6db6144418c97a8e0fe7 (patch) | |
| tree | d80b52641b954a42ae532057727d9df27ba9b17a /src/term.asm | |
| parent | osk: bind START to Enter (CR) (diff) | |
| download | gbos-fe51f65be393161da81d6db6144418c97a8e0fe7.tar.gz gbos-fe51f65be393161da81d6db6144418c97a8e0fe7.tar.xz gbos-fe51f65be393161da81d6db6144418c97a8e0fe7.zip | |
term/osk: scroll region so the OSK never hides the input line
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.
Diffstat (limited to '')
| -rw-r--r-- | src/term.asm | 69 |
1 files changed, 57 insertions, 12 deletions
diff --git a/src/term.asm b/src/term.asm index ba9ff93..8105285 100644 --- a/src/term.asm +++ b/src/term.asm @@ -36,6 +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 wAssign EQU $D590 ; assign[18]: screen row -> line-slot ($D590-$D5A1) DEF CUR_L EQU $E0 ; cursor underline, left cell (3px) @@ -81,6 +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 ; clear the buffer (all slots) to spaces ld hl, TERM_BUF @@ -432,21 +435,38 @@ 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:: + ld a, [wTermRows] + dec a + ld [wScratch], a ; wScratch = bottom row of the region ld a, [wAssign] - ld [wScratch], a ; freed line-slot + 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 hl, wAssign+1 ld de, wAssign - ld b, TROWS-1 .rot ld a, [hl+] ld [de], a inc de - dec b + dec c jr nz, .rot +.norot + ; assign[bottom] = freed ld a, [wScratch] - ld [wAssign + TROWS-1], a ; new bottom row uses the freed slot - ; clear that slot to spaces + add LOW(wAssign) + ld l, a + ld a, HIGH(wAssign) + adc 0 + ld h, a + ld [hl], b + ; clear buffer[freed] to spaces + ld a, b ld l, a ld h, 0 add hl, hl @@ -463,11 +483,12 @@ term_scroll:: ld [hl+], a dec b jr nz, .clr - ; rebuild bottom line tiles (screen row 17) + ; rebuild the region's bottom line ld c, 0 .build push bc - ld b, TROWS-1 + ld a, [wScratch] + ld b, a call render_tile pop bc inc c @@ -477,18 +498,42 @@ term_scroll:: call term_write_tilemap ret -; cursor_down - advance cursor row, scrolling if it runs off the bottom. +; cursor_down - advance the cursor row, scrolling the region if it overflows. cursor_down: ld a, [wCurRow] inc a - cp TROWS - jr c, .ok + ld b, a + ld a, [wTermRows] + cp b + jr z, .scroll + jr c, .scroll ; candidate >= wTermRows + ld a, b + ld [wCurRow], a + ret +.scroll call term_scroll - ld a, TROWS-1 -.ok + ld a, [wTermRows] + dec a 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_putc - A = character. Print at the cursor, advance, handle \n \r \b. ; ----------------------------------------------------------------------------- |
