summaryrefslogtreecommitdiff
path: root/src/ap
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2021-01-09 09:01:05 +0000
committerJuan J. Martinez <jjm@usebox.net>2021-01-09 09:01:05 +0000
commit9bcf1e97960c0da7322a868efdbc07e2650716fe (patch)
treede6d32ad5b0e567991bd3eb262902c15a77074d9 /src/ap
parent3b31adf01305e522f7e28c1435fb47418ce43267 (diff)
downloadubox-msx-lib-9bcf1e97960c0da7322a868efdbc07e2650716fe.tar.gz
ubox-msx-lib-9bcf1e97960c0da7322a868efdbc07e2650716fe.zip
Extra libs: ap.lib
aPLib support with apultra.
Diffstat (limited to 'src/ap')
-rw-r--r--src/ap/Makefile19
-rw-r--r--src/ap/ap.z80157
2 files changed, 176 insertions, 0 deletions
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
+