In a2_pack_*.py implement fixup flags (makes the two mini-linkers more similar)
authorNick Downing <nick@ndcode.org>
Tue, 21 Jun 2022 08:52:27 +0000 (18:52 +1000)
committerNick Downing <nick@ndcode.org>
Tue, 21 Jun 2022 08:52:27 +0000 (18:52 +1000)
loader/a2_pack_fwd.py
loader/a2_pack_rev.py

index 2b70384..86bcedb 100755 (executable)
@@ -208,11 +208,13 @@ segments = (
 )
 
 # 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
@@ -308,7 +310,10 @@ for i in range(len(segments) - 2, -2, -2):
     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
@@ -341,19 +346,26 @@ for i in range(len(segments) - 2, -2, -2):
     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)
@@ -377,7 +389,10 @@ section_payload.data.extend(
 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)
@@ -408,25 +423,23 @@ for report_type, addr0, addr1, addr2, addr3 in report[::-1]:
 
 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]
 
index f93f23b..7c942f6 100755 (executable)
@@ -210,15 +210,13 @@ segments = (
 )
 
 # 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
@@ -333,7 +331,9 @@ for i in range(0, len(segments), 2):
     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
@@ -366,19 +366,21 @@ for i in range(0, len(segments), 2):
     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
@@ -420,21 +422,21 @@ for report_type, addr0, addr1, addr2, addr3 in report:
 
 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]