wok view plop/stuff/unzx0.S @ rev 25612

Add zx0 (again)
author Pascal Bellard <pascal.bellard@slitaz.org>
date Tue Aug 01 19:11:36 2023 +0000 (10 months ago)
parents
children be3de88419e0
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 call .get_elias // read number of literals to copy
51 rep movsb // copy literal bytes
53 addb %al, %al // shift bit queue, and high bit into carry
54 jc .get_offset // if 1: read offset, if 0: rep-match
56 call .get_elias // read rep-match length (starts at 1)
58 .macro norm ds,si,reg,reg2
59 movw \si, \reg
60 andw $0xF, \si
61 # ifdef ONLY8086
62 shrw $1, \reg
63 shrw $1, \reg
64 shrw $1, \reg
65 shrw $1, \reg
66 # else
67 shrw $4, \reg
68 # endif
69 addw \reg, \reg2
70 movw \reg2, \ds
71 .endm
73 .copy_match:
74 #if !defined(FLAT16) && !defined(FLAT32)
75 movw %ds, %dx
76 norm %ds, %si, %bp, %dx
77 #endif
78 #if !defined(FLAT16OUT) && !defined(FLAT32)
79 movw %es, %dx
80 norm %es, %di, %bp, %dx
81 #endif
82 push SI // save si (current pointer to compressed data)
83 lea (BX,DI), SI // point to destination in es:di + offset in bx
84 #if !defined(FLAT16OUT) && !defined(FLAT32)
85 pushw %ds
86 movw %es, %dx
87 cmpw %si, %di
88 ja .sameseg
89 subb $0x10, %dh
90 .sameseg:
91 norm %ds, %si, %bp, %dx
92 rep movsb // copy matched bytes
93 popw %ds
94 #else
95 rep movsb %es:(SI), %es:(DI) // copy matched bytes
96 #endif
97 pop SI // restore si
99 addb %al, %al // read 'literal or match' bit
100 jnc .literals // if 0: go copy literals
102 .get_offset:
103 movb $0xfe, %cl // initialize value to FEh
104 call .elias_loop // read high byte of match offset, set carry
105 incb %cl // obtain negative offset high byte
106 je .done // exit if EOD marker
108 movb %cl, %bh // transfer negative high byte into bh
109 movw $1, %cx // initialize match length value to 1
110 movb (%si), %bl // read low byte of offset + 1 bit of len
111 incw %si // inc instruction keep carry set
112 // set high bit that is shifted into bit 15
113 rcrw $1, %bx // shift len bit into carry/offset in place
114 call .elias_bt // if len bit is set, no need for more
115 // else read rest of elias-encoded match length
116 incw %cx // fix match length
117 jmp .copy_match // go copy match
119 .get_elias:
120 movw $1, %cx // initialize value to 1
121 .elias_loop:
122 addb %al, %al // shift bit queue, and high bit into carry
123 jnz .got_bit // queue not empty, bits remain
124 lodsb // read 8 new bits
125 adcb %al, %al // shift bit queue, and high bit into carry
126 .got_bit:
127 .elias_bt:
128 jc .got_elias // done if control bit is 1
129 addb %al, %al // read data bit
130 adcw %cx, %cx // shift into cx
131 jmp .elias_loop // keep reading
132 .got_elias:
133 .done:
134 ret