# #print('c', item)
# dist = item & ((1 << DIST_BITS1) - 1)
# _len = item >> DIST_BITS1
- # else:
+ # else:
# item = lzss1.pop()
# #print('b', item)
# dist = item & ((1 << DIST_BITS0) - 1)
REPORT_TYPE_COMPRESSED = 2
report = []
-# epilogue
+# prologue
+section_payload.fixups.extend(
+ [
+ (
+ FIXUP_FLAG_LO_BYTE | FIXUP_FLAG_HI_BYTE,
+ len(section_payload.data) + 1,
+ section_loader,
+ 0
+ ),
+ ]
+)
+section_payload.data.extend(
+ [
+ 0x4c, 0x00, 0x00, # jmp loader
+ ]
+)
section_loader.data.extend(
[
- 0x4c, entry_point & 0xff, entry_point >> 8, # jmp entry_point
- ][::-1]
+ 0xd8, # cld
+ 0xa2, 0xff, # ldx #0xff
+ 0x9a, # txs
+ ]
)
# segments
-# constructed top to bottom (in reverse order of unpacking: bottom to top)
-for i in range(len(segments) - 2, -2, -2):
+# loader is constructed in order of execution (bottom to top)
+# payload is constructed in order of unpacking (bottom to top)
+for i in range(0, len(segments), 2):
addr0 = segments[i]
addr1 = segments[i + 1]
data = list(intelhex.tobinstr(addr0, addr1 - 1))
)
# use of zpage version is determined byte by byte
- for i in data[::-1]:
- addr1 -= 1
+ for i in data:
section_loader.data.extend(
[
0xa9, i, # lda #data
- 0x85, addr1, # sta *addr1
- ][::-1]
- if addr1 < 0x100 else
+ 0x85, addr0, # sta *addr0
+ ]
+ if addr0 < 0x100 else
[
0xa9, i, # lda #data
- 0x8d, addr1 & 0xff, addr1 >> 8, # sta addr1
- ][::-1]
+ 0x8d, addr0 & 0xff, addr0 >> 8, # sta addr0
+ ]
)
+ addr0 += 1
elif len(data) <= 0x100:
- addr3 = -len(section_payload.data)
+ addr2 = len(section_payload.data)
section_payload.data.extend(
- data[::-1]
+ data
)
- addr2 = -len(section_payload.data)
+ addr3 = len(section_payload.data)
report.append(
(REPORT_TYPE_UNCOMPRESSED, addr0, addr1, addr2, addr3)
)
# use of zpage version is determined in advance (if completely fits)
- zpage = addr1 < 0x100
+ zpage = addr1 <= 0x100
addr1 -= 0x100
addr3 -= 0x100
+ section_loader.fixups.extend(
+ [
+ (
+ FIXUP_FLAG_LO_BYTE | FIXUP_FLAG_HI_BYTE,
+ len(section_loader.data) + 3,
+ section_payload,
+ addr3
+ ),
+ ]
+ )
section_loader.data.extend(
[
0xa2, -len(data) & 0xff, # ldx #-count
0x95, addr1 & 0xff, # sta *addr1,x
0xe8, # inx
0xd0, 0xf8 # bne .-6
- ][::-1]
+ ]
if zpage else
[
0xa2, -len(data) & 0xff, # ldx #-count
0x9d, addr1 & 0xff, (addr1 >> 8) & 0xff, # sta addr1,x
0xe8, # inx
0xd0, 0xf7 # bne .-7
- ][::-1]
- )
- section_loader.fixups.extend(
- [
- (
- FIXUP_FLAG_FIXUP_END_RELATIVE |
- FIXUP_FLAG_TARGET_END_RELATIVE |
- FIXUP_FLAG_LO_BYTE |
- FIXUP_FLAG_HI_BYTE,
- 3 - len(section_loader.data),
- section_payload,
- addr3
- ),
]
)
else:
- addr3 = -len(section_payload.data)
+ addr2 = len(section_payload.data)
section_payload.data.extend(
- lzss_pack(addr0, data)[::-1]
+ lzss_pack(addr0, data)
)
- addr2 = -len(section_payload.data)
+ addr3 = len(section_payload.data)
report.append(
(REPORT_TYPE_COMPRESSED, addr0, addr1, addr2, addr3)
)
if len(section_lzss_unpack.data) == 0:
section_lzss_unpack.data.extend(
- lzss_unpack_fwd[::-1]
+ lzss_unpack_fwd
)
addr2 += 5 - 0x100
- section_loader.data.extend(
- [
- 0xa9, 0x00, # lda #<addr2
- 0xa0, 0x00, # ldy #>addr2
- 0x20, 0x00, 0x00, # jsr lzss_unpack_fwd
- ][::-1]
- )
section_loader.fixups.extend(
[
(
- FIXUP_FLAG_FIXUP_END_RELATIVE |
- FIXUP_FLAG_TARGET_END_RELATIVE |
- FIXUP_FLAG_LO_BYTE,
- 1 - len(section_loader.data),
+ FIXUP_FLAG_LO_BYTE,
+ len(section_loader.data) + 1,
section_payload,
addr2
),
(
- FIXUP_FLAG_FIXUP_END_RELATIVE |
- FIXUP_FLAG_TARGET_END_RELATIVE |
- FIXUP_FLAG_HI_BYTE,
- 3 - len(section_loader.data),
+ FIXUP_FLAG_HI_BYTE,
+ len(section_loader.data) + 3,
section_payload,
addr2
),
(
- FIXUP_FLAG_FIXUP_END_RELATIVE |
- FIXUP_FLAG_TARGET_END_RELATIVE |
- FIXUP_FLAG_LO_BYTE |
- FIXUP_FLAG_HI_BYTE,
- 5 - len(section_loader.data),
+ FIXUP_FLAG_LO_BYTE | FIXUP_FLAG_HI_BYTE,
+ len(section_loader.data) + 5,
section_lzss_unpack,
- -len(section_lzss_unpack.data)
+ 0
),
]
)
+ section_loader.data.extend(
+ [
+ 0xa9, 0x00, # lda #<addr2
+ 0xa0, 0x00, # ldy #>addr2
+ 0x20, 0x00, 0x00, # jsr lzss_unpack_fwd
+ ]
+ )
-# prologue
+# epilogue
section_loader.data.extend(
[
- 0xd8, # cld
- 0xa2, 0xff, # ldx #0xff
- 0x9a, # txs
- ][::-1]
-)
-section_payload.data.extend(
- [
- 0x4c, 0x00, 0x00, # jmp loader
- ][::-1]
-)
-section_payload.fixups.extend(
- [
- (
- FIXUP_FLAG_FIXUP_END_RELATIVE |
- FIXUP_FLAG_TARGET_END_RELATIVE |
- FIXUP_FLAG_LO_BYTE |
- FIXUP_FLAG_HI_BYTE,
- 1 - len(section_payload.data),
- section_loader,
- -len(section_loader.data)
- ),
- ]
+ 0x4c, entry_point & 0xff, entry_point >> 8, # jmp entry_point
+ ]
)
-# sections that were constructed in reverse can now be made normal
-section_lzss_unpack.data = section_lzss_unpack.data[::-1]
-section_loader.data = section_loader.data[::-1]
-section_payload.data = section_payload.data[::-1]
-
# relocate from top down
load_addr = end_addr
for section in sections[::-1]:
section.load_addr = load_addr
load_size = end_addr - load_addr
-for report_type, addr0, addr1, addr2, addr3 in report[::-1]:
+for report_type, addr0, addr1, addr2, addr3 in report:
if report_type == REPORT_TYPE_DIRECT_POKE:
print(f'[0x{addr0:04x}, 0x{addr1:04x})')
else:
- addr2 += section_payload.load_addr + len(section_payload.data)
- addr3 += section_payload.load_addr + len(section_payload.data)
+ offset = section_payload.load_addr
+ addr2 += offset
+ addr3 += offset
print(
f'[0x{addr0:04x}, 0x{addr1:04x}) -> [0x{addr2:04x}, 0x{addr3:04x})' + (
f'{100. * (addr3 - addr2) / (addr1 - addr0):6.1f}%'
# prologue
section_loader.data.extend(
[
- 0x4c, entry_point & 0xff, entry_point >> 8, # jmp entry_point
- ][::-1]
+ 0xd8, # cld
+ 0xa2, 0xff, # ldx #0xff
+ 0x9a, # txs
+ ]
)
# segments
-# constructed bottom to top (in reverse order of unpacking: top to bottom)
-for i in range(0, len(segments), 2):
+# loader is constructed in order of execution (bottom to top)
+# payload is constructed in order of unpacking (top to bottom)
+for i in range(len(segments) - 2, -2, -2):
addr0 = segments[i]
addr1 = segments[i + 1]
data = list(intelhex.tobinstr(addr0, addr1 - 1))
)
# use of zpage version is determined byte by byte
- for i in data:
+ for i in data[::-1]:
+ addr1 -= 1
section_loader.data.extend(
[
0xa9, i, # lda #data
- 0x85, addr0, # sta *addr0
- ][::-1]
- if addr0 < 0x100 else
+ 0x85, addr1, # sta *addr1
+ ]
+ if addr1 < 0x100 else
[
0xa9, i, # lda #data
- 0x8d, addr0 & 0xff, addr0 >> 8, # sta addr0
- ][::-1]
+ 0x8d, addr1 & 0xff, addr1 >> 8, # sta addr1
+ ]
)
- addr0 += 1
elif len(data) <= 0x100:
- addr2 = len(section_payload.data)
+ addr3 = -len(section_payload.data)
section_payload.data.extend(
- data
+ data[::-1]
)
- addr3 = len(section_payload.data)
+ addr2 = -len(section_payload.data)
report.append(
(REPORT_TYPE_UNCOMPRESSED, addr0, addr1, addr2, addr3)
)
# use of zpage version is determined in advance (if completely fits)
- zpage = addr1 < 0x100
+ zpage = addr1 <= 0x100
+ section_loader.fixups.extend(
+ [
+ (
+ FIXUP_FLAG_TARGET_END_RELATIVE |
+ FIXUP_FLAG_LO_BYTE |
+ FIXUP_FLAG_HI_BYTE,
+ len(section_loader.data) + 3,
+ section_payload,
+ addr2
+ ),
+ ]
+ )
if len(data) == 0x100:
# for the full count we will copy forward (an exception)
section_loader.data.extend(
0x95, addr0 & 0xff, # sta *addr0,x
0xe8, # inx
0xd0, 0xf8 # bne .-6
- ][::-1]
+ ]
if zpage else
[
0xa2, 0x00, # ldx #0
0x9d, addr0 & 0xff, (addr0 >> 8) & 0xff, # sta addr0,x
0xe8, # inx
0xd0, 0xf7 # bne .-7
- ][::-1]
+ ]
)
else:
addr0 -= 1
0x95, addr0 & 0xff, # sta *addr0,x
0xca, # dex
0xd0, 0xf8 # bne .-6
- ][::-1]
+ ]
if zpage else
[
0xa2, len(data), # ldx #count
0x9d, addr0 & 0xff, (addr0 >> 8) & 0xff, # sta addr0,x
0xca, # dex
0xd0, 0xf7 # bne .-7
- ][::-1]
+ ]
)
- section_loader.fixups.extend(
- [
- (
- FIXUP_FLAG_FIXUP_END_RELATIVE |
- FIXUP_FLAG_LO_BYTE |
- FIXUP_FLAG_HI_BYTE,
- 3 - len(section_loader.data),
- section_payload,
- addr2
- ),
- ]
- )
else:
- addr2 = len(section_payload.data)
+ addr3 = -len(section_payload.data)
section_payload.data.extend(
- lzss_pack(addr1 - 1, data)
+ lzss_pack(addr1 - 1, data)[::-1]
)
- addr3 = len(section_payload.data)
+ addr2 = -len(section_payload.data)
report.append(
(REPORT_TYPE_COMPRESSED, addr0, addr1, addr2, addr3)
)
)
addr3 -= 5 + 1
- section_loader.data.extend(
- [
- 0xa9, 0x00, # lda #<addr3
- 0xa0, 0x00, # ldy #>addr3
- 0x20, 0x00, 0x00, # jsr lzss_unpack_rev
- ][::-1]
- )
section_loader.fixups.extend(
[
(
- FIXUP_FLAG_FIXUP_END_RELATIVE | FIXUP_FLAG_LO_BYTE,
- 1 - len(section_loader.data),
+ FIXUP_FLAG_TARGET_END_RELATIVE | FIXUP_FLAG_LO_BYTE,
+ len(section_loader.data) + 1,
section_payload,
addr3
),
(
- FIXUP_FLAG_FIXUP_END_RELATIVE | FIXUP_FLAG_HI_BYTE,
- 3 - len(section_loader.data),
+ FIXUP_FLAG_TARGET_END_RELATIVE | FIXUP_FLAG_HI_BYTE,
+ len(section_loader.data) + 3,
section_payload,
addr3
),
(
- FIXUP_FLAG_FIXUP_END_RELATIVE |
- FIXUP_FLAG_LO_BYTE |
- FIXUP_FLAG_HI_BYTE,
- 5 - len(section_loader.data),
+ FIXUP_FLAG_LO_BYTE | FIXUP_FLAG_HI_BYTE,
+ len(section_loader.data) + 5,
section_lzss_unpack,
0
),
]
)
+ section_loader.data.extend(
+ [
+ 0xa9, 0x00, # lda #<addr3
+ 0xa0, 0x00, # ldy #>addr3
+ 0x20, 0x00, 0x00, # jsr lzss_unpack_rev
+ ]
+ )
-
-# prologue
+# epilogue
section_loader.data.extend(
[
- 0xd8, # cld
- 0xa2, 0xff, # ldx #0xff
- 0x9a, # txs
- ][::-1]
+ 0x4c, entry_point & 0xff, entry_point >> 8, # jmp entry_point
+ ]
)
-section_loader.data = section_loader.data[::-1]
-# relocate
+# sections that were constructed in reverse can now be made normal
+section_payload.data = section_payload.data[::-1]
+
+# relocate from bottom up
end_addr = load_addr
for section in sections:
section.load_addr = end_addr
if report_type == REPORT_TYPE_DIRECT_POKE:
print(f'[0x{addr0:04x}, 0x{addr1:04x})')
else:
- addr2 += section_payload.load_addr
- addr3 += section_payload.load_addr
+ offset = section_payload.load_addr + len(section_payload.data)
+ addr2 += offset
+ addr3 += offset
print(
f'[0x{addr0:04x}, 0x{addr1:04x}) -> [0x{addr2:04x}, 0x{addr3:04x})' + (
f'{100. * (addr3 - addr2) / (addr1 - addr0):6.1f}%'