wok view plop/stuff/unzx0.S @ rev 25647
Backout salvador 10% speedup: crashes with large files
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Fri Jan 26 12:15:51 2024 +0000 (9 months ago) |
parents | be3de88419e0 |
children | 54dc5622a785 |
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 cld // make string operations go forward
44 movb $0x80, %al // initialize empty bit queue
45 // plus bit to roll into carry
46 stc
47 sbb BX, BX // initialize rep-offset to 1
49 .literals:
50 #if !defined(FLAT16) && !defined(FLAT32)
51 movw $32768, %dx
52 cmpw %dx, %si // assume 32767 literals max
53 jb .si_ok
54 subw %dx, %si
55 movw %ds, %dx
56 addb $8, %dh
57 movw %dx, %ds
58 .si_ok:
59 #endif
60 call .get_elias // read number of literals to copy
61 rep movsb // copy literal bytes
63 addb %al, %al // shift bit queue, and high bit into carry
64 jc .get_offset // if 1: read offset, if 0: rep-match
66 call .get_elias // read rep-match length (starts at 1)
68 #if !defined(FLAT16OUT) && !defined(FLAT32)
69 jmp .copy_match
70 .fix_di:
71 subw $256, %di
72 movw %es, %dx
73 addw $16, %dx
74 movw %dx, %es
75 .copy_match:
76 cmpw $-32640, %di // assume 32639 max window
77 ja .fix_di
78 #else
79 .copy_match:
80 #endif
81 push SI // save si (current pointer to compressed data)
82 lea (BX,DI), SI // point to destination in es:di + offset in bx
83 #ifdef ONLY8086
84 .copy_loop:
85 movsb %es:(SI), %es:(DI) // copy matched bytes using NMOS 8088/8086 workaround.
86 loop .copy_loop
87 #else
88 rep movsb %es:(SI), %es:(DI) // copy matched bytes
89 #endif
90 pop SI // restore si
92 addb %al, %al // read 'literal or match' bit
93 jnc .literals // if 0: go copy literals
95 .get_offset:
96 movb $0xfe, %cl // initialize value to FEh
97 call .elias_loop // read high byte of match offset, set carry
98 incb %cl // obtain negative offset high byte
99 je .done // exit if EOD marker
101 movb %cl, %bh // transfer negative high byte into bh
102 movw $1, %cx // initialize match length value to 1
103 movb (%si), %bl // read low byte of offset + 1 bit of len
104 incw %si // inc instruction keep carry set
105 // set high bit that is shifted into bit 15
106 rcrw $1, %bx // shift len bit into carry/offset in place
107 call .elias_bt // if len bit is set, no need for more
108 // else read rest of elias-encoded match length
109 incw %cx // fix match length
110 jmp .copy_match // go copy match
112 .get_elias:
113 movw $1, %cx // initialize value to 1
114 .elias_loop:
115 addb %al, %al // shift bit queue, and high bit into carry
116 jnz .got_bit // queue not empty, bits remain
117 lodsb // read 8 new bits
118 adcb %al, %al // shift bit queue, and high bit into carry
119 .got_bit:
120 .elias_bt:
121 jc .got_elias // done if control bit is 1
122 addb %al, %al // read data bit
123 adcw %cx, %cx // shift into cx
124 jmp .elias_loop // keep reading
125 .got_elias:
126 .done:
127 ret