In a2_pack_*.py make the loader be constructed in order of execution (always bottom...
authorNick Downing <nick@ndcode.org>
Tue, 21 Jun 2022 09:33:29 +0000 (19:33 +1000)
committerNick Downing <nick@ndcode.org>
Tue, 21 Jun 2022 09:38:45 +0000 (19:38 +1000)
loader/a2_pack_fwd.py
loader/a2_pack_rev.py

index d5c49cf..d474b32 100755 (executable)
@@ -153,7 +153,7 @@ def lzss_pack(dest, bin):
   #      #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)
@@ -241,16 +241,34 @@ REPORT_TYPE_UNCOMPRESSED = 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))
@@ -261,34 +279,44 @@ for i in range(len(segments) - 2, -2, -2):
     )
 
     # 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
@@ -296,7 +324,7 @@ for i in range(len(segments) - 2, -2, -2):
         0x95, addr1 & 0xff,                            # sta *addr1,x
         0xe8,                                          # inx
         0xd0, 0xf8                                     # bne .-6
-      ][::-1]
+      ]
     if zpage else
       [
         0xa2, -len(data) & 0xff,                       # ldx #-count
@@ -304,106 +332,61 @@ for i in range(len(segments) - 2, -2, -2):
         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]:
@@ -411,12 +394,13 @@ 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}%'
index 7c942f6..a836597 100755 (executable)
@@ -246,13 +246,16 @@ report = []
 # 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))
@@ -263,32 +266,44 @@ for i in range(0, len(segments), 2):
     )
 
     # 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(
@@ -298,7 +313,7 @@ for i in range(0, len(segments), 2):
           0x95, addr0 & 0xff,                          # sta *addr0,x
           0xe8,                                                # inx
           0xd0, 0xf8                                   # bne .-6
-        ][::-1]
+        ]
       if zpage else
         [
           0xa2, 0x00,                                  # ldx #0
@@ -306,7 +321,7 @@ for i in range(0, len(segments), 2):
           0x9d, addr0 & 0xff, (addr0 >> 8) & 0xff,     # sta addr0,x
           0xe8,                                                # inx
           0xd0, 0xf7                                   # bne .-7
-        ][::-1]
+        ]
       )
     else:
       addr0 -= 1
@@ -318,7 +333,7 @@ for i in range(0, len(segments), 2):
           0x95, addr0 & 0xff,                          # sta *addr0,x
           0xca,                                                # dex
           0xd0, 0xf8                                   # bne .-6
-        ][::-1]
+        ]
       if zpage else
         [
           0xa2, len(data),                             # ldx #count
@@ -326,26 +341,14 @@ for i in range(0, len(segments), 2):
           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)
     )
@@ -356,50 +359,47 @@ for i in range(0, len(segments), 2):
       )
 
     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
@@ -410,8 +410,9 @@ 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
-    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}%'