aboutsummaryrefslogtreecommitdiffstats
path: root/src/font.asm
diff options
context:
space:
mode:
authoruser <user@clank>2026-07-16 13:54:23 +0200
committeruser <user@clank>2026-07-16 13:54:23 +0200
commit4656a1003226709e9b3c804ec32b4913fca4c7f4 (patch)
tree516185fb1827495f0fe747b6365eb963ad5cf031 /src/font.asm
parentfs: reject open()/read() on a directory (EISDIR) (diff)
downloadgbos-4656a1003226709e9b3c804ec32b4913fca4c7f4.tar.gz
gbos-4656a1003226709e9b3c804ec32b4913fca4c7f4.tar.xz
gbos-4656a1003226709e9b3c804ec32b4913fca4c7f4.zip
term: 40-column text terminal on the CGB LCD (4x8 dynamic tiles)
Add a background-tile text terminal that packs TWO 4px-wide characters into each 8x8 tile, giving a 40x18 grid instead of the 20x18 you'd get from an 8x8 font. The tilemap is static (one dedicated VRAM tile per screen position); we rebuild a tile's 16 bytes from two glyphs whenever a character changes. 360 tiles exceed the 256 a single tilemap can address, so positions 256-359 live in VRAM bank 1 via the CGB tilemap attribute bank-bit -- hence CGB-only. - Switch the ROM to CGB (rgbfix -C). Safe for the FS: every process has PROC_WRAMB=1, so SVBK stays on bank 1 and the WRAMX FS caches don't move. - CGB BG palette 0 = white bg / black text via BCPS/BCPD. - src/term.asm: term_init (palette + static tilemap + clear buffer), build_tile (combine two 4px glyphs -> one 8x8 tile, correct VRAM bank), term_redraw (rebuild all tiles), term_puts, term_show, term_test. - src/font.asm: 96-glyph 3x5-in-4x8 font, generated by tools/genfont.py. - 40x18 text buffer at $D600 (WRAMX, above the FS caches). - tools/ppmview.py: render a --shot PPM as ASCII so the LCD is inspectable from the shell during development. Verified via emulator screenshot: "GBOS TERMINAL", the alphabet, and a bank-1 row all render legibly at 40 columns. Serial shell + filesystem still work unchanged. Note: a full term_redraw builds 360 tiles and takes ~8 frames; fine for incremental single-char updates, but scrolling needs a smarter path (next milestone). Input (no keyboard) is also still TODO.
Diffstat (limited to 'src/font.asm')
-rw-r--r--src/font.asm99
1 files changed, 99 insertions, 0 deletions
diff --git a/src/font.asm b/src/font.asm
new file mode 100644
index 0000000..a6ff7d9
--- /dev/null
+++ b/src/font.asm
@@ -0,0 +1,99 @@
+; auto-generated by tools/genfont.py - 4x8 font (3x5 glyphs), 96 glyphs
+SECTION "font", ROM0
+FontData::
+ db $00,$00,$00,$00,$00,$00,$00,$00 ; ' '
+ db $04,$04,$04,$00,$04,$00,$00,$00 ; '!'
+ db $0A,$0A,$00,$00,$00,$00,$00,$00 ; '"'
+ db $0A,$0E,$0A,$0E,$0A,$00,$00,$00 ; '#'
+ db $04,$06,$0C,$06,$0C,$00,$00,$00 ; '$'
+ db $0A,$02,$04,$08,$0A,$00,$00,$00 ; '%'
+ db $04,$0A,$04,$0A,$06,$00,$00,$00 ; '&'
+ db $04,$04,$00,$00,$00,$00,$00,$00 ; '''
+ db $02,$04,$04,$04,$02,$00,$00,$00 ; '('
+ db $08,$04,$04,$04,$08,$00,$00,$00 ; ')'
+ db $0A,$04,$0E,$04,$0A,$00,$00,$00 ; '*'
+ db $00,$04,$0E,$04,$00,$00,$00,$00 ; '+'
+ db $00,$00,$00,$04,$08,$00,$00,$00 ; ','
+ db $00,$00,$0E,$00,$00,$00,$00,$00 ; '-'
+ db $00,$00,$00,$00,$04,$00,$00,$00 ; '.'
+ db $02,$02,$04,$08,$08,$00,$00,$00 ; '/'
+ db $04,$0A,$0A,$0A,$04,$00,$00,$00 ; '0'
+ db $04,$0C,$04,$04,$0E,$00,$00,$00 ; '1'
+ db $0C,$02,$04,$08,$0E,$00,$00,$00 ; '2'
+ db $0C,$02,$04,$02,$0C,$00,$00,$00 ; '3'
+ db $0A,$0A,$0E,$02,$02,$00,$00,$00 ; '4'
+ db $0E,$08,$0C,$02,$0C,$00,$00,$00 ; '5'
+ db $06,$08,$0C,$0A,$04,$00,$00,$00 ; '6'
+ db $0E,$02,$04,$04,$04,$00,$00,$00 ; '7'
+ db $04,$0A,$04,$0A,$04,$00,$00,$00 ; '8'
+ db $04,$0A,$06,$02,$0C,$00,$00,$00 ; '9'
+ db $00,$04,$00,$04,$00,$00,$00,$00 ; ':'
+ db $00,$04,$00,$04,$08,$00,$00,$00 ; ';'
+ db $02,$04,$08,$04,$02,$00,$00,$00 ; '<'
+ db $00,$0E,$00,$0E,$00,$00,$00,$00 ; '='
+ db $08,$04,$02,$04,$08,$00,$00,$00 ; '>'
+ db $0C,$02,$04,$00,$04,$00,$00,$00 ; '?'
+ db $04,$0A,$0E,$08,$06,$00,$00,$00 ; '@'
+ db $0C,$0A,$0E,$0A,$0A,$00,$00,$00 ; 'A'
+ db $0C,$0A,$0C,$0A,$0C,$00,$00,$00 ; 'B'
+ db $06,$08,$08,$08,$06,$00,$00,$00 ; 'C'
+ db $0C,$0A,$0A,$0A,$0C,$00,$00,$00 ; 'D'
+ db $0E,$08,$0C,$08,$0E,$00,$00,$00 ; 'E'
+ db $0E,$08,$0C,$08,$08,$00,$00,$00 ; 'F'
+ db $06,$08,$0A,$0A,$06,$00,$00,$00 ; 'G'
+ db $0A,$0A,$0E,$0A,$0A,$00,$00,$00 ; 'H'
+ db $0E,$04,$04,$04,$0E,$00,$00,$00 ; 'I'
+ db $02,$02,$02,$0A,$04,$00,$00,$00 ; 'J'
+ db $0A,$0A,$0C,$0A,$0A,$00,$00,$00 ; 'K'
+ db $08,$08,$08,$08,$0E,$00,$00,$00 ; 'L'
+ db $0A,$0E,$0E,$0A,$0A,$00,$00,$00 ; 'M'
+ db $0A,$0E,$0E,$0E,$0A,$00,$00,$00 ; 'N'
+ db $04,$0A,$0A,$0A,$04,$00,$00,$00 ; 'O'
+ db $0C,$0A,$0C,$08,$08,$00,$00,$00 ; 'P'
+ db $04,$0A,$0A,$04,$02,$00,$00,$00 ; 'Q'
+ db $0C,$0A,$0C,$0A,$0A,$00,$00,$00 ; 'R'
+ db $06,$08,$04,$02,$0C,$00,$00,$00 ; 'S'
+ db $0E,$04,$04,$04,$04,$00,$00,$00 ; 'T'
+ db $0A,$0A,$0A,$0A,$06,$00,$00,$00 ; 'U'
+ db $0A,$0A,$0A,$04,$04,$00,$00,$00 ; 'V'
+ db $0A,$0A,$0E,$0E,$0A,$00,$00,$00 ; 'W'
+ db $0A,$0A,$04,$0A,$0A,$00,$00,$00 ; 'X'
+ db $0A,$0A,$04,$04,$04,$00,$00,$00 ; 'Y'
+ db $0E,$02,$04,$08,$0E,$00,$00,$00 ; 'Z'
+ db $0C,$08,$08,$08,$0C,$00,$00,$00 ; '['
+ db $08,$08,$04,$02,$02,$00,$00,$00 ; '?'
+ db $06,$02,$02,$02,$06,$00,$00,$00 ; ']'
+ db $04,$0A,$00,$00,$00,$00,$00,$00 ; '^'
+ db $00,$00,$00,$00,$0E,$00,$00,$00 ; '_'
+ db $08,$04,$00,$00,$00,$00,$00,$00 ; '`'
+ db $0C,$0A,$0E,$0A,$0A,$00,$00,$00 ; 'a'
+ db $0C,$0A,$0C,$0A,$0C,$00,$00,$00 ; 'b'
+ db $06,$08,$08,$08,$06,$00,$00,$00 ; 'c'
+ db $0C,$0A,$0A,$0A,$0C,$00,$00,$00 ; 'd'
+ db $0E,$08,$0C,$08,$0E,$00,$00,$00 ; 'e'
+ db $0E,$08,$0C,$08,$08,$00,$00,$00 ; 'f'
+ db $06,$08,$0A,$0A,$06,$00,$00,$00 ; 'g'
+ db $0A,$0A,$0E,$0A,$0A,$00,$00,$00 ; 'h'
+ db $0E,$04,$04,$04,$0E,$00,$00,$00 ; 'i'
+ db $02,$02,$02,$0A,$04,$00,$00,$00 ; 'j'
+ db $0A,$0A,$0C,$0A,$0A,$00,$00,$00 ; 'k'
+ db $08,$08,$08,$08,$0E,$00,$00,$00 ; 'l'
+ db $0A,$0E,$0E,$0A,$0A,$00,$00,$00 ; 'm'
+ db $0A,$0E,$0E,$0E,$0A,$00,$00,$00 ; 'n'
+ db $04,$0A,$0A,$0A,$04,$00,$00,$00 ; 'o'
+ db $0C,$0A,$0C,$08,$08,$00,$00,$00 ; 'p'
+ db $04,$0A,$0A,$04,$02,$00,$00,$00 ; 'q'
+ db $0C,$0A,$0C,$0A,$0A,$00,$00,$00 ; 'r'
+ db $06,$08,$04,$02,$0C,$00,$00,$00 ; 's'
+ db $0E,$04,$04,$04,$04,$00,$00,$00 ; 't'
+ db $0A,$0A,$0A,$0A,$06,$00,$00,$00 ; 'u'
+ db $0A,$0A,$0A,$04,$04,$00,$00,$00 ; 'v'
+ db $0A,$0A,$0E,$0E,$0A,$00,$00,$00 ; 'w'
+ db $0A,$0A,$04,$0A,$0A,$00,$00,$00 ; 'x'
+ db $0A,$0A,$04,$04,$04,$00,$00,$00 ; 'y'
+ db $0E,$02,$04,$08,$0E,$00,$00,$00 ; 'z'
+ db $02,$04,$0C,$04,$02,$00,$00,$00 ; '{'
+ db $04,$04,$04,$04,$04,$00,$00,$00 ; '|'
+ db $08,$04,$06,$04,$08,$00,$00,$00 ; '}'
+ db $00,$06,$0C,$00,$00,$00,$00,$00 ; '~'
+ db $0E,$0A,$0A,$0A,$0E,$00,$00,$00 ; '?'