summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/m6809/m6809make.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/m6809/m6809make.py')
-rw-r--r--src/devices/cpu/m6809/m6809make.py125
1 files changed, 125 insertions, 0 deletions
diff --git a/src/devices/cpu/m6809/m6809make.py b/src/devices/cpu/m6809/m6809make.py
new file mode 100644
index 00000000000..28e018f8b2d
--- /dev/null
+++ b/src/devices/cpu/m6809/m6809make.py
@@ -0,0 +1,125 @@
+#!/usr/bin/python
+
+import sys
+import re
+
+# Initial state
+state = 1
+text = ""
+dispatch_to_states = { "MAIN" : 0 }
+states_to_dispatch = { 0 : "MAIN" }
+
+def load_file(fname, lines):
+ path = fname.rpartition('/')[0]
+ if path != "":
+ path += '/'
+ 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)
+
+ rawlines = re.split('(\n|; *\n?)', f.read())
+ count = 0
+ while count < len(rawlines)-1:
+ line = rawlines[count+0] + rawlines[count+1]
+ if line.startswith("#include"):
+ load_file(path + line.split('"')[1], lines)
+ else:
+ lines.append(line)
+ count += 2
+
+ f.close()
+
+# Get lines
+lines = []
+load_file(sys.argv[1], lines)
+
+count = 0
+while count < len(lines):
+ # Retrieve this line
+ line = lines[count]
+
+ # Retrieve the whitespace
+ whitespace = line[:len(line) - len(line.lstrip())]
+
+ # Check to see if the next line is a return
+ next_line_is_return = (count + 1 == len(lines)) or lines[count+1].strip() == "return;"
+
+ # Check to see if the next line is a dispatch followed by return
+ next_line_is_dispatch_and_return = (count + 1 < len(lines)) and re.match('([A-Za-z0-9\t ]+\:)*\s*\%', lines[count+1]) and lines[count+2].strip() == "return;"
+
+ if re.match('([A-Za-z0-9\t ]+\:)*\s*\%', line):
+ # This is a dispatch - find the '%'
+ percent_pos = line.find("%")
+ dispatch = line[percent_pos+1:].strip("\t\n; ")
+
+ # Do we have a label?
+ label = line[:percent_pos].strip()
+ if label != "":
+ text += whitespace + label + "\n"
+ whitespace += "\t"
+
+ # Create the goto command
+ if dispatch[-1:] == "*":
+ goto_command = "if (is_register_register_op_16_bit()) goto %s16; else goto %s8;\n" %(dispatch[:-1], dispatch[:-1])
+ else:
+ goto_command = "goto %s;\n" % dispatch
+
+ # Are we right before a 'return'?
+ if next_line_is_return:
+ text += whitespace + goto_command
+ count += 1 # Skip the return
+ elif next_line_is_dispatch_and_return:
+ # We are followed by a dispatch/return combo; identify the next dispatch
+ percent_pos = lines[count+1].find("%")
+ next_dispatch = lines[count+1][percent_pos+1:].strip("\t\n; ")
+
+ # If there is no state number associated with the next dispatch, make one
+ if next_dispatch not in dispatch_to_states:
+ dispatch_to_states[next_dispatch] = state
+ states_to_dispatch[state] = next_dispatch
+ state += 1
+
+ text += whitespace + "push_state(%s);\t// %s\n" % (dispatch_to_states[next_dispatch], next_dispatch)
+ text += whitespace + goto_command
+ count += 2 # Skip the dispatch/return
+
+ else:
+ # Normal dispatch
+ text += whitespace + "push_state(%s);\n" % state
+ text += whitespace + goto_command
+ text += "state_%s:\n" % state
+ state += 1
+ else:
+ # "Normal" code
+ # Is there an '@' here?
+ check_icount = line.lstrip().startswith("@")
+ if check_icount:
+ line = line.replace("@", "", 1)
+
+ # Output the line
+ text += line
+
+ # If we have to decrement the icount, output more info
+ if check_icount and not next_line_is_return:
+ text += whitespace + "if (UNEXPECTED(m_icount <= 0)) { push_state(%s); return; }\n" % state
+ text += "state_%s:\n" % state
+ state += 1
+
+ # Advance to next line
+ count += 1
+
+# Output the case labels
+for i in range(0, state):
+ print("\tcase %d: goto %s;" % (i, states_to_dispatch.get(i, "state_%d" % i)))
+
+# Output a default case
+print "\tdefault:"
+print "\t\tfatalerror(\"Unexpected state\");"
+print "\t\tbreak;"
+print
+
+# Finally output the text
+print text