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