wok rev 25612

Add zx0 (again)
author Pascal Bellard <pascal.bellard@slitaz.org>
date Tue Aug 01 19:11:36 2023 +0000 (9 months ago)
parents cb71c3a76f5a
children be3de88419e0
files memtest/stuff/unzx0.S memtest64/stuff/unzx0.S plop/stuff/unzx0.S
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/memtest/stuff/unzx0.S	Tue Aug 01 19:11:36 2023 +0000
     1.3 @@ -0,0 +1,134 @@
     1.4 +#ifndef FLAT32
     1.5 +//   input   ds:si=inStream, es:di=outStream
     1.6 +//   output  outStream[], ds:si, es:di
     1.7 +	.code16
     1.8 +#define BX	%bx
     1.9 +#define SI	%si
    1.10 +#define DI	%di
    1.11 +#else
    1.12 +//   input   esi=inStream, edi=outStream
    1.13 +//   output  outStream[], ds:esi, es:edi
    1.14 +	.code32
    1.15 +#define BX	%ebx
    1.16 +#define SI	%esi
    1.17 +#define DI	%edi
    1.18 +#endif
    1.19 +
    1.20 +//  unzx0_8088.S - ZX0 decompressor for 8088 - 73 bytes - NASM
    1.21 +//
    1.22 +//  inputs:
    1.23 +//  * ds:si: start of compressed data
    1.24 +//  * es:di: start of decompression buffer
    1.25 +//
    1.26 +//  Copyright (C) 2021 Emmanuel Marty
    1.27 +//  ZX0 compression (c) 2021 Einar Saukas, https://github.com/einar-saukas/ZX0
    1.28 +//
    1.29 +//  This software is provided 'as-is', without any express or implied
    1.30 +//  warranty.  In no event will the authors be held liable for any damages
    1.31 +//  arising from the use of this software.
    1.32 +//
    1.33 +//  Permission is granted to anyone to use this software for any purpose,
    1.34 +//  including commercial applications, and to alter it and redistribute it
    1.35 +//  freely, subject to the following restrictions:
    1.36 +//
    1.37 +//  1. The origin of this software must not be misrepresented; you must not
    1.38 +//     claim that you wrote the original software. If you use this software
    1.39 +//     in a product, an acknowledgment in the product documentation would be
    1.40 +//     appreciated but is not required.
    1.41 +//  2. Altered source versions must be plainly marked as such, and must not be
    1.42 +//     misrepresented as being the original software.
    1.43 +//  3. This notice may not be removed or altered from any source distribution.
    1.44 +
    1.45 +zx0_decompress:
    1.46 +        cld                     // make string operations go forward
    1.47 +        movb    $0x80, %al      // initialize empty bit queue
    1.48 +                                // plus bit to roll into carry
    1.49 +	stc
    1.50 +        sbb     BX, BX          // initialize rep-offset to 1
    1.51 +
    1.52 +.literals:
    1.53 +        call    .get_elias      // read number of literals to copy
    1.54 +        rep     movsb           // copy literal bytes
    1.55 +
    1.56 +        addb     %al, %al       // shift bit queue, and high bit into carry
    1.57 +        jc      .get_offset     // if 1: read offset, if 0: rep-match
    1.58 +
    1.59 +        call    .get_elias      // read rep-match length (starts at 1)
    1.60 +
    1.61 +.macro norm	ds,si,reg,reg2
    1.62 +	movw	\si, \reg
    1.63 +	andw	$0xF, \si
    1.64 +# ifdef ONLY8086
    1.65 +	shrw	$1, \reg
    1.66 +	shrw	$1, \reg
    1.67 +	shrw	$1, \reg
    1.68 +	shrw	$1, \reg
    1.69 +# else
    1.70 +	shrw	$4, \reg
    1.71 +# endif
    1.72 +	addw	\reg, \reg2
    1.73 +	movw	\reg2, \ds
    1.74 +.endm 
    1.75 +
    1.76 +.copy_match:
    1.77 +#if !defined(FLAT16) && !defined(FLAT32)
    1.78 +	movw	%ds, %dx
    1.79 +	norm	%ds, %si, %bp, %dx
    1.80 +#endif
    1.81 +#if !defined(FLAT16OUT) && !defined(FLAT32)
    1.82 +	movw	%es, %dx
    1.83 +	norm	%es, %di, %bp, %dx
    1.84 +#endif
    1.85 +        push    SI              // save si (current pointer to compressed data)
    1.86 +        lea     (BX,DI), SI     // point to destination in es:di + offset in bx
    1.87 +#if !defined(FLAT16OUT) && !defined(FLAT32)
    1.88 +	pushw	%ds
    1.89 +	movw	%es, %dx
    1.90 +	cmpw	%si, %di
    1.91 +	ja	.sameseg
    1.92 +	subb	$0x10, %dh
    1.93 +.sameseg:
    1.94 +	norm	%ds, %si, %bp, %dx
    1.95 +	rep movsb               // copy matched bytes
    1.96 +	popw	%ds
    1.97 +#else
    1.98 +	rep movsb %es:(SI), %es:(DI)  // copy matched bytes
    1.99 +#endif
   1.100 +        pop     SI              // restore si
   1.101 +
   1.102 +        addb    %al, %al        // read 'literal or match' bit
   1.103 +        jnc     .literals       // if 0: go copy literals
   1.104 +
   1.105 +.get_offset:
   1.106 +        movb    $0xfe, %cl      // initialize value to FEh
   1.107 +        call    .elias_loop     // read high byte of match offset, set carry
   1.108 +        incb    %cl             // obtain negative offset high byte
   1.109 +        je      .done           // exit if EOD marker
   1.110 +        
   1.111 +        movb    %cl, %bh        // transfer negative high byte into bh
   1.112 +        movw    $1, %cx         // initialize match length value to 1
   1.113 +        movb    (%si), %bl      // read low byte of offset + 1 bit of len
   1.114 +        incw    %si             // inc instruction keep carry set
   1.115 +                                // set high bit that is shifted into bit 15
   1.116 +        rcrw    $1, %bx         // shift len bit into carry/offset in place
   1.117 +        call    .elias_bt       // if len bit is set, no need for more
   1.118 +                                // else read rest of elias-encoded match length
   1.119 +        incw    %cx             // fix match length
   1.120 +        jmp     .copy_match     // go copy match
   1.121 +
   1.122 +.get_elias:
   1.123 +        movw    $1, %cx         // initialize value to 1
   1.124 +.elias_loop:
   1.125 +        addb    %al, %al        // shift bit queue, and high bit into carry
   1.126 +        jnz     .got_bit        // queue not empty, bits remain
   1.127 +        lodsb                   // read 8 new bits
   1.128 +        adcb    %al, %al        // shift bit queue, and high bit into carry
   1.129 +.got_bit:
   1.130 +.elias_bt:
   1.131 +        jc      .got_elias      // done if control bit is 1
   1.132 +        addb    %al, %al        // read data bit
   1.133 +        adcw    %cx, %cx        // shift into cx
   1.134 +        jmp     .elias_loop     // keep reading
   1.135 +.got_elias:
   1.136 +.done:
   1.137 +        ret
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/memtest64/stuff/unzx0.S	Tue Aug 01 19:11:36 2023 +0000
     2.3 @@ -0,0 +1,134 @@
     2.4 +#ifndef FLAT32
     2.5 +//   input   ds:si=inStream, es:di=outStream
     2.6 +//   output  outStream[], ds:si, es:di
     2.7 +	.code16
     2.8 +#define BX	%bx
     2.9 +#define SI	%si
    2.10 +#define DI	%di
    2.11 +#else
    2.12 +//   input   esi=inStream, edi=outStream
    2.13 +//   output  outStream[], ds:esi, es:edi
    2.14 +	.code32
    2.15 +#define BX	%ebx
    2.16 +#define SI	%esi
    2.17 +#define DI	%edi
    2.18 +#endif
    2.19 +
    2.20 +//  unzx0_8088.S - ZX0 decompressor for 8088 - 73 bytes - NASM
    2.21 +//
    2.22 +//  inputs:
    2.23 +//  * ds:si: start of compressed data
    2.24 +//  * es:di: start of decompression buffer
    2.25 +//
    2.26 +//  Copyright (C) 2021 Emmanuel Marty
    2.27 +//  ZX0 compression (c) 2021 Einar Saukas, https://github.com/einar-saukas/ZX0
    2.28 +//
    2.29 +//  This software is provided 'as-is', without any express or implied
    2.30 +//  warranty.  In no event will the authors be held liable for any damages
    2.31 +//  arising from the use of this software.
    2.32 +//
    2.33 +//  Permission is granted to anyone to use this software for any purpose,
    2.34 +//  including commercial applications, and to alter it and redistribute it
    2.35 +//  freely, subject to the following restrictions:
    2.36 +//
    2.37 +//  1. The origin of this software must not be misrepresented; you must not
    2.38 +//     claim that you wrote the original software. If you use this software
    2.39 +//     in a product, an acknowledgment in the product documentation would be
    2.40 +//     appreciated but is not required.
    2.41 +//  2. Altered source versions must be plainly marked as such, and must not be
    2.42 +//     misrepresented as being the original software.
    2.43 +//  3. This notice may not be removed or altered from any source distribution.
    2.44 +
    2.45 +zx0_decompress:
    2.46 +        cld                     // make string operations go forward
    2.47 +        movb    $0x80, %al      // initialize empty bit queue
    2.48 +                                // plus bit to roll into carry
    2.49 +	stc
    2.50 +        sbb     BX, BX          // initialize rep-offset to 1
    2.51 +
    2.52 +.literals:
    2.53 +        call    .get_elias      // read number of literals to copy
    2.54 +        rep     movsb           // copy literal bytes
    2.55 +
    2.56 +        addb     %al, %al       // shift bit queue, and high bit into carry
    2.57 +        jc      .get_offset     // if 1: read offset, if 0: rep-match
    2.58 +
    2.59 +        call    .get_elias      // read rep-match length (starts at 1)
    2.60 +
    2.61 +.macro norm	ds,si,reg,reg2
    2.62 +	movw	\si, \reg
    2.63 +	andw	$0xF, \si
    2.64 +# ifdef ONLY8086
    2.65 +	shrw	$1, \reg
    2.66 +	shrw	$1, \reg
    2.67 +	shrw	$1, \reg
    2.68 +	shrw	$1, \reg
    2.69 +# else
    2.70 +	shrw	$4, \reg
    2.71 +# endif
    2.72 +	addw	\reg, \reg2
    2.73 +	movw	\reg2, \ds
    2.74 +.endm 
    2.75 +
    2.76 +.copy_match:
    2.77 +#if !defined(FLAT16) && !defined(FLAT32)
    2.78 +	movw	%ds, %dx
    2.79 +	norm	%ds, %si, %bp, %dx
    2.80 +#endif
    2.81 +#if !defined(FLAT16OUT) && !defined(FLAT32)
    2.82 +	movw	%es, %dx
    2.83 +	norm	%es, %di, %bp, %dx
    2.84 +#endif
    2.85 +        push    SI              // save si (current pointer to compressed data)
    2.86 +        lea     (BX,DI), SI     // point to destination in es:di + offset in bx
    2.87 +#if !defined(FLAT16OUT) && !defined(FLAT32)
    2.88 +	pushw	%ds
    2.89 +	movw	%es, %dx
    2.90 +	cmpw	%si, %di
    2.91 +	ja	.sameseg
    2.92 +	subb	$0x10, %dh
    2.93 +.sameseg:
    2.94 +	norm	%ds, %si, %bp, %dx
    2.95 +	rep movsb               // copy matched bytes
    2.96 +	popw	%ds
    2.97 +#else
    2.98 +	rep movsb %es:(SI), %es:(DI)  // copy matched bytes
    2.99 +#endif
   2.100 +        pop     SI              // restore si
   2.101 +
   2.102 +        addb    %al, %al        // read 'literal or match' bit
   2.103 +        jnc     .literals       // if 0: go copy literals
   2.104 +
   2.105 +.get_offset:
   2.106 +        movb    $0xfe, %cl      // initialize value to FEh
   2.107 +        call    .elias_loop     // read high byte of match offset, set carry
   2.108 +        incb    %cl             // obtain negative offset high byte
   2.109 +        je      .done           // exit if EOD marker
   2.110 +        
   2.111 +        movb    %cl, %bh        // transfer negative high byte into bh
   2.112 +        movw    $1, %cx         // initialize match length value to 1
   2.113 +        movb    (%si), %bl      // read low byte of offset + 1 bit of len
   2.114 +        incw    %si             // inc instruction keep carry set
   2.115 +                                // set high bit that is shifted into bit 15
   2.116 +        rcrw    $1, %bx         // shift len bit into carry/offset in place
   2.117 +        call    .elias_bt       // if len bit is set, no need for more
   2.118 +                                // else read rest of elias-encoded match length
   2.119 +        incw    %cx             // fix match length
   2.120 +        jmp     .copy_match     // go copy match
   2.121 +
   2.122 +.get_elias:
   2.123 +        movw    $1, %cx         // initialize value to 1
   2.124 +.elias_loop:
   2.125 +        addb    %al, %al        // shift bit queue, and high bit into carry
   2.126 +        jnz     .got_bit        // queue not empty, bits remain
   2.127 +        lodsb                   // read 8 new bits
   2.128 +        adcb    %al, %al        // shift bit queue, and high bit into carry
   2.129 +.got_bit:
   2.130 +.elias_bt:
   2.131 +        jc      .got_elias      // done if control bit is 1
   2.132 +        addb    %al, %al        // read data bit
   2.133 +        adcw    %cx, %cx        // shift into cx
   2.134 +        jmp     .elias_loop     // keep reading
   2.135 +.got_elias:
   2.136 +.done:
   2.137 +        ret
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/plop/stuff/unzx0.S	Tue Aug 01 19:11:36 2023 +0000
     3.3 @@ -0,0 +1,134 @@
     3.4 +#ifndef FLAT32
     3.5 +//   input   ds:si=inStream, es:di=outStream
     3.6 +//   output  outStream[], ds:si, es:di
     3.7 +	.code16
     3.8 +#define BX	%bx
     3.9 +#define SI	%si
    3.10 +#define DI	%di
    3.11 +#else
    3.12 +//   input   esi=inStream, edi=outStream
    3.13 +//   output  outStream[], ds:esi, es:edi
    3.14 +	.code32
    3.15 +#define BX	%ebx
    3.16 +#define SI	%esi
    3.17 +#define DI	%edi
    3.18 +#endif
    3.19 +
    3.20 +//  unzx0_8088.S - ZX0 decompressor for 8088 - 73 bytes - NASM
    3.21 +//
    3.22 +//  inputs:
    3.23 +//  * ds:si: start of compressed data
    3.24 +//  * es:di: start of decompression buffer
    3.25 +//
    3.26 +//  Copyright (C) 2021 Emmanuel Marty
    3.27 +//  ZX0 compression (c) 2021 Einar Saukas, https://github.com/einar-saukas/ZX0
    3.28 +//
    3.29 +//  This software is provided 'as-is', without any express or implied
    3.30 +//  warranty.  In no event will the authors be held liable for any damages
    3.31 +//  arising from the use of this software.
    3.32 +//
    3.33 +//  Permission is granted to anyone to use this software for any purpose,
    3.34 +//  including commercial applications, and to alter it and redistribute it
    3.35 +//  freely, subject to the following restrictions:
    3.36 +//
    3.37 +//  1. The origin of this software must not be misrepresented; you must not
    3.38 +//     claim that you wrote the original software. If you use this software
    3.39 +//     in a product, an acknowledgment in the product documentation would be
    3.40 +//     appreciated but is not required.
    3.41 +//  2. Altered source versions must be plainly marked as such, and must not be
    3.42 +//     misrepresented as being the original software.
    3.43 +//  3. This notice may not be removed or altered from any source distribution.
    3.44 +
    3.45 +zx0_decompress:
    3.46 +        cld                     // make string operations go forward
    3.47 +        movb    $0x80, %al      // initialize empty bit queue
    3.48 +                                // plus bit to roll into carry
    3.49 +	stc
    3.50 +        sbb     BX, BX          // initialize rep-offset to 1
    3.51 +
    3.52 +.literals:
    3.53 +        call    .get_elias      // read number of literals to copy
    3.54 +        rep     movsb           // copy literal bytes
    3.55 +
    3.56 +        addb     %al, %al       // shift bit queue, and high bit into carry
    3.57 +        jc      .get_offset     // if 1: read offset, if 0: rep-match
    3.58 +
    3.59 +        call    .get_elias      // read rep-match length (starts at 1)
    3.60 +
    3.61 +.macro norm	ds,si,reg,reg2
    3.62 +	movw	\si, \reg
    3.63 +	andw	$0xF, \si
    3.64 +# ifdef ONLY8086
    3.65 +	shrw	$1, \reg
    3.66 +	shrw	$1, \reg
    3.67 +	shrw	$1, \reg
    3.68 +	shrw	$1, \reg
    3.69 +# else
    3.70 +	shrw	$4, \reg
    3.71 +# endif
    3.72 +	addw	\reg, \reg2
    3.73 +	movw	\reg2, \ds
    3.74 +.endm 
    3.75 +
    3.76 +.copy_match:
    3.77 +#if !defined(FLAT16) && !defined(FLAT32)
    3.78 +	movw	%ds, %dx
    3.79 +	norm	%ds, %si, %bp, %dx
    3.80 +#endif
    3.81 +#if !defined(FLAT16OUT) && !defined(FLAT32)
    3.82 +	movw	%es, %dx
    3.83 +	norm	%es, %di, %bp, %dx
    3.84 +#endif
    3.85 +        push    SI              // save si (current pointer to compressed data)
    3.86 +        lea     (BX,DI), SI     // point to destination in es:di + offset in bx
    3.87 +#if !defined(FLAT16OUT) && !defined(FLAT32)
    3.88 +	pushw	%ds
    3.89 +	movw	%es, %dx
    3.90 +	cmpw	%si, %di
    3.91 +	ja	.sameseg
    3.92 +	subb	$0x10, %dh
    3.93 +.sameseg:
    3.94 +	norm	%ds, %si, %bp, %dx
    3.95 +	rep movsb               // copy matched bytes
    3.96 +	popw	%ds
    3.97 +#else
    3.98 +	rep movsb %es:(SI), %es:(DI)  // copy matched bytes
    3.99 +#endif
   3.100 +        pop     SI              // restore si
   3.101 +
   3.102 +        addb    %al, %al        // read 'literal or match' bit
   3.103 +        jnc     .literals       // if 0: go copy literals
   3.104 +
   3.105 +.get_offset:
   3.106 +        movb    $0xfe, %cl      // initialize value to FEh
   3.107 +        call    .elias_loop     // read high byte of match offset, set carry
   3.108 +        incb    %cl             // obtain negative offset high byte
   3.109 +        je      .done           // exit if EOD marker
   3.110 +        
   3.111 +        movb    %cl, %bh        // transfer negative high byte into bh
   3.112 +        movw    $1, %cx         // initialize match length value to 1
   3.113 +        movb    (%si), %bl      // read low byte of offset + 1 bit of len
   3.114 +        incw    %si             // inc instruction keep carry set
   3.115 +                                // set high bit that is shifted into bit 15
   3.116 +        rcrw    $1, %bx         // shift len bit into carry/offset in place
   3.117 +        call    .elias_bt       // if len bit is set, no need for more
   3.118 +                                // else read rest of elias-encoded match length
   3.119 +        incw    %cx             // fix match length
   3.120 +        jmp     .copy_match     // go copy match
   3.121 +
   3.122 +.get_elias:
   3.123 +        movw    $1, %cx         // initialize value to 1
   3.124 +.elias_loop:
   3.125 +        addb    %al, %al        // shift bit queue, and high bit into carry
   3.126 +        jnz     .got_bit        // queue not empty, bits remain
   3.127 +        lodsb                   // read 8 new bits
   3.128 +        adcb    %al, %al        // shift bit queue, and high bit into carry
   3.129 +.got_bit:
   3.130 +.elias_bt:
   3.131 +        jc      .got_elias      // done if control bit is 1
   3.132 +        addb    %al, %al        // read data bit
   3.133 +        adcw    %cx, %cx        // shift into cx
   3.134 +        jmp     .elias_loop     // keep reading
   3.135 +.got_elias:
   3.136 +.done:
   3.137 +        ret