FoenixToolbox/utils/srec2bin.py
Gered b35e5efd01 change build output location. make srec2bin.py more flexible
the Makefile now builds all artifacts, including final output s37 and
bin files under "build" so as to not clutter up the root directory
and making it easier to gitignore all build artifacts now and into the
future.

as well, the Makefile now has a new target to invoke srec2bin.py for us
to build ready-to-flash artifacts

srec2bin.py has been updated to be more flexible and do some minimal
argument error checking. it now also will output a CSV file for use
with FoenixMgr's flash-bulk option. this is useful as the number of
8k bin files can and will vary now and into the future, especially if
you are building with -O2 optimizations for size, etc.
2025-02-09 13:02:02 -05:00

85 lines
2.3 KiB
Python
Executable file

#!/usr/bin/env python
#
# Convert Motorola SREC to binary ROM files (both a 512KB main file and 8KB sector files for non-empty sectors)
#
# usage: python srec2bin.py
#
import os
import re
import sys
def srec_add_data(rom, address, data):
"""Add a line of data from an SREC file (hex digits) to the binary image at the given address"""
data_bytes = bytearray.fromhex(data)
for i in range(len(data_bytes)):
rom[address + i] = data_bytes[i]
def srec_process(rom, line):
"""Process a line of a Motorola SREC file"""
m = re.match(r'^S(\d)([0-9a-fA-F]{2})([0-9a-fA-F]+)$', line)
if m:
type = int(m.group(1), 10)
size = int(m.group(2), 16)
addr_data_chk = m.group(3)
if type == 3:
m2 = re.match(r'^([0-9a-fA-F]{8})([0-9a-fA-F]+)([0-9a-fA-F]{2})$', addr_data_chk)
if m2:
address = int(m2.group(1),16)
data = m2.group(2)
chksum = m2.group(3)
if address >= rom_base:
srec_add_data(rom, address - rom_base, data)
def bank_has_data(rom, bank):
"""Check to see if a bank is empty (all 0xFF)"""
start = bank * 8192
end = start + 8192
for i in range(start, end):
if rom[i] != 0xff:
# Return True if we find a non-blank entry
return True
return False
rom_size = 512 * 1024
rom_base = 0xf80000
output_name_base = "toolbox"
if len(sys.argv) != 2:
print("Usage: srec2bin.py [toolbox rom s37 file]")
sys.exit()
input_file = sys.argv[1]
if not os.path.exists(input_file) or not os.path.isfile(input_file):
print("Cannot read input file: " + input_file)
sys.exit()
output_dir = os.path.dirname(input_file)
output_file = output_dir + os.path.sep + output_name_base + ".bin"
output_bank_name_format = output_dir + os.path.sep + output_name_base + "-{:02X}.bin"
output_csv_file = output_dir + os.path.sep + output_name_base + ".csv"
rom_image = bytearray(rom_size)
for i in range(rom_size):
rom_image[i] = 0xff
with open(input_file, "r") as input:
for line in input:
srec_process(rom_image, line)
with open(output_file, "wb") as output:
output.write(rom_image)
with open(output_csv_file, "w") as csv:
for bank in range(0, 64):
if bank_has_data(rom_image, bank):
output_bank_name = output_bank_name_format.format(bank)
with open(output_bank_name, "wb") as output:
output.write(rom_image[bank * 8192:bank * 8192 + 8192])
csv.write('"{:02X}","{}-{:02X}.bin"\n'.format(bank, output_name_base, bank))