aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--c/count.c16
-rw-r--r--include/gbos.inc1
-rw-r--r--src/osk.asm5
-rw-r--r--src/programs.asm7
-rw-r--r--src/term.asm69
6 files changed, 87 insertions, 13 deletions
diff --git a/Makefile b/Makefile
index b7fe95d..62401b3 100644
--- a/Makefile
+++ b/Makefile
@@ -20,7 +20,7 @@ $(BUILD)/%.o: src/%.asm | $(BUILD)
# C programs: compiled with SDCC into ROM-bank blobs and INCBIN'd by programs.asm
CBLOBS := c/chello.bin c/echo.bin c/true.bin c/false.bin c/uname.bin \
c/pid.bin c/cat.bin c/wc.bin c/head.bin c/args.bin \
- c/ls.bin c/save.bin c/rm.bin c/sh.bin c/ps.bin c/kill.bin c/spin.bin c/blk.bin c/mkdir.bin
+ c/ls.bin c/save.bin c/rm.bin c/sh.bin c/ps.bin c/kill.bin c/spin.bin c/blk.bin c/mkdir.bin c/count.bin
$(BUILD)/programs.o: $(CBLOBS)
# C programs also depend on the shared libc sources
diff --git a/c/count.c b/c/count.c
new file mode 100644
index 0000000..37cdcce
--- /dev/null
+++ b/c/count.c
@@ -0,0 +1,16 @@
+#include "gbos.h"
+/* count [n]: print n numbered lines (default 25) to observe terminal scrolling
+ and the OSK scroll-region. Each line is tagged so you can tell which lines
+ are visible after scrolling. */
+void main(void) {
+ char *argv[4];
+ unsigned char argc = argv_parse(argv, 4);
+ unsigned char n = 25, i;
+ if (argc >= 1) n = atou(argv[0]);
+ for (i = 1; i <= n; i++) {
+ puts("line ");
+ putu(i);
+ puts(" ------------------");
+ nl();
+ }
+}
diff --git a/include/gbos.inc b/include/gbos.inc
index 92b82c9..6dcefce 100644
--- a/include/gbos.inc
+++ b/include/gbos.inc
@@ -202,5 +202,6 @@ DEF PROG_KILL EQU 17
DEF PROG_SPIN EQU 18
DEF PROG_BLK EQU 19
DEF PROG_MKDIR EQU 20
+DEF PROG_COUNT EQU 21
ENDC
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 >/</| and
@@ -187,6 +190,8 @@ ProgramTable::
dw ProgBlk
db LOW(BANK(ProgMkdir)), HIGH(BANK(ProgMkdir))
dw ProgMkdir
+ db LOW(BANK(ProgCount)), HIGH(BANK(ProgCount))
+ dw ProgCount
; -----------------------------------------------------------------------------
; NameTable (ROM0) - command name -> 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.
; -----------------------------------------------------------------------------