Add the ability to remove a jump to the real entry point when encoding and reinstate...
authorNick Downing <nick@ndcode.org>
Tue, 14 Jun 2022 14:26:15 +0000 (00:26 +1000)
committerNick Downing <nick@ndcode.org>
Tue, 14 Jun 2022 14:26:15 +0000 (00:26 +1000)
loader/rle2_decode.py
loader/rle2_encode.py
loader/rle_decode.py
loader/rle_encode.py
loader/tree_decode.py
loader/tree_encode.py

index 022ba70..fd8be12 100755 (executable)
@@ -36,10 +36,7 @@ assert rle2[0xc] == 0xa9 # lda #NN
 dest = rle2[9] + (rle2[0xd] << 8)
 
 assert rle2[0x6b] == 0x4c # jmp NNNN
-load_addr = rle2[0x6c] | (rle2[0x6d] << 8)
-load_size = dest + 1 - load_addr
-
-print(f'rle2 {load_size0:04x} orig {load_size:04x}')
+entry_point = rle2[0x6c] | (rle2[0x6d] << 8)
 
 rle2 = rle2[0xa1:]
 bin = []
@@ -59,10 +56,17 @@ while True:
     bin.extend(rle2[-1:-3:-1] * (count >> 1) + rle2[-1:] * (count & 1))
     del rle2[-2:]
 assert len(rle2) == 0
-assert len(bin) == load_size
-
 bin = bin[::-1]
-hdr = [load_addr & 0xff, load_addr >> 8, load_size & 0xff, load_size >> 8]
 
+load_size = len(bin)
+print(f'rle2 {load_size0:04x} orig {load_size:04x}')
+
+load_addr = dest + 1 - load_size
+if entry_point != load_addr:
+  bin = [0x4c, entry_point & 0xff, entry_point >> 8] + bin # jmp NNNN
+  load_addr -= 3
+  load_size += 3
+
+hdr = [load_addr & 0xff, load_addr >> 8, load_size & 0xff, load_size >> 8]
 with open(out_bin, 'wb') as fout:
   fout.write(bytes(hdr + bin))
index 49b4e80..587289a 100755 (executable)
@@ -36,6 +36,17 @@ load_addr0 = hdr[0] | (hdr[1] << 8)
 load_size0 = hdr[2] | (hdr[3] << 8)
 assert load_size0 == len(bin)
 
+# absorb a jump to the real entry point, ensuring that we
+# can losslessly reconstruct the jump when decoding later
+entry_point = load_addr0
+if bin[0] == 0x4c: # jmp NNNN
+  entry_point = bin[1] | (bin[2] << 8)
+  assert entry_point != load_addr0 + 3
+
+  bin = bin[3:]
+  load_addr0 += 3
+  load_size0 -= 3
+
 rle2 = []
 while len(bin):
   # look for a run
@@ -117,10 +128,9 @@ assert rle2[0xc] == 0xa9 # lda #NN
 rle2[0xd] = dest >> 8
 
 assert rle2[0x6b] == 0x4c # jmp NNNN
-rle2[0x6c] = load_addr0 & 0xff
-rle2[0x6d] = load_addr0 >> 8
+rle2[0x6c] = entry_point & 0xff
+rle2[0x6d] = entry_point >> 8
 
 hdr = [load_addr & 0xff, load_addr >> 8, load_size & 0xff, load_size >> 8]
-
 with open(out_bin, 'wb') as fout:
   fout.write(bytes(hdr + rle2))
index 619eba6..9777438 100755 (executable)
@@ -35,10 +35,7 @@ assert rle[0xc] == 0xa9 # lda #NN
 dest = rle[9] + (rle[0xd] << 8)
 
 assert rle[0x67] == 0x4c # jmp NNNN
-load_addr = rle[0x68] | (rle[0x69] << 8)
-load_size = dest + 1 - load_addr
-
-print(f'rle {load_size0:04x} orig {load_size:04x}')
+entry_point = rle[0x68] | (rle[0x69] << 8)
 
 rle = rle[0x6a:]
 bin = []
@@ -54,10 +51,17 @@ while True:
     bin.extend(rle[-1:] * count)
     del rle[-1:]
 assert len(rle) == 0
-assert len(bin) == load_size
-
 bin = bin[::-1]
-hdr = [load_addr & 0xff, load_addr >> 8, load_size & 0xff, load_size >> 8]
 
+load_size = len(bin)
+print(f'rle {load_size0:04x} orig {load_size:04x}')
+
+load_addr = dest + 1 - load_size
+if entry_point != load_addr:
+  bin = [0x4c, entry_point & 0xff, entry_point >> 8] + bin # jmp NNNN
+  load_addr -= 3
+  load_size += 3
+
+hdr = [load_addr & 0xff, load_addr >> 8, load_size & 0xff, load_size >> 8]
 with open(out_bin, 'wb') as fout:
   fout.write(bytes(hdr + bin))
index 2d0e0a9..f7e27ff 100755 (executable)
@@ -34,6 +34,17 @@ load_addr0 = hdr[0] | (hdr[1] << 8)
 load_size0 = hdr[2] | (hdr[3] << 8)
 assert load_size0 == len(bin)
 
+# absorb a jump to the real entry point, ensuring that we
+# can losslessly reconstruct the jump when decoding later
+entry_point = load_addr0
+if bin[0] == 0x4c: # jmp NNNN
+  entry_point = bin[1] | (bin[2] << 8)
+  assert entry_point != load_addr0 + 3
+
+  bin = bin[3:]
+  load_addr0 += 3
+  load_size0 -= 3
+
 rle = []
 while len(bin):
   # look for a run
@@ -92,10 +103,9 @@ assert rle[0xc] == 0xa9 # lda #NN
 rle[0xd] = dest >> 8
 
 assert rle[0x67] == 0x4c # jmp NNNN
-rle[0x68] = load_addr0 & 0xff
-rle[0x69] = load_addr0 >> 8
+rle[0x68] = entry_point & 0xff
+rle[0x69] = entry_point >> 8
 
 hdr = [load_addr & 0xff, load_addr >> 8, load_size & 0xff, load_size >> 8]
-
 with open(out_bin, 'wb') as fout:
   fout.write(bytes(hdr + rle))
index 708036f..daf2338 100755 (executable)
@@ -36,7 +36,7 @@ assert tree[0x2f] & ~0x20 == 0x18 # clc
 bits = tree[0x2e] | ((tree[0x2f] & 0x20) << 3)
 
 assert tree[0x60] == 0x4c # jmp NNNN
-load_addr = tree[0x61] | (tree[0x62] << 8)
+entry_point = tree[0x61] | (tree[0x62] << 8)
 
 assert tree[0x65] == 0xe9 # sbc #NN
 break3 = tree[0x66]
@@ -94,7 +94,11 @@ load_size = len(bin)
 print(f'tree {load_size0:04x} orig {load_size:04x}')
 
 load_addr = dest + 1 - load_size
-hdr = [load_addr & 0xff, load_addr >> 8, load_size & 0xff, load_size >> 8]
+if entry_point != load_addr:
+  bin = [0x4c, entry_point & 0xff, entry_point >> 8] + bin # jmp NNNN
+  load_addr -= 3
+  load_size += 3
 
+hdr = [load_addr & 0xff, load_addr >> 8, load_size & 0xff, load_size >> 8]
 with open(out_bin, 'wb') as fout:
   fout.write(bytes(hdr + bin))
index 69bcc9b..c51c4d3 100755 (executable)
@@ -28,7 +28,16 @@ load_addr0 = hdr[0] | (hdr[1] << 8)
 load_size0 = hdr[2] | (hdr[3] << 8)
 assert load_size0 == len(bin)
 
-bin = list(bin)
+# absorb a jump to the real entry point, ensuring that we
+# can losslessly reconstruct the jump when decoding later
+entry_point = load_addr0
+if bin[0] == 0x4c: # jmp NNNN
+  entry_point = bin[1] | (bin[2] << 8)
+  assert entry_point != load_addr0 + 3
+
+  bin = bin[3:]
+  load_addr0 += 3
+  load_size0 -= 3
 
 freq = heapdict() #{}
 for i in range(len(bin) - 1):
@@ -184,8 +193,8 @@ assert tree[0x2f] == 0x18 # clc
 tree[0x2f] |= (bits >> 3) & 0x20 # clc or sec
 
 assert tree[0x60] == 0x4c # jmp NNNN
-tree[0x61] = load_addr0 & 0xff
-tree[0x62] = load_addr0 >> 8
+tree[0x61] = entry_point & 0xff
+tree[0x62] = entry_point >> 8
 
 assert tree[0x65] == 0xe9 # sbc #NN
 tree[0x66] = break3
@@ -204,6 +213,5 @@ tree[0x7d] = left1 & 0xff
 tree[0x7e] = left1 >> 8
 
 hdr = [load_addr & 0xff, load_addr >> 8, load_size & 0xff, load_size >> 8]
-
 with open(out_bin, 'wb') as fout:
   fout.write(bytes(hdr + tree))