wok-tiny view linux/stuff/unlzsa1.S @ rev 179

linux: rewrite stuff/pack
author Pascal Bellard <pascal.bellard@slitaz.org>
date Tue Aug 15 09:20:55 2023 +0000 (9 months ago)
parents 2c80994c5e30
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
29 #ifdef ONLY8086
30 movb \cnt, %cl
31 shrw %cl, \obj
32 #else
33 shrw \cnt, \obj
34 #endif
35 .endm
37 #ifdef FLAT16OUT
38 #define RAW_FORMAT
39 #endif
40 lzsa1main:
41 #ifdef PARANOIA
42 cld
43 #endif
44 #ifndef RAW_FORMAT
45 # ifndef NO_LZSA1_HEADER
46 lodsw
47 cmpw $0x9E7B, %ax // magic
48 jne lzsa1main
49 lodsb
50 // cmpb $0, %al // lzsa1
51 // jne lzsa1main
52 # endif
53 xorw %ax, %ax
54 xchgw %ax, %di
55 shrclw $4, %ax
56 jmp lzsa1blockz // %di *MUST* be paragraph aligned
57 # ifndef PACKED_ONLY
58 lzsa1copy:
59 movsb // handle 64K case
60 decw %cx
61 rep movsb // copy block
62 # endif
63 lzsa1block: // uncompress chunk
64 movw $0x1000, %ax
65 lzsa1blockz:
66 movw %es, %bx
67 addw %ax, %bx
68 movw %bx, %es
69 # ifndef FLAT16
70 movw %si, %ax
71 andw $0xf, %si
72 shrclw $4, %ax
73 movw %ds, %bx
74 addw %ax, %bx
75 movw %bx, %ds
76 # endif
77 lodsw // block size
78 xchgw %ax, %cx
79 movw %cx, %dx
80 lodsb
81 # ifndef PACKED_ONLY
82 orb %al, %al
83 js lzsa1copy
84 jne lzsa1full // 64Kb block
85 # endif
86 jcxz lzsa1quit // bail if we hit EOD
87 lzsa1full:
88 addw %si, %dx
89 #endif
90 lzsa1chunk: // uncompress chunk
91 lodsb // get token O|LLL|MMMM
92 movb %al, %bl // keep token in bl
93 shrclw $4, %ax // shift literals length into place
94 movw $LITERALS_RUN_LEN+256*MIN_LITERALS_SIZE, %cx
95 call lzsa1len // %ch = LITERALS_RUN_LEN
96 rep movsb // copy %cx literals from %ds:%si to %es:%di
97 #ifndef RAW_FORMAT
98 cmpw %dx, %si
99 je lzsa1block // bail if we hit EOD
100 #endif
101 #ifdef FLAT32
102 orl $-1, %eax
103 #endif
104 testb %bl, %bl // check match offset size in token (O bit)
105 js lzsa1LongOfs
106 #ifndef FLAT32
107 movb $-1, %ah // set offset bits 15-8 to 1
108 #endif
109 lodsb
110 .byte 0x3C // mask lodsw with cmpb $0xAD, %al
111 lzsa1LongOfs:
112 lodsw
113 xchg AX, BX // %bx: match offset %ax: original token
114 movw $MATCH_RUN_LEN+256*MIN_MATCH_SIZE, %cx
115 call lzsa1len
116 #ifdef RAW_FORMAT
117 jcxz lzsa1quit // bail if we hit EOD
118 #endif
120 #if !defined(FLAT16OUT) && !defined(FLAT32)
121 xchg AX, SI // save %si
122 lea (BX,DI), SI
123 pushw %ds
124 movw %es, %bp
125 cmpw %si, %di
126 jnc lzsa1sameSeg
127 pushw %si
128 # ifdef ONLY8086
129 pushw %cx
130 # endif
131 shrclw $4, %si
132 # ifdef ONLY8086
133 popw %cx
134 # endif
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 lzsa2movsb:
156 movsb %es:(SI), %es:(DI) // NMOS 8088/8086 workaround.
157 loop lzsa2movsb
158 # else
159 rep movsb %es:(SI), %es:(DI)
160 # endif
161 #define lzsa1chunkz lzsa1chunk
162 #endif
163 xchg AX, SI // restore %si
164 jmp lzsa1chunk
165 #ifdef FASTFILL
166 lzsa1fast:
167 # if FASTFILL == 1
168 # if !defined(FLAT16OUT) && !defined(FLAT32)
169 lodsb
170 # else
171 movb %es:(BX,DI), %al
172 # endif
173 rep stosb
174 # endif
175 # if FASTFILL == 2
176 # if !defined(FLAT16OUT) && !defined(FLAT32)
177 lodsw
178 # else
179 movw %es:(BX,DI), %ax
180 # endif
181 je lzsa1fastword
182 movb %ah, %al
183 lzsa1fastword:
184 shr $1, CX
185 rep stosw
186 jnc lzsa1chunkz
187 stosb
188 # endif
189 jmp lzsa1chunkz
190 #endif
192 lzsa1len: // get length in %ecx
193 andb %cl, %al
194 cbw // clear %ah
195 cmpb %al, %cl
196 jne lzsa1minNumber // S=0-6, L=0-14 %cx = %ch + %al if (%al & %cl != %cl)
197 addb %al, %ch
198 lodsb
199 lzsa1minNumber:
200 addb %ch, %al
201 jnc lzsa1gotNumber // 0-255 %cx = %ch + %cl + byte if (%al & %cl == %cl && %ch + %cl + byte < 0x100)
202 movb %al, %ah // S=256-1791, L=256-4607 or S=256-511, L=256-511
203 jne lzsa1midNumber
204 lodsw // 0-65535 %cx = word if (%al & %cl == %cl && %ch + %cl + byte == 0x100)
205 .byte 0x3C // mask lodsb with cmpb $0xAC, %al
206 lzsa1midNumber:
207 lodsb // %cx = (%ch + %cl + byte)*256 + byte2 if (%al & %cl == %cl && %ch + %cl + byte > 0x100)
208 lzsa1gotNumber:
209 xchgw %ax, %cx
210 lzsa1quit:
211 ret