wok-tiny view linux/stuff/unlzsa2.S @ rev 174

Up linux 2.6.20 (avoid 386 & 486 problems)
author Pascal Bellard <pascal.bellard@slitaz.org>
date Wed Jul 14 14:20:00 2021 +0000 (2021-07-14)
parents
children d5c772484b59
line source
1 // based on
2 // decompress_small.S - space-efficient decompressor implementation for 8088
3 //
4 // Copyright (C) 2019 Emmanuel Marty
5 //
6 // This software is provided 'as-is', without any express or implied
7 // warranty. In no event will the authors be held liable for any damages
8 // arising from the use of this software.
9 //
10 // Permission is granted to anyone to use this software for any purpose,
11 // including commercial applications, and to alter it and redistribute it
12 // freely, subject to the following restrictions:
13 //
14 // 1. The origin of this software must not be misrepresented; you must not
15 // claim that you wrote the original software. If you use this software
16 // in a product, an acknowledgment in the product documentation would be
17 // appreciated but is not required.
18 // 2. Altered source versions must be plainly marked as such, and must not be
19 // misrepresented as being the original software.
20 // 3. This notice may not be removed or altered from any source distribution.
22 // ---------------------------------------------------------------------------
23 // Decompress raw LZSA2 block
24 // inputs:
25 // * %ds:%si: raw LZSA2 block
26 // * %es:%di: output buffer
27 // ---------------------------------------------------------------------------
29 .code16
30 lzsa2_decompress:
31 //pushw %di // remember decompression offset
32 //cld // make string operations (lods, movs, stos..) move forward
34 xorw %cx, %cx
35 movw $0x100, %bx
36 xorw %bp, %bp
38 lzsa2_decode_token:
39 movw %cx, %ax // clear %ah - %cx is zero from above or from after rep movsb in lzsa2_copy_match
40 lodsb // read token byte: XYZ|LL|MMMM
41 movw %ax,%dx // keep token in %dl
43 andb $0x18, %al // isolate literals length in token (LL)
44 #ifdef ONLY8086
45 movb $3, %cl
46 shrb %cl, %al // shift literals length into place
47 #else
48 shrb $3, %al // shift literals length into place
49 #endif
51 cmpb $3, %al // LITERALS_RUN_LEN_V2?
52 jne lzsa2_got_literals // no, we have the full literals count from the token, go copy
54 call lzsa2_get_nibble // get extra literals length nibble
55 addb %cl, %al // add len from token to nibble
56 cmpb $0x12, %al // LITERALS_RUN_LEN_V2 + 15 ?
57 jne lzsa2_got_literals // if not, we have the full literals count, go copy
58 lodsb // grab extra length byte
59 addb $0x12, %al // overflow?
60 jnc lzsa2_got_literals // if not, we have the full literals count, go copy
62 lodsw // grab 16-bit extra length
64 lzsa2_got_literals:
65 xchgw %ax, %cx
66 rep movsb // copy %cx literals from %ds:%si to %es:%di
68 testb $0xC0, %dl // check match offset size in token (X bit)
69 js lzsa2_rep_match_or_large_offset
71 //cmpb $0x40, %dl // check if this is a 5 or 9-bit offset (Y bit)
72 // discovered via the test with bit 6 set
73 xchgw %ax, %cx // clear %ah - %cx was zero from the rep movsb above
74 jne lzsa2_offset_9_bit
76 // 5 bit offset
77 cmpb $0x20, %dl // test bit 5
78 call lzsa2_get_nibble_x
79 jmp lzsa2_dec_offset_top
81 lzsa2_offset_9_bit: // 9 bit offset
82 lodsb // get 8 bit offset from stream in A
83 decb %ah // set offset bits 15-8 to 1
84 testb $0x20, %dl // test bit Z (offset bit 8)
85 je lzsa2_get_match_length
86 lzsa2_dec_offset_top:
87 decb %ah // clear bit 8 if Z bit is clear
88 // or set offset bits 15-8 to 1
89 jmp lzsa2_get_match_length
91 lzsa2_rep_match_or_large_offset:
92 //cmpb $0xC0, %dl // check if this is a 13-bit offset or a 16-bit offset/rep match (Y bit)
93 jpe lzsa2_rep_match_or_16_bit
95 // 13 bit offset
97 cmpb $0xA0, %dl // test bit 5 (knowing that bit 7 is also set)
98 xchgb %al, %ah
99 call lzsa2_get_nibble_x
100 subb $2, %al // substract 512
101 jmp lzsa2_get_match_length_1
103 lzsa2_rep_match_or_16_bit:
104 testb $0x20, %dl // test bit Z (offset bit 8)
105 jne lzsa2_repeat_match // rep-match
107 // 16 bit offset
108 lodsb // Get 2-byte match offset
110 lzsa2_get_match_length_1:
111 xchgb %al, %ah
112 lodsb // load match offset bits 0-7
114 lzsa2_get_match_length:
115 xchgw %ax, %bp // %bp: offset
116 lzsa2_repeat_match:
117 xchgw %ax, %dx // %ax: original token
118 andb $7, %al // isolate match length in token (MMM)
119 addb $2, %al // add MIN_MATCH_SIZE_V2
121 cmpb $9, %al // MIN_MATCH_SIZE_V2 + MATCH_RUN_LEN_V2?
122 jne lzsa2_got_matchlen // no, we have the full match length from the token, go copy
124 call lzsa2_get_nibble // get extra literals length nibble
125 addb %cl, %al // add len from token to nibble
126 cmpb $0x18, %al // MIN_MATCH_SIZE_V2 + MATCH_RUN_LEN_V2 + 15?
127 jne lzsa2_got_matchlen // no, we have the full match length from the token, go copy
129 lodsb // grab extra length byte
130 addb $0x18, %al // overflow?
131 jnc lzsa2_got_matchlen // if not, we have the entire length
132 je lzsa2_done_decompressing // detect EOD code
134 lodsw // grab 16-bit length
136 lzsa2_got_matchlen:
137 xchgw %ax, %cx // copy match length into %cx
138 xchgw %ax, %si // save %si (current pointer to compressed data)
139 leaw (%bx,%di), %si // %es:%si now points at back reference in output data
140 rep movsb %es:(%si), %es:(%di) // copy match
141 xchgw %ax, %si // restore %si
142 jmp lzsa2_decode_token // go decode another token
144 //lzsa2_done_decompressing:
145 // popw %ax // retrieve the original decompression offset
146 // xchgw %ax, %di // compute decompressed size
147 // subw %di, %ax
148 // ret // done
150 lzsa2_get_nibble_x:
151 cmc // carry set if bit 4 was set
152 rcrb $1, %al
153 call lzsa2_get_nibble // get nibble for offset bits 0-3
154 orb %cl, %al // merge nibble
155 rolb $1, %al
156 xorb $0xE1, %al // set offset bits 7-5 to 1
157 lzsa2_done_decompressing:
158 ret
160 lzsa2_get_nibble:
161 negb %bh // nibble ready?
162 jns lzsa2_has_nibble
164 xchgw %ax, %bx
165 lodsb // load two nibbles
166 xchgw %ax, %bx
168 lzsa2_has_nibble:
169 #ifdef ONLY8086
170 movb $4, %cl // swap 4 high and low bits of nibble
171 rorb %cl, %bl
172 #else
173 rorb $4, %bl
174 #endif
175 movb $0xF, %cl
176 andb %bl, %cl
177 ret