wok diff memtest64/stuff/unlzsa2.S @ rev 25514
Add memtest64
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Thu Feb 16 14:18:05 2023 +0000 (16 months ago) |
parents | |
children | f2b4a9eb8bdd |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/memtest64/stuff/unlzsa2.S Thu Feb 16 14:18:05 2023 +0000 1.3 @@ -0,0 +1,274 @@ 1.4 +// Lzsa2Decode: 1.5 +#ifndef FLAT32 1.6 +// input ds:si=inStream, es:di=outStream 1.7 +// output outStream[], ds:si, es:di 1.8 + .code16 1.9 +#define AX %ax 1.10 +#define BX %bx 1.11 +#define BP %bp 1.12 +#define SI %si 1.13 +#define DI %di 1.14 +#else 1.15 +// input esi=inStream, edi=outStream 1.16 +// output outStream[], ds:esi, es:edi 1.17 + .code32 1.18 +#define AX %eax 1.19 +#define BX %ebx 1.20 +#define BP %ebp 1.21 +#define SI %esi 1.22 +#define DI %edi 1.23 +#endif 1.24 + 1.25 +MATCH_RUN_LEN = 7 1.26 +LITERALS_RUN_LEN = 3 1.27 +MIN_MATCH_SIZE = 2 1.28 +MIN_LITERALS_SIZE = 0 1.29 + 1.30 +#define PACKED_ONLY // assume no copy block, optional 1.31 +//#define PARANOIA // cover rare cases, optional 1.32 + 1.33 +lzsa2main: 1.34 +#ifdef PARANOIA 1.35 + cld 1.36 +#endif 1.37 +#ifdef FLAT16OUT 1.38 +#define RAW_FORMAT 1.39 +#endif 1.40 +#ifndef RAW_FORMAT 1.41 +# if defined(PARANOIA) && !defined(FLAT32) && !defined(FLAT16) 1.42 + xorw %cx, %cx 1.43 + call normalize 1.44 +# endif 1.45 +# ifndef NO_LZSA2_HEADER 1.46 + lodsw 1.47 + cmpw $0x9E7B, %ax // magic 1.48 + jne lzsa2main 1.49 + lodsb 1.50 + testb $0x20, %al // lzsa2 1.51 + je lzsa2main 1.52 +# endif 1.53 +lzsa2block: // uncompress chunk 1.54 +# if !defined(FLAT32) && !defined(FLAT16) 1.55 + xorw %cx, %cx 1.56 + call normalize 1.57 +# endif 1.58 + lodsw // block size 1.59 + xchgw %ax, %cx 1.60 + lodsb 1.61 +# ifndef PACKED_ONLY 1.62 + orb %al, %al 1.63 + jns lzsa2compressed 1.64 +# if !defined(FLAT32) && !defined(FLAT16OUT) 1.65 + movw %cx, %dx 1.66 + movb $0, %cl 1.67 + movb $0, %dh 1.68 +copytail: 1.69 + call lzsa1movStr 1.70 + xchg %dx, %cx 1.71 + incw %cx 1.72 + loop copytail 1.73 +# else 1.74 + movsb // copy block 1.75 +copylp: 1.76 + movsb // copy block 1.77 + loop copylp // handle 64K case 1.78 +# endif 1.79 + jmp lzsa2block // end of block 1.80 +lzsa2compressed: 1.81 + jne lzsa2chunk // 64Kb block 1.82 +# endif 1.83 + jcxz lzsa2quit // bail if we hit EOD 1.84 +# if !defined(FLAT16) 1.85 + pushw %cx 1.86 + xorw %cx, %cx 1.87 + call normalize 1.88 +# define NeedNormalize 1.89 + popw %dx 1.90 + addw %si, %dx 1.91 +# else 1.92 + movw %si, %dx 1.93 + addw %cx, %dx 1.94 +# endif 1.95 +#else 1.96 +# if !defined(FLAT16) 1.97 + xorw %cx, %cx 1.98 + call normalize 1.99 +# define NeedNormalize 1.100 +# endif 1.101 +#endif 1.102 + movb $0, %bh // no nibble stored 1.103 +lzsa2chunk: // uncompress chunk 1.104 + lodsb // get token XYZ|LL|MMM 1.105 + movb %al, %bl // keep token in bl 1.106 + movw $LITERALS_RUN_LEN+256*MIN_LITERALS_SIZE, %cx 1.107 + shrb %cl, %al // shift literals length into place 1.108 + call lzsa2len // %cl = LITERALS_RUN_LEN 1.109 +#if defined(NeedNormalize) 1.110 + pushw %bp 1.111 + call lzsa2movLit // copy %cx literals from %ds:%si to %es:%di 1.112 + popw %bp 1.113 +#else 1.114 + rep movsb // copy %cx literals from %ds:%si to %es:%di 1.115 +#endif 1.116 +#ifndef RAW_FORMAT 1.117 +maxsi: 1.118 + cmpw %dx, %si 1.119 + jae lzsa2block // bail if we hit EOD 1.120 +#endif 1.121 +#ifdef FLAT32 1.122 + orl $-1, %eax // set offset bits 31-8 to 1 1.123 +#else 1.124 + movb $-1, %ah // set offset bits 15-8 to 1 1.125 +#endif 1.126 +// XYZ 1.127 + testb $0xC0, %bl // check match offset mode in token (X bit) 1.128 + bt $5, %bx // move bit 5 to carry 1.129 + js rep_match_or_large_offset 1.130 + jne offset_9_bit 1.131 +// 00Z 5-bit offset: read a nibble for offset bits 1-4 and use the inverted bit Z of the token as bit 0 of the offset. 1.132 +// set bits 5-15 of the offset to 1. 1.133 + call getByteFromNibbleAndC 1.134 + jmp get_match_length 1.135 +offset_9_bit: 1.136 +// 01Z 9-bit offset: read a byte for offset bits 0-7 and use the inverted bit Z for bit 8 of the offset. 1.137 +// set bits 9-15 of the offset to 1. 1.138 + sbbb %cl, %ah // clear bit 8 if Z bit is clear 1.139 + jmp get_match_length_0 1.140 + 1.141 +getNibble: 1.142 + xorb $0xF0, %bh // toggle nibble stored flags 1.143 + movb %bh, %al 1.144 + jns gotnibble 1.145 + lodsb 1.146 + movb $0xF0, %bh 1.147 + orb %al, %bh 1.148 + shrb $4, %al 1.149 +gotnibble: 1.150 +lzsa2quit: 1.151 + ret 1.152 + 1.153 +rep_match_or_large_offset: 1.154 + jpe rep_match_or_16_bit 1.155 +//10Z 13-bit offset: read a nibble for offset bits 9-12 and use the inverted bit Z for bit 8 of the offset, 1.156 +// then read a byte for offset bits 0-7. set bits 13-15 of the offset to 1. 1.157 +// substract 512 from the offset to get the final value. 1.158 + call getByteFromNibbleAndC 1.159 + subb $2, %al // substract 512 1.160 + jmp get_match_length_1 1.161 +rep_match_or_16_bit: 1.162 + jc repeat_match // rep-match 1.163 +//110 16-bit offset: read a byte for offset bits 8-15, then another byte for offset bits 0-7. 1.164 + lodsb // Get 2-byte match offset 1.165 +get_match_length_1: 1.166 + xchgb %al, %ah 1.167 +get_match_length_0: 1.168 + lodsb // load match offset bits 0-7 1.169 +get_match_length: 1.170 + xchgw %ax, %bp // bp: offset 1.171 +repeat_match: 1.172 +//111 repeat offset: reuse the offset value of the previous match command. 1.173 + 1.174 + movb %bl, %al // %al: original token 1.175 + movw $MATCH_RUN_LEN+256*MIN_MATCH_SIZE, %cx 1.176 + call lzsa2len 1.177 +#ifdef RAW_FORMAT 1.178 + jcxz lzsa2quit // bail if we hit EOD 1.179 +#endif 1.180 +#if !defined(FLAT32) && !defined(FLAT16OUT) 1.181 + pushw %ds 1.182 + pushw %si 1.183 + movw %di, %si 1.184 + addw %bp, %si 1.185 + movw %es, %ax 1.186 + jc axok 1.187 + subb $0x10, %ah 1.188 +axok: 1.189 +.macro norm reg 1.190 + movw %si, \reg 1.191 + subw %si, %dx 1.192 + andw $0xF, %si 1.193 + addw %si, %dx 1.194 + shrw $4, \reg 1.195 + addw \reg, %ax 1.196 + movw %ax, %ds 1.197 + movw %di, \reg 1.198 + andw $0xF, %di 1.199 + shrw $4, \reg 1.200 + movw %es, %ax 1.201 + addw \reg, %ax 1.202 + movw %ax, %es 1.203 +.endm 1.204 + pushw %bp 1.205 + pushw %dx 1.206 +# if defined(NeedNormalize) || defined(PARANOIA) 1.207 + call lzsa2movStr // copy string 1.208 +# else 1.209 + norm %bp 1.210 + rep movsb 1.211 +# endif 1.212 + popw %dx 1.213 + popw %bp 1.214 + popw %si 1.215 + popw %ds 1.216 +#else 1.217 + xchg AX, SI // save %si 1.218 + lea (BP,DI), SI 1.219 + rep movsb %es:(SI), %es:(DI) 1.220 + xchg AX, SI // restore %si 1.221 +#endif 1.222 + jmp lzsa2chunk 1.223 + 1.224 +getByteFromNibbleAndC: 1.225 + pushfw 1.226 + call getNibble // get nibble for offset bits 0-3 1.227 + popfw 1.228 + rclb $1, %al 1.229 + xorb $0xE1, %al // set offset bits 7-5 to 1 1.230 + ret 1.231 + 1.232 +lzsa2len: // get length in %cx 1.233 + andb %cl, %al 1.234 + cbw // clear %ah 1.235 + cmpb %al, %cl 1.236 + jne lzsa2minNumber // S=0-2, L=0-6 1.237 + call getNibble 1.238 + cmp $0xF, %al 1.239 + jne lzsa2noExtraByte 1.240 + addb %al, %ch 1.241 + lodsb 1.242 +lzsa2noExtraByte: 1.243 + addb %cl, %ch 1.244 +lzsa2minNumber: 1.245 + addb %ch, %al 1.246 + jnc lzsa2gotNumber // 0-255 1.247 +#if 0 1.248 + je lzsa2BigNumber 1.249 + movb %al, %ah // S=256-767, L=256-1791 1.250 + lodsb 1.251 + .byte 0xB1 // mask lodsw with movb $0xAD, %cl 1.252 +lzsa2BigNumber: 1.253 +#endif 1.254 + lodsw // 0-65535 1.255 +lzsa2gotNumber: 1.256 + xchgw %ax, %cx 1.257 + ret 1.258 + 1.259 +#if defined(NeedNormalize) || defined(PARANOIA) 1.260 +# if defined(PARANOIA) 1.261 +lzsa2movlp: 1.262 + decw %ch 1.263 + rep movsb 1.264 + incw %ch 1.265 +# endif 1.266 +normalize: 1.267 +lzsa2movLit: 1.268 + movw %ds, %ax 1.269 +lzsa2movStr: 1.270 + norm %bp 1.271 +# if defined(PARANOIA) 1.272 + cmpb $0xFF, %ch // catch FFFX case 1.273 + je lzsa2movlp 1.274 +# endif 1.275 + rep movsb 1.276 + ret 1.277 +#endif