.enum $c141 ; memory used: 4 bytes
rowCount dw
rowCountTotal dw
.ende
.section "High School! Kimengumi tile decompressor" free
; Usage:
; bc = source data
; de = destination (VRAM address ORed with $4000)
decode:
call _decode
; clean up
xor a
ld (rowCount),a
ld (rowCount+1),a
ld (rowCountTotal),a
ld (rowCountTotal+1),a
ret
_decode:
ld a,(bc) ; hl = (bc)
ld l,a
inc bc
ld a,(bc)
ld h,a
dec bc
ld (rowCount),hl ; load row count into RAM
ld (rowCountTotal),hl
ld h,b ; hl = bc
ld l,c
inc hl ; hl += 2
inc hl
_nextBlock:
ld a,(hl) ; read control byte
or a ; 0 = terminator
ret z
bit 7,a ; if bit 7 = 1 then it's raw
jr nz,+
; RLE
ld b,a ; run length
inc hl ; run value
-: call _outputByte
djnz -
inc hl ; next control byte
jp _nextBlock
+: ; Raw
and $7f ; length
ld b,a
inc hl ; value
-: call _outputByte
inc hl
djnz -
jp _nextBlock
_outputByte:
; writes a byte from hl to VRAM address de with interleaving 4
; set VRAM address
ld a,e
out ($bf),a
ld a,d
out ($bf),a
; write value
ld a,(hl)
out ($be),a
; decrement row counter
push hl
ld hl,(rowCount)
dec hl
ld a,h ; if zero, move to next bitplane
or l
jr z,_setNextBitplane
ld (rowCount),hl
inc de ; de += 4 (interleaving)
inc de
inc de
inc de
pop hl
ret
_setNextBitplane:
ld hl,(rowCountTotal) ; restore the counter
ld (rowCount),hl
; now:
; - hl = number of tile rows
; - de = last byte written in previous bitplane
; so we want to set de = de - hl * 4 + 5
; first calculate hl = hl * 4
xor a ; clear carry
rl l ; shift hl left by 1
rl h
xor a ; repeat
rl l
rl h
; subtract hl and add 5
ex de,hl
xor a ; clear carry
sbc hl,de
inc hl
inc hl
inc hl
inc hl
inc hl
ex de,hl
pop hl
ret
.ends