FIXUP_FLAG_LO_BYTE = 4
FIXUP_FLAG_HI_BYTE = 8
-# each section has a data area, an end address and a list of fixups
-# the data is constructed from top to bottom, hence is reversed here
-# relocation is done after section lengths and end addresses known
+# each section has a data area, a load address and a list of fixups
+# relocation is done after section lengths and load addresses known
class Section:
- def __init__(self, data, end_addr, fixups):
+ def __init__(self, data, load_addr, fixups):
self.data = data
- self.end_addr = end_addr
+ self.load_addr = load_addr
self.fixups = fixups
section_lzss_unpack = Section([], 0, [])
section_loader = Section([], 0, [])
section_payload = Section([], 0, [])
-# sections are output to the a2bin file from top to bottom as follows:
-sections = [section_lzss_unpack, section_loader, section_payload]
+# sections are output to the a2bin file from bottom to top as follows:
+sections = [section_payload, section_loader, section_lzss_unpack]
# report is a 5-tuple:
# (report type, ihx start, ihx end, a2bin start, a2bin end)
]
)
-# relocate
+# 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:
- section.end_addr = load_addr
+for section in sections[::-1]:
load_addr -= len(section.data)
+ section.load_addr = load_addr
load_size = end_addr - load_addr
for report_type, addr0, addr1, addr2, addr3 in report[::-1]:
if report_type == REPORT_TYPE_DIRECT_POKE:
print(f'[0x{addr0:04x}, 0x{addr1:04x})')
else:
- addr2 += section_payload.end_addr
- addr3 += section_payload.end_addr
+ addr2 += section_payload.load_addr + len(section_payload.data)
+ addr3 += section_payload.load_addr + len(section_payload.data)
print(
f'[0x{addr0:04x}, 0x{addr1:04x}) -> [0x{addr2:04x}, 0x{addr3:04x})' + (
f'{100. * (addr3 - addr2) / (addr1 - addr0):6.1f}%'
bin = []
for section in sections:
for fixup_flags, fixup_addr, target_section, target_addr in section.fixups:
- assert fixup_flags & FIXUP_FLAG_TARGET_END_RELATIVE
- target_addr += target_section.end_addr
-
- # fixup_addr is in range -len(section.data) .. -1
- # -1 means last byte of target_section, but since the target_section data is
- # reversed, a fixup at -1 would be done at data[0] and so forth
- assert fixup_flags & FIXUP_FLAG_FIXUP_END_RELATIVE
- fixup_addr = ~fixup_addr
+ if fixup_flags & FIXUP_FLAG_FIXUP_END_RELATIVE:
+ fixup_addr += len(section.data)
+ if fixup_flags & FIXUP_FLAG_TARGET_END_RELATIVE:
+ target_addr += len(target_section.data)
+
+ target_addr += target_section.load_addr
if fixup_flags & FIXUP_FLAG_LO_BYTE:
assert section.data[fixup_addr] == 0
section.data[fixup_addr] = target_addr & 0xff
- fixup_addr -= 1
+ fixup_addr += 1
if fixup_flags & FIXUP_FLAG_HI_BYTE:
assert section.data[fixup_addr] == 0
section.data[fixup_addr] = target_addr >> 8
- #fixup_addr -= 1
+ #fixup_addr += 1
bin.extend(section.data)
-bin = bin[::-1]
hdr = [load_addr & 0xff, load_addr >> 8, load_size & 0xff, load_size >> 8]
with open(out_a2bin, 'wb') as fout: