Gered
b35e5efd01
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.
85 lines
2.3 KiB
Python
Executable file
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))
|