public void CompileProgram_Padding_FillsROM() { byte padding = 255; var rom = new Sharp_LR35902_Assembler.Assembler().CompileProgram(new string[0], null, padding); ListEqual(IEnumerableExtensions.ListOf(padding, rom.Length), rom); }
public void CompileProgram_MultipleLines() { var result = new Sharp_LR35902_Assembler.Assembler().CompileProgram(new[] { "EI", "EI" }, null); StartsWith( new byte[] { 0xFB, 0xFB, 0x00 }, result ); }
public void TryParseConstant_Math_WithLabel() { ushort val = 0; var assembler = new Sharp_LR35902_Assembler.Assembler(); assembler.AddLabelLocation("P", 77); Assert.IsTrue(assembler.TryParseImmediate("P + 3", ref val, true)); Assert.AreEqual(80, val); }
public void ParseDirective_Org_Align() { ushort currentlocation = 10; var assembler = new Sharp_LR35902_Assembler.Assembler(); assembler.ParseDirective(".ORG align 16", ref currentlocation); Assert.AreEqual(16, currentlocation); }
public void TryParseConstant_Math_WithConstant() { ushort currentlocation = 0; ushort val = 0; var assembler = new Sharp_LR35902_Assembler.Assembler(); assembler.ParseDirective("#DEFINE O 77", ref currentlocation); Assert.IsTrue(assembler.TryParseImmediate("O + 3", ref val)); Assert.AreEqual(80, val); }
public void TryParseConstant_GetDefinition_DefaultValue() { var assembler = new Sharp_LR35902_Assembler.Assembler(); assembler.SetDefintion("B"); ushort value = 11; Assert.IsTrue(assembler.TryParseImmediate("B", ref value)); Assert.AreEqual(0, value); }
public void CompileInstruction_FindsDefinition_CaseInsensitive() { ushort val = 11; var assembler = new Sharp_LR35902_Assembler.Assembler(); assembler.SetDefintion("x", val); var result = assembler.CompileInstruction("LD A x"); Is(result, 0x3E, (byte)val); }
public void CompileProgram_AddsDefintition_RequiresParsing() { ushort expectedvalue = 0x7F; var assembler = new Sharp_LR35902_Assembler.Assembler(); assembler.CompileProgram(new[] { "#DEFINE X 0x7F" }, null); ushort value = 0; Assert.IsTrue(assembler.TryParseImmediate("X", ref value)); Assert.AreEqual(expectedvalue, value); }
public void AddDefinition_Overrides() { var assembler = new Sharp_LR35902_Assembler.Assembler(); assembler.SetDefintion("X", 1); assembler.SetDefintion("X", 2); ushort val = 0; Assert.IsTrue(assembler.TryParseImmediate("X", ref val)); Assert.AreEqual(2, val); }
public void TryParseConstant_GetDefinition_FindsIt() { ushort expectedvalue = 0x7F00; var assembler = new Sharp_LR35902_Assembler.Assembler(); assembler.SetDefintion("XX", expectedvalue); ushort value = 0; Assert.IsTrue(assembler.TryParseImmediate("XX", ref value)); Assert.AreEqual(expectedvalue, value); }
public void CompileProgram_AddsDefintition() { ushort expectedvalue = 0x7F; var assembler = new Sharp_LR35902_Assembler.Assembler(); assembler.CompileProgram(new List <string> { $"#DEFINE X {expectedvalue}" }); ushort value = 0; Assert.IsTrue(assembler.TryParseImmediate("X", ref value)); Assert.AreEqual(expectedvalue, value); }
public void CompileProgram_ReplacesLabelLocation_Jump() { var instructions = new[] { "XOR A", "jumplabel:", "JP jumplabel" }; var binary = new Sharp_LR35902_Assembler.Assembler().CompileProgram(instructions, null); StartsWith( new byte[] { 0xAF, 0xC3, 0x01, 0x00 }, binary ); }
public void ParseDirective_Byte() { ushort currentlocation = 0; var rom = new Sharp_LR35902_Assembler.Assembler().ParseDirective(".byte 1 0x01 0b00000001", ref currentlocation); StartsWith( new byte[] { 0x01, 0x01, 0x01 }, rom ); }
public void CompileProgram_ReplacesLabelLocation_NonCaseSensitive() { var instructions = new List <string> { "XOR A", "AbCdEFDG:", "JP AbCdEFDG" }; var binary = new Sharp_LR35902_Assembler.Assembler().CompileProgram(instructions); StartsWith( new byte[] { 0xAF, 0xC3, 0x01, 0x00 }, binary ); }
public void CompileProgram_ReplacesLabelLocation_Call() { var instructions = new List <string> { "XOR A", "calllabel:", "CALL calllabel" }; var binary = new Sharp_LR35902_Assembler.Assembler().CompileProgram(instructions); StartsWith( new byte[] { 0xAF, 0xCD, 0x01, 0x00 }, binary ); }
public void CompileProgram_OverwriteInstruction_ThrowsWarning() { var assembler = new Sharp_LR35902_Assembler.Assembler(); var exceptions = new List <Exception>(); assembler.CompileProgram(new[] { ".byte 255", ".org 0", ".byte 0" }, exceptions); Assert.AreEqual(1, exceptions.Count); Assert.IsInstanceOfType(exceptions[0], typeof(OverwriteException)); }
public void ParseDirective_Text() { ushort currentlocation = 0; var rom = new Sharp_LR35902_Assembler.Assembler().ParseDirective(".text hello", ref currentlocation); StartsWith( new byte[] { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o' }, rom ); }
public static void Main(string[] args) { if (args.Length == 0 || args.Length == 1 && (args[0] == "/?" || args[0] == "-?")) { Console.WriteLine("Compiles assembly code that uses the Sharp LR35902 instruction-set into a binary."); Console.WriteLine(); Console.WriteLine("Compiler [options] [-in inputfilepath] [-out outputfilepath]"); Console.WriteLine("Options:"); Console.WriteLine("-FHS: Fix currupted HALTs and STOPs by ensuring a following NOP"); // TODO: Add any switches here return; } byte optimizationlevel = 1; string inputpath = null, outputpath = null; var fixhaltsandstops = false; for (var i = 0; i < args.Length; i++) { switch (args[i].ToLower()) { case "-in": inputpath = args[++i]; break; case "-out": outputpath = args[++i]; break; case "-o": optimizationlevel = byte.Parse(args[++i]); break; case "-fhs": fixhaltsandstops = true; break; default: Console.WriteLine($"Unknown switch '{args[i]}'"); return; } } if (inputpath == null) { Console.WriteLine("Input path not set"); return; } if (outputpath == null) { Console.WriteLine("Output path not set"); return; } var instructions = new List <string>(File.ReadAllLines(inputpath)); var assembler = new Assembler(); Formatter.Format(instructions); if (fixhaltsandstops) { Formatter.EnsureNOPAfterSTOPOrHALT(instructions); } Optimizer.Optimize(instructions, optimizationlevel); byte[] bytecode; try { bytecode = assembler.CompileProgram(instructions); } catch (Exception e) { Console.WriteLine(e.Message); Console.WriteLine("Output file has not been written."); return; } using (var outputfile = File.Create(outputpath)) { outputfile.Write(bytecode, 0, bytecode.Length); } }