UrForth: cosmetix
[urasm.git] / libs / exomiser / deexo.zas
blob43a9f2cc2f4e3424463c42fc25656707b5ea3a5f
1 ;Exomizer 2 Z80 decoder
2 ; by Metalbrain
4 ; optimized by Antonio Villena
6 ; compression algorithm by Magnus Lind
8 ;input:
9 ;   hl=compressed data start
10 ;   de=uncompressed destination start
12 ;   you may change exo_mapbasebits to point to any free buffer
14 deexo:
15   ld   iy,exo_mapbasebits
16   ld   a,(hl)
17   inc  hl
18   ld   b,52
19   push de
20 exo_initbits:
21   ex   af,af'
22   ld   a,b
23   sub  4
24   and  15
25   jr   nz,exo_node1
26   ld   de,1    ;DE=b2
27 exo_node1:
28   ld   c,16
29   ex   af,af'
30 exo_get4bits:
31   call exo_getbit
32   rl   c
33   jr   nc,exo_get4bits
34   ld   (iy+0),c  ;bits[i]=b1
35   push hl
36   ld   hl,1
37   defb 210   ;3 bytes nop (JP NC)
38 exo_setbit:
39   add  hl,hl
40   dec  c
41   jr   nz,exo_setbit
42   ld   (iy+52),e
43   ld   (iy+104),d  ;base[i]=b2
44   add  hl,de
45   ex   de,hl
46   inc  iy
47   pop  hl
48   djnz exo_initbits
49   pop  de
50   db   218   ;3 bytes nop (JP C) --> jr exo_mainloop
51 exo_literalcopy:
52   ldir
53 exo_mainloop:
54   ld   c,1   ;lenght=1
55   call exo_getbit  ;literal?
56   jr   c,exo_literalcopy
57   ld   c,255
58 exo_getindex:
59   inc  c
60   call exo_getbit
61   jr   nc,exo_getindex
62   bit  4,c
63   jr   z,exo_continue
64   bit  0,c
65   ret  z
66   push de
67   ld   d,16
68   call exo_getbits
69   pop  de
70   jr   exo_literalcopy
71 exo_continue:
72   push de
73   call exo_getpair
74   push bc
75   pop  ix
76   ld   de,512+48 ;2 bits, 48 offset
77   inc  b
78   djnz exo_dontgo
79   dec  c
80   jr   z,exo_goforit
81   dec  c   ;2?
82 exo_dontgo:
83   ld   de,1024+32  ;4 bits, 32 offset
84   jr   z,exo_goforit
85   ld   e,16    ;16 offset
86 exo_goforit:
87   call exo_getbits
88   ex   af,af'
89   ld   a,e
90   add  a,c
91   ld   c,a
92   ex   af,af'
93   call exo_getpair
94   pop  de    ;bc=offset
95   push hl    ;de=destination
96   ld   h,d
97   ld   l,e
98   sbc  hl,bc   ;hl=origin
99   push ix
100   pop  bc    ;bc=lenght
101   ldir
102   pop  hl    ;Keep HL, DE is updated
103   jr   exo_mainloop  ;Next!
105 exo_getpair:
106   ld   iy,exo_mapbasebits
107   ld   b,0
108   add  iy,bc
109   ld   d,(iy+0)
110   call exo_getbits
111   push hl
112   ld   l,(iy+52)
113   ld   h,(iy+104)
114   add  hl,bc    ;Always clear C flag
115   ld   b,h
116   ld   c,l
117   pop  hl
118   ret
120 exo_getbits:
121   ld   bc,0    ;get D bits in BC
122 exo_gettingbits:
123   dec  d
124   ret  m
125   call exo_getbit
126   rl   c
127   rl   b
128   jr   exo_gettingbits
130 exo_getbit:
131   srl  a
132   ret  nz
133   ld   a,(hl)
134   inc  hl
135   rra
136   ret
138 exo_mapbasebits_size equ 156
139 ;exo_mapbasebits: defs 156 ;tables for bits, baseL, baseH