wok annotate plop/stuff/unlzsa1.S @ rev 25521

created recipes for unibilium and unibilium-dev 2.1.1
author Hans-G?nter Theisgen
date Fri Feb 24 17:05:40 2023 +0100 (16 months ago)
parents 7f7bd3c9775e
children f2b4a9eb8bdd
rev   line source
pascal@25504 1 // Lzsa1Decode:
pascal@25504 2 #ifndef FLAT32
pascal@25504 3 // input ds:si=inStream, es:di=outStream
pascal@25504 4 // output outStream[], ds:si, es:di
pascal@25504 5 .code16
pascal@25504 6 #define AX %ax
pascal@25504 7 #define BX %bx
pascal@25504 8 #define SI %si
pascal@25504 9 #define DI %di
pascal@25504 10 #else
pascal@25504 11 // input esi=inStream, edi=outStream
pascal@25504 12 // output outStream[], ds:esi, es:edi
pascal@25504 13 .code32
pascal@25504 14 #define AX %eax
pascal@25504 15 #define BX %ebx
pascal@25504 16 #define SI %esi
pascal@25504 17 #define DI %edi
pascal@25504 18 #endif
pascal@25504 19
pascal@25504 20 MATCH_RUN_LEN = 15
pascal@25504 21 LITERALS_RUN_LEN = 7
pascal@25504 22 MIN_MATCH_SIZE = 3
pascal@25504 23 MIN_LITERALS_SIZE = 0
pascal@25504 24
pascal@25504 25 #define PACKED_ONLY // assume no copy block, optional
pascal@25504 26 //#define PARANOIA // cover rare cases, optional
pascal@25504 27
pascal@25504 28 lzsa1main:
pascal@25504 29 #ifdef PARANOIA
pascal@25504 30 cld
pascal@25504 31 #endif
pascal@25505 32 #ifdef FLAT16OUT
pascal@25505 33 #define RAW_FORMAT
pascal@25505 34 #endif
pascal@25504 35 #ifndef RAW_FORMAT
pascal@25504 36 # if defined(PARANOIA) && !defined(FLAT32) && !defined(FLAT16)
pascal@25504 37 xorw %cx, %cx
pascal@25504 38 call normalize
pascal@25504 39 # endif
pascal@25504 40 # ifndef NO_LZSA1_HEADER
pascal@25504 41 lodsw
pascal@25504 42 cmpw $0x9E7B, %ax // magic
pascal@25504 43 jne lzsa1main
pascal@25504 44 lodsb
pascal@25504 45 cmpb $0, %al // lzsa1
pascal@25504 46 jne lzsa1main
pascal@25504 47 # endif
pascal@25504 48 lzsa1block: // uncompress chunk
pascal@25504 49 lodsw // block size
pascal@25504 50 xchgw %ax, %cx
pascal@25504 51 lodsb
pascal@25504 52 # ifndef PACKED_ONLY
pascal@25504 53 orb %al, %al
pascal@25504 54 jns lzsa1compressed
pascal@25504 55 # if !defined(FLAT32) && !defined(FLAT16OUT)
pascal@25504 56 movw %cx, %dx
pascal@25504 57 movb $0, %cl
pascal@25504 58 movb $0, %dh
pascal@25504 59 copytail:
pascal@25504 60 call lzsa1movStr
pascal@25504 61 xchg %dx, %cx
pascal@25504 62 incw %cx
pascal@25504 63 loop copytail
pascal@25504 64 # else
pascal@25504 65 movsb // copy block
pascal@25504 66 copylp:
pascal@25504 67 movsb // copy block
pascal@25504 68 loop copylp // handle 64K case
pascal@25504 69 # endif
pascal@25505 70 jmp lzsa1block // end of block
pascal@25504 71 lzsa1compressed:
pascal@25504 72 jne lzsa1chunk // 64Kb block
pascal@25504 73 # endif
pascal@25504 74 jcxz lzsa1quit // bail if we hit EOD
pascal@25504 75 pushw %cx
pascal@25504 76 # if !defined(FLAT32) && !defined(FLAT16)
pascal@25504 77 xorw %cx, %cx
pascal@25504 78 call normalize
pascal@25504 79 # define NeedNormalize
pascal@25504 80 # endif
pascal@25504 81 popw %dx
pascal@25504 82 addw %si, %dx
pascal@25504 83 #endif
pascal@25504 84 lzsa1chunk: // uncompress chunk
pascal@25504 85 lodsb // get token O|LLL|MMMM
pascal@25504 86 movb %al, %bl // keep token in bl
pascal@25504 87 shrb $4, %al // shift literals length into place
pascal@25504 88 movw $LITERALS_RUN_LEN*256+MIN_LITERALS_SIZE, %cx
pascal@25504 89 call lzsa1len // %ch = LITERALS_RUN_LEN
pascal@25504 90 #if defined(NeedNormalize)
pascal@25504 91 call lzsa1movLit // copy %cx literals from %ds:%si to %es:%di
pascal@25504 92 #else
pascal@25504 93 rep movsb // copy %cx literals from %ds:%si to %es:%di
pascal@25504 94 #endif
pascal@25504 95 #ifndef RAW_FORMAT
pascal@25504 96 cmpw %dx, %si
pascal@25504 97 jae lzsa1block // bail if we hit EOD
pascal@25504 98 #endif
pascal@25504 99 #ifdef FLAT32
pascal@25504 100 orl $-1, %eax
pascal@25504 101 #else
pascal@25504 102 movb $-1, %ah
pascal@25504 103 #endif
pascal@25504 104 testb %bl, %bl // check match offset size in token (O bit)
pascal@25504 105 jns lzsa1ShortOfs
pascal@25504 106 lodsw
pascal@25504 107 .byte 0x3C // mask lodsb with cmpb $0xAC, %al
pascal@25504 108 lzsa1ShortOfs:
pascal@25504 109 lodsb
pascal@25504 110 xchg AX, BX // %bx: match offset %ax: original token
pascal@25504 111 movw $MATCH_RUN_LEN*256+MIN_MATCH_SIZE, %cx
pascal@25504 112 call lzsa1len
pascal@25505 113 #ifdef RAW_FORMAT
pascal@25505 114 jcxz lzsa1quit // bail if we hit EOD
pascal@25505 115 #endif
pascal@25504 116 #if !defined(FLAT32) && !defined(FLAT16OUT)
pascal@25504 117 pushw %ds
pascal@25504 118 pushw %si
pascal@25504 119 movw %di, %si
pascal@25504 120 addw %bx, %si
pascal@25504 121 movw %es, %ax
pascal@25504 122 jc axok
pascal@25504 123 subb $0x10, %ah
pascal@25504 124 axok:
pascal@25504 125 .macro norm reg
pascal@25504 126 movw %si, \reg
pascal@25504 127 subw %si, %dx
pascal@25504 128 andw $0xF, %si
pascal@25504 129 addw %si, %dx
pascal@25504 130 shrw $4, \reg
pascal@25504 131 addw \reg, %ax
pascal@25504 132 movw %ax, %ds
pascal@25504 133 movw %di, \reg
pascal@25504 134 andw $0xF, %di
pascal@25504 135 shrw $4, \reg
pascal@25504 136 movw %es, %ax
pascal@25504 137 addw \reg, %ax
pascal@25504 138 movw %ax, %es
pascal@25504 139 .endm
pascal@25504 140 pushw %dx
pascal@25504 141 # if defined(NeedNormalize) || defined(PARANOIA)
pascal@25504 142 call lzsa1movStr // copy string
pascal@25504 143 # else
pascal@25504 144 norm %bp
pascal@25504 145 rep movsb
pascal@25504 146 # endif
pascal@25504 147 popw %dx
pascal@25504 148 popw %si
pascal@25504 149 popw %ds
pascal@25504 150 #else
pascal@25504 151 xchg AX, SI // save %si
pascal@25504 152 lea (BX,DI), SI
pascal@25504 153 rep movsb %es:(SI), %es:(DI)
pascal@25504 154 xchg AX, SI // restore %si
pascal@25504 155 #endif
pascal@25504 156 jmp lzsa1chunk
pascal@25504 157
pascal@25504 158 lzsa1len: // get length in %ecx
pascal@25504 159 andb %ch, %al
pascal@25504 160 cbw // clear %ah
pascal@25504 161 cmpb %ch, %al
pascal@25504 162 jne lzsa1minNumber // S=0-6, L=0-14
pascal@25504 163 lodsb
pascal@25504 164 addb %ch, %cl
pascal@25504 165 lzsa1minNumber:
pascal@25504 166 addb %cl, %al
pascal@25504 167 jnc lzsa1gotNumber // 0-255
pascal@25504 168 movb %al, %ah // S=256-1791, L=256-3839 or S=256-511, L=256-511
pascal@25504 169 jne lzsa1midNumber
pascal@25504 170 lodsw // 0-65535
pascal@25504 171 .byte 0x3C // mask lodsb with cmpb $0xAC, %al
pascal@25504 172 lzsa1midNumber:
pascal@25504 173 lodsb
pascal@25504 174 lzsa1gotNumber:
pascal@25504 175 xchgw %ax, %cx
pascal@25504 176 lzsa1quit:
pascal@25504 177 ret
pascal@25504 178
pascal@25504 179 #if defined(NeedNormalize) || defined(PARANOIA)
pascal@25504 180 # if defined(PARANOIA)
pascal@25504 181 lzsa1movlp:
pascal@25504 182 decw %ch
pascal@25504 183 rep movsb
pascal@25504 184 incw %ch
pascal@25504 185 # endif
pascal@25504 186 normalize:
pascal@25504 187 lzsa1movLit:
pascal@25504 188 movw %ds, %ax
pascal@25504 189 lzsa1movStr:
pascal@25504 190 norm %bp
pascal@25504 191 # if defined(PARANOIA)
pascal@25504 192 cmpb $0xFF, %ch // catch FFFX case
pascal@25504 193 je lzsa1movlp
pascal@25504 194 # endif
pascal@25504 195 rep movsb
pascal@25504 196 ret
pascal@25504 197 #endif