aboutsummaryrefslogtreecommitdiffstats
path: root/usr/libc.s
diff options
context:
space:
mode:
authoruser <user@clank>2026-07-18 22:19:59 +0200
committeruser <user@clank>2026-07-18 22:19:59 +0200
commitc2b512e803285223959e0a97601c017730d1b0bb (patch)
tree8cb28702cffcfccce8a244d7d5bfabb0424c30a3 /usr/libc.s
parentdemo: boot through the CGB BIOS + double-speed ROM in the README gif (diff)
downloadgbos-c2b512e803285223959e0a97601c017730d1b0bb.tar.gz
gbos-c2b512e803285223959e0a97601c017730d1b0bb.tar.xz
gbos-c2b512e803285223959e0a97601c017730d1b0bb.zip
term+libc: batched write rendering - one tile render per write(), 2.3x lines
sys_write sets wBatch; render_cursor_tile - the single choke point all of term_putc's visible mutations pass through - then marks a dirty span (per LINE-SLOT, so spans survive scroll rotation for free) instead of rendering. term_write_end renders every dirty tile exactly once, then the cursor. Scrolls stay immediate (blank rebuild is cheap and artifact-free); file-bound writes flush for free. The enabler is in libc: puts() was a SYS_PUTC trap PER CHARACTER, so almost no console output ever went through sys_write. It now issues one SYS_WRITE for the whole string - one trap, one batch, and every line-printer (echo, irc, the shell) gets the batched path. Measured: 37-char write = 128k cycles (3.5k/char) vs ~8k/char down the per-char trap path. Full demo passes; GIF regenerated.
Diffstat (limited to 'usr/libc.s')
-rw-r--r--usr/libc.s26
1 files changed, 18 insertions, 8 deletions
diff --git a/usr/libc.s b/usr/libc.s
index 2366cd8..fbca836 100644
--- a/usr/libc.s
+++ b/usr/libc.s
@@ -33,18 +33,28 @@ _putc:
rst #0x30
ret
- ;; void puts(const char *s /*DE*/) - write until NUL (no newline)
+ ;; void puts(const char *s /*DE*/) - write until NUL (no newline).
+ ;; ONE SYS_WRITE for the whole string instead of a SYS_PUTC per char:
+ ;; a single trap, and the kernel defers tile rendering for the whole
+ ;; run (sys_write batching), so a line paints each tile once.
_puts:
-1$: ld a, (de)
+ push de
+ ld h, d
+ ld l, e
+ ld b, #0
+1$: ld a, (hl)
+ or a
+ jr z, 2$
+ inc hl
+ inc b
+ jr 1$
+2$: pop de
+ ld a, b
or a
ret z
- push de
- ld e, a
- ld c, #16 ; SYS_PUTC
+ ld c, #3 ; SYS_WRITE (DE=buf, B=len)
rst #0x30
- pop de
- inc de
- jr 1$
+ ret
;; void nl(void) - CRLF via stdout
_nl: