.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