From fe51f65be393161da81d6db6144418c97a8e0fe7 Mon Sep 17 00:00:00 2001 From: user Date: Thu, 16 Jul 2026 16:30:33 +0200 Subject: 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. --- src/osk.asm | 5 ++++ src/programs.asm | 7 ++++++ src/term.asm | 69 ++++++++++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 69 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/osk.asm b/src/osk.asm index c761aed..a34a863 100644 --- a/src/osk.asm +++ b/src/osk.asm @@ -236,6 +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 ld a, [rLCDC] or %00100000 ld [rLCDC], a @@ -244,6 +247,8 @@ osk_toggle:: ld a, [rLCDC] and %11011111 ld [rLCDC], a + ld a, 18 ; restore full-height terminal + call term_set_rows ret ; movement with wrap-around; each moves the highlight diff --git a/src/programs.asm b/src/programs.asm index 64efc4d..40d9034 100644 --- a/src/programs.asm +++ b/src/programs.asm @@ -103,6 +103,9 @@ ProgBlk: SECTION "prog_mkdir", ROMX[$4000], BANK[22] ProgMkdir: INCBIN "c/mkdir.bin" +SECTION "prog_count", ROMX[$4000], BANK[23] +ProgCount: + INCBIN "c/count.bin" ; ----------------------------------------------------------------------------- ; PROG_SH (bank 3) - the shell, now written in C (c/sh.c): parses >/ program id, searched by sys_lookup. @@ -235,4 +240,6 @@ NameTable:: db PROG_BLK db "mkdir", 0 db PROG_MKDIR + db "count", 0 + db PROG_COUNT db 0 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. ; ----------------------------------------------------------------------------- -- cgit v1.3.1-sl0p