summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/mcs96/mcs96make.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/mcs96/mcs96make.py')
-rw-r--r--src/devices/cpu/mcs96/mcs96make.py196
1 files changed, 196 insertions, 0 deletions
diff --git a/src/devices/cpu/mcs96/mcs96make.py b/src/devices/cpu/mcs96/mcs96make.py
new file mode 100644
index 00000000000..72d8f36cfa6
--- /dev/null
+++ b/src/devices/cpu/mcs96/mcs96make.py
@@ -0,0 +1,196 @@
+#!/usr/bin/python
+
+from __future__ import print_function
+
+USAGE = """
+Usage:
+%s mcs96ops.lst mcs96.inc
+"""
+import sys
+
+def save_full_one(f, t, name, source):
+ print("void %s_device::%s_full()" % (t, name), file=f)
+ print("{", file=f)
+ for line in source:
+ print(line, file=f)
+ print("}", file=f)
+ print("", file=f)
+
+class Opcode:
+ def __init__(self, rng, name, amode, is_196, ea):
+ rng1 = rng.split("-")
+ self.rng_start = int(rng1[0], 16)
+ if len(rng1) == 2:
+ self.rng_end = int(rng1[1], 16)
+ else:
+ self.rng_end = self.rng_start
+ self.name = name
+ self.amode = amode
+ self.source = []
+ self.is_196 = is_196
+ if amode in ea:
+ for line in ea[amode].source:
+ self.source.append(line)
+
+ def add_source_line(self, line):
+ self.source.append(line)
+
+class Special:
+ def __init__(self, name):
+ self.name = name
+ self.source = []
+
+ def add_source_line(self, line):
+ self.source.append(line)
+
+class Macro:
+ def __init__(self, tokens):
+ self.name = tokens[1]
+ self.params = []
+ for i in range(2, len(tokens)):
+ self.params.append(tokens[i])
+ self.source = []
+
+ def add_source_line(self, line):
+ self.source.append(line)
+
+ def apply(self, target, tokens):
+ values = []
+ for i in range(1, len(tokens)):
+ values.append(tokens[i])
+ for i in range(0, len(self.source)):
+ line = self.source[i]
+ for j in range(0, len(self.params)):
+ line = line.replace(self.params[j], values[j])
+ target.add_source_line(line)
+
+class OpcodeList:
+ def __init__(self, fname, is_196):
+ self.opcode_info = []
+ self.opcode_per_id = {}
+ self.ea = {}
+ self.macros = {}
+ try:
+ f = open(fname, "rU")
+ except Exception:
+ err = sys.exc_info()[1]
+ sys.stderr.write("Cannot read opcodes file %s [%s]\n" % (fname, err))
+ sys.exit(1)
+
+ inf = None
+ for line in f:
+ if line.startswith("#"):
+ continue
+ line = line.rstrip()
+ if not line:
+ continue
+ if line.startswith(" ") or line.startswith("\t"):
+ # append instruction to last opcode, maybe expand a macro
+ tokens = line.split()
+ if tokens[0] in self.macros:
+ self.macros[tokens[0]].apply(inf, tokens)
+ else:
+ inf.add_source_line(line)
+ else:
+ # New something
+ tokens = line.split()
+ # Addressing mode header
+ if tokens[0] == "eadr":
+ inf = Special(tokens[1])
+ self.ea[inf.name] = inf
+ elif tokens[0] == "fetch":
+ inf = Special(tokens[0])
+ self.fetch = inf
+ elif tokens[0] == "fetch_noirq":
+ inf = Special(tokens[0])
+ self.fetch_noirq = inf
+ elif tokens[0] == "macro":
+ inf = Macro(tokens)
+ self.macros[inf.name] = inf
+ else:
+ inf = Opcode(tokens[0], tokens[1], tokens[2], len(tokens) >= 4 and tokens[3] == "196", self.ea)
+ self.opcode_info.append(inf)
+ if is_196 or not inf.is_196:
+ for i in range(inf.rng_start, inf.rng_end+1):
+ self.opcode_per_id[i] = inf
+
+ def save_dasm(self, f, t):
+ print("const %s_device::disasm_entry %s_device::disasm_entries[0x100] = {" % (t, t), file=f)
+ for i in range(0, 0x100):
+ if i in self.opcode_per_id:
+ opc = self.opcode_per_id[i]
+ alt = "NULL"
+ if i + 0xfe00 in self.opcode_per_id:
+ alt = "\"" + self.opcode_per_id[i+0xfe00].name + "\""
+ if opc.name == "scall" or opc.name == "lcall":
+ flags = "DASMFLAG_STEP_OVER"
+ elif opc.name == "rts":
+ flags = "DASMFLAG_STEP_OUT"
+ else:
+ flags = "0"
+ print("\t{ \"%s\", %s, DASM_%s, %s }," % (opc.name, alt, opc.amode, flags), file=f)
+ else:
+ print("\t{ \"???\", NULL, DASM_none, 0 },", file=f)
+ print("};", file=f)
+ print("", file=f)
+
+ def save_opcodes(self, f, t):
+ pf = ""
+ is_196 = False
+ if t == "i8xc196":
+ pf = "_196"
+ is_196 = True
+ for opc in self.opcode_info:
+ if opc.is_196 == is_196:
+ save_full_one(f, t, opc.name + "_" + opc.amode + pf, opc.source)
+ if not is_196:
+ save_full_one(f, t, "fetch", self.fetch.source)
+ save_full_one(f, t, "fetch_noirq", self.fetch_noirq.source)
+
+ def save_exec(self, f, t):
+ print("void %s_device::do_exec_full()" % t, file=f)
+ print("{", file=f)
+ print("\tswitch(inst_state) {", file=f)
+ for i in range(0x000, 0x200):
+ opc = None
+ if i >= 0x100 and i-0x100+0xfe00 in self.opcode_per_id:
+ opc = self.opcode_per_id[i-0x100+0xfe00]
+ if opc is None and (i & 0xff) in self.opcode_per_id:
+ opc = self.opcode_per_id[i & 0xff]
+ if opc is not None:
+ nm = opc.name + "_" + opc.amode
+ if opc.is_196:
+ nm += "_196"
+ print("\tcase 0x%03x: %s_full(); break;" % (i, nm), file=f)
+ print("\tcase 0x200: fetch_full(); break;", file=f)
+ print("\tcase 0x201: fetch_noirq_full(); break;", file=f)
+ print("\t}", file=f)
+ print("}", file=f)
+
+def main(argv):
+ if len(argv) != 4:
+ print(USAGE % argv[0])
+ return 1
+
+ t = argv[1]
+ opcodes = OpcodeList(argv[2], t == "i8xc196")
+
+ try:
+ f = open(argv[3], "w")
+ except Exception:
+ err = sys.exc_info()[1]
+ sys.stderr.write("cannot write file %s [%s]\n" % (argv[3], err))
+ sys.exit(1)
+
+ if t != "mcs96":
+ opcodes.save_dasm(f, t)
+ if t != "i8x9x":
+ opcodes.save_opcodes(f, t)
+ if t != "mcs96":
+ opcodes.save_exec(f, t)
+ f.close()
+
+# ======================================================================
+if __name__ == "__main__":
+ sys.exit(main(sys.argv))
+