; C convention .globl _ap_uncompress ; register call ; ; hl = source ; de = dest .globl ap_uncompress ; The original Z80 decompressors for ApLib were written by Dan Weiss (Dwedit). ; ; aPPack decompressor ; original source by dwedit ; very slightly adapted by utopian ; optimized by Metalbrain ; this is to enable undocumented Z80 opcodes in SDCC assembler .ez80 _ap_uncompress:: ld hl, #2 add hl, sp ld e, (hl) inc hl ld d, (hl) inc hl ld a, (hl) inc hl ld h, (hl) ld l, a ap_depack:: ld ixl, #128 apbranch1: ldi aploop0: ld ixh, #1 ;LWM = 0 aploop: call ap_getbit jr nc, apbranch1 call ap_getbit jr nc, apbranch2 ld b, #0 call ap_getbit jr nc, apbranch3 ld c, #16 ;get an offset apget4bits: call ap_getbit rl c jr nc, apget4bits jr nz, apbranch4 ld a, b apwritebyte: ld (de), a ;write a 0 inc de jr aploop0 apbranch4: and a ex de, hl ;write a previous byte (1-15 away from dest) sbc hl, bc ld a, (hl) add hl, bc ex de, hl jr apwritebyte apbranch3: ld c, (hl) ;use 7 bit offset, length = 2 or 3 inc hl rr c ret z ;if a zero is encountered here, it is EOF ld a, #2 adc a,b push hl ld iyh, b ld iyl, c ld h, d ld l, e sbc hl, bc ld c, a jr ap_finishup2 apbranch2: call ap_getgamma ;use a gamma code * 256 for offset, another gamma code for length dec c ld a, c sub ixh jr z, ap_r0_gamma ;if gamma code is 2, use old r0 offset, dec a ;do I even need this code? ;bc=bc*256+(hl), lazy 16bit way ld b, a ld c, (hl) inc hl ld iyh, b ld iyl, c push bc call ap_getgamma ex (sp), hl ;bc = len, hl=offs push de ex de, hl ld a, #4 cp d jr nc, apskip2 inc bc or a apskip2: ld hl, #127 sbc hl, de jr c, apskip3 inc bc inc bc apskip3: pop hl ;bc = len, de = offs, hl=junk push hl or a ap_finishup: sbc hl, de pop de ;hl=dest-offs, bc=len, de = dest ap_finishup2: ldir pop hl ld ixh, b jr aploop ap_r0_gamma: call ap_getgamma ;and a new gamma code for length push hl push de ex de, hl ld d, iyh ld e, iyl jr ap_finishup ap_getbit: ld a, ixl add a, a ld ixl, a ret nz ld a, (hl) inc hl rla ld ixl, a ret ap_getgamma: ld bc, #1 ap_getgammaloop: call ap_getbit rl c rl b call ap_getbit jr c, ap_getgammaloop ret