summaryrefslogtreecommitdiffstats
path: root/assembler.vala
diff options
context:
space:
mode:
authorSebastian Reichel <sre@ring0.de>2011-12-12 00:11:34 +0100
committerSebastian Reichel <sre@ring0.de>2011-12-12 00:11:34 +0100
commit90c9a148a94ed92c93d42110e45d8787f7ac1eff (patch)
tree447e0ec7bfa5c60a87468851c2fff741d6e645f2 /assembler.vala
downloadlp5523-assembler-90c9a148a94ed92c93d42110e45d8787f7ac1eff.tar.bz2
initial import
Diffstat (limited to 'assembler.vala')
-rw-r--r--assembler.vala140
1 files changed, 140 insertions, 0 deletions
diff --git a/assembler.vala b/assembler.vala
new file mode 100644
index 0000000..e44ceb8
--- /dev/null
+++ b/assembler.vala
@@ -0,0 +1,140 @@
+/* assembler.vala
+ * Copyright 2011, Sebastian Reichel <sre@ring0.de>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+const OptionEntry[] option_entries = {
+ {"assemble", 'a', OptionFlags.NO_ARG, OptionArg.CALLBACK, (void*) parse_mode, "use assemble mode", null},
+ {"disassemble", 'd', OptionFlags.NO_ARG, OptionArg.CALLBACK, (void*) parse_mode, "use disassemble mode", null},
+ { "", 0, 0, OptionArg.FILENAME_ARRAY, ref files, "input file", "FILE" },
+ {null}
+};
+
+enum mode {
+ ASSEMBLE,
+ DISASSEMBLE
+}
+
+static string[] files;
+static mode m;
+
+bool parse_mode(string key, string? val) throws OptionError {
+ switch(key) {
+ case "--assemble":
+ case "-a":
+ m = mode.ASSEMBLE;
+ return true;
+ case "--disassemble":
+ case "-d":
+ m = mode.DISASSEMBLE;
+ return true;
+ default:
+ throw new OptionError.UNKNOWN_OPTION("Unknown Option " + key);
+ }
+}
+
+string assemble(FileStream stream) throws lp5523.ParsingError {
+ string line;
+ string result = "";
+
+ /* read until EOF */
+ while((line = stream.read_line()) != null) {
+ /* skip comment lines */
+ line = line.strip();
+ if(line.has_prefix("#"))
+ continue;
+
+ /* remove inline comments */
+ line = line.split("#", 2)[0];
+ line = line.strip();
+
+ result += "%04hx".printf(lp5523.assemble(line));
+ }
+
+ /* size check */
+ if(result.length/4 > lp5523.PROGSPACE_SIZE)
+ warning("this does not fit into lp5523 progspace");
+
+ result += "\n";
+
+ return result;
+}
+
+public string disassemble(FileStream stream) throws lp5523.ParsingError {
+ string line;
+ string result = "";
+
+ line = stream.read_line();
+
+ if(line == null)
+ return "";
+
+ /* remove trailing newline */
+ if(line.length % 2 == 1 && line.has_suffix("\n"))
+ line = line.substring(0, line.length-1);
+
+ /* disassemble */
+ for(int i=0; i<line.length/4; i++) {
+ var cmd = line.substring(i*4, 4);
+ uint16 opcode;
+ cmd.scanf("%04hx", out opcode);
+ result += lp5523.disassemble(opcode) + "\n";
+ }
+
+ return result;
+}
+
+int main(string[] args) {
+ unowned FileStream stream;
+ FileStream file;
+
+ /* parse parameters from shell */
+ var context = new OptionContext("- lp5523 (dis-)assembler");
+ context.set_help_enabled(true);
+ context.add_main_entries(option_entries, "lp5523-as");
+
+ try {
+ context.parse(ref args);
+ } catch(OptionError e) {
+ stderr.puts(e.message + "\n");
+ return 1;
+ }
+
+ /* open file or stdin respectively */
+ if(files == null || files[0] == "-") {
+ stream = stdin;
+ } else {
+ file = FileStream.open(files[0], "r");
+
+ if(file == null) {
+ stderr.printf("Could not open '%s'.\n", files[0]);
+ return 1;
+ }
+
+ stream = file;
+ }
+
+ /* do the actual work */
+ try {
+ if(m == mode.ASSEMBLE)
+ stdout.puts(assemble(stream));
+ else if(m == mode.DISASSEMBLE)
+ stdout.puts(disassemble(stream));
+ } catch(Error e) {
+ stderr.puts(e.message + "\n");
+ return 1;
+ }
+
+ return 0;
+}