wok annotate plop/stuff/unlzma.S @ rev 25002

updated nrg2iso (0.4 -> 0.4.1)
author Hans-G?nter Theisgen
date Mon May 16 14:45:30 2022 +0100 (2022-05-16)
parents c4968381aed9
children 1f9238437d3b
rev   line source
pascal@23919 1 // #define RC_NORMALIZE if (Range < kTopValue) { Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
pascal@23919 2 //
pascal@23919 3 // #define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
pascal@23919 4 // #define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
pascal@23919 5 // #define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
pascal@23919 6 //
pascal@23919 7 //#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \
pascal@23919 8 // { UpdateBit0(p); mi <<= 1; A0; } else \
pascal@23919 9 // { UpdateBit1(p); mi = (mi + mi) + 1; A1; }
pascal@23919 10 //
pascal@23919 11 // #define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)
pascal@23919 12 //
pascal@23919 13 // #define RangeDecoderBitTreeDecode(probs, numLevels, res) \
pascal@23919 14 // { int i = numLevels; res = 1; \
pascal@23919 15 // do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \
pascal@23919 16 // res -= (1 << numLevels); }
pascal@23919 17 /*
pascal@23919 18 * Compression with : lzma e src dst -eos -pb2 -lp0 -lc3
pascal@23919 19 */
pascal@23919 20
pascal@24046 21 #define PROP_PB 2
pascal@23919 22 #define PROP_LP 0
pascal@24046 23 #define PROP_LC 3
pascal@23919 24 #define PROPS (PROP_LC+(PROP_LP*9)+(PROP_PB*45))
pascal@23919 25
pascal@23919 26 // static const Byte *Buffer;
pascal@23919 27 // static UInt32 bound, Code, Range;
pascal@23919 28
pascal@23919 29 /*
pascal@23919 30 * Buffer register DS:SI
pascal@23919 31 * all var based ws=ss:bp
pascal@23919 32 */
pascal@23919 33
pascal@23919 34 rep0 = -4 // long
pascal@23919 35 rep1 = rep0-4 // long
pascal@23919 36 rep2 = rep0-8 // long
pascal@23919 37 rep3 = rep0-12 // long
pascal@23919 38 state = -17 // byte, 0..11
pascal@23919 39 posState = state-1 // byte, 0..15
pascal@23919 40 posState2 = posState-1 // byte, 0..15
pascal@23919 41 scratched = rep0-16 // byte = 1
pascal@23919 42 Code = -24 // long
pascal@23919 43 outStream = -28 // long
pascal@23919 44 nowPos = outStream // long
pascal@23919 45 Range = Code-8 // long
pascal@23919 46 #define LOCALS 32
pascal@23919 47
pascal@23919 48 // int LzmaDecode(CLzmaDecoderState *vs,
pascal@23919 49 // const unsigned char *inStream,
pascal@23919 50 // unsigned char *outStream)
pascal@23919 51 // {
pascal@23919 52 // CProb *p = vs->Probs;
pascal@23919 53 // SizeT nowPos = 0;
pascal@23919 54 // #define posStateMask = (1 << (vs->Properties.pb)) - 1;
pascal@23919 55 // #define literalPosMask = (1 << (vs->Properties.lp)) - 1;
pascal@23919 56 // int lc = vs->Properties.lc, state = 0, len = 0;
pascal@23919 57 // UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
pascal@23919 58 //
pascal@23919 59 // {
pascal@23919 60 // UInt32 i, numProbs = Literal /*1846*/
pascal@23919 61 // + ((UInt32)LZMA_LIT_SIZE /*768*/ << (lc + vs->Properties.lp));
pascal@23919 62 // for (i = 0; i < numProbs; i++) p[i] = kBitModelTotal /*2048*/ >> 1;
pascal@23919 63
pascal@23919 64 #define WS (1846+(768<<(PROP_LC+PROP_LP)))
pascal@23919 65 #if (WS+WS+LOCALS) >= 65000
pascal@23919 66 /* MAX WS = (1846+(768<<(8+4))) > 3MB! */
pascal@23919 67 #error invalid (lc,lp,pb) : out of memory
pascal@23919 68 #endif
pascal@23919 69
pascal@23919 70 ws1 = WS
pascal@23919 71 ws2 = ws1*2
pascal@23919 72 ws = ws2+LOCALS+15
pascal@23919 73
pascal@23919 74 #ifndef FLAT32
pascal@23919 75 #define AX %ax
pascal@23919 76 #define BX %bx
pascal@23919 77 #define CX %cx
pascal@23919 78 #define DX %dx
pascal@23919 79 #define SI %si
pascal@23919 80 #define DI %di
pascal@23919 81 #define BP %bp
pascal@23919 82 #define SP %sp
pascal@23919 83 #define CWD cwd
pascal@23919 84 #else
pascal@23919 85 #define AX %eax
pascal@23919 86 #define BX %ebx
pascal@23919 87 #define CX %ecx
pascal@23919 88 #define DX %edx
pascal@23919 89 #define SI %esi
pascal@23919 90 #define DI %edi
pascal@23919 91 #define BP %ebp
pascal@23919 92 #define SP %esp
pascal@23919 93 #define CWD cdq
pascal@23919 94 #endif
pascal@23919 95 /*
pascal@23919 96 * LzmaDecode:
pascal@23919 97 #ifndef FLAT32
pascal@23919 98 * input ds:si=inStream, es:di=outStream
pascal@23919 99 * output outStream[], ds:si, es:di
pascal@23919 100 .code 16
pascal@23919 101 #else
pascal@23919 102 * input esi=inStream, edi=outStream
pascal@23919 103 * output outStream[], esi, edi
pascal@23919 104 .code 32
pascal@23919 105 #endif
pascal@23919 106 */
pascal@23919 107
pascal@23919 108 mov $ws1, CX
pascal@23919 109 #ifdef ONLY8086
pascal@23919 110 movw $2048/2, %ax
pascal@23919 111 lzd1:
pascal@23919 112 pushw %ax
pascal@23919 113 #else
pascal@23919 114 lzd1:
pascal@23919 115 pushw $2048/2
pascal@23919 116 #endif
pascal@23919 117 loop lzd1
pascal@23919 118 mov SP, BP
pascal@23919 119 movb $((LOCALS+3)/4)*2, %cl
pascal@23919 120 #ifdef ONLY8086
pascal@23919 121 movw $1, %ax
pascal@23919 122 cwd
pascal@23919 123 initlocals:
pascal@23919 124 pushw %dx
pascal@23919 125 pushw %ax
pascal@23919 126 #else
pascal@23919 127 initlocals:
pascal@23919 128 pushl $1
pascal@23919 129 #endif
pascal@23919 130 loop initlocals
pascal@23919 131
pascal@23919 132 #if !defined(FLAT32) && !defined(FLAT16OUT)
pascal@23919 133 movb $4, %cl
pascal@23919 134 movw %es, %bx
pascal@23919 135 shrw %cl, %bx
pascal@23919 136 movw %es, %dx
pascal@23919 137 shlw %cl, %dx
pascal@23919 138 addw %dx, %di
pascal@23919 139 movw %di, outStream(%bp)
pascal@23919 140 adcb %bh, outStream+2(%bp)
pascal@23919 141 incw %cx
pascal@23919 142 #else
pascal@23919 143 movb $5, %cl
pascal@23919 144 mov DI, outStream(BP)
pascal@23919 145 #endif
pascal@23919 146
pascal@23919 147 // Byte previousByte = 0;
pascal@23919 148 xor BX, BX
pascal@23919 149
pascal@23919 150 // #define RC_INIT(buffer)
pascal@23919 151 // Buffer = buffer; Code = 0; Range = 0xFFFFFFFF;
pascal@23919 152 // { int i; for(i=0; i<5; i++) { Code = (Code<<8) | RC_READ_BYTE; }}
pascal@23919 153 // }
pascal@23919 154 // RC_INIT(inStream);
pascal@23919 155
pascal@23919 156 #ifndef NO_LZMA_HEADER
pascal@23919 157 #ifdef CHECK_LZMA_HEADER
pascal@23919 158 cmp.w $0x5A4C, (SI) // lzip header ('LZIP' version:1 dicobits:1)
pascal@23919 159 je lzip_header
pascal@23919 160 cmp.w $0x5D, (SI) // lzma header (0x5D dicosz:4 orgsz:8)
pascal@23919 161 jne no_header
pascal@23919 162 add $13-6, SI // skip lzma header
pascal@23919 163 lzip_header:
pascal@23919 164 add $6, SI // skip lzip header
pascal@23919 165 no_header:
pascal@23919 166 #else
pascal@23919 167 add $13, SI // skip lzma header (0x5D dicosz:4 orgsz:8)
pascal@23919 168 #endif
pascal@23919 169 #endif
pascal@23919 170 setrep:
pascal@23919 171 call RC_LOAD_BYTE
pascal@23919 172 decb Range(BP)
pascal@23919 173 loop setrep
pascal@23919 174
pascal@23919 175 lzdmainlp:
pascal@23919 176 // while(1) {
pascal@23919 177 // CProb *prob;
pascal@23919 178 // int posState = (int)((nowPos) & posStateMask);
pascal@23919 179 //
pascal@23919 180 // prob = p + IsMatch /*0*/ + (state << kNumPosBitsMax /*4*/) + posState;
pascal@23919 181 // if (Bit0(prob)) { /* char */
pascal@23919 182
pascal@23919 183 xor DX, DX
pascal@23919 184 call Bit1state // Bit1(dx + (state << kNumPosBitsMax /*4*/) + posState)
pascal@23919 185 mov $state, DI
pascal@23919 186 jc lzdstring
pascal@23919 187
pascal@23919 188 // prob = p + Literal /*1846*/ + (LZMA_LIT_SIZE /*768*/ *
pascal@23919 189 // ((((nowPos) & literalPosMask) << lc) + (previousByte >> (8 - lc))));
pascal@23919 190
pascal@23919 191 #if PROP_LC != 0
pascal@23919 192 # ifdef ONLY8086
pascal@23919 193 movb $8-PROP_LC, %cl
pascal@23919 194 shrb %cl, %bl
pascal@23919 195 # else
pascal@23919 196 shrb $8-PROP_LC, %bl
pascal@23919 197 # endif
pascal@24046 198 #else
pascal@24046 199 xor %bx,%bx
pascal@23919 200 #endif
pascal@23919 201
pascal@23919 202 #if PROP_LP != 0
pascal@23919 203 movb posState2(BP), %dl
pascal@24046 204 # if PROP_LC != 0
pascal@24046 205 # ifdef ONLY8086
pascal@23919 206 movb $PROP_LC, %cl
pascal@23919 207 shl %cl, DX
pascal@24046 208 # else
pascal@23919 209 shl $PROP_LC, DX
pascal@24046 210 # endif
pascal@24046 211 movb $0, %bh
pascal@23919 212 # endif
pascal@23919 213 add BX, DX
pascal@23919 214 #endif
pascal@23919 215
pascal@23919 216 movb $3, %ah
pascal@23919 217 mul BX // dx = 3*bh
pascal@23919 218 add $1846, AX
pascal@23919 219
pascal@23919 220 // int symbol = 1;
pascal@23919 221
pascal@23919 222 CWD
pascal@23919 223 inc DX // symbol = 1
pascal@23919 224 xchg AX, CX // save prob
pascal@23919 225
pascal@23919 226 // if (state >= kNumLitStates /*7*/) { /* previous was string */
pascal@23919 227 // if (state < 4) state = 0;
pascal@23919 228
pascal@23919 229 lzd6z:
pascal@23919 230 subb $3, (BP, DI)
pascal@23919 231
pascal@23919 232 // if (state < 4) state = 0;
pascal@23919 233
pascal@23919 234 jnc lzd6
pascal@23919 235 movb %dh, (BP, DI) // %dh = 0
pascal@23919 236
pascal@23919 237 lzd6:
pascal@23919 238 // else if (state < 10) state -= 3;
pascal@23919 239
pascal@23919 240 cmpb $10-3, (BP, DI)
pascal@23919 241
pascal@23919 242 // else state -= 6;
pascal@23919 243
pascal@23919 244 jnb lzd6z
pascal@23919 245 cmpb $7-3-1, (BP, DI)
pascal@23919 246 jbe lzd3
pascal@23919 247
pascal@23919 248 // int matchByte = outStream[nowPos - rep0];
pascal@23919 249
pascal@23919 250 call DicoRep02ESDI // %bl = outStream[nowPos - rep0];
pascal@23919 251
pascal@23919 252 // do {
pascal@23919 253 // int bit;
pascal@23919 254 // CProb *probLit;
pascal@23919 255 // matchByte <<= 1; bit = (matchByte & 0x100);
pascal@23919 256
pascal@23919 257 movb $1, %bh
pascal@23919 258 lzd4:
pascal@23919 259 shlb $1, %bl // matchByte <<= 1
pascal@23919 260 sbb DI, DI // save bit=C
pascal@23919 261
pascal@23919 262 // probLit = prob + 0x100 + bit + symbol;
pascal@23919 263
pascal@23919 264 mov CX, AX // restore prob
pascal@23919 265 adcb %bh, %ah // + bit + 0x100
pascal@23919 266
pascal@23919 267 // RC_GET_BIT2(probLit, symbol, if (bit) break, if (!bit) break)
pascal@23919 268
pascal@23919 269 call Bit1axdx // C,%ax = Bit1(prob+%ax)
pascal@23919 270 rclb $1, %dl // symbol <<= 1; symbol |= C
pascal@23919 271 jc lzd5 // if symbol >= 0x100
pascal@23919 272 cmp DI, AX
pascal@23919 273 jz lzd4 // if bit == Bit1(prob+%ax)
pascal@23919 274
pascal@23919 275 // } while (symbol < 0x100);
pascal@23919 276 // }
pascal@23919 277 lzd3:
pascal@23919 278 // while (symbol < 0x100) {
pascal@23919 279 // CProb *probLit = prob + symbol;
pascal@23919 280 // RC_GET_BIT(probLit, symbol)
pascal@23919 281 // }
pascal@23919 282
pascal@23919 283 xor BX, BX
pascal@23919 284 jmp lzd4
pascal@23919 285 lzd5:
pascal@23919 286
pascal@23919 287 // outStream[nowPos++] = previousByte = (Byte)symbol;
pascal@23919 288
pascal@23919 289 xchg AX, DX
pascal@23919 290 call outchar // %bl = outStream[nowPos++] = %al;
pascal@23919 291 jmp lzdmainlp
pascal@23919 292
pascal@23919 293 // }
pascal@23919 294
pascal@23919 295 lzdstring:
pascal@23919 296 mov $1, CX
pascal@23919 297
pascal@23919 298 // else { /* string */
pascal@23919 299 // prob = p + IsRep /*192*/ + state;
pascal@23919 300
pascal@23919 301 movb $192, %dl
pascal@23919 302 addb (BP, DI), %dl
pascal@23919 303 mov $rep0, DI
pascal@23919 304
pascal@23919 305 // if (Bit0(prob)) {
pascal@23919 306
pascal@23919 307 call Bit1dx // Bit1(prob)
pascal@23919 308 jc lzd8
pascal@23919 309
pascal@23919 310 // rep3 = rep2; rep2 = rep1; rep1 = rep0;
pascal@23919 311 // state = (state < kNumLitStates /*7*/) ? 0 : 3;
pascal@23919 312
pascal@23919 313 stc
pascal@23919 314
pascal@23919 315 // prob = p + LenCoder /*818*/;
pascal@23919 316
pascal@23919 317 mov $818, DX
pascal@23919 318
pascal@23919 319 // }
pascal@23919 320
pascal@23919 321 jmp lzd11a
pascal@23919 322
pascal@23919 323 // else {
pascal@23919 324 lzd8:
pascal@23919 325 // prob += kNumStates /*12*/;
pascal@23919 326 // if (Bit0(prob)) {
pascal@23919 327 call Bit1dx12 // prob += 12; Bit1(prob)
pascal@23919 328 jc lzd11
pascal@23919 329 // prob = p + IsRep0Long /*240*/ + (state << kNumPosBitsMax /*4*/)
pascal@23919 330 // + posState;
pascal@23919 331 movb $240, %dl // dh=0
pascal@23919 332
pascal@23919 333 // if (Bit0(prob)) {
pascal@23919 334
pascal@23919 335 call Bit1state // Bit1(dx + (state << kNumPosBitsMax /*4*/) + posState)
pascal@23919 336 jc lzd12
pascal@23919 337
pascal@23919 338 // // if (nowPos == 0) return LZMA_RESULT_DATA_ERROR;
pascal@23919 339 // state = (state < kNumLitStates /*7*/) ? 9 : 11;
pascal@23919 340
pascal@23919 341 movb $9, %dl
pascal@23919 342
pascal@23919 343 // len++; goto string;
pascal@23919 344 jmp lzd13string // ax = 0
pascal@23919 345 // }
pascal@23919 346 // }
pascal@23919 347 // else {
pascal@23919 348 lzd11:
pascal@23919 349 // UInt32 distance = rep1;
pascal@23919 350 // prob += kNumStates /*12*/;
pascal@23919 351 // if (!Bit0(prob)) {
pascal@23919 352
pascal@23919 353 call Bit1dx12 // prob += 12; Bit1(prob)
pascal@23919 354 jnc lzd11z
pascal@23919 355
pascal@23919 356 // prob += kNumStates /*12*/;
pascal@23919 357 // if (Bit0(prob)) distance = rep2;
pascal@23919 358
pascal@23919 359 call Bit1dx12 // prob += 12; Bit1(prob)
pascal@23919 360 lzd11a:
pascal@23919 361 adcb %cl, %cl
pascal@23919 362
pascal@23919 363 // else { distance = rep3; rep3 = rep2; }
pascal@23919 364 // rep2 = rep1;
pascal@23919 365 // }
pascal@23919 366 // rep1 = rep0; rep0 = distance;
pascal@23919 367
pascal@23919 368 lzd11z:
pascal@23919 369 # ifdef ONLY8086
pascal@23919 370 shl $1, CX
pascal@23919 371 shl $1, CX // 8->32 bits
pascal@23919 372 sub CX, DI // &rep[cx]
pascal@23919 373 movw (BP, DI), %ax
pascal@23919 374 pushw 2(BP, DI)
pascal@23919 375 rotreplp:
pascal@23919 376 movb 4(BP, DI), %bl
pascal@23919 377 movb %bl, (BP, DI)
pascal@23919 378 inc DI
pascal@23919 379 loop rotreplp
pascal@23919 380 popw %bx
pascal@23919 381 testb %dh, %dh
pascal@23919 382 jnz lzd10
pascal@23919 383 movw %ax, (BP, DI)
pascal@23919 384 movw %bx, 2(BP, DI)
pascal@23919 385 # else
pascal@23919 386 shl $2, CX // 8->32 bits
pascal@23919 387 sub CX, DI // &rep[cx]
pascal@23919 388 movl (BP, DI), %eax
pascal@23919 389 rotreplp:
pascal@23919 390 movb 4(BP, DI), %bl
pascal@23919 391 movb %bl, (BP, DI)
pascal@23919 392 inc DI
pascal@23919 393 loop rotreplp
pascal@23919 394 testb %dh, %dh
pascal@23919 395 jnz lzd10
pascal@23919 396 movl %eax, (BP, DI)
pascal@23919 397 # endif
pascal@23919 398
pascal@23919 399 // }
pascal@23919 400 lzd12:
pascal@23919 401 // state = (state < kNumLitStates /*7*/) ? 8 : 11;
pascal@23919 402
pascal@23919 403 movb $0x08, %cl
pascal@23919 404
pascal@23919 405 // prob = p + RepLenCoder /*1332*/;
pascal@23919 406
pascal@23919 407 mov $1332, DX
pascal@23919 408
pascal@23919 409 // }
pascal@23919 410 lzd10:
pascal@23919 411 push CX // CX = 0
pascal@23919 412
pascal@23919 413 // { /* get len */
pascal@23919 414 // int numBits, offset;
pascal@23919 415 // CProb *probLen = prob + LenChoice /*0*/;
pascal@23919 416 // numBits = kLenNumLowBits /*3*/;
pascal@23919 417
pascal@23919 418 movb $8, %cl // numBits : 3,3,8
pascal@23919 419
pascal@23919 420 // if (Bit0(probLen)) {
pascal@23919 421
pascal@23919 422 call Bit1dx // Bit1(prob)
pascal@23919 423 xchg AX, BX
pascal@23919 424 inc DX
pascal@23919 425 jnc lzd15 // bx=0
pascal@23919 426
pascal@23919 427 // probLen = prob + LenLow/*2*/ + (posState << kLenNumLowBits/*3*/);
pascal@23919 428 // offset = 0;
pascal@23919 429 // }
pascal@23919 430 // else {
pascal@23919 431 // probLen = prob + LenChoice2 /*1*/;
pascal@23919 432
pascal@23919 433 call Bit1dx // Bit1(prob)
pascal@23919 434 add AX, BX
pascal@23919 435
pascal@23919 436 #if PROP_PB != 0
pascal@23919 437 inc AX // ah=0
pascal@23919 438 #endif
pascal@23919 439 jc lzd16 // %ax=0, %bx=-2
pascal@23919 440 lzd15:
pascal@23919 441 #if PROP_PB != 0
pascal@23919 442 movb $8, %al
pascal@23919 443 mulb posState(BP)
pascal@23919 444 #endif
pascal@23919 445
pascal@23919 446 // if (Bit0(probLen)) {
pascal@23919 447 // probLen = prob + LenMid/*130*/ + (posState << kLenNumMidBits/*3*/);
pascal@23919 448
pascal@23919 449 movb $3, %cl // numBits : 3,3,8
pascal@23919 450 lzd16:
pascal@23919 451 #if PROP_PB != 0
pascal@23919 452 add $2-128-1, AX // probLen : 2,130,258
pascal@23919 453 #else
pascal@23919 454 mov $2-128-1, AX // probLen : 2,130,258
pascal@23919 455 #endif
pascal@23919 456 add DX, AX
pascal@23919 457 mov $-8+1, DX // offset : 0,8,16
pascal@23919 458 lzdargslp:
pascal@23919 459 add $8, DX
pascal@23919 460 add $128, AX
pascal@23919 461 inc BX
pascal@23919 462 jle lzdargslp // leave with bx=1
pascal@23919 463
pascal@23919 464 // offset = kLenNumLowSymbols /*8*/;
pascal@23919 465 // //numBits = kLenNumMidBits /*3*/;
pascal@23919 466 // }
pascal@23919 467 // else {
pascal@23919 468 // probLen = prob + LenHigh /*258*/;
pascal@23919 469 // offset = kLenNumLowSymbols /*8*/ + kLenNumMidSymbols /*8*/;
pascal@23919 470 // numBits = kLenNumHighBits /*8*/;
pascal@23919 471 // }
pascal@23919 472 // }
pascal@23919 473 // RangeDecoderBitTreeDecode(probLen, numBits, len); len += offset;
pascal@23919 474
pascal@23919 475 push DX
pascal@23919 476 call RangeDecoder // %ax=probs, %cx=numLevels, %ax=res
pascal@23919 477 pop DX
pascal@23919 478 add DX, AX // offset
pascal@23919 479 pop DX // 0
pascal@23919 480 lzd13string:
pascal@23919 481 push AX
pascal@23919 482
pascal@23919 483 // state = (state < kNumLitStates /*7*/) ? dl : dl|3;
pascal@23919 484
pascal@23919 485 movb $7, %cl
pascal@23919 486 cmpb %cl, state(BP)
pascal@23919 487 jb new_state
pascal@23919 488 orb $3, %dl
pascal@23919 489 new_state:
pascal@23919 490 movb %dl, state(BP)
pascal@23919 491
pascal@23919 492 // } /* get len */
pascal@23919 493 // if (state < 4) {
pascal@23919 494
pascal@23919 495 cmpb $4-1, %dl
pascal@23919 496 ja lzd19
pascal@23919 497
pascal@23919 498 // int posSlot;
pascal@23919 499 // state += kNumLitStates /*7*/;
pascal@23919 500
pascal@23919 501 addb %cl, state(BP)
pascal@23919 502
pascal@23919 503 // prob = p + PosSlot /*432*/ + (((len < kNumLenToPosStates /*4*/) ?
pascal@23919 504 // len : kNumLenToPosStates - 1) << kNumPosSlotBits /*6*/);
pascal@23919 505
pascal@23919 506 cmp $4+1, AX
pascal@23919 507 jb lzd21
pascal@23919 508 mov $3+1, AX
pascal@23919 509
pascal@23919 510 lzd21:
pascal@23919 511
pascal@23919 512 dec CX // cx = 6
pascal@23919 513 shl %cl, AX
pascal@23919 514 add $432-64, AX
pascal@23919 515
pascal@23919 516 // RangeDecoderBitTreeDecode(prob, kNumPosSlotBits /*6*/, posSlot);
pascal@23919 517
pascal@23919 518 call RangeDecoder // %ax=probs, %cx=numLevels, %ax=res
pascal@23919 519
pascal@23919 520 // if (posSlot >= kStartPosModelIndex /*4*/) {
pascal@23919 521 // int numDirectBits = ((posSlot >> 1) - 1);
pascal@23919 522
pascal@23919 523 #ifndef FLAT32
pascal@23919 524 movw %cx, 2(%bp, %di) // %cx = 0
pascal@23919 525 #endif
pascal@23919 526 mov AX, (BP, DI)
pascal@23919 527 mov AX, CX
pascal@23919 528 shrw $1, CX
pascal@23919 529 dec CX
pascal@23919 530 cmpb $4, %al
pascal@23919 531 jb lzd22
pascal@23919 532
pascal@23919 533 // rep0 = (2 | ((UInt32)posSlot & 1));
pascal@23919 534
pascal@23919 535 andb %bl, (BP, DI) // %bx=1
pascal@23919 536 orb $2, (BP, DI)
pascal@23919 537
pascal@23919 538 // if (posSlot < kEndPosModelIndex /*14*/) {
pascal@23919 539
pascal@23919 540 cmpb $14, %al
pascal@23919 541 jnb lzd23
pascal@23919 542
pascal@23919 543 // rep0 <<= numDirectBits;
pascal@23919 544
pascal@23919 545 neg AX
pascal@23919 546 # ifdef ONLY8086
pascal@23919 547 pushw %cx
pascal@23919 548 movb $0, %ch
pascal@23919 549 shllrep0:
pascal@23919 550 shlw $1, (BP, DI)
pascal@23919 551 rclw $1, 2(BP, DI)
pascal@23919 552 loop shllrep0
pascal@23919 553 popw %cx
pascal@23919 554 # else
pascal@23919 555 shll %cl, (BP, DI)
pascal@23919 556 # endif
pascal@23919 557 add (BP, DI), AX
pascal@23919 558
pascal@23919 559 // prob = p + SpecPos /*688*/ + rep0 - posSlot - 1;
pascal@23919 560
pascal@23919 561 add $687, AX
pascal@23919 562 jmp lzd24
pascal@23919 563
pascal@23919 564 // }
pascal@23919 565 // else {
pascal@23919 566 lzd23:
pascal@23919 567 // numDirectBits -= kNumAlignBits /*4*/;
pascal@23919 568 // do {
pascal@23919 569 // RC_NORMALIZE; Range >>= 1; rep0 <<= 1;
pascal@23919 570 // if (Code >= Range) { Code -= Range; rep0 |= 1; }
pascal@23919 571
pascal@23919 572 lzd23z:
pascal@23919 573 call RC_NORMALIZE
pascal@23919 574 # ifdef ONLY8086
pascal@23919 575 pushw %dx
pascal@23919 576 shrw $1, Range+2(BP)
pascal@23919 577 rcrw $1, Range(BP)
pascal@23919 578 movw Range(BP), %ax
pascal@23919 579 movw Range+2(BP), %dx
pascal@23919 580 cmpw Code+2(BP), %dx
pascal@23919 581 ja lzd25
pascal@23919 582 jb lzd25x
pascal@23919 583 cmpw Code(BP), %ax
pascal@23919 584 ja lzd25
pascal@23919 585 lzd25x:
pascal@23919 586 subw %ax, Code(BP)
pascal@23919 587 sbbw %dx, Code+2(BP)
pascal@23919 588 stc
pascal@23919 589 lzd25:
pascal@23919 590 popw %dx
pascal@23919 591 rclw $1, (BP, DI)
pascal@23919 592 rclw $1, 2(BP, DI)
pascal@23919 593 # else
pascal@23919 594 shrl $1, Range(BP)
pascal@23919 595 movl Range(BP), %eax
pascal@23919 596 cmpl Code(BP), %eax
pascal@23919 597 ja lzd25
pascal@23919 598 subl %eax, Code(BP)
pascal@23919 599 stc
pascal@23919 600 lzd25:
pascal@23919 601 rcll $1, (BP, DI)
pascal@23919 602 # endif
pascal@23919 603
pascal@23919 604 // } while (--numDirectBits != 0);
pascal@23919 605
pascal@23919 606 cmpb $4+1, %cl
pascal@23919 607 loopne lzd23z
pascal@23919 608
pascal@23919 609 // prob = p + Align /* 802 */; numDirectBits = kNumAlignBits /*4*/;
pascal@23919 610 // rep0 <<= numDirectBits;
pascal@23919 611
pascal@23919 612 # ifdef ONLY8086
pascal@23919 613 pushw %cx
pascal@23919 614 movb $0, %ch
pascal@23919 615 shlrep0:
pascal@23919 616 shlw $1, (BP, DI)
pascal@23919 617 rclw $1, 2(BP, DI)
pascal@23919 618 loop shlrep0
pascal@23919 619 popw %cx
pascal@23919 620 # else
pascal@23919 621 shll %cl, (BP, DI)
pascal@23919 622 # endif
pascal@23919 623 mov $802, AX
pascal@23919 624 // }
pascal@23919 625
pascal@23919 626 lzd24:
pascal@23919 627 call RangeDecoder // %ax=probs, %cx=numLevels, %ax=res
pascal@23919 628
pascal@23919 629 // {
pascal@23919 630 // int i = 1, mi = 1;
pascal@23919 631 // do {
pascal@23919 632 // CProb *prob3 = prob + mi;
pascal@23919 633 // RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
pascal@23919 634
pascal@23919 635 orb %dh, (BP, DI) // update rep0 with DirectBits
pascal@23919 636
pascal@23919 637 // i <<= 1;
pascal@23919 638 // } while(--numDirectBits != 0);
pascal@23919 639 // }
pascal@23919 640 // } else rep0 = posSlot;
pascal@23919 641 lzd22:
pascal@23919 642 // if (++rep0 == (UInt32)(0)) break; /* EOF */
pascal@23919 643
pascal@23919 644 # ifdef ONLY8086
pascal@23919 645 incw (BP, DI)
pascal@23919 646 jnz lzd19
pascal@23919 647 incw 2(BP, DI)
pascal@23919 648 # else
pascal@23919 649 incl (BP, DI)
pascal@23919 650 # endif
pascal@23919 651
pascal@23919 652 lzd19:
pascal@23919 653 pop CX
pascal@23919 654 jz lzdone
pascal@23919 655
pascal@23919 656 // }
pascal@23919 657 // len += kMatchMinLen;/*2*/
pascal@23919 658
pascal@23919 659 inc CX
pascal@23919 660
pascal@23919 661 // string: // if (rep0 > nowPos) return LZMA_RESULT_DATA_ERROR;
pascal@23919 662 // do {
pascal@23919 663 lzd13z:
pascal@23919 664 // previousByte = outStream[nowPos - rep0];
pascal@23919 665 // outStream[nowPos++] = previousByte;
pascal@23919 666
pascal@23919 667 call outcharDico // %bl = outStream[nowPos++] = outStream[nowPos - rep0]
pascal@23919 668
pascal@23919 669 // } while(--len != 0);
pascal@23919 670
pascal@23919 671 loop lzd13z
pascal@23919 672
pascal@23919 673 // } /* char/string */
pascal@23919 674 // }
pascal@23919 675
pascal@23919 676 jmp lzdmainlp
pascal@23919 677
pascal@23919 678 lzdone:
pascal@23919 679 // //RC_NORMALIZE;
pascal@23919 680 // //*inSizeProcessed = (SizeT)(Buffer - inStream); *outSizeProcessed = nowPos;
pascal@23919 681 // return LZMA_RESULT_OK;
pascal@23919 682 call Dico2ESDI // set es & di (rep0 = 0)
pascal@23919 683 lea ws2(BP), SP // dealloc
pascal@23919 684 ret
pascal@23919 685 // }
pascal@23919 686
pascal@23919 687 // al = outStream[nowPos - rep0];
pascal@23919 688
pascal@23919 689 /*
pascal@23919 690 * output es:di, al
pascal@23919 691 * scratch bh, cl, flags
pascal@23919 692 */
pascal@23919 693
pascal@23919 694 DicoRep02ESDI:
pascal@23919 695 stc
pascal@23919 696
pascal@23919 697 // bl = outStream[nowPos];
pascal@23919 698
pascal@23919 699 /*
pascal@23919 700 * output es:di, bl
pascal@23919 701 * scratch bh, cl, flags
pascal@23919 702 */
pascal@23919 703
pascal@23919 704 Dico2ESDI:
pascal@23919 705 #if !defined(FLAT32) && !defined(FLAT16OUT)
pascal@23919 706 # ifdef ONLY8086
pascal@23919 707 pushw %ax
pascal@23919 708 movw nowPos(%bp), %bx
pascal@23919 709 movw nowPos+2(%bp), %ax
pascal@23919 710 jnc Dico2ESDIz
pascal@23919 711 subw rep0(%bp), %bx
pascal@23919 712 sbbw rep0+2(%bp), %ax
pascal@23919 713 Dico2ESDIz:
pascal@23919 714 movw $0xF, %di
pascal@23919 715 andw %bx, %di
pascal@23919 716 pushw %cx
pascal@23919 717 movb $4, %cl
pascal@23919 718 shrw %cl, %bx
pascal@23919 719 shlw %cl, %ax
pascal@23919 720 popw %cx
pascal@23919 721 addb %al, %bh
pascal@23919 722 popw %ax
pascal@23919 723 # else
pascal@23919 724 movl nowPos(%bp), %ebx
pascal@23919 725 jnc Dico2ESDIz
pascal@23919 726 subl rep0(%bp), %ebx
pascal@23919 727 Dico2ESDIz:
pascal@23919 728 movw %bx, %di
pascal@23919 729 xorw %bx, %bx
pascal@23919 730 shrl $4, %ebx
pascal@23919 731 # endif
pascal@23919 732 movw %bx, %es
pascal@23919 733 #else
pascal@23919 734 mov nowPos(BP), DI
pascal@23919 735 jnc Dico2ESDIz
pascal@23919 736 sub rep0(BP), DI
pascal@23919 737 Dico2ESDIz:
pascal@23919 738 #endif
pascal@23919 739 #ifdef FLAT32
pascal@23919 740 movb (DI), %bl
pascal@23919 741 #else
pascal@23919 742 movb %es:(%di), %bl
pascal@23919 743 #endif
pascal@23919 744 ret
pascal@23919 745
pascal@23919 746 outcharDico:
pascal@23919 747
pascal@23919 748 // bl = outStream[nowPos++] = outStream[nowPos - rep0]
pascal@23919 749
pascal@23919 750 /*
pascal@23919 751 * output es:di, bl
pascal@23919 752 * update nowPos
pascal@23919 753 * scratch ax, dx, bh, cl, flags
pascal@23919 754 */
pascal@23919 755
pascal@23919 756 call DicoRep02ESDI // %bl = outStream[nowPos - rep0]
pascal@23919 757 xchg AX, BX
pascal@23919 758 outchar:
pascal@23919 759
pascal@23919 760 // bl = outStream[nowPos++] = previousByte = al;
pascal@23919 761
pascal@23919 762 /*
pascal@23919 763 * output bl
pascal@23919 764 * update nowPos
pascal@23919 765 * scratch ax, dx, bh, di, cl, flags
pascal@23919 766 */
pascal@23919 767
pascal@23919 768 clc
pascal@23919 769 call Dico2ESDI
pascal@23919 770 stosb
pascal@23919 771 xchg AX, BX // previous byte
pascal@23919 772
pascal@23919 773 // int posState = (int)((nowPos) & posStateMask);
pascal@23919 774
pascal@23919 775 #if PROP_PB != 0 && PROP_LP != 0
pascal@23919 776 addw $0x0101, posState2(BP)
pascal@23919 777 andb $(((1 << PROP_PB) -1)<<8)+((1 << PROP_LP) -1), posState2(BP)
pascal@23919 778 #else
pascal@23919 779 # if PROP_PB != 0
pascal@23919 780 incb posState(BP)
pascal@23919 781 andb $((1 << PROP_PB) -1), posState(BP)
pascal@23919 782 # endif
pascal@23919 783 # if PROP_LP != 0
pascal@23919 784 incb posState2(BP)
pascal@23919 785 andb $((1 << PROP_LP) -1), posState2(BP)
pascal@23919 786 # endif
pascal@23919 787 #endif
pascal@23919 788 #ifdef ONLY8086
pascal@23919 789 incw nowPos(BP)
pascal@23919 790 jnz incnowPosDone
pascal@23919 791 incw nowPos+2(BP)
pascal@23919 792 incnowPosDone:
pascal@23919 793 #else
pascal@23919 794 incl nowPos(BP)
pascal@23919 795 #endif
pascal@23919 796 ret
pascal@23919 797
pascal@23919 798 //
pascal@23919 799 // #define RC_NORMALIZE if (Range < kTopValue)
pascal@23919 800 // { Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
pascal@23919 801
pascal@23919 802 /*
pascal@23919 803 * update Range, Code, ds:si
pascal@23919 804 * scratch flags
pascal@23919 805 */
pascal@23919 806
pascal@23919 807 RC_NORMALIZE:
pascal@23919 808 cmpb $0, Range+3(BP)
pascal@23919 809 jne RC_NORMALIZE_1
pascal@23919 810 RC_LOAD_BYTE:
pascal@23919 811 push AX
pascal@23919 812 #ifdef ONLY8086
pascal@23919 813 movw Range+1(BP), %ax
pascal@23919 814 movw %ax, Range+2(BP)
pascal@23919 815 movw Code+1(BP), %ax
pascal@23919 816 movw %ax, Code+2(BP)
pascal@23919 817 xorw %ax, %ax
pascal@23919 818 movb Range(BP), %ah
pascal@23919 819 movw %ax, Range(BP)
pascal@23919 820 movb Code(BP), %ah
pascal@23919 821 movw %ax, Code(BP)
pascal@23919 822 #else
pascal@23919 823 shll $8, Range(BP)
pascal@23919 824 shll $8, Code(BP)
pascal@23919 825 #endif
pascal@23919 826 #if !defined(FLAT16) && !defined(FLAT32)
pascal@23919 827 testw %si, %si
pascal@23919 828 jns RC_READ_BYTE
pascal@23919 829 movw %ds, %ax
pascal@23919 830 incw %ax
pascal@23919 831 movw %ax, %ds
pascal@23919 832 addw $-16, %si
pascal@23919 833 RC_READ_BYTE:
pascal@23919 834 #endif
pascal@23919 835 lodsb
pascal@23919 836 movb %al, Code(BP)
pascal@23919 837 pop AX
pascal@23919 838 RC_NORMALIZE_1:
pascal@23919 839 ret
pascal@23919 840
pascal@23919 841 // Bit1(dx + (state << kNumPosBitsMax /*4*/) + posState)
pascal@23919 842
pascal@23919 843 Bit1state:
pascal@23919 844 movb $16, %al
pascal@23919 845 mulb state(BP)
pascal@23919 846 # if PROP_PB != 0
pascal@23919 847 addb posState(BP), %al
pascal@23919 848 # endif
pascal@23919 849 Bit1axdx:
pascal@23919 850 add DX, AX
pascal@23919 851 jmp Bit1
pascal@23919 852
pascal@23919 853 // prob += 12; Bit1(prob)
pascal@23919 854
pascal@23919 855 Bit1dx12:
pascal@23919 856 add $12, DX
pascal@23919 857 Bit1dx:
pascal@23919 858 mov DX, AX
pascal@23919 859
pascal@23919 860 // static int Bit1(CProb *p)
pascal@23919 861
pascal@23919 862 Bit1:
pascal@23919 863 /*
pascal@23919 864 * input ax=p
pascal@23919 865 * output C, ax
pascal@23919 866 * update bound, Range, Code, ds:si
pascal@23919 867 * scratch flags
pascal@23919 868 */
pascal@23919 869
pascal@23919 870 // {
pascal@23919 871 // RC_NORMALIZE;
pascal@23919 872
pascal@23919 873 call RC_NORMALIZE // kill %ax, update %si
pascal@23919 874
pascal@23919 875 #ifdef ONLY8086
pascal@23919 876 pushw %ax
pascal@23919 877 pushw %cx
pascal@23919 878 pushw %dx
pascal@23919 879 pushw %di
pascal@23919 880 #else
pascal@23919 881 pushal
pascal@23919 882 #endif
pascal@23919 883
pascal@23919 884 xchg AX, DI
pascal@23919 885 add DI, DI // short *
pascal@23919 886
pascal@23919 887
pascal@23919 888 // bound = (Range>>kNumBitModelTotalBits /*11*/) * *(p);
pascal@23919 889
pascal@23919 890 #ifdef ONLY8086
pascal@23919 891 movw Range(BP), %dx
pascal@23919 892 movw Range+2(BP), %ax
pascal@23919 893 movw $11, %cx
pascal@23919 894 shr11lp:
pascal@23919 895 shrw $1, %ax
pascal@23919 896 rcrw $1, %dx
pascal@23919 897 loop shr11lp
pascal@23919 898 movw %dx, %cx
pascal@23919 899 mulw (BP, DI)
pascal@23919 900 xchgw %ax, %cx
pascal@23919 901 mulw (BP, DI)
pascal@23919 902 addw %cx, %dx
pascal@23919 903 #else
pascal@23919 904 movl Range(BP), %eax
pascal@23919 905 shrl $11, %eax
pascal@23919 906 movzwl (BP, DI), %edx
pascal@23919 907 mull %edx
pascal@23919 908 #endif
pascal@23919 909
pascal@23919 910 // if (Code < bound) {
pascal@23919 911
pascal@23919 912 #ifdef ONLY8086
pascal@23919 913 cmpw Code+2(BP), %dx
pascal@23919 914 jb Bit1_1
pascal@23919 915 ja Bit1_1x
pascal@23919 916 cmpw Code(BP), %ax
pascal@23919 917 jbe Bit1_1
pascal@23919 918 Bit1_1x:
pascal@23919 919
pascal@23919 920 // Range = bound;
pascal@23919 921
pascal@23919 922 movw %ax, Range(BP)
pascal@23919 923 movw %dx, Range+2(BP)
pascal@23919 924 #else
pascal@23919 925 cmpl Code(BP), %eax
pascal@23919 926 jbe Bit1_1
pascal@23919 927
pascal@23919 928 // Range = bound;
pascal@23919 929
pascal@23919 930 movl %eax, Range(BP)
pascal@23919 931 #endif
pascal@23919 932
pascal@23919 933 // *(p) += (kBitModelTotal /*2048*/ - *(p)) >> kNumMoveBits /*5*/;
pascal@23919 934
pascal@23919 935 movw $2048, %ax
pascal@23919 936
pascal@23919 937 // return 0;
pascal@23919 938
pascal@23919 939 jmp Bit1_2
pascal@23919 940
pascal@23919 941 // }
pascal@23919 942 // else {
pascal@23919 943
pascal@23919 944 Bit1_1:
pascal@23919 945
pascal@23919 946 // Range -= bound; Code -= bound;
pascal@23919 947
pascal@23919 948 #ifdef ONLY8086
pascal@23919 949 subw %ax, Range(BP)
pascal@23919 950 sbbw %dx, Range+2(BP)
pascal@23919 951 subw %ax, Code(BP)
pascal@23919 952 sbbw %dx, Code+2(BP)
pascal@23919 953 #else
pascal@23919 954 subl %eax, Range(BP)
pascal@23919 955 subl %eax, Code(BP)
pascal@23919 956 #endif
pascal@23919 957
pascal@23919 958 // *(p) -= (*(p)) >> kNumMoveBits /*5*/;
pascal@23919 959
pascal@23919 960 movw $31, %ax
pascal@23919 961
pascal@23919 962 // return 1;
pascal@23919 963
pascal@23919 964 stc
pascal@23919 965 Bit1_2:
pascal@23919 966 pushf
pascal@23919 967 subw (BP, DI), %ax
pascal@23919 968 #ifdef ONLY8086
pascal@23919 969 movb $5, %cl
pascal@23919 970 sarw %cl, %ax
pascal@23919 971 #else
pascal@23919 972 sarw $5, %ax
pascal@23919 973 #endif
pascal@23919 974 addw %ax, (BP, DI)
pascal@23919 975 popf
pascal@23919 976 #ifdef ONLY8086
pascal@23919 977 popw %di
pascal@23919 978 popw %dx
pascal@23919 979 popw %cx
pascal@23919 980 popw %ax
pascal@23919 981 #else
pascal@23919 982 popal
pascal@23919 983 #endif
pascal@23919 984 sbb AX, AX
pascal@23919 985
pascal@23919 986 // }
pascal@23919 987 // }
pascal@23919 988
pascal@23919 989 ret
pascal@23919 990
pascal@23919 991 RangeDecoder:
pascal@23919 992
pascal@23919 993 /*
pascal@23919 994 * input ax=probs cx=numLevels (< 8) bx=1
pascal@23919 995 * output ax=res (backward), dh (forward)
pascal@23919 996 * update bound, Range, Code, ds:si
pascal@23919 997 * scratch flags, cx=0, dl
pascal@23919 998 */
pascal@23919 999
pascal@23919 1000 push BX
pascal@23919 1001
pascal@23919 1002 // { int i = numLevels; res = 1;
pascal@23919 1003 mov BX, DX // res = 1
pascal@23919 1004
pascal@23919 1005 // do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0);
pascal@23919 1006
pascal@23919 1007 RangeDecoder_1:
pascal@23919 1008 push AX
pascal@23919 1009 call Bit1axdx // C,%ax = Bit1(prob+%ax)
pascal@23919 1010 rclb $1, %dl // res <<= 1; res |= C
pascal@23919 1011 andb %bl, %al // current bit
pascal@23919 1012 orb %al, %bh // store in bh
pascal@23919 1013 shlb $1, %bl // update max
pascal@23919 1014 pop AX
pascal@23919 1015 loop RangeDecoder_1
pascal@23919 1016
pascal@23919 1017 // res -= (1 << numLevels); }
pascal@23919 1018
pascal@23919 1019 xchg AX, BX // move bh to dh
pascal@23919 1020 xchg AX, DX // and dl to al
pascal@23919 1021 sub %dl, %al // sub max
pascal@23919 1022 pop BX
pascal@23919 1023 ret