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