aboutsummaryrefslogtreecommitdiff
path: root/lib/aplib.z80
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2023-11-05 11:22:55 +0000
committerJuan J. Martinez <jjm@usebox.net>2023-11-05 11:31:28 +0000
commit2fbdf974338bde8576efdae40a819a76b2391033 (patch)
tree64d41a37470143f142344f9a439d96de3e7918c2 /lib/aplib.z80
downloadkitsunes-curse-2fbdf974338bde8576efdae40a819a76b2391033.tar.gz
kitsunes-curse-2fbdf974338bde8576efdae40a819a76b2391033.zip
Initial import of the open source release
Diffstat (limited to 'lib/aplib.z80')
-rw-r--r--lib/aplib.z80162
1 files changed, 162 insertions, 0 deletions
diff --git a/lib/aplib.z80 b/lib/aplib.z80
new file mode 100644
index 0000000..6a5d8d4
--- /dev/null
+++ b/lib/aplib.z80
@@ -0,0 +1,162 @@
+; See apultra for licence.
+;
+; Z80 Version by Dan Weiss
+; Call depack.
+;
+; hl = source
+; de = dest
+
+; C convention
+.globl _aplib_uncompress
+; register call
+.globl aplib_depack
+
+; aPPack decompressor
+; original source by dwedit
+; very slightly adapted by utopian
+; optimized by Metalbrain
+
+;hl = source
+;de = dest
+
+; this is to enable undocumented Z80 opcodes in SDCC assembler
+.ez80
+
+_aplib_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
+
+aplib_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
+