From 9bcf1e97960c0da7322a868efdbc07e2650716fe Mon Sep 17 00:00:00 2001 From: "Juan J. Martinez" Date: Sat, 9 Jan 2021 09:01:05 +0000 Subject: Extra libs: ap.lib aPLib support with apultra. --- src/ap/Makefile | 19 +++++++ src/ap/ap.z80 | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 176 insertions(+) create mode 100644 src/ap/Makefile create mode 100644 src/ap/ap.z80 (limited to 'src') diff --git a/src/ap/Makefile b/src/ap/Makefile new file mode 100644 index 0000000..3559f71 --- /dev/null +++ b/src/ap/Makefile @@ -0,0 +1,19 @@ +LIB = ../../lib/ap.lib +all: $(LIB) + +AS = sdasz80 +AR = sdar + +SOURCES = ap.z80 +OBJS = $(patsubst %.z80,%.rel,$(SOURCES)) + +$(LIB): $(OBJS) + $(AR) -rcD $(LIB) $(OBJS) + +%.rel: %.z80 + $(AS) -o $< + +.PHONY: clean +clean: + rm -f $(OBJS) $(LIB) + diff --git a/src/ap/ap.z80 b/src/ap/ap.z80 new file mode 100644 index 0000000..5dc7fe2 --- /dev/null +++ b/src/ap/ap.z80 @@ -0,0 +1,157 @@ +; 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 + -- cgit v1.2.3