wok view plop/stuff/unlzsa2.S @ rev 25613
Add grub-btrfs
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Wed Aug 02 09:46:03 2023 +0000 (12 months ago) |
parents | f2b4a9eb8bdd |
children | a794ec0a6495 |
line source
1 // Lzsa2Decode:
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 = 7
21 LITERALS_RUN_LEN = 3
22 MIN_MATCH_SIZE = 2
23 MIN_LITERALS_SIZE = 0
25 #define PACKED_ONLY // assume no copy block, optional
26 //#define PARANOIA // cover rare cases, optional
28 .macro shrcl cnt,obj
29 #ifdef ONLY8086
30 movb \cnt, %cl
31 shr %cl, \obj
32 #else
33 shr \cnt, \obj
34 #endif
35 .endm
37 #ifdef FLAT16OUT
38 #define RAW_FORMAT
39 #endif
40 lzsa2main:
41 #ifdef PARANOIA
42 cld
43 #endif
44 #ifndef RAW_FORMAT
45 # ifndef NO_LZSA2_HEADER
46 lodsw
47 cmpw $0x9E7B, %ax // magic
48 jne lzsa2main
49 lodsb
50 // testb $0x20, %al // lzsa2
51 // je lzsa2main
52 # endif
53 xorw %ax, %ax
54 cwd // no nibble stored
55 xchgw %ax, %di
56 shrcl $4, %ax
57 jmp lzsa2blockz // %di *MUST* be paragraph aligned
58 # ifndef PACKED_ONLY
59 lzsa2copy:
60 movsb // handle 64K case
61 decw %cx
62 rep movsb // copy block
63 # endif
64 lzsa2block: // uncompress chunk
65 movw $0x1000, %ax
66 lzsa2blockz:
67 movw %es, %bx
68 addw %ax, %bx
69 movw %bx, %es
70 # ifndef FLAT16
71 movw %si, %ax
72 andw $0xf, %si
73 shrcl $4, %ax
74 movw %ds, %bx
75 addw %ax, %bx
76 movw %bx, %ds
77 # endif
78 lodsw // block size
79 xchgw %ax, %cx
80 movw %cx, %bp
81 lodsb
82 # ifndef PACKED_ONLY
83 orb %al, %al
84 js lzsa2copy
85 jne lzsa2full // 64Kb block
86 # endif
87 jcxz lzsa2quit // bail if we hit EOD
88 lzsa2full:
89 addw %si, %bp
90 #else
91 movb $0, %dh // no nibble stored
92 #endif
93 #ifdef FLAT32
94 orl $-1, %ebx // set offset bits 31-16 to 1
95 #endif
96 lzsa2chunk: // uncompress chunk
97 lodsb // get token XYZ|LL|MMM
98 pushw %ax // keep token
99 movw $LITERALS_RUN_LEN+256*MIN_LITERALS_SIZE, %cx
100 shrb %cl, %al // shift literals length into place
101 call lzsa2len // %cl = LITERALS_RUN_LEN
102 rep movsb // copy %cx literals from %ds:%si to %es:%di
103 popw %ax // restore token
104 #ifndef RAW_FORMAT
105 cmpw %bp, %si
106 je lzsa2block // bail if we hit EOD
107 #endif
108 pushw %ax // save token
109 // Decode XYZ bits to SZC flags
110 andb $0xE0, %al // filter XYZ
111 movb %al, %ah
112 orb $0xDF, %al
113 incw %ax
114 sahf // ah=SZ.A.P.C
115 je no_nibble_in_offset // Y=1
117 call getNibble // get nibble for offset bits 0-3, kill %cl
118 sahf
119 rclb $1, %al
120 xorb $0xE1, %al // set offset bits 7-5 to 1
121 sahf
122 cbw // set offset bits 15-8 to 1
123 // 00Z 5-bit offset: read a nibble for offset bits 1-4 and use the inverted bit Z of the token as bit 0 of the offset.
124 // set bits 5-15 of the offset to 1.
125 jns get_match_length // 5-bit offset
126 //10Z 13-bit offset: read a nibble for offset bits 9-12 and use the inverted bit Z for bit 8 of the offset,
127 // then read a byte for offset bits 0-7. set bits 13-15 of the offset to 1.
128 // substract 512 from the offset to get the final value.
129 subb $2, %al // substract 512, clear C
130 jmp get_match_length_1
132 getNibble:
133 xorb $0xF0, %dh // toggle nibble stored flags
134 movb %dh, %al
135 jns gotnibble
136 lodsb
137 movb $0xF0, %dh
138 orb %al, %dh
139 shrcl $4, %al
140 gotnibble:
141 lzsa2quit:
142 ret
144 no_nibble_in_offset:
145 movb $-1, %ah // set offset bits 15-8 to 1
146 jns offset_9_bit // X=0 Y=1
147 jc repeat_match // rep-match X=1 Y=1 Z=1
148 //110 16-bit offset: read a byte for offset bits 8-15, then another byte for offset bits 0-7.
149 lodsb // Get 2-byte match offset
150 get_match_length_1:
151 xchgb %al, %ah
153 offset_9_bit: // Z=C
154 // 01Z 9-bit offset: read a byte for offset bits 0-7 and use the inverted bit Z for bit 8 of the offset.
155 // set bits 9-15 of the offset to 1.
156 sbbb %ch, %ah // clear bit 8 if Z bit is clear (%ch == 0)
157 lodsb // load match offset bits 0-7
158 get_match_length:
159 xchgw %ax, %bx // bx: offset
160 repeat_match:
161 //111 repeat offset: reuse the offset value of the previous match command.
163 popw %ax // restore original token in %al
164 movw $MATCH_RUN_LEN+256*MIN_MATCH_SIZE, %cx
165 call lzsa2len
166 #if !defined(ENHANCED_FORMAT) && defined(RAW_FORMAT)
167 je lzsa2quit // bail if we hit EOD in (%si-2)
168 #endif
170 #if !defined(FLAT16OUT) && !defined(FLAT32)
171 xchg AX, SI // save %si
172 lea (BX,DI), SI
173 pushw %ds
174 # ifndef RAW_FORMAT
175 pushw %bp // save end
176 # endif
177 movw %es, %bp
178 cmpw %si, %di
179 jnc lzsa2sameSeg
180 pushw %si
181 # ifdef ONLY8086
182 pushw %cx
183 # endif
184 shrcl $4, %si
185 # ifdef ONLY8086
186 popw %cx
187 # endif
188 lea -4096(%bp,%si), %bp
189 popw %si
190 andw $0xF, %si
191 lzsa2sameSeg:
192 movw %bp, %ds
193 # ifdef FASTFILL
194 cmp $-FASTFILL,BX
195 jae lzsa2fast
196 # endif
197 rep movsb
198 lzsa2chunkz:
199 # ifndef RAW_FORMAT
200 popw %bp // restore end
201 # endif
202 popw %ds
203 #else
204 # ifdef FASTFILL
205 cmp $-FASTFILL,BX
206 jae lzsa2fast
207 # endif
208 xchg AX, SI // save %si
209 lea (BX,DI), SI
210 rep movsb %es:(SI), %es:(DI)
211 #define lzsa2chunkz lzsa2chunk
212 #endif
213 xchg AX, SI // restore %si
214 jmp lzsa2chunk
215 #ifdef FASTFILL
216 lzsa2fast:
217 # if FASTFILL == 1
218 # if !defined(FLAT16OUT) && !defined(FLAT32)
219 lodsb
220 # else
221 movb %es:(BX,DI), %al
222 # endif
223 rep stosb
224 # endif
225 # if FASTFILL == 2
226 # if !defined(FLAT16OUT) && !defined(FLAT32)
227 lodsw
228 # else
229 movw %es:(BX,DI), %ax
230 # endif
231 je lzsa2fastword
232 movb %ah, %al
233 lzsa2fastword:
234 shr $1, CX
235 rep stosw
236 jnc lzsa2chunkz
237 stosb
238 # endif
239 jmp lzsa2chunkz
240 #endif
242 lzsa2len: // get length in %cx
243 andb %cl, %al
244 cbw // clear %ah
245 cmpb %al, %cl
246 jne lzsa2minNumber // S=0-2, L=0-6 %cx = %ch + %al if (%al & %cl != %cl)
247 addb %al, %ch
248 call getNibble // kill %cl
249 cmp $0xF, %al
250 jne lzsa2minNumber // %cx = %ch + %cl + nibble if (%al & %cl == %cl && nibble != 0xF)
251 addb %al, %ch
252 lodsb
253 lzsa2minNumber:
254 addb %ch, %al
255 jnc lzsa2gotNumber // 0-255 %cx = %ch + %cl + 0xF + byte if (%al & %cl == %cl && nibble == 0xF && %ch + %cl + 0xF + byte < 0x100)
256 #ifdef ENHANCED_FORMAT
257 decw %ax
258 je lzsa2maxNumber
259 # ifdef RAW_FORMAT
260 jns lzsa2midNumber
261 popw %ax
262 ret // bail if we hit EOD
263 lzsa2midNumber:
264 # endif
265 xchgb %al, %ah // S=256-4351, L=256-5887
266 lodsb // %cx = (%ch + %cl + 0xE + byte)*256 + byte2 if (%al & %cl == %cl && nibble == 0xF && %ch + %cl + 0xF + byte > 0x100)
267 .byte 0xB1 // mask lodsw with movb $0xAD, %cl
268 lzsa2maxNumber:
269 #endif
270 lodsw // 0-65535 %cx = word if (%al & %cl == %cl && nibble == 0xF && %ch + %cl + 0xF + byte == 0x100)
271 lzsa2gotNumber:
272 xchgw %ax, %cx
273 ret