mirror of
https://github.com/badvision/lawless-legends.git
synced 2024-10-03 21:55:17 +00:00
Rearranged gamma scheme for faster decomp.
This commit is contained in:
parent
05a63b3e54
commit
7d8c562ffa
@ -36,7 +36,8 @@ public class Lx47Algorithm
|
||||
int next;
|
||||
}
|
||||
|
||||
int countEliasGammaBits(int value) {
|
||||
// It's Elias Gamma, bit the value bits interspersed with the mark bits
|
||||
int countGammaBits(int value) {
|
||||
int bits;
|
||||
assert value >= 1 && value <= 255;
|
||||
|
||||
@ -48,15 +49,11 @@ public class Lx47Algorithm
|
||||
return bits;
|
||||
}
|
||||
|
||||
int countEliasExpGammaBits(int value, int exp) {
|
||||
return (exp==0) ? countEliasGammaBits(value) : (countEliasGammaBits((value >> exp) + 1) + exp);
|
||||
}
|
||||
|
||||
int countCodePair(int prevLits, int matchLen, int offset) {
|
||||
int nBits = (prevLits>0 ? 0 : 1)
|
||||
+ 8 // 8 for the byte that's always emitted
|
||||
+ (offset>=64 ? countEliasGammaBits(offset>>6) : 0)
|
||||
+ (matchLen>2 ? countEliasGammaBits(matchLen-2) : 0);
|
||||
+ (offset>=64 ? countGammaBits(offset>>6) : 0)
|
||||
+ (matchLen>2 ? countGammaBits(matchLen-2) : 0);
|
||||
return nBits;
|
||||
}
|
||||
|
||||
@ -66,7 +63,7 @@ public class Lx47Algorithm
|
||||
int bits = lits * 8;
|
||||
while (lits > 0) {
|
||||
int n = Math.min(254, lits);
|
||||
bits += countEliasGammaBits(n+1);
|
||||
bits += countGammaBits(n+1);
|
||||
lits -= n;
|
||||
}
|
||||
return bits;
|
||||
@ -185,17 +182,36 @@ public class Lx47Algorithm
|
||||
bitPos++;
|
||||
}
|
||||
|
||||
void writeEliasGamma(int value) {
|
||||
void writeGamma(int value) {
|
||||
assert value >= 1 && value <= 255;
|
||||
|
||||
int i;
|
||||
for (i = 2; i <= value; i <<= 1)
|
||||
|
||||
// Find highest set bit
|
||||
for (i = 128; (i&value) == 0; i >>= 1)
|
||||
;
|
||||
|
||||
// Write out extra bits with markers
|
||||
while (i > 1) {
|
||||
i >>= 1;
|
||||
writeBit(0);
|
||||
while ((i >>= 1) > 0)
|
||||
writeBit(value & i);
|
||||
}
|
||||
|
||||
// And finish
|
||||
writeBit(1);
|
||||
}
|
||||
|
||||
// 1: 1
|
||||
// 2: 010 -> 001
|
||||
// 3: 011 -> 011
|
||||
// 4: 00100 -> 00001
|
||||
// 5: 00101 -> 00011
|
||||
// 6: 00110 -> 01001
|
||||
// 7: 00111 -> 01011
|
||||
|
||||
void writeLiteralLen(int value) {
|
||||
writeEliasGamma(value+1);
|
||||
writeGamma(value+1);
|
||||
}
|
||||
|
||||
void writeCodePair(int matchLen, int offset)
|
||||
@ -211,9 +227,9 @@ public class Lx47Algorithm
|
||||
writeByte(data);
|
||||
|
||||
if (offset >= 64)
|
||||
writeEliasGamma(offset>>6);
|
||||
writeGamma(offset>>6);
|
||||
if (matchLen > 2)
|
||||
writeEliasGamma(matchLen-2);
|
||||
writeGamma(matchLen-2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -328,20 +344,15 @@ public class Lx47Algorithm
|
||||
return ret;
|
||||
}
|
||||
|
||||
int readEliasGamma() {
|
||||
int nBits = 0;
|
||||
while (readBit() == 0)
|
||||
++nBits;
|
||||
if (nBits >= 16)
|
||||
return -99; // EOF marker
|
||||
int readGamma() {
|
||||
int out = 1;
|
||||
while (nBits-- > 0)
|
||||
while (readBit() == 0)
|
||||
out = (out << 1) | readBit();
|
||||
return out;
|
||||
}
|
||||
|
||||
int readLiteralLen() {
|
||||
return readEliasGamma() - 1;
|
||||
return readGamma() - 1;
|
||||
}
|
||||
|
||||
int readCodePair()
|
||||
@ -350,9 +361,9 @@ public class Lx47Algorithm
|
||||
int offset = data & 63; // 6 bits
|
||||
int matchLen = 2;
|
||||
if ((data & 64) == 64)
|
||||
offset |= readEliasGamma() << 6;
|
||||
offset |= readGamma() << 6;
|
||||
if ((data & 128) == 128)
|
||||
matchLen += readEliasGamma();
|
||||
matchLen += readGamma();
|
||||
return matchLen | (offset<<16);
|
||||
}
|
||||
}
|
||||
|
137
Platform/Apple/virtual/src/core/decomp.s
Normal file
137
Platform/Apple/virtual/src/core/decomp.s
Normal file
@ -0,0 +1,137 @@
|
||||
;****************************************************************************************
|
||||
; Copyright (C) 2017 The 8-Bit Bunch. Licensed under the Apache License, Version 1.1
|
||||
; (the "License"); you may not use this file except in compliance with the License.
|
||||
; You may obtain a copy of the License at <http://www.apache.org/licenses/LICENSE-1.1>.
|
||||
; Unless required by applicable law or agreed to in writing, software distributed under
|
||||
; the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
; ANY KIND, either express or implied. See the License for the specific language
|
||||
; governing permissions and limitations under the License.
|
||||
;****************************************************************************************
|
||||
|
||||
;@com.wudsn.ide.asm.hardware=APPLE2
|
||||
; Memory manager
|
||||
; ------------------
|
||||
;
|
||||
; See detailed description in mem.i
|
||||
|
||||
* = $2000 ; PLASMA loader loads us initially at $2000
|
||||
|
||||
; Use hi-bit ASCII for Apple II
|
||||
!convtab "../include/hiBitAscii.ct"
|
||||
|
||||
; Global definitions
|
||||
!source "../include/global.i"
|
||||
|
||||
bits = $B ; len 1
|
||||
pSrc = $C ; len 2
|
||||
pDst = $E ; len 2
|
||||
|
||||
; Decompress from pSrc to pDst. They can overlap, as long as the source block
|
||||
; ends (at least) 2 bytes beyond the end of the dest block, e.g.
|
||||
; DDDDDDDDDDDDDDD
|
||||
; SSSSSSSSSSSss <-- 2 bytes beyond dest
|
||||
; This guarantees that the decompression won't overwrite any source material
|
||||
; before it gets used.
|
||||
decomp ldy #0 ; invariant: Y=0 unless we're mid-copy
|
||||
sty bits
|
||||
beq .lits
|
||||
|
||||
.lits jsr rdGamma
|
||||
tax
|
||||
dex
|
||||
beq +
|
||||
- lda (pSrc),y
|
||||
sta (pDst),y
|
||||
iny
|
||||
dex
|
||||
bne -
|
||||
jsr advSrc
|
||||
jsr advDst
|
||||
cpy #254 ; special case: long literal string
|
||||
beq .lits
|
||||
ldy #0 ; back to invariant
|
||||
.endchk cmp pEnd
|
||||
lda pDst+1
|
||||
sbc pEnd+1
|
||||
bcc .seq
|
||||
rts
|
||||
|
||||
.seq lda (pSrc),y
|
||||
iny
|
||||
asl
|
||||
php ; save high bit for later len check
|
||||
asl
|
||||
bcs .bigoff
|
||||
lsr
|
||||
lsr
|
||||
sta tmp
|
||||
ldx #0
|
||||
beq .gotoff ; always taken
|
||||
.bigoff sta tmp
|
||||
jsr rdGamma
|
||||
lsr
|
||||
rol tmp
|
||||
lsr
|
||||
rol tmp
|
||||
tax
|
||||
.gotoff lda pDst
|
||||
sec
|
||||
sbc tmp
|
||||
sta pTmp
|
||||
txa
|
||||
eor #$FF
|
||||
adc pDst+1
|
||||
sta pDst+1
|
||||
.len ldx #2
|
||||
plp
|
||||
bcc .gotlen
|
||||
jsr rdGamma ; A>=1 + sec + 1 => final len 3 or more
|
||||
adc #1
|
||||
tax
|
||||
.gotlen jsr advSrc
|
||||
ldy #0
|
||||
- lda (pTmp),y
|
||||
sta (pDst),y
|
||||
iny
|
||||
dex
|
||||
bne -
|
||||
jsr advDst
|
||||
ldy #0
|
||||
beq .lits ; always taken
|
||||
|
||||
rdGamma lda #1
|
||||
- asl bits
|
||||
bne +
|
||||
jsr getBits
|
||||
+ bcs .ret
|
||||
asl bits
|
||||
bne +
|
||||
jsr getBits
|
||||
+ rol
|
||||
bcc - ; always taken except if overflow error
|
||||
.ret rts
|
||||
|
||||
getBits pha
|
||||
lda (pSrc),y
|
||||
iny
|
||||
sec
|
||||
rol
|
||||
sta bits
|
||||
pla
|
||||
rts
|
||||
|
||||
advSrc tya
|
||||
clc
|
||||
adc pSrc
|
||||
sta pSrc
|
||||
bcc +
|
||||
inc pSrc+1
|
||||
+ rts
|
||||
|
||||
advDst tya
|
||||
clc
|
||||
adc pDst
|
||||
sta pDst
|
||||
bcc +
|
||||
inc pDst+1
|
||||
+ rts
|
Loading…
Reference in New Issue
Block a user