In a2_pack_*.py make each section be a variable instead of accessed by indexing
authorNick Downing <nick@ndcode.org>
Tue, 21 Jun 2022 08:31:45 +0000 (18:31 +1000)
committerNick Downing <nick@ndcode.org>
Tue, 21 Jun 2022 08:31:45 +0000 (18:31 +1000)
loader/a2_pack_fwd.py
loader/a2_pack_rev.py

index 1211917..2b70384 100755 (executable)
@@ -207,12 +207,6 @@ segments = (
   intersect(segments, [0x100, 0x200])
 )
 
-# sections are output to the a2bin file from top to bottom as follows:
-SECTION_UNPACKER = 0
-SECTION_LOADER = 1
-SECTION_PAYLOAD = 2
-N_SECTIONS = 3
-
 # 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
@@ -228,7 +222,12 @@ class Section:
     self.data = data
     self.end_addr = end_addr
     self.fixups = fixups
-sections = [Section([], 0, []) for i in range(N_SECTIONS)]
+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]
 
 # report is a 5-tuple:
 #   (report type, ihx start, ihx end, a2bin start, a2bin end)
@@ -242,7 +241,7 @@ REPORT_TYPE_COMPRESSED = 2
 report = []
 
 # epilogue
-sections[SECTION_LOADER].data.extend(
+section_loader.data.extend(
   [
     0x4c, entry_point & 0xff, entry_point >> 8,        # jmp entry_point
   ][::-1]
@@ -263,7 +262,7 @@ 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
-      sections[SECTION_LOADER].data.extend(
+      section_loader.data.extend(
         [
           0xa9, i,                             # lda #data
           0x85, addr1,                         # sta *addr1
@@ -275,11 +274,11 @@ for i in range(len(segments) - 2, -2, -2):
         ][::-1]
       )
   elif len(data) <= 0x100:
-    addr3 = -len(sections[SECTION_PAYLOAD].data)
-    sections[SECTION_PAYLOAD].data.extend(
+    addr3 = -len(section_payload.data)
+    section_payload.data.extend(
       data[::-1]
     )
-    addr2 = -len(sections[SECTION_PAYLOAD].data)
+    addr2 = -len(section_payload.data)
     report.append(
       (REPORT_TYPE_UNCOMPRESSED, addr0, addr1, addr2, addr3)
     )
@@ -289,7 +288,7 @@ for i in range(len(segments) - 2, -2, -2):
 
     addr1 -= 0x100
     addr3 -= 0x100
-    sections[SECTION_LOADER].data.extend(
+    section_loader.data.extend(
       [
         0xa2, -len(data) & 0xff,                       # ldx #-count
         0xbd, 0x00, 0x00,                              # lda addr3,x
@@ -306,99 +305,99 @@ for i in range(len(segments) - 2, -2, -2):
         0xd0, 0xf7                                     # bne .-7
       ][::-1]
     )
-    sections[SECTION_LOADER].fixups.extend(
+    section_loader.fixups.extend(
       [
         (
           FIXUP_TYPE_WORD,
-          3 - len(sections[SECTION_LOADER].data),
-          SECTION_PAYLOAD,
+          3 - len(section_loader.data),
+          section_payload,
           addr3
         ),
       ]
     )
   else:
-    addr3 = -len(sections[SECTION_PAYLOAD].data)
-    sections[SECTION_PAYLOAD].data.extend(
+    addr3 = -len(section_payload.data)
+    section_payload.data.extend(
       lzss_pack(addr0, data)[::-1]
     )
-    addr2 = -len(sections[SECTION_PAYLOAD].data)
+    addr2 = -len(section_payload.data)
     report.append(
       (REPORT_TYPE_COMPRESSED, addr0, addr1, addr2, addr3)
     )
 
-    if len(sections[SECTION_UNPACKER].data) == 0:
-      sections[SECTION_UNPACKER].data.extend(
+    if len(section_lzss_unpack.data) == 0:
+      section_lzss_unpack.data.extend(
         lzss_unpack_fwd[::-1]
       )
 
     addr2 += 5 - 0x100
-    sections[SECTION_LOADER].data.extend(
+    section_loader.data.extend(
       [
         0xa9, 0x00,            # lda #<addr2
         0xa0, 0x00,            # ldy #>addr2
         0x20, 0x00, 0x00,      # jsr lzss_unpack_fwd
       ][::-1]
     )
-    sections[SECTION_LOADER].fixups.extend(
+    section_loader.fixups.extend(
       [
         (
           FIXUP_TYPE_LO_BYTE,
-          1 - len(sections[SECTION_LOADER].data),
-          SECTION_PAYLOAD,
+          1 - len(section_loader.data),
+          section_payload,
           addr2
         ),
         (
           FIXUP_TYPE_HI_BYTE,
-          3 - len(sections[SECTION_LOADER].data),
-          SECTION_PAYLOAD,
+          3 - len(section_loader.data),
+          section_payload,
           addr2
         ),
         (
           FIXUP_TYPE_WORD,
-          5 - len(sections[SECTION_LOADER].data),
-          SECTION_UNPACKER,
-          -len(sections[SECTION_UNPACKER].data)
+          5 - len(section_loader.data),
+          section_lzss_unpack,
+          -len(section_lzss_unpack.data)
         ),
       ]
     )
 
 # prologue
-sections[SECTION_LOADER].data.extend(
+section_loader.data.extend(
   [
     0xd8,      # cld
     0xa2, 0xff,        # ldx #0xff
     0x9a,      # txs
   ][::-1]
 )
-sections[SECTION_PAYLOAD].data.extend(
+section_payload.data.extend(
   [
     0x4c, 0x00, 0x00,  # jmp loader
   ][::-1]
 )
-sections[SECTION_PAYLOAD].fixups.extend(
+section_payload.fixups.extend(
   [
     (
       FIXUP_TYPE_WORD,
-      1 - len(sections[SECTION_PAYLOAD].data),
-      SECTION_LOADER,
-      -len(sections[SECTION_LOADER].data)
+      1 - len(section_payload.data),
+      section_loader,
+      -len(section_loader.data)
     ),
   ] 
 )
 
 # relocate
 load_addr = end_addr
-for i in range(N_SECTIONS):
-  sections[i].end_addr = load_addr
-  load_addr -= len(sections[i].data)
+for section in sections:
+  section.end_addr = load_addr
+  load_addr -= len(section.data)
 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 += sections[SECTION_PAYLOAD].end_addr
-    addr3 += sections[SECTION_PAYLOAD].end_addr
+    addr2 += section_payload.end_addr
+    addr3 += section_payload.end_addr
     print(
       f'[0x{addr0:04x}, 0x{addr1:04x}) -> [0x{addr2:04x}, 0x{addr3:04x})' + (
         f'{100. * (addr3 - addr2) / (addr1 - addr0):6.1f}%'
@@ -408,27 +407,27 @@ for report_type, addr0, addr1, addr2, addr3 in report[::-1]:
     )
 
 bin = []
-for i in range(N_SECTIONS):
-  for fixup_type, fixup_addr, section, addr in sections[i].fixups:
-    addr += sections[section].end_addr
+for section in sections:
+  for fixup_type, fixup_addr, target_section, target_addr in section.fixups:
+    target_addr += target_section.end_addr
 
-    # fixup_addr is in range -len(sections[i].data) .. -1
-    # -1 means last byte of section, but since the section data is
+    # 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 sections[i].data[~fixup_addr] == 0
-      sections[i].data[~fixup_addr] = addr & 0xff
+      assert section.data[~fixup_addr] == 0
+      section.data[~fixup_addr] = target_addr & 0xff
     elif fixup_type == FIXUP_TYPE_HI_BYTE:
-      assert sections[i].data[~fixup_addr] == 0
-      sections[i].data[~fixup_addr] = addr >> 8
+      assert section.data[~fixup_addr] == 0
+      section.data[~fixup_addr] = target_addr >> 8
     elif fixup_type == FIXUP_TYPE_WORD:
-      assert sections[i].data[~fixup_addr] == 0
-      sections[i].data[~fixup_addr] = addr & 0xff
-      assert sections[i].data[~fixup_addr - 1] == 0
-      sections[i].data[~fixup_addr - 1] = addr >> 8
+      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
-  bin.extend(sections[i].data)
+  bin.extend(section.data)
 bin = bin[::-1]
 
 hdr = [load_addr & 0xff, load_addr >> 8, load_size & 0xff, load_size >> 8]
index 2145cda..f93f23b 100755 (executable)
@@ -209,12 +209,6 @@ segments = (
   intersect(segments, [0x200, 0x10000])
 )
 
-# sections are output to the a2bin file from bottom to top as follows:
-SECTION_LOADER = 0
-SECTION_UNPACKER = 1
-SECTION_PAYLOAD = 2
-N_SECTIONS = 3
-
 # fixup is a 4-tuple:
 #   (fixup type, fixup address, target section, target address)
 # both addresses are relative to the load address of the section,
@@ -233,7 +227,12 @@ class Section:
     self.data = data
     self.load_addr = load_addr
     self.fixups = fixups
-sections = [Section([], 0, []) for i in range(N_SECTIONS)]
+section_lzss_unpack = Section([], 0, [])
+section_loader = Section([], 0, [])
+section_payload = Section([], 0, [])
+
+# sections are output to the a2bin file from bottom to top as follows:
+sections = [section_loader, section_lzss_unpack, section_payload]
 
 # report is a 5-tuple:
 #   (report type, ihx start, ihx end, a2bin start, a2bin end)
@@ -247,7 +246,7 @@ REPORT_TYPE_COMPRESSED = 2
 report = []
 
 # prologue
-sections[SECTION_LOADER].data.extend(
+section_loader.data.extend(
   [
     0x4c, entry_point & 0xff, entry_point >> 8,        # jmp entry_point
   ][::-1]
@@ -267,7 +266,7 @@ for i in range(0, len(segments), 2):
 
     # use of zpage version is determined byte by byte
     for i in data:
-      sections[SECTION_LOADER].data.extend(
+      section_loader.data.extend(
         [
           0xa9, i,                             # lda #data
           0x85, addr0,                         # sta *addr0
@@ -280,11 +279,11 @@ for i in range(0, len(segments), 2):
       )
       addr0 += 1
   elif len(data) <= 0x100:
-    addr2 = len(sections[SECTION_PAYLOAD].data)
-    sections[SECTION_PAYLOAD].data.extend(
+    addr2 = len(section_payload.data)
+    section_payload.data.extend(
       data
     )
-    addr3 = len(sections[SECTION_PAYLOAD].data)
+    addr3 = len(section_payload.data)
     report.append(
       (REPORT_TYPE_UNCOMPRESSED, addr0, addr1, addr2, addr3)
     )
@@ -294,7 +293,7 @@ for i in range(0, len(segments), 2):
 
     if len(data) == 0x100:
       # for the full count we will copy forward (an exception)
-      sections[SECTION_LOADER].data.extend(
+      section_loader.data.extend(
         [
           0xa2, 0x00,                                  # ldx #0
           0xbd, 0x00, 0x00,                            # lda addr2,x
@@ -314,7 +313,7 @@ for i in range(0, len(segments), 2):
     else:
       addr0 -= 1
       addr2 -= 1
-      sections[SECTION_LOADER].data.extend(
+      section_loader.data.extend(
         [
           0xa2, len(data),                             # ldx #count
           0xbd, 0x00, 0x00,                            # lda addr2,x
@@ -331,57 +330,57 @@ for i in range(0, len(segments), 2):
           0xd0, 0xf7                                   # bne .-7
         ][::-1]
       )
-    sections[SECTION_LOADER].fixups.extend(
+    section_loader.fixups.extend(
       [
         (
           FIXUP_TYPE_WORD,
-          3 - len(sections[SECTION_LOADER].data),
-          SECTION_PAYLOAD,
+          3 - len(section_loader.data),
+          section_payload,
           addr2
         ),
       ]
     )
   else:
-    addr2 = len(sections[SECTION_PAYLOAD].data)
-    sections[SECTION_PAYLOAD].data.extend(
+    addr2 = len(section_payload.data)
+    section_payload.data.extend(
       lzss_pack(addr1 - 1, data)
     )
-    addr3 = len(sections[SECTION_PAYLOAD].data)
+    addr3 = len(section_payload.data)
     report.append(
       (REPORT_TYPE_COMPRESSED, addr0, addr1, addr2, addr3)
     )
 
-    if len(sections[SECTION_UNPACKER].data) == 0:
-      sections[SECTION_UNPACKER].data.extend(
+    if len(section_lzss_unpack.data) == 0:
+      section_lzss_unpack.data.extend(
         lzss_unpack_rev
       )
 
     addr3 -= 5 + 1
-    sections[SECTION_LOADER].data.extend(
+    section_loader.data.extend(
       [
         0xa9, 0x00,            # lda #<addr3
         0xa0, 0x00,            # ldy #>addr3
         0x20, 0x00, 0x00,      # jsr lzss_unpack_rev
       ][::-1]
     )
-    sections[SECTION_LOADER].fixups.extend(
+    section_loader.fixups.extend(
       [
         (
           FIXUP_TYPE_LO_BYTE,
-          1 - len(sections[SECTION_LOADER].data),
-          SECTION_PAYLOAD,
+          1 - len(section_loader.data),
+          section_payload,
           addr3
         ),
         (
           FIXUP_TYPE_HI_BYTE,
-          3 - len(sections[SECTION_LOADER].data),
-          SECTION_PAYLOAD,
+          3 - len(section_loader.data),
+          section_payload,
           addr3
         ),
         (
           FIXUP_TYPE_WORD,
-          5 - len(sections[SECTION_LOADER].data),
-          SECTION_UNPACKER,
+          5 - len(section_loader.data),
+          section_lzss_unpack,
           0
         ),
       ]
@@ -389,28 +388,28 @@ for i in range(0, len(segments), 2):
 
 
 # prologue
-sections[SECTION_LOADER].data.extend(
+section_loader.data.extend(
   [
     0xd8,      # cld
     0xa2, 0xff,        # ldx #0xff
     0x9a,      # txs
   ][::-1]
 )
-sections[SECTION_LOADER].data = sections[SECTION_LOADER].data[::-1]
+section_loader.data = section_loader.data[::-1]
 
 # relocate
 end_addr = load_addr
-for i in range(N_SECTIONS):
-  sections[i].load_addr = end_addr
-  end_addr += len(sections[i].data)
+for section in sections:
+  section.load_addr = end_addr
+  end_addr += len(section.data)
 load_size = end_addr - load_addr
 
 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 += sections[SECTION_PAYLOAD].load_addr
-    addr3 += sections[SECTION_PAYLOAD].load_addr
+    addr2 += section_payload.load_addr
+    addr3 += section_payload.load_addr
     print(
       f'[0x{addr0:04x}, 0x{addr1:04x}) -> [0x{addr2:04x}, 0x{addr3:04x})' + (
         f'{100. * (addr3 - addr2) / (addr1 - addr0):6.1f}%'
@@ -420,23 +419,23 @@ for report_type, addr0, addr1, addr2, addr3 in report:
     )
 
 bin = []
-for i in range(N_SECTIONS):
-  for fixup_type, fixup_addr, section, addr in sections[i].fixups:
-    addr += sections[section].load_addr
+for section in sections:
+  for fixup_type, fixup_addr, target_section, target_addr in section.fixups:
+    target_addr += target_section.load_addr
     if fixup_type == FIXUP_TYPE_LO_BYTE:
-      assert sections[i].data[fixup_addr] == 0
-      sections[i].data[fixup_addr] = addr & 0xff
+      assert section.data[fixup_addr] == 0
+      section.data[fixup_addr] = target_addr & 0xff
     elif fixup_type == FIXUP_TYPE_HI_BYTE:
-      assert sections[i].data[fixup_addr] == 0
-      sections[i].data[fixup_addr] = addr >> 8
+      assert section.data[fixup_addr] == 0
+      section.data[fixup_addr] = target_addr >> 8
     elif fixup_type == FIXUP_TYPE_WORD:
-      assert sections[i].data[fixup_addr] == 0
-      sections[i].data[fixup_addr] = addr & 0xff
-      assert sections[i].data[fixup_addr + 1] == 0
-      sections[i].data[fixup_addr + 1] = addr >> 8
+      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
-  bin.extend(sections[i].data)
+  bin.extend(section.data)
 
 hdr = [load_addr & 0xff, load_addr >> 8, load_size & 0xff, load_size >> 8]
 with open(out_a2bin, 'wb') as fout: