wok view plop/stuff/unlzsa1.S @ rev 25779
Up fdutils (5.6), lite (1.11), again
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Fri Sep 20 09:24:30 2024 +0000 (5 months ago) |
parents | a794ec0a6495 |
children |
line source
1 // Lzsa1Decode:
2 #ifndef FLAT32
3 // input ds:si=inStream, es:di=outStream
4 // output outStream[], ds:si, es:di
5 .code16
6 #define AX %ax
7 #define BX %bx
8 #define SI %si
9 #define DI %di
10 #else
11 // input esi=inStream, edi=outStream
12 // output outStream[], ds:esi, es:edi
13 .code32
14 #define AX %eax
15 #define BX %ebx
16 #define SI %esi
17 #define DI %edi
18 #endif
20 MATCH_RUN_LEN = 15
21 LITERALS_RUN_LEN = 7
22 MIN_MATCH_SIZE = 3
23 MIN_LITERALS_SIZE = 0
25 #define PACKED_ONLY // assume no copy block, optional
26 //#define PARANOIA // cover rare cases, optional
28 .macro shrclw cnt,obj,keepcx=0
29 #ifdef ONLY8086
30 .if \keepcx
31 pushw %cx
32 .endif
33 movb \cnt, %cl
34 shrw %cl, \obj
35 .if \keepcx
36 popw %cx
37 .endif
38 #else
39 shrw \cnt, \obj
40 #endif
41 .endm
43 #ifdef FLAT16OUT
44 #define RAW_FORMAT
45 #endif
46 lzsa1main:
47 #ifdef PARANOIA
48 cld
49 #endif
50 #ifndef RAW_FORMAT
51 # ifndef NO_LZSA1_HEADER
52 lodsw
53 cmpw $0x9E7B, %ax // magic
54 jne lzsa1main
55 lodsb
56 // cmpb $0, %al // lzsa1
57 // jne lzsa1main
58 # endif
59 xorw %ax, %ax
60 xchgw %ax, %di
61 shrclw $4, %ax
62 jmp lzsa1blockz // %di *MUST* be paragraph aligned
63 # ifndef PACKED_ONLY
64 lzsa1copy:
65 movsb // handle 64K case
66 decw %cx
67 rep movsb // copy block
68 # endif
69 lzsa1block: // uncompress chunk
70 movw $0x1000, %ax
71 lzsa1blockz:
72 movw %es, %cx
73 addw %ax, %cx
74 movw %cx, %es
75 # ifndef FLAT16
76 movw %si, %ax
77 andw $0xf, %si
78 shrclw $4, %ax
79 movw %ds, %cx
80 addw %ax, %cx
81 movw %cx, %ds
82 # endif
83 lodsw // block size
84 xchgw %ax, %cx
85 movw %cx, %dx
86 lodsb
87 # ifndef PACKED_ONLY
88 orb %al, %al
89 js lzsa1copy
90 jne lzsa1full // 64Kb block
91 # endif
92 jcxz lzsa1quit // bail if we hit EOD
93 lzsa1full:
94 addw %si, %dx
95 #endif
96 lzsa1chunk: // uncompress chunk
97 lodsb // get token O|LLL|MMMM
98 movb %al, %bl // keep token in bl
99 shrclw $4, %ax // shift literals length into place
100 movw $LITERALS_RUN_LEN+256*MIN_LITERALS_SIZE, %cx
101 call lzsa1len // %ch = LITERALS_RUN_LEN
102 rep movsb // copy %cx literals from %ds:%si to %es:%di
103 #ifndef RAW_FORMAT
104 cmpw %dx, %si
105 je lzsa1block // bail if we hit EOD
106 #endif
107 #ifdef FLAT32
108 orl $-1, %eax
109 #endif
110 testb %bl, %bl // check match offset size in token (O bit)
111 js lzsa1LongOfs
112 #ifndef FLAT32
113 movb $-1, %ah // set offset bits 15-8 to 1
114 #endif
115 lodsb
116 .byte 0xA8 // mask lodsw with testb $0xAD, %al
117 lzsa1LongOfs:
118 lodsw
119 xchg AX, BX // %bx: match offset %ax: original token
120 movw $MATCH_RUN_LEN+256*MIN_MATCH_SIZE, %cx
121 call lzsa1len
122 #ifdef RAW_FORMAT
123 jcxz lzsa1quit // bail if we hit EOD
124 #endif
126 #if !defined(FLAT16OUT) && !defined(FLAT32)
127 xchg AX, SI // save %si
128 lea (BX,DI), SI
129 pushw %ds
130 movw %es, %bp
131 cmpw %si, %di
132 jnc lzsa1sameSeg
133 pushw %si
134 shrclw $4, %si, 1
135 lea -4096(%bp,%si), %bp
136 popw %si
137 andw $0xF, %si
138 lzsa1sameSeg:
139 movw %bp, %ds
140 # ifdef FASTFILL
141 cmp $-FASTFILL,BX
142 jae lzsa1fast
143 # endif
144 rep movsb
145 lzsa1chunkz:
146 popw %ds
147 #else
148 # ifdef FASTFILL
149 cmp $-FASTFILL,BX
150 jae lzsa1fast
151 # endif
152 xchg AX, SI // save %si
153 lea (BX,DI), SI
154 # ifdef ONLY8086
155 # jcxz 1f
156 2:
157 movsb %es:(SI), %es:(DI) // NMOS 8088/8086 workaround.
158 loop 2b
159 1:
160 # else
161 rep movsb %es:(SI), %es:(DI)
162 # endif
163 #define lzsa1chunkz lzsa1chunk
164 #endif
165 xchg AX, SI // restore %si
166 jmp lzsa1chunk
167 #ifdef FASTFILL
168 lzsa1fast:
169 # if FASTFILL == 1
170 # if !defined(FLAT16OUT) && !defined(FLAT32)
171 lodsb
172 # else
173 movb %es:(BX,DI), %al
174 # endif
175 rep stosb
176 # endif
177 # if FASTFILL == 2
178 # if !defined(FLAT16OUT) && !defined(FLAT32)
179 lodsw
180 # else
181 movw %es:(BX,DI), %ax
182 # endif
183 je lzsa1fastword
184 movb %ah, %al
185 lzsa1fastword:
186 shr $1, CX
187 rep stosw
188 jnc lzsa1chunkz
189 stosb
190 # endif
191 jmp lzsa1chunkz
192 #endif
194 lzsa1len: // get length in %ecx
195 andb %cl, %al
196 cbw // clear %ah
197 cmpb %al, %cl
198 jne lzsa1minNumber // S=0-6, L=0-14 %cx = %ch + %al if (%al & %cl != %cl)
199 addb %al, %ch
200 lodsb
201 lzsa1minNumber:
202 addb %ch, %al
203 jnc lzsa1gotNumber // 0-255 %cx = %ch + %cl + byte if (%al & %cl == %cl && %ch + %cl + byte < 0x100)
204 movb %al, %ah // S=256-1791, L=256-4607 or S=256-511, L=256-511
205 jne lzsa1midNumber
206 lodsw // 0-65535 %cx = word if (%al & %cl == %cl && %ch + %cl + byte == 0x100)
207 .byte 0xA8 // mask lodsb with testb $0xAC, %al
208 lzsa1midNumber:
209 lodsb // %cx = (%ch + %cl + byte)*256 + byte2 if (%al & %cl == %cl && %ch + %cl + byte > 0x100)
210 lzsa1gotNumber:
211 xchgw %ax, %cx
212 lzsa1quit:
213 ret