fxconv: add toolchain/arch/section command-line parameters

New parameters are:
* --toolchain: specify the target triplet (eg. "sh3eb-elf")
* --arch: specify the binary architecture (eg. "sh3")
* --section: specify the output section (eg. ".rodata")
This commit is contained in:
Lephenixnoir 2019-09-09 09:18:59 +02:00
parent 4f145cb202
commit d74785d34d
No known key found for this signature in database
GPG key ID: 1BBA026E13FC0495
2 changed files with 43 additions and 27 deletions

View file

@ -43,7 +43,8 @@ def main():
modes = "script binary image font" modes = "script binary image font"
mode = "s" mode = "s"
output = None output = None
target = None model = None
target = { 'toolchain': None, 'arch': None, 'section': None }
# Parse command-line arguments # Parse command-line arguments
@ -53,7 +54,7 @@ def main():
try: try:
opts, args = getopt.gnu_getopt(sys.argv[1:], "hsbifo:", opts, args = getopt.gnu_getopt(sys.argv[1:], "hsbifo:",
("help output= fx cg "+modes).split()) ("help output= fx cg toolchain= arch= section= "+modes).split())
except getopt.GetoptError as error: except getopt.GetoptError as error:
err(error) err(error)
sys.exit(1) sys.exit(1)
@ -69,7 +70,13 @@ def main():
elif name in [ "-o", "--output" ]: elif name in [ "-o", "--output" ]:
output = value output = value
elif name in [ "--fx", "--cg" ]: elif name in [ "--fx", "--cg" ]:
target = name[2:] model = name[2:]
elif name == "--toolchain":
target['toolchain'] = value
elif name == "--arch":
target['arch'] = value
elif name == "--section":
target['section'] = value
# Other names are modes # Other names are modes
else: else:
mode = name[1] if len(name)==2 else name[2] mode = name[1] if len(name)==2 else name[2]
@ -114,7 +121,7 @@ def main():
params["type"] = { "b": "binary", "i": "image", "f": "font" }[mode] params["type"] = { "b": "binary", "i": "image", "f": "font" }[mode]
try: try:
fxconv.convert(input, params, output, target) fxconv.convert(input, params, target, output, model)
except fxconv.FxconvError as e: except fxconv.FxconvError as e:
err(e) err(e)
sys.exit(1) sys.exit(1)

View file

@ -234,15 +234,15 @@ class Grid:
# Binary conversion # Binary conversion
# #
def convert_binary(input, output, params): def convert_binary(input, output, params, target):
data = open(input, "rb").read() data = open(input, "rb").read()
elf(data, output, "_" + params["name"]) elf(data, output, "_" + params["name"], **target)
# #
# Image conversion for fx-9860G # Image conversion for fx-9860G
# #
def convert_bopti_fx(input, output, params): def convert_bopti_fx(input, output, params, target):
img = Image.open(input) img = Image.open(input)
if img.width >= 4096 or img.height >= 4096: if img.width >= 4096 or img.height >= 4096:
raise FxconvError(f"'{input}' is too large (max. 4095x4095)") raise FxconvError(f"'{input}' is too large (max. 4095x4095)")
@ -295,7 +295,7 @@ def convert_bopti_fx(input, output, params):
# Generate the object file # Generate the object file
elf(header + data, output, "_" + params["name"]) elf(header + data, output, "_" + params["name"], **target)
def _image_project(img, f): def _image_project(img, f):
# New width and height # New width and height
@ -317,7 +317,7 @@ def _image_project(img, f):
# Image conversion for fx-CG 50 # Image conversion for fx-CG 50
# #
def convert_bopti_cg(input, output, params): def convert_bopti_cg(input, output, params, target):
img = Image.open(input) img = Image.open(input)
if img.width >= 65536 or img.height >= 65536: if img.width >= 65536 or img.height >= 65536:
raise FxconvError(f"'{input}' is too large (max. 65535x65535)") raise FxconvError(f"'{input}' is too large (max. 65535x65535)")
@ -347,7 +347,7 @@ def convert_bopti_cg(input, output, params):
h >> 8, h & 0xff, # Height h >> 8, h & 0xff, # Height
]) ])
elf(header + encoded, output, "_" + params["name"]) elf(header + encoded, output, "_" + params["name"], **target)
# #
# Font conversion # Font conversion
@ -376,7 +376,7 @@ def _pad(seq, length):
n = max(0, length - len(seq)) n = max(0, length - len(seq))
return seq + bytearray(n) return seq + bytearray(n)
def convert_topti(input, output, params): def convert_topti(input, output, params, target):
#-- #--
# Image area and grid # Image area and grid
@ -488,7 +488,7 @@ def convert_topti(input, output, params):
else: else:
data = header + fixed_header + data_glyphs + title data = header + fixed_header + data_glyphs + title
elf(data, output, "_" + params["name"]) elf(data, output, "_" + params["name"], **target)
# #
# Exceptions # Exceptions
@ -636,7 +636,7 @@ def r5g6b5(img):
return encoded, alpha return encoded, alpha
def convert(input, params, output=None, target=None): def convert(input, params, target, output=None, model=None):
""" """
Convert a data file into an object that exports the following symbols: Convert a data file into an object that exports the following symbols:
* _<varname> * _<varname>
@ -647,8 +647,9 @@ def convert(input, params, output=None, target=None):
Arguments: Arguments:
input -- Input file path input -- Input file path
params -- Parameter dictionary params -- Parameter dictionary
target -- String dictionary keys 'toolchain', 'arch' and 'section'
output -- Output file name [default: <input> with suffix '.o'] output -- Output file name [default: <input> with suffix '.o']
target -- 'fx' or 'cg' (some conversions require this) [default: None] model -- 'fx' or 'cg' (some conversions require this) [default: None]
Produces an output file and returns nothing. Produces an output file and returns nothing.
""" """
@ -662,15 +663,15 @@ def convert(input, params, output=None, target=None):
if "type" not in params: if "type" not in params:
raise FxconvError(f"missing type in conversion '{input}'") raise FxconvError(f"missing type in conversion '{input}'")
elif params["type"] == "binary": elif params["type"] == "binary":
convert_binary(input, output, params) convert_binary(input, output, params, target)
elif params["type"] == "image" and target in [ "fx", None ]: elif params["type"] == "image" and model in [ "fx", None ]:
convert_bopti_fx(input, output, params) convert_bopti_fx(input, output, params, target)
elif params["type"] == "image" and target == "cg": elif params["type"] == "image" and model == "cg":
convert_bopti_cg(input, output, params) convert_bopti_cg(input, output, params, target)
elif params["type"] == "font": elif params["type"] == "font":
convert_topti(input, output, params) convert_topti(input, output, params, target)
def elf(data, output, symbol, section=None, arch="sh3"): def elf(data, output, symbol, toolchain=None, arch=None, section=None):
""" """
Call objcopy to create an object file from the specified data. The object Call objcopy to create an object file from the specified data. The object
file will export three symbols: file will export three symbols:
@ -690,19 +691,27 @@ def elf(data, output, symbol, section=None, arch="sh3"):
--binary-architecture flag of objcopy. --binary-architecture flag of objcopy.
Arguments: Arguments:
data -- A bytes-like object with data to embed into the object file data -- A bytes-like object with data to embed into the object file
output -- Name of output file output -- Name of output file
symbol -- Chosen symbol name symbol -- Chosen symbol name
section -- Target section [default: above variation of .rodata] toolchain -- Target triplet [default: "sh3eb-elf"]
arch -- Target architecture: "sh3" or "sh4" [default: "sh3"] arch -- Target architecture [default: from toolchain, if trivial]
section -- Target section [default: above variation of .rodata]
Produces an output file and returns nothing. Produces an output file and returns nothing.
""" """
toolchain = { "sh3": "sh3eb-elf", "sh4": "sh4eb-nofpu-elf" }[arch] if toolchain is None:
toolchain = "sh3eb-elf"
if section is None: if section is None:
section = ".rodata,contents,alloc,load,readonly,data" section = ".rodata,contents,alloc,load,readonly,data"
if arch is None and toolchain in "sh3eb-elf sh4eb-elf sh4eb-nofpu-elf":
arch = toolchain.replace("eb-", "-")[:-4]
if arch is None:
raise FxconvError(f"non-trivial architecture for {toolchain} must be "+
"specified")
with tempfile.NamedTemporaryFile() as fp: with tempfile.NamedTemporaryFile() as fp:
fp.write(data) fp.write(data)
fp.flush() fp.flush()