diff options
author | Sebastian Reichel <sre@ring0.de> | 2011-12-12 00:11:34 +0100 |
---|---|---|
committer | Sebastian Reichel <sre@ring0.de> | 2011-12-12 00:11:34 +0100 |
commit | 90c9a148a94ed92c93d42110e45d8787f7ac1eff (patch) | |
tree | 447e0ec7bfa5c60a87468851c2fff741d6e645f2 /assembler.vala | |
download | lp5523-assembler-90c9a148a94ed92c93d42110e45d8787f7ac1eff.tar.bz2 |
initial import
Diffstat (limited to 'assembler.vala')
-rw-r--r-- | assembler.vala | 140 |
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; +} |