)
# fixup is a 4-tuple:
-# (fixup type, fixup address, target section, target address)
-# both addresses are negative and relative to the end address of the section
-FIXUP_TYPE_LO_BYTE = 0
-FIXUP_TYPE_HI_BYTE = 1
-FIXUP_TYPE_WORD = 2
+# (fixup flags, fixup address, target section, target address)
+# either address can be start relative or end relative
+# either lo byte, hi byte or both (lo byte first) can be fixed up
+FIXUP_FLAG_FIXUP_END_RELATIVE = 1
+FIXUP_FLAG_TARGET_END_RELATIVE = 2
+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
section_loader.fixups.extend(
[
(
- FIXUP_TYPE_WORD,
+ 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
section_loader.fixups.extend(
[
(
- FIXUP_TYPE_LO_BYTE,
+ FIXUP_FLAG_FIXUP_END_RELATIVE |
+ FIXUP_FLAG_TARGET_END_RELATIVE |
+ FIXUP_FLAG_LO_BYTE,
1 - len(section_loader.data),
section_payload,
addr2
),
(
- FIXUP_TYPE_HI_BYTE,
+ FIXUP_FLAG_FIXUP_END_RELATIVE |
+ FIXUP_FLAG_TARGET_END_RELATIVE |
+ FIXUP_FLAG_HI_BYTE,
3 - len(section_loader.data),
section_payload,
addr2
),
(
- FIXUP_TYPE_WORD,
+ FIXUP_FLAG_FIXUP_END_RELATIVE |
+ FIXUP_FLAG_TARGET_END_RELATIVE |
+ FIXUP_FLAG_LO_BYTE |
+ FIXUP_FLAG_HI_BYTE,
5 - len(section_loader.data),
section_lzss_unpack,
-len(section_lzss_unpack.data)
section_payload.fixups.extend(
[
(
- FIXUP_TYPE_WORD,
+ 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)
bin = []
for section in sections:
- for fixup_type, fixup_addr, target_section, target_addr in section.fixups:
+ 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
- if fixup_type == FIXUP_TYPE_LO_BYTE:
- assert section.data[~fixup_addr] == 0
- section.data[~fixup_addr] = target_addr & 0xff
- elif fixup_type == FIXUP_TYPE_HI_BYTE:
- assert section.data[~fixup_addr] == 0
- section.data[~fixup_addr] = target_addr >> 8
- elif fixup_type == FIXUP_TYPE_WORD:
- assert section.data[~fixup_addr] == 0
- section.data[~fixup_addr] = target_addr & 0xff
- assert section.data[~fixup_addr - 1] == 0
- section.data[~fixup_addr - 1] = target_addr >> 8
- else:
- assert False
+ assert fixup_flags & FIXUP_FLAG_FIXUP_END_RELATIVE
+ fixup_addr = ~fixup_addr
+ if fixup_flags & FIXUP_FLAG_LO_BYTE:
+ assert section.data[fixup_addr] == 0
+ section.data[fixup_addr] = target_addr & 0xff
+ 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
bin.extend(section.data)
bin = bin[::-1]
)
# fixup is a 4-tuple:
-# (fixup type, fixup address, target section, target address)
-# both addresses are relative to the load address of the section,
-# except if the fixup address is negative it is relative to end
-# (needed for the loader section, which has to be constructed in
-# reverse, because the 6502 cannot execute in reverse, thus the
-# order of execution has to be opposite to the payload section)
-FIXUP_TYPE_LO_BYTE = 0
-FIXUP_TYPE_HI_BYTE = 1
-FIXUP_TYPE_WORD = 2
+# (fixup flags, fixup address, target section, target address)
+# either address can be start relative or end relative
+# either lo byte, hi byte or both (lo byte first) can be fixed up
+FIXUP_FLAG_FIXUP_END_RELATIVE = 1
+FIXUP_FLAG_TARGET_END_RELATIVE = 2
+FIXUP_FLAG_LO_BYTE = 4
+FIXUP_FLAG_HI_BYTE = 8
# each section has a data area, a load address and a list of fixups
# relocation is done after section lengths and load addresses known
section_loader.fixups.extend(
[
(
- FIXUP_TYPE_WORD,
+ FIXUP_FLAG_FIXUP_END_RELATIVE |
+ FIXUP_FLAG_LO_BYTE |
+ FIXUP_FLAG_HI_BYTE,
3 - len(section_loader.data),
section_payload,
addr2
section_loader.fixups.extend(
[
(
- FIXUP_TYPE_LO_BYTE,
+ FIXUP_FLAG_FIXUP_END_RELATIVE | FIXUP_FLAG_LO_BYTE,
1 - len(section_loader.data),
section_payload,
addr3
),
(
- FIXUP_TYPE_HI_BYTE,
+ FIXUP_FLAG_FIXUP_END_RELATIVE | FIXUP_FLAG_HI_BYTE,
3 - len(section_loader.data),
section_payload,
addr3
),
(
- FIXUP_TYPE_WORD,
+ FIXUP_FLAG_FIXUP_END_RELATIVE |
+ FIXUP_FLAG_LO_BYTE |
+ FIXUP_FLAG_HI_BYTE,
5 - len(section_loader.data),
section_lzss_unpack,
0
bin = []
for section in sections:
- for fixup_type, fixup_addr, target_section, target_addr in section.fixups:
+ for fixup_flags, fixup_addr, target_section, target_addr in section.fixups:
+ 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_type == FIXUP_TYPE_LO_BYTE:
+ if fixup_flags & FIXUP_FLAG_LO_BYTE:
assert section.data[fixup_addr] == 0
section.data[fixup_addr] = target_addr & 0xff
- elif fixup_type == FIXUP_TYPE_HI_BYTE:
+ fixup_addr += 1
+ if fixup_flags & FIXUP_FLAG_HI_BYTE:
assert section.data[fixup_addr] == 0
section.data[fixup_addr] = target_addr >> 8
- elif fixup_type == FIXUP_TYPE_WORD:
- assert section.data[fixup_addr] == 0
- section.data[fixup_addr] = target_addr & 0xff
- assert section.data[fixup_addr + 1] == 0
- section.data[fixup_addr + 1] = target_addr >> 8
- else:
- assert False
+ #fixup_addr += 1
bin.extend(section.data)
hdr = [load_addr & 0xff, load_addr >> 8, load_size & 0xff, load_size >> 8]