Fixed decompression bug: min 'underlap' needs to be 5 instead of 3 - case brought on by gen_flags.b

This commit is contained in:
Martin Haye 2019-08-01 08:11:28 -07:00
parent c13776bd8e
commit bb4be7a173
3 changed files with 26 additions and 11 deletions

View File

@ -1657,9 +1657,10 @@ class A2PackPartitions
def compressedLen = compressedData.length
assert compressedLen > 0
// As a check, verify that decompression works with only a 3-byte underlap
// As a check, verify that decompression works with only a 5-byte underlap
// Note: used to think 3 bytes was sufficient, then gen_flags.b blew that out of the water.
if (debugCompression && (uncompressedLen - compressedLen) > 0) {
def underlap = 3
def underlap = 5
def checkData = new byte[uncompressedLen+underlap]
def initialOffset = uncompressedLen - compressedLen + underlap
System.arraycopy(compressedData, 0, checkData, initialOffset, compressedLen)

View File

@ -178,6 +178,7 @@ public class Lx47Algorithm
}
void writeByte(int value) {
//System.out.format("byte: pos=%d val=$%x\n", outPos, (byte)(value & 0xFF));
buf[outPos++] = (byte)(value & 0xFF);
bitPos += 8;
}
@ -189,6 +190,7 @@ public class Lx47Algorithm
writeByte(0);
bitPos -= 8;
}
//System.out.format("bit: pos=%d mask=$%x bit=%d\n", bitIndex, mask, value > 0 ? 1 : 0);
if (value > 0)
buf[bitIndex] |= mask;
mask >>= 1;
@ -344,24 +346,30 @@ public class Lx47Algorithm
public byte[] buf;
public int inPos;
private int indexByte;
private int inStart;
private int indexPos;
private int mask;
Lx47Reader(byte[] inBuf, int inStart) {
this.inStart = inStart;
buf = inBuf;
mask = 0;
inPos = inStart;
}
int readByte() {
//System.out.format("byte: pos=%d val=$%x\n", inPos - inStart, buf[inPos] & 0xFF);
return buf[inPos++] & 0xFF;
}
int readBit() {
if (mask == 0) {
mask = 128;
indexPos = inPos - inStart;
indexByte = readByte();
}
int ret = ((indexByte & mask) != 0) ? 1 : 0;
//System.out.format("bit: pos=%d mask=$%x bit=%d\n", indexPos, mask, ret);
mask >>= 1;
return ret;
}
@ -400,7 +408,7 @@ public class Lx47Algorithm
String expect = debugs.removeFirst();
assert expect.equals(toCheck) :
String.format("Expecting '%s', got '%s'", expect, toCheck);
//System.out.format("OK [%d]: %s\n", debugs.size(), expect);
System.out.format("OK [%d]: %s\n", debugs.size(), expect);
}
public void decompress(byte[] input_data, int inStart, byte[] output_data, int outStart, int outLen)

View File

@ -29,6 +29,12 @@ MAX_SEGS = 96
DEBUG = 0
; We overlap the compressed and uncompressed as much as possible, e.g.:
; DDDDDDDDDDDDDD
; SSSSSSSSSsssss ; sssss is the 5-byte 'underlap'
; Note: used to think this was 3, then found a case (gen_flags.b) requiring 5.
UNDERLAP = 5
; Zero page temporary variables.
; Don't move these - they overlap in clever ways with ProRWTS shadows (see below)
tmp = $2 ; len 2
@ -2124,12 +2130,12 @@ disk_queueLoad: !zone
lda resNum
cmp #1
bne +
; Take $BFFD - size. Why $BFFD and not $C000? Because decomp temporarily overwrites 3-byte "unnderlap" after.
lda #$FD
; Conservative end-of-mem, because decomp temporarily overwrites 5-byte "underlap" after.
lda #<($C000-UNDERLAP)
sec
sbc reqLen
sta targetAddr
lda #$BF
lda #>($C000-UNDERLAP)
sbc reqLen+1
sta targetAddr+1
+ jsr shared_alloc ; reserve memory for this resource (main or aux as appropriate)
@ -2304,7 +2310,7 @@ disk_finishLoad: !zone
; Calculate end of uncompressed data, and start of compressed data.
; We overlap the compressed and uncompressed as much as possible, e.g.:
; DDDDDDDDDDDDDD
; SSSSSSSSSsss ; sss is the 3-byte 'underlap'
; SSSSSSSSSsssss ; sssss is the 5-byte 'underlap'
sta pSrc
sty pSrc+1
clc
@ -2316,7 +2322,7 @@ disk_finishLoad: !zone
sta pEnd+1
tay
txa
adc #3 ; this is the max "underlap" required for decompressing overlapped buffers
adc #UNDERLAP ; this is the max "underlap" required for decompressing overlapped buffers
bcc +
iny
+ sec
@ -2325,8 +2331,8 @@ disk_finishLoad: !zone
tya
sbc reqLen+1
sta pDst+1
; save the 3 byte underlap bytes because we're going to read over them
ldy #2
; save the 5 underlap bytes because we're going to read over them
ldy #UNDERLAP-1
ldx isAuxCmd
sta clrAuxRd,x ; from aux mem if appropriate
- lda (pEnd),y
@ -2349,7 +2355,7 @@ disk_finishLoad: !zone
- pla
sta (pEnd),y
iny
cpy #3
cpy #UNDERLAP
bne -
sta clrAuxRd
sta clrAuxWr