wok view plop/stuff/unzx0.S @ rev 25779
Up fdutils (5.6), lite (1.11), again
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Fri Sep 20 09:24:30 2024 +0000 (5 months ago) |
parents | 54dc5622a785 |
children |
line source
1 #ifndef FLAT32
2 // input ds:si=inStream, es:di=outStream
3 // output outStream[], ds:si, es:di
4 .code16
5 #define BX %bx
6 #define SI %si
7 #define DI %di
8 #else
9 // input esi=inStream, edi=outStream
10 // output outStream[], ds:esi, es:edi
11 .code32
12 #define BX %ebx
13 #define SI %esi
14 #define DI %edi
15 #endif
17 // unzx0_8088.S - ZX0 decompressor for 8088 - 73 bytes - NASM
18 //
19 // inputs:
20 // * ds:si: start of compressed data
21 // * es:di: start of decompression buffer
22 //
23 // Copyright (C) 2021 Emmanuel Marty
24 // ZX0 compression (c) 2021 Einar Saukas, https://github.com/einar-saukas/ZX0
25 //
26 // This software is provided 'as-is', without any express or implied
27 // warranty. In no event will the authors be held liable for any damages
28 // arising from the use of this software.
29 //
30 // Permission is granted to anyone to use this software for any purpose,
31 // including commercial applications, and to alter it and redistribute it
32 // freely, subject to the following restrictions:
33 //
34 // 1. The origin of this software must not be misrepresented; you must not
35 // claim that you wrote the original software. If you use this software
36 // in a product, an acknowledgment in the product documentation would be
37 // appreciated but is not required.
38 // 2. Altered source versions must be plainly marked as such, and must not be
39 // misrepresented as being the original software.
40 // 3. This notice may not be removed or altered from any source distribution.
42 zx0_decompress:
43 movb $0x80, %al // initialize empty bit queue
44 // plus bit to roll into carry
45 movw $-1, BX // initialize rep-offset to 1
47 .literals:
48 #if !defined(FLAT16) && !defined(FLAT32)
49 movw $32768, %dx
50 cmpw %dx, %si // assume 32767 literals max
51 jb .si_ok
52 subw %dx, %si
53 movw %ds, %dx
54 addb $8, %dh
55 movw %dx, %ds
56 .si_ok:
57 #endif
58 call .get_elias // read number of literals to copy
59 rep movsb // copy literal bytes
61 addb %al, %al // shift bit queue, and high bit into carry
62 jc .get_offset // if 1: read offset, if 0: rep-match
64 call .get_elias // read rep-match length (starts at 1)
66 #if !defined(FLAT16OUT) && !defined(FLAT32)
67 jmp .copy_match
68 .fix_di:
69 subw $64, %di
70 movw %es, %dx
71 addw $4, %dx
72 movw %dx, %es
73 .copy_match:
74 cmpw $-32640, %di // assume 32639 max window
75 ja .fix_di
76 # ifndef FLAT16
77 test %si, si
78 # ifdef BACKWARD
79 js .si_ok
80 movw %ds, %dx
81 subw $8, %dh
82 # else
83 jns .si_ok
84 movw %ds, %dx
85 addw $8, %dh
86 # endif
87 movw %dx, %ds
88 xorw $0x8000, %si
89 .si_ok:
90 # endif
91 #else
92 .copy_match:
93 #endif
94 push SI // save si (current pointer to compressed data)
95 lea (BX,DI), SI // point to destination in es:di + offset in bx
96 #ifdef ONLY8086
97 # jcxz 1f
98 2:
99 movsb %es:(SI), %es:(DI) // copy matched bytes using NMOS 8088/8086 workaround.
100 loop 2b
101 1:
102 #else
103 rep movsb %es:(SI), %es:(DI) // copy matched bytes
104 #endif
105 pop SI // restore si
107 addb %al, %al // read 'literal or match' bit
108 jnc .literals // if 0: go copy literals
110 .get_offset:
111 movb $0xfe, %cl // initialize value to FEh
112 call .elias_loop // read high byte of match offset, set carry
113 incb %cl // obtain negative offset high byte
114 je .done // exit if EOD marker
116 movb %cl, %bh // transfer negative high byte into bh
117 xchgw %ax, %bx
118 lodsb // read low byte of offset + 1 bit of len
119 xchgw %ax, %bx
120 movw $1, %cx // initialize match length value to 1
121 // set high bit that is shifted into bit 15
122 rcrw %cl, %bx // shift len bit into carry/offset in place
123 call .elias_bt // if len bit is set, no need for more
124 // else read rest of elias-encoded match length
125 incw %cx // fix match length
126 jmp .copy_match // go copy match
128 .get_elias:
129 movw $1, %cx // initialize value to 1
130 .elias_loop:
131 addb %al, %al // shift bit queue, and high bit into carry
132 jnz .got_bit // queue not empty, bits remain
133 lodsb // read 8 new bits
134 adcb %al, %al // shift bit queue, and high bit into carry
135 .got_bit:
136 .elias_bt:
137 jc .got_elias // done if control bit is 1
138 addb %al, %al // read data bit
139 adcw %cx, %cx // shift into cx
140 jmp .elias_loop // keep reading
141 .got_elias:
142 .done:
143 ret