aboutsummaryrefslogtreecommitdiffstats
path: root/src/term.asm
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/term.asm242
1 files changed, 141 insertions, 101 deletions
diff --git a/src/term.asm b/src/term.asm
index aebe7e3..fbeaea3 100644
--- a/src/term.asm
+++ b/src/term.asm
@@ -34,8 +34,6 @@ DEF ACACHE EQU 40 ; attr cache in COL_BUF's spare stride bytes: the tile
; per tile instead of color_setup per tile per scroll).
; terminal state (WRAMX gap $D580-$D5FF)
-DEF wGlyphL EQU $D580 ; 2
-DEF wGlyphR EQU $D582 ; 2
DEF wVram EQU $D584 ; 2
DEF wCurRow EQU $D586 ; cursor screen row 0..17
DEF wCurCol EQU $D587 ; cursor screen col 0..39
@@ -92,6 +90,9 @@ term_init::
ld [wViewTop], a ; view starts unshifted (all 18 rows)
ld [wOskVisible], a ; OSK hidden until toggled
ld [wAnsiState], a ; ANSI parser idle
+ ld a, $FF
+ ld [wCSPL], a ; invalidate the color_setup memo (no packed
+ ; color is $FF: bg/fg nibbles are 0..7)
ld a, 1
ld [wCursorOn], a
ld a, 7
@@ -151,15 +152,32 @@ term_write_tilemap::
ld a, 1
ld [rVBK], a
- ld c, 0
+ xor a
+ ld [wRT_sr], a ; screen row (render_tile scratch, free here)
.a_row
- call .slot20 ; DE = pos, HL = tilemap addr, wTMSlot = slot
- ld b, TCOLS/2
-.a_col
- ; attribute = cached palette bits (render_tile keeps the cache fresh)
- ; | bank bit(pos hi). No color math here - just a table read.
- push hl ; save tilemap write ptr
- push de ; save pos
+ ld a, [wRT_sr]
+ ld c, a
+ call .slot20 ; DE = pos start, HL = tilemap addr, wTMSlot set
+ ; Split the row at the pos-256 VRAM-bank boundary: the first k tiles are
+ ; bank 0 (attr = cache byte), the rest bank 1 (attr | $08). Each run is
+ ; then a tight cache->tilemap copy: no per-tile addressing or bank test.
+ ld a, d
+ or a
+ jr nz, .k0 ; pos >= 256: whole row is bank 1
+ xor a
+ sub e ; 256 - LOW(pos) (mod 256; 0 means 256)
+ jr z, .k20
+ cp TCOLS/2
+ jr c, .khave ; boundary lands inside this row
+.k20
+ ld a, TCOLS/2
+ jr .khave
+.k0
+ xor a
+.khave
+ ld [wRT_tcol], a ; k = bank-0 tiles in this row
+ ; DE = &cache[slot][0] (pos isn't needed beyond the split above)
+ push hl
ld a, [wTMSlot]
ld l, a
ld h, 0
@@ -171,26 +189,39 @@ term_write_tilemap::
add hl, hl ; slot*64
ld de, COL_BUF + ACACHE
add hl, de
- ld a, TCOLS/2
- sub b ; tcol
- add l
- ld l, a
- ld a, h
- adc 0
- ld h, a
- ld a, [hl] ; A = cached attr (palette bits)
- pop de ; restore pos
- pop hl ; restore tilemap write ptr
- bit 0, d ; HIGH(pos): 0 or 1 -> VRAM bank bit
- jr z, .aw
- or $08 ; VRAM bank 1 tile
-.aw
+ ld d, h
+ ld e, l
+ pop hl
+ ; run 1: k tiles in bank 0
+ ld a, [wRT_tcol]
+ ld b, a
+ or a
+ jr z, .run2
+.r1
+ ld a, [de]
+ inc de
ld [hl+], a
+ dec b
+ jr nz, .r1
+.run2
+ ; run 2: the remaining tiles in bank 1
+ ld a, [wRT_tcol]
+ ld b, a
+ ld a, TCOLS/2
+ sub b
+ jr z, .arnext
+ ld b, a
+.r2
+ ld a, [de]
inc de
+ or $08
+ ld [hl+], a
dec b
- jr nz, .a_col
- inc c
- ld a, c
+ jr nz, .r2
+.arnext
+ ld a, [wRT_sr]
+ inc a
+ ld [wRT_sr], a
cp TROWS
jr c, .a_row
xor a
@@ -287,9 +318,21 @@ glyph_ptr:
; preserves B, C (so it runs inside the tilemap column loop).
; -----------------------------------------------------------------------------
color_setup:
+ ; memo: same (colL,colR) pair as the previous call? wPalAttr and all four
+ ; plane masks are still valid - skip the whole Fano walk. Runs of same-
+ ; colored cells (= almost all text) hit this.
+ ld a, [wCSPL]
+ cp d
+ jr nz, .miss
+ ld a, [wCSPR]
+ cp e
+ ret z
+.miss
ld a, d
+ ld [wCSPL], a
ld [wCSL], a
ld a, e
+ ld [wCSPR], a
ld [wCSR], a
; set = union of the (non-black) colors of both cells
xor a
@@ -428,91 +471,88 @@ build_tile::
ld [wVram], a
ld a, h
ld [wVram+1], a
+ ; ---- fast path: two spaces = bg-only planes, 8 constant rows ----
+ ; (the case term_scroll's cleared line and every blank region hits)
ld a, b
- call glyph_ptr
- ld a, l
- ld [wGlyphL], a
- ld a, h
- ld [wGlyphL+1], a
+ cp $20
+ jr nz, .glyphs
ld a, c
- call glyph_ptr
- ld a, l
- ld [wGlyphR], a
- ld a, h
- ld [wGlyphR+1], a
- ld b, 8 ; row counter
- ld a, [wVram]
- ld l, a
- ld a, [wVram+1]
- ld h, a ; HL = VRAM dest
-.brow
+ cp $20
+ jr nz, .glyphs
+ ld a, [wBGP0]
+ ld d, a ; plane 0 = bg mask (g = 0)
+ ld a, [wBGP1]
+ ld e, a ; plane 1 = bg mask
+ ld b, 7
+.blank
+ ld a, d
+ ld [hl+], a
+ ld a, e
+ ld [hl+], a
+ dec b
+ jr nz, .blank
+ ld a, [wCurMask] ; last row: cursor underline
+ or d
+ ld [hl+], a
+ ld [hl], e
+ ret
+
+.glyphs
+ ; ---- phase 1: combine both glyphs into wRowBuf (8 nibble-pair rows).
+ ; Sequential pointers live in HL/DE registers; the old per-row 16-bit
+ ; pointer walk through WRAM was most of the blit cost.
+ ld a, c
+ call glyph_ptr ; (clobbers DE, so right glyph first...)
push hl
- ld a, [wGlyphL]
- ld e, a
- ld a, [wGlyphL+1]
- ld d, a
- ld a, [de]
+ ld a, b
+ call glyph_ptr ; HL = left glyph
+ pop de ; DE = right glyph
+FOR I, 8
+ ld a, [hl+]
swap a
and $F0
- ld c, a ; left glyph -> high nibble
- ld a, [wGlyphR]
- ld e, a
- ld a, [wGlyphR+1]
- ld d, a
+ ld c, a ; left -> high nibble
ld a, [de]
+ inc de
and $0F
- or c ; A = glyph row g (left=hi nibble, right=lo)
- ld c, a ; C = g
+ or c ; g = left | right
+ ld [wRowBuf + I], a
+ENDR
+ ; ---- phase 2: compose the bitplanes, unrolled, plane-0 masks in B/C ----
+ ld a, [wFGP0]
+ ld b, a
+ ld a, [wBGP0]
+ ld c, a
+ ld a, [wVram]
+ ld l, a
+ ld a, [wVram+1]
+ ld h, a ; HL = VRAM dest
+FOR I, 8
+ ld a, [wRowBuf + I]
+ ld d, a ; D = g
+ and b ; g & FGP0
+ ld e, a
+ ld a, d
cpl
- ld d, a ; D = ~g (the empty pixels = background)
- ; plane1 = (g & wFGP1) | (~g & wBGP1) -> hold in E for the write below
- ld a, [wFGP1]
- and c
+ and c ; ~g & BGP0
+ or e ; plane 0
+ IF I == 7
ld e, a
- ld a, [wBGP1]
- and d
+ ld a, [wCurMask] ; cursor underline on the last row
or e
- ld e, a ; E = plane 1
- ; plane0 = (g & wFGP0) | (~g & wBGP0) (+cursor underline on the last row)
- ld a, [wFGP0]
- and c
- ld c, a ; C = g & wFGP0
- ld a, [wBGP0]
+ ENDC
+ ld [hl+], a
+ ld a, d
+ cpl
+ ld e, a ; ~g
+ ld a, [wBGP1]
+ and e
+ ld e, a
+ ld a, [wFGP1]
and d
- or c ; A = plane 0 base
- ld c, a
- ld a, b
- dec a
- jr nz, .nocur ; last row (b==1)? add cursor underline
- ld a, [wCurMask]
- or c
- jr .wr
-.nocur
- ld a, c
-.wr
- pop hl
- ld [hl+], a ; plane 0
- ld a, e
- ld [hl+], a ; plane 1
- ; advance glyph pointers - MUST NOT touch HL (it holds the VRAM dest!)
- ld a, [wGlyphL]
- inc a
- ld [wGlyphL], a
- jr nz, .nl
- ld a, [wGlyphL+1]
- inc a
- ld [wGlyphL+1], a
-.nl
- ld a, [wGlyphR]
- inc a
- ld [wGlyphR], a
- jr nz, .nr
- ld a, [wGlyphR+1]
- inc a
- ld [wGlyphR+1], a
-.nr
- dec b
- jr nz, .brow
+ or e ; plane 1
+ ld [hl+], a
+ENDR
ret
; -----------------------------------------------------------------------------