count = lzss[0x12] + (lzss[0x16] << 8)
assert lzss[0x19] == 0xa9 # lda #NN
-#assert lzss[0x1d] & ~0x20 == 0x18 # clc
-bits = lzss[0x1a] #| ((lzss[0x1d] & 0x20) << 3)
+assert lzss[0x1d] & ~0x20 == 0x18 # clc
+bits = lzss[0x1a] | ((lzss[0x1d] & 0x20) << 3)
-assert lzss[0x42] == 0x4c # jmp NNNN
-entry_point = lzss[0x43] | (lzss[0x44] << 8)
+assert lzss[0x40] == 0x4c # jmp NNNN
+entry_point = lzss[0x41] | (lzss[0x42] << 8)
assert src == load_addr0 + load_size0
count = ~count & 0xffff
+# undo optimization: initial 9-bit buffer via clc/sec
+if bits & 0x100:
+ # note the cf will be preserved during copy of first byte,
+ # so the byte we do not have to store is the second byte
+ lzss[-1:-1] = [bits & 0xff]
+ bits = 1
+ count += 1
+
+# undo optimization: the first byte has to be literal
+bits <<= 1
+if bits & 0x100:
+ lzss.append(bits & 0xff)
+ bits = 1
+ count += 1
+
bin = []
lzss = lzss
count = count
else:
#print('a', lzss[-1])
bin.append(lzss.pop())
-assert len(lzss) == 0xb6
+assert len(lzss) == 0xb4
bin = bin[::-1]
load_size = len(bin)
with open(lzss_loader_bin, 'rb') as fin:
lzss_loader = list(fin.read())
-assert len(lzss_loader) == 0xb6
+assert len(lzss_loader) == 0xb4
with open(in_bin, 'rb') as fin:
data = list(fin.read())
bits = 1
count += 1
lzss = lzss1
-load_size = len(lzss)
-print('orig', f'{load_size0:04x}', 'lzss', f'{load_size:04x}')
# checking
#bin1 = []
#bin1 = bin1[::-1]
#assert bin == bin1
+# optimization: provided the input is not null, the first byte
+# has to be literal, so the loader can fall straight into the
+# literal decoding routine (saves a jump to the official loop)
+if bits == 1:
+ print('opt1')
+ assert count
+ count -= 1
+ bits = lzss.pop() | 0x100
+assert (bits & 1) == 0
+bits >>= 1
+
+# optimization: provide an initial 9-bit buffer via clc/sec
+if bits == 1:
+ print('opt2')
+ # note the cf will be preserved during copy of first byte,
+ # so the byte we do not have to store is the second byte
+ assert count
+ count -= 1
+ bits = lzss.pop(-2) | 0x100
+
+load_size = len(lzss)
+print('orig', f'{load_size0:04x}', 'lzss', f'{load_size:04x}')
+
src = load_addr + load_size
dest = load_addr0 + load_size0 - 1
count = ~count & 0xffff # inc/test is easier than test/dec
lzss[0x16] = count >> 8
assert lzss[0x19] == 0xa9 # lda #NN
-lzss[0x1a] = bits #& 0xff
-#assert lzss[0x1b] == 0x18 # clc
-#lzss[0x1b] |= (bits >> 3) & 0x20 # clc or sec
+lzss[0x1a] = bits & 0xff
+assert lzss[0x1d] == 0x18 # clc
+lzss[0x1d] |= (bits >> 3) & 0x20 # clc or sec
-assert lzss[0x42] == 0x4c # jmp NNNN
-lzss[0x43] = entry_point & 0xff
-lzss[0x44] = entry_point >> 8
+assert lzss[0x40] == 0x4c # jmp NNNN
+lzss[0x41] = entry_point & 0xff
+lzss[0x42] = entry_point >> 8
hdr = [load_addr & 0xff, load_addr >> 8, load_size & 0xff, load_size >> 8]
with open(out_bin, 'wb') as fout: