wok view plop/stuff/unzx0.S @ rev 25726
renamed xfce4-ristretto to ristretto
author | Hans-G?nter Theisgen |
---|---|
date | Sat Aug 17 17:30:48 2024 +0100 (2 months ago) |
parents | a794ec0a6495 |
children | 1b965c2713aa |
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 $256*64, %di
70 movw %es, %dx
71 addw $16*64, %dx
72 movw %dx, %es
73 .copy_match:
74 cmpw $-32640, %di // assume 32639 max window
75 ja .fix_di
76 #else
77 .copy_match:
78 #endif
79 push SI // save si (current pointer to compressed data)
80 lea (BX,DI), SI // point to destination in es:di + offset in bx
81 #ifdef ONLY8086
82 .copy_loop:
83 movsb %es:(SI), %es:(DI) // copy matched bytes using NMOS 8088/8086 workaround.
84 loop .copy_loop
85 #else
86 rep movsb %es:(SI), %es:(DI) // copy matched bytes
87 #endif
88 pop SI // restore si
90 addb %al, %al // read 'literal or match' bit
91 jnc .literals // if 0: go copy literals
93 .get_offset:
94 movb $0xfe, %cl // initialize value to FEh
95 call .elias_loop // read high byte of match offset, set carry
96 incb %cl // obtain negative offset high byte
97 je .done // exit if EOD marker
99 movb %cl, %bh // transfer negative high byte into bh
100 xchgw %ax, %bx
101 lodsb // read low byte of offset + 1 bit of len
102 xchgw %ax, %bx
103 movw $1, %cx // initialize match length value to 1
104 // set high bit that is shifted into bit 15
105 rcrw %cl, %bx // shift len bit into carry/offset in place
106 call .elias_bt // if len bit is set, no need for more
107 // else read rest of elias-encoded match length
108 incw %cx // fix match length
109 jmp .copy_match // go copy match
111 .get_elias:
112 movw $1, %cx // initialize value to 1
113 .elias_loop:
114 addb %al, %al // shift bit queue, and high bit into carry
115 jnz .got_bit // queue not empty, bits remain
116 lodsb // read 8 new bits
117 adcb %al, %al // shift bit queue, and high bit into carry
118 .got_bit:
119 .elias_bt:
120 jc .got_elias // done if control bit is 1
121 addb %al, %al // read data bit
122 adcw %cx, %cx // shift into cx
123 jmp .elias_loop // keep reading
124 .got_elias:
125 .done:
126 ret