wok-tiny annotate linux/stuff/unzx0.S @ rev 179

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