intersect(segments, [0x100, 0x200])
)
-compressed = []
-uncompressed = []
-for i in range(0, len(segments), 2):
- addr0 = segments[i]
- addr1 = segments[i + 1]
- data = list(intelhex.tobinstr(addr0, addr1 - 1))
- if len(data) > 0x100:
- compressed.append((addr0, addr1, lzss_pack(addr0, data)))
- else:
- uncompressed.append((addr0, addr1, data))
-
bin = [0x4c, 0x00, 0x00] # jmp 0 (fixup: loader)
loader = [
0xd8, # cld
0xa2, 0xff, # ldx #0xff
0x9a, # txs
]
-compressed_addr = load_addr + len(bin)
-for addr0, addr1, data in compressed:
- addr2 = load_addr + len(bin)
- bin.extend(data)
- addr3 = load_addr + len(bin)
- print(
- f'[0x{addr0:04x}, 0x{addr1:04x}) -> [0x{addr2:04x}, 0x{addr3:04x}) {100. * (addr3 - addr2) / (addr1 - addr0):5.1f}%'
- )
- if addr2 == compressed_addr:
- loader.extend(
- [
- 0xa9, compressed_addr & 0xff, # lda #<compressed_addr
- 0x85, 0xf0, # sta src
- 0xa9, compressed_addr >> 8, # lda #>compressed_addr
- 0x85, 0xf1, # sta src + 1
- ]
- )
- loader.extend([0x20, 0x00, 0x00]) # jsr 0 (fixup: lzss_unpack)
-for addr0, addr1, data in uncompressed:
- count = addr1 - addr0
- zpage = addr0 < 0x100
- if count >= 8:
+fixup_lzss_unpack = []
+for i in range(0, len(segments), 2):
+ addr0 = segments[i]
+ addr1 = segments[i + 1]
+ data = list(intelhex.tobinstr(addr0, addr1 - 1))
+ if len(data) > 0x100:
addr2 = load_addr + len(bin)
- bin.extend(data)
+ bin.extend(lzss_pack(addr0, data))
addr3 = load_addr + len(bin)
print(
- f'[0x{addr0:04x}, 0x{addr1:04x}) -> [0x{addr2:04x}, 0x{addr3:04x})'
+ f'[0x{addr0:04x}, 0x{addr1:04x}) -> [0x{addr2:04x}, 0x{addr3:04x}) {100. * (addr3 - addr2) / (addr1 - addr0):5.1f}%'
)
- addr1 -= 0x100
- addr3 -= 0x100
+ addr2 += 5 - 0x100
loader.extend(
[
- 0xa2, -count & 0xff, # ldx #-count
- 0xbd, addr3 & 0xff, (addr3 >> 8) & 0xff, # lda addr3,x
- 0x95, addr1 & 0xff, # sta *addr1,x
- 0xe8, # inx
- 0xd0, 0xf8 # bne .-6
- ]
- if zpage else
- [
- 0xa2, -count & 0xff, # ldx #-count
- 0xbd, addr3 & 0xff, (addr3 >> 8) & 0xff, # lda addr3,x
- 0x9d, addr1 & 0xff, (addr1 >> 8) & 0xff, # sta addr1,x
- 0xe8, # inx
- 0xd0, 0xf7 # bne .-7
+ 0xa9, addr2 & 0xff, # lda #<addr2
+ 0xa0, addr2 >> 8, # ldy #>addr2
+ 0x20, 0x00, 0x00, # jsr 0 (fixup: lzss_unpack)
]
)
+ fixup_lzss_unpack.append(len(loader) - 2)
else:
- print(f'[0x{addr0:04x}, 0x{addr1:04x})')
- for i in range(count):
+ count = addr1 - addr0
+ zpage = addr0 < 0x100
+ if count > 4:
+ addr2 = load_addr + len(bin)
+ bin.extend(data)
+ addr3 = load_addr + len(bin)
+ print(
+ f'[0x{addr0:04x}, 0x{addr1:04x}) -> [0x{addr2:04x}, 0x{addr3:04x})'
+ )
+
+ addr1 -= 0x100
+ addr3 -= 0x100
loader.extend(
[
- 0xa9, data[i], # lda #data
- 0x85, addr0, # sta *addr0
+ 0xa2, -count & 0xff, # ldx #-count
+ 0xbd, addr3 & 0xff, (addr3 >> 8) & 0xff, # lda addr3,x
+ 0x95, addr1 & 0xff, # sta *addr1,x
+ 0xe8, # inx
+ 0xd0, 0xf8 # bne .-6
]
if zpage else
[
- 0xa9, data[i], # lda #data
- 0x8d, addr0 & 0xff, addr0 >> 8 # sta addr0
+ 0xa2, -count & 0xff, # ldx #-count
+ 0xbd, addr3 & 0xff, (addr3 >> 8) & 0xff, # lda addr3,x
+ 0x9d, addr1 & 0xff, (addr1 >> 8) & 0xff, # sta addr1,x
+ 0xe8, # inx
+ 0xd0, 0xf7 # bne .-7
]
-
)
- addr0 += 1
-if len(compressed):
+ else:
+ print(f'[0x{addr0:04x}, 0x{addr1:04x})')
+ for i in range(count):
+ loader.extend(
+ [
+ 0xa9, data[i], # lda #data
+ 0x85, addr0, # sta *addr0
+ ]
+ if zpage else
+ [
+ 0xa9, data[i], # lda #data
+ 0x8d, addr0 & 0xff, addr0 >> 8 # sta addr0
+ ]
+ )
+ addr0 += 1
+loader.extend(
+ [0x4c, entry_point & 0xff, entry_point >> 8] # jmp entry_point
+)
+if len(fixup_lzss_unpack):
lzss_unpack_addr = load_addr + len(bin)
- for i in range(len(compressed)):
- assert loader[12 + i * 3] == 0x20 # jsr
- loader[12 + i * 3 + 1] = lzss_unpack_addr & 0xff
- loader[12 + i * 3 + 2] = lzss_unpack_addr >> 8
+ for i in fixup_lzss_unpack:
+ loader[i] = lzss_unpack_addr & 0xff
+ loader[i + 1] = lzss_unpack_addr >> 8
bin.extend(lzss_unpack)
loader_addr = load_addr + len(bin)
-assert bin[0] == 0x4c # jmp
bin[1] = loader_addr & 0xff
bin[2] = loader_addr >> 8
-bin.extend(
- loader + [0x4c, entry_point & 0xff, entry_point >> 8] # jmp entry_point
-)
+bin.extend(loader)
load_size = len(bin)
hdr = [load_addr & 0xff, load_addr >> 8, load_size & 0xff, load_size >> 8]