FoenixToolbox/utils/srec2bin.py

85 lines
2.3 KiB
Python
Raw Normal View History

#!/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))