|
@@ -1,400 +0,0 @@
|
1
|
|
-/*****************************************************************************
|
2
|
|
- * NOTE: This code is no longer used in Etherboot. The obsolete
|
3
|
|
- * Makefile target .lzrom refers to it, but it is no longer being
|
4
|
|
- * maintained and may no longer work. Use .zrom instead (which uses
|
5
|
|
- * the unnrv2b decompressor).
|
6
|
|
- *****************************************************************************
|
7
|
|
- */
|
8
|
|
-
|
9
|
|
-/* At entry, the processor is in 16 bit real mode and the code is being
|
10
|
|
- * executed from an address it was not linked to. Code must be pic and
|
11
|
|
- * 32 bit sensitive until things are fixed up.
|
12
|
|
- */
|
13
|
|
-
|
14
|
|
-
|
15
|
|
-/* LZHuf (LZSS) Decompressing boot loader for ROM images
|
16
|
|
- *
|
17
|
|
- * this code is based on the work of Haruyasu Yoshizaki and Haruhiko Okumura
|
18
|
|
- * who implemented the original compressor and decompressor in C code
|
19
|
|
- *
|
20
|
|
- * Converted to 32bit assembly 16 July 2002 Eric Biederman <ebiederman@lnxi.com>
|
21
|
|
- * Made PIC 10 Aug 2002 Eric Biederman <ebiederman@lnxi.com>
|
22
|
|
- *
|
23
|
|
- * Copyright 1997 by M. Gutschke <gutschk@math.uni-muenster.de>
|
24
|
|
- *
|
25
|
|
- * Compression pays off, as soon as the uncompressed image is bigger than
|
26
|
|
- * about 1.5kB. This assumes an average compressibility of about 60%.
|
27
|
|
- */
|
28
|
|
-
|
29
|
|
-
|
30
|
|
-/* Do not change these values unless you really know what you are doing
|
31
|
|
- * the pre-computed lookup tables rely on the buffer size being 4kB or
|
32
|
|
- * smaller. The buffer size must be a power of two. The lookahead size has
|
33
|
|
- * to fit into 6 bits. If you change any of these numbers, you will also
|
34
|
|
- * have to adjust the compressor accordingly.
|
35
|
|
- */
|
36
|
|
-#define BUFSZ 4096
|
37
|
|
-#define LOOKAHEAD 60
|
38
|
|
-#define THRESHOLD 2
|
39
|
|
-#define NCHAR (256+LOOKAHEAD-THRESHOLD)
|
40
|
|
-#define TABLESZ (NCHAR+NCHAR-1)
|
41
|
|
-#define ROOT (TABLESZ-1)
|
42
|
|
-
|
43
|
|
- .text
|
44
|
|
- .arch i386
|
45
|
|
- .globl _start
|
46
|
|
-_start:
|
47
|
|
- cli
|
48
|
|
-
|
49
|
|
- /* Save the initial register values */
|
50
|
|
- pushal
|
51
|
|
-
|
52
|
|
- /*
|
53
|
|
- * See where I am running, and compute %ebp
|
54
|
|
- */
|
55
|
|
- call 1f
|
56
|
|
-1: pop %ebp
|
57
|
|
- subl $1b, %ebp
|
58
|
|
-
|
59
|
|
-/*
|
60
|
|
- * INIT -- initializes all data structures
|
61
|
|
- * ====
|
62
|
|
- */
|
63
|
|
-
|
64
|
|
-init:
|
65
|
|
- cld
|
66
|
|
- leal dcodrle(%ebp), %esi /* uncompress run length encoded */
|
67
|
|
- leal dcode(%ebp), %edi /* lookup table for codes */
|
68
|
|
- movb $6, %dl
|
69
|
|
- movb $0x20, %dh
|
70
|
|
- xorb %bh,%bh
|
71
|
|
-init0:
|
72
|
|
- lodsb
|
73
|
|
- movb %al,%bl
|
74
|
|
-init1:
|
75
|
|
- xorl %ecx, %ecx
|
76
|
|
- movb %dh,%cl
|
77
|
|
- movb %bh,%al
|
78
|
|
- rep
|
79
|
|
- stosb
|
80
|
|
- incb %bh
|
81
|
|
- decb %bl
|
82
|
|
- jnz init1
|
83
|
|
- shrb %dh
|
84
|
|
- decb %dl
|
85
|
|
- jnz init0
|
86
|
|
- movb $1, %bl /* uncompress run length encoded */
|
87
|
|
- movb $6, %bh /* lookup table for code lengths */
|
88
|
|
-init2:
|
89
|
|
- lodsb
|
90
|
|
- xorl %ecx, %ecx
|
91
|
|
- movb %al,%cl
|
92
|
|
- movb %bl,%al
|
93
|
|
- rep
|
94
|
|
- stosb
|
95
|
|
- incb %bl
|
96
|
|
- decb %bh
|
97
|
|
- jnz init2
|
98
|
|
-
|
99
|
|
- movl $NCHAR, %ecx /* set all frequencies of leaf nodes */
|
100
|
|
- movw $1, %ax /* to one */
|
101
|
|
- rep
|
102
|
|
- stosw
|
103
|
|
- leal freq(%ebp), %esi
|
104
|
|
- movl $ROOT+1-NCHAR, %ecx
|
105
|
|
-init3:
|
106
|
|
- lodsw /* update frequencies of non-leaf nodes */
|
107
|
|
- movw %ax,%bx
|
108
|
|
- lodsw
|
109
|
|
- addw %bx,%ax
|
110
|
|
- stosw
|
111
|
|
- loop init3
|
112
|
|
- movw $0xFFFF, %ax
|
113
|
|
- stosw /* sentinel with infinite frequency */
|
114
|
|
- movl $NCHAR, %ecx
|
115
|
|
- movw $TABLESZ, %ax
|
116
|
|
-init4:
|
117
|
|
- stosw /* update son pointers for leaf nodes */
|
118
|
|
- incw %ax
|
119
|
|
- loop init4
|
120
|
|
- movl $ROOT+1-NCHAR, %ecx
|
121
|
|
- xorw %ax,%ax
|
122
|
|
-init5:
|
123
|
|
- stosw /* update son ptrs for non-leaf nodes */
|
124
|
|
- addw $2, %ax
|
125
|
|
- loop init5
|
126
|
|
- movl $ROOT+1-NCHAR, %ecx
|
127
|
|
- movw $NCHAR, %ax
|
128
|
|
-init6:
|
129
|
|
- stosw /* update parent ptrs for non-leaf nd. */
|
130
|
|
- stosw
|
131
|
|
- incw %ax
|
132
|
|
- loop init6
|
133
|
|
- movl $NCHAR, %ecx
|
134
|
|
- xorw %ax,%ax
|
135
|
|
- stosw /* root node has no parent */
|
136
|
|
-init7:
|
137
|
|
- stosw /* update parent ptrs for leaf nodes */
|
138
|
|
- incw %ax
|
139
|
|
- loop init7
|
140
|
|
- xorw %ax,%ax
|
141
|
|
- stosb /* clear getlen */
|
142
|
|
- stosw /* clear getbuf */
|
143
|
|
- movb $0x20, %al /* fill text buffer with spaces */
|
144
|
|
- leal spaces(%ebp), %edi
|
145
|
|
- movl $BUFSZ-LOOKAHEAD, %ecx
|
146
|
|
- rep
|
147
|
|
-
|
148
|
|
- stosb
|
149
|
|
- /* fall thru */
|
150
|
|
-
|
151
|
|
-/*
|
152
|
|
- * MAIN -- reads compressed codes and writes decompressed data
|
153
|
|
- * ====
|
154
|
|
- */
|
155
|
|
-
|
156
|
|
- leal _payload(%ebp), %esi /* get length of compressed data stream */
|
157
|
|
- leal uncompressed(%ebp), %edi
|
158
|
|
-
|
159
|
|
- lodsl
|
160
|
|
- movl %eax, %ecx
|
161
|
|
-main1:
|
162
|
|
- pushl %ecx
|
163
|
|
- call dcdchr /* decode one code symbol */
|
164
|
|
- orb %ah,%ah /* test if 8bit character */
|
165
|
|
- jnz main2
|
166
|
|
- stosb /* store verbatim */
|
167
|
|
- popl %ecx
|
168
|
|
- loop main1 /* proceed with next compressed code */
|
169
|
|
- jmp done /* until end of input is detected */
|
170
|
|
-main2:
|
171
|
|
- pushl %eax
|
172
|
|
- call dcdpos /* compute position in output buffer */
|
173
|
|
- movl %esi, %eax
|
174
|
|
- subl %edi, %ebx
|
175
|
|
- notl %ebx
|
176
|
|
- movl %ebx, %esi /* si := di - dcdpos() - 1 */
|
177
|
|
- popl %ecx
|
178
|
|
- subl $255-THRESHOLD, %ecx /* compute length of code sequence */
|
179
|
|
- movl %ecx, %edx
|
180
|
|
- rep
|
181
|
|
- movsb
|
182
|
|
- movl %eax,%esi
|
183
|
|
- popl %ecx
|
184
|
|
- subl %edx, %ecx /* check end of input condition */
|
185
|
|
- jnz main1 /* proceed with next compressed code */
|
186
|
|
-done:
|
187
|
|
- /* Start Etherboot */
|
188
|
|
- popal
|
189
|
|
- jmp uncompressed
|
190
|
|
-/*
|
191
|
|
- * GETBIT -- gets one bit pointed to by DS:ESI
|
192
|
|
- * ======
|
193
|
|
- *
|
194
|
|
- * changes: AX,CX,DL
|
195
|
|
- */
|
196
|
|
-
|
197
|
|
-getbit:
|
198
|
|
- movb $8, %cl
|
199
|
|
- movb getlen(%ebp), %dl /* compute number of bits required */
|
200
|
|
- subb %dl,%cl /* to fill read buffer */
|
201
|
|
- jae getbit1
|
202
|
|
- movw getbuf(%ebp), %ax /* there is still enough read ahead data */
|
203
|
|
- jmp getbit2
|
204
|
|
-getbit1:
|
205
|
|
- lodsb /* get next byte from input stream */
|
206
|
|
- xorb %ah,%ah
|
207
|
|
- shlw %cl,%ax /* shift, so that it will fit into */
|
208
|
|
- movw getbuf(%ebp), %cx /* read ahead buffer */
|
209
|
|
- orw %cx,%ax
|
210
|
|
- addb $8, %dl /* update number of bits in buffer */
|
211
|
|
-getbit2:
|
212
|
|
- movw %ax,%cx
|
213
|
|
- shlw %cx /* extract one bit from buffer */
|
214
|
|
- movw %cx, getbuf(%ebp)
|
215
|
|
- decb %dl
|
216
|
|
- movb %dl, getlen(%ebp) /* and update number of bits */
|
217
|
|
- shlw %ax /* return in carry flag */
|
218
|
|
- ret
|
219
|
|
-
|
220
|
|
-
|
221
|
|
-/*
|
222
|
|
- * DCDPOS -- decodes position in textbuffer as pointed to by DS:SI, result in BX
|
223
|
|
- * ======
|
224
|
|
- *
|
225
|
|
- * changes: AX,EBX,ECX,DX
|
226
|
|
- */
|
227
|
|
-
|
228
|
|
-dcdpos:
|
229
|
|
- movl $0x0800, %ebx
|
230
|
|
-dcdpos1:
|
231
|
|
- shlb %bl /* read one byte */
|
232
|
|
- call getbit
|
233
|
|
- jnc dcdpos2
|
234
|
|
- incb %bl
|
235
|
|
-dcdpos2:
|
236
|
|
- decb %bh
|
237
|
|
- jnz dcdpos1
|
238
|
|
- movb %bl,%dh /* read length of code from table */
|
239
|
|
- xorb %bh,%bh
|
240
|
|
- xorl %ecx, %ecx
|
241
|
|
- movb dlen(%ebx, %ebp),%cl
|
242
|
|
- movb dcode(%ebx, %ebp),%bl /* get top six bits from table */
|
243
|
|
- shll $6, %ebx
|
244
|
|
-dcdpos3:
|
245
|
|
- pushl %ecx /* read the rest from the input stream */
|
246
|
|
- shlb %dh
|
247
|
|
- call getbit
|
248
|
|
- jnc dcdpos4
|
249
|
|
- incb %dh
|
250
|
|
-dcdpos4:
|
251
|
|
- popl %ecx
|
252
|
|
- loop dcdpos3
|
253
|
|
- andb $0x3f, %dh /* combine upper and lower half of code */
|
254
|
|
- orb %dh,%bl
|
255
|
|
- ret
|
256
|
|
-
|
257
|
|
-/*
|
258
|
|
- * DCDCHR -- decodes one compressed character pointed to by DS:SI
|
259
|
|
- * ======
|
260
|
|
- *
|
261
|
|
- * changes: AX,BX,CX,DX
|
262
|
|
- */
|
263
|
|
-
|
264
|
|
-dcdchr:
|
265
|
|
- movl $ROOT, %ebx /* start at root entry */
|
266
|
|
- shll %ebx
|
267
|
|
- movzwl son(%ebx, %ebp),%ebx
|
268
|
|
-dcdchr1:
|
269
|
|
- call getbit /* get a single bit */
|
270
|
|
- jnc dcdchr2
|
271
|
|
- incl %ebx /* travel left or right */
|
272
|
|
-dcdchr2:
|
273
|
|
- shll %ebx
|
274
|
|
- movzwl son(%ebx, %ebp), %ebx
|
275
|
|
- cmpl $TABLESZ, %ebx /* until we come to a leaf node */
|
276
|
|
- jb dcdchr1
|
277
|
|
- movl %ebx, %eax
|
278
|
|
- subl $TABLESZ, %eax
|
279
|
|
- /* fall thru */
|
280
|
|
-
|
281
|
|
-/*
|
282
|
|
- * UPDATE -- updates huffman tree after incrementing frequency for code in BX
|
283
|
|
- * ======
|
284
|
|
- *
|
285
|
|
- * changes: BX,CX,DX
|
286
|
|
- */
|
287
|
|
-
|
288
|
|
-update:
|
289
|
|
- /* we do not check whether the frequency count has overrun.
|
290
|
|
- * this will cause problems for large files, but be should be fine
|
291
|
|
- * as long as the compressed size does not exceed 32kB and we
|
292
|
|
- * cannot do more than this anyways, because we load into the
|
293
|
|
- * upper 32kB of conventional memory
|
294
|
|
- */
|
295
|
|
- pushl %esi
|
296
|
|
- pushl %eax
|
297
|
|
- shll %ebx
|
298
|
|
- movzwl parent(%ebx, %ebp),%ebx
|
299
|
|
-update1:
|
300
|
|
- shll %ebx
|
301
|
|
- movzwl freq(%ebx, %ebp), %edx
|
302
|
|
- incl %edx /* increment frequency count by one */
|
303
|
|
- movw %dx, freq(%ebx, %ebp)
|
304
|
|
- leal 2+freq(%ebx, %ebp), %esi
|
305
|
|
- lodsw /* check if nodes need reordering */
|
306
|
|
- cmpw %ax, %dx
|
307
|
|
- jbe update5
|
308
|
|
-update2:
|
309
|
|
- lodsw
|
310
|
|
- cmpw %dx, %ax
|
311
|
|
- jb update2
|
312
|
|
- movzwl -4(%esi), %ecx
|
313
|
|
- movw %cx, freq(%ebx, %ebp) /* swap frequency of entries */
|
314
|
|
- movw %dx, -4(%esi)
|
315
|
|
-
|
316
|
|
- movl %esi, %eax /* compute index of new entry */
|
317
|
|
- subl $freq+4, %eax
|
318
|
|
- subl %ebp, %eax
|
319
|
|
-
|
320
|
|
- movl %eax, %edx
|
321
|
|
- shrl %eax
|
322
|
|
- movzwl son(%ebx, %ebp), %ecx /* get son of old entry */
|
323
|
|
- movl %ecx, %esi
|
324
|
|
- addl %esi, %esi
|
325
|
|
- movw %ax, parent(%esi, %ebp) /* and update the ptr to new parent */
|
326
|
|
- cmpl $TABLESZ, %ecx
|
327
|
|
- jae update3 /* do this for both branches */
|
328
|
|
- movw %ax, parent+2(%esi, %ebp) /* if not a leaf node */
|
329
|
|
-update3:
|
330
|
|
- movl %edx, %esi
|
331
|
|
- movzwl son(%esi, %ebp), %edx /* get son of new entry */
|
332
|
|
- movw %cx, son(%esi, %ebp) /* update its contents */
|
333
|
|
- movl %edx, %esi
|
334
|
|
- addl %esi, %esi
|
335
|
|
- movl %ebx, %ecx
|
336
|
|
- shrl %ecx
|
337
|
|
- movw %cx, parent(%esi, %ebp) /* and update the ptr to new paren */
|
338
|
|
- cmpl $TABLESZ, %edx
|
339
|
|
- jae update4 /* do this for both branches */
|
340
|
|
- movw %cx, parent+2(%esi, %ebp) /* if not a leaf node */
|
341
|
|
-update4:
|
342
|
|
- movw %dx, son(%ebx, %ebp) /* update son of old entry */
|
343
|
|
- movl %eax, %ebx /* continue with new entry */
|
344
|
|
- shll %ebx
|
345
|
|
-update5:
|
346
|
|
- movzwl parent(%ebx, %ebp), %ebx /* continue with parent */
|
347
|
|
- orl %ebx, %ebx
|
348
|
|
- jnz update1 /* until we found the root entry */
|
349
|
|
- popl %eax
|
350
|
|
- popl %esi
|
351
|
|
- ret
|
352
|
|
-
|
353
|
|
-/*
|
354
|
|
- * constant data. this part of the program resides in ROM and cannot be
|
355
|
|
- * changed
|
356
|
|
- *
|
357
|
|
- * run length encoded tables will be uncompressed into the bss segment
|
358
|
|
- * take care with any symbols here for .com files to add 0x100 to address
|
359
|
|
- */
|
360
|
|
-
|
361
|
|
-dcodrle: .byte 0x01,0x03,0x08,0x0C,0x18,0x10
|
362
|
|
-dlenrle: .byte 0x20,0x30,0x40,0x30,0x30,0x10
|
363
|
|
-
|
364
|
|
-/*
|
365
|
|
- * variable data segment (bss)
|
366
|
|
- * this segment will always be found at 0x90000 (i.e. at RELOC - SCRATCH)
|
367
|
|
- *
|
368
|
|
- * do not change the order or the sizes of any of the following tables
|
369
|
|
- * the initialization code makes assumptions on the exact layout of the
|
370
|
|
- * data structures...
|
371
|
|
- */
|
372
|
|
-
|
373
|
|
-.bss
|
374
|
|
-/* lookup table for index into buffer of recently output characters */
|
375
|
|
-dcode: .skip 256
|
376
|
|
-
|
377
|
|
-/* lookup table for length of code sequence from buffer of recent characters */
|
378
|
|
-dlen: .skip 256
|
379
|
|
-
|
380
|
|
-/* table with frequency counts for all codes */
|
381
|
|
-freq: .skip 2*(TABLESZ+1)
|
382
|
|
-
|
383
|
|
-/* pointer to child nodes */
|
384
|
|
-son: .skip 2*(TABLESZ)
|
385
|
|
-
|
386
|
|
-/* the first part of this table contains all the codes (0..TABLESZ-1) */
|
387
|
|
-/* the second part contains all leaf nodes (TABLESZ..) */
|
388
|
|
-parent: .skip 2*(TABLESZ+NCHAR)
|
389
|
|
-
|
390
|
|
-/* temporary storage for extracting bits from compressed data stream */
|
391
|
|
-getlen: .skip 1
|
392
|
|
-getbuf: .skip 1
|
393
|
|
-
|
394
|
|
- /* the initial buffer has to be filled with spaces */
|
395
|
|
- .balign 4
|
396
|
|
-spaces:
|
397
|
|
- .skip BUFSZ - LOOKAHEAD
|
398
|
|
- /* uncompressed data will be written here */
|
399
|
|
-uncompressed:
|
400
|
|
-
|