public void TestAssert()
        {
            var line = new SourceLine();

            line.LineNumber  = 1;
            line.Filename    = "test";
            line.Instruction = ".assert";
            line.Operand     = "5 == 6";
            LineAssembler.AssembleLine(line);

            Assert.IsTrue(Controller.Log.HasErrors);

            var error = Controller.Log.Entries.Last();

            Assert.AreEqual("Error in file 'test' at line 1: Assertion Failed: '5 == 6'", error);

            Controller.Log.ClearAll();

            line.Operand = "5 == 6, \"My custom error!\"";
            LineAssembler.AssembleLine(line);

            Assert.IsTrue(Controller.Log.HasErrors);
            error = Controller.Log.Entries.Last();
            Assert.AreEqual("Error in file 'test' at line 1: My custom error!", error);

            Controller.Log.ClearAll();

            line.Operand = "5 == 5";
            LineAssembler.AssembleLine(line);
            Assert.IsFalse(Controller.Log.HasErrors);
        }
        public void TestConditionals()
        {
            var line = new SourceLine();

            line.LineNumber  = 1;
            line.Filename    = "test";
            line.Instruction = ".errorif";
            line.Operand     = "5 != 6, \"5 doesn't equal 6!\"";
            LineAssembler.AssembleLine(line);

            Assert.IsTrue(Controller.Log.HasErrors);
            var error = Controller.Log.Entries.Last();

            Assert.AreEqual("Error in file 'test' at line 1: 5 doesn't equal 6!", error);
            Controller.Log.ClearAll();

            line.Operand = "5 == 6, \"5 equals 6!\"";
            LineAssembler.AssembleLine(line);

            Assert.IsFalse(Controller.Log.HasErrors);
        }
        public void TestFill()
        {
            var line = new SourceLine();

            line.Instruction = ".byte";
            line.Operand     = "0";
            LineAssembler.AssembleLine(line);
            Assert.IsFalse(Controller.Log.HasErrors);
            Assert.AreEqual(0x0001, Controller.Output.LogicalPC);
            Assert.IsTrue(Controller.Output.GetCompilation().Count == 1);

            // test uninitialized
            line.Instruction = ".fill";
            line.Operand     = "10";
            TestInstruction(line, 0x000b, 10, new byte[] { 0x00 });

            // test uninitialized another way
            line.Operand = "10, ?";
            TestInstruction(line, 0x000a, 10, null);

            // test fill bytes
            line.Operand = "10, $ea";
            TestInstruction(line, 0x000a, 10, new byte[] { 0xea, 0xea, 0xea, 0xea, 0xea,
                                                           0xea, 0xea, 0xea, 0xea, 0xea });

            // test larger size
            line.Operand = "10, $ffd2";
            TestInstruction(line, 0x000a, 10, new byte[] { 0xd2, 0xff, 0xd2, 0xff, 0xd2, 0xff, 0xd2, 0xff, 0xd2, 0xff });

            line.Operand = "10, $112233";
            TestInstruction(line, 0x000a, 10, new byte[] { 0x33, 0x22, 0x11, 0x33, 0x22, 0x11, 0x33, 0x22, 0x11, 0x33 });

            line.Operand = string.Empty;
            TestForFailure <InvalidOperationException>(line);

            line.Operand = "10, $ea, $20";
            TestForFailure(line);
        }
        public void TestEor()
        {
            var pseudoAsm = new PseudoAssembler(Controller, m => false);
            var line      = new SourceLine
            {
                Instruction = ".eor",
                Operand     = "$ff"
            };

            LineAssembler.AssembleLine(line);
            Assert.IsFalse(Controller.Log.HasErrors);

            line.Instruction = ".byte";
            line.Operand     = "$00";
            TestInstruction(line, pseudoAsm, 0x0001, 0x0001, new byte[] { 0xff });

            line.Instruction = ".eor";
            line.Operand     = "-129";
            TestForFailure <OverflowException>(line);

            line.Operand = "256";
            TestForFailure <OverflowException>(line);
        }
        public void TestAlign()
        {
            var line = new SourceLine();

            line.Instruction = ".byte";
            line.Operand     = "0";
            line.PC          = 1;
            LineAssembler.AssembleLine(line);
            Assert.IsFalse(Controller.Log.HasErrors);
            Assert.AreEqual(0x0001, Controller.Output.LogicalPC);
            Assert.IsTrue(Controller.Output.GetCompilation().Count == 1);

            // align to nearest page, uninitialized
            line.Instruction = ".align";
            line.Operand     = "$100";
            TestInstruction(line, 0x0100, 255, new byte[] { 0x00 });

            // align to nearest page, uninitialized
            Controller.Output.SetPC(1);
            line.PC      = 1;
            line.Operand = "$100, ?";
            TestInstruction(line, 0x0100, 255, null);

            // align to nearest 0x10, filled
            Controller.Output.SetPC(0x0006);
            line.PC      = 0x0006;
            line.Operand = "$10, $ea";
            TestInstruction(line, 0x0010, 10, new byte[] { 0xea, 0xea, 0xea, 0xea, 0xea,
                                                           0xea, 0xea, 0xea, 0xea, 0xea });

            line.Operand = string.Empty;
            TestForFailure <InvalidOperationException>(line);

            line.Operand = "$100, $10, $02";
            TestForFailure(line);
        }
        public void TestEncodingDefine()
        {
            var line = new SourceLine();

            line.Instruction = ".encoding";
            line.Operand     = "test";
            LineAssembler.AssembleLine(line);

            line.Instruction = ".map";
            line.Operand     = "\"A\", \"a\"";
            LineAssembler.AssembleLine(line);

            var translated = (char)Controller.Encoding.GetEncodedValue("A");

            Assert.AreEqual('a', translated);

            line.Instruction = ".byte";
            line.Operand     = "'A'";
            TestInstruction(line, 0x0001, 1, new byte[] { (byte)'a' });

            line.Instruction = ".unmap";
            line.Operand     = "$41";
            LineAssembler.AssembleLine(line);

            line.Instruction = ".byte";
            line.Operand     = "'A'";
            TestInstruction(line, 0x0001, 1, new byte[] { (byte)'A' });

            line.Instruction = ".encoding";
            line.Operand     = "none";
            LineAssembler.AssembleLine(line);

            translated = (char)Controller.Encoding.GetEncodedValue("A");
            Assert.AreEqual('A', translated);

            line.Instruction = ".byte";
            line.Operand     = "'A'";
            TestInstruction(line, 0x0001, 1, new byte[] { (byte)'A' });

            line.Instruction = ".encoding";
            line.Operand     = "test";
            LineAssembler.AssembleLine(line);

            line.Instruction = ".map";
            line.Operand     = "\"az\", \"A\"";
            LineAssembler.AssembleLine(line);

            string test = "hello reality";

            line.Instruction = ".string";
            line.Operand     = string.Format("\"{0}\"", test);
            TestInstruction(line, test.Length, test.Length, Encoding.UTF8.GetBytes(test.ToUpper()));

            line.Instruction = ".unmap";
            line.Operand     = "\"az\"";
            LineAssembler.AssembleLine(line);

            line.Instruction = ".string";
            line.Operand     = string.Format("\"{0}\"", test);
            TestInstruction(line, test.Length, test.Length, Encoding.UTF8.GetBytes(test));

            line.Instruction = ".map";
            line.Operand     = "$80, $ff, '\\0'";
            LineAssembler.AssembleLine(line);

            translated = (char)Controller.Encoding.GetEncodedValue("\xc1");
            Assert.AreEqual('A', translated);

            line.Instruction = ".map";
            line.Operand     = "\"π\", $5e";
            LineAssembler.AssembleLine(line);

            line.Instruction = ".byte";
            line.Operand     = "'π'";
            TestInstruction(line, 0x0001, 0x0001, new byte[] { (byte)'^' });

            line.Instruction = ".map";
            line.Operand     = "\"♣\", $d8";
            LineAssembler.AssembleLine(line);

            line.Instruction = ".byte";
            line.Operand     = "'♣'";
            TestInstruction(line, 0x0001, 0x0001, new byte[] { 0xd8 });

            line.Instruction = ".map";
            line.Operand     = "\"▒\", 255";
            LineAssembler.AssembleLine(line);

            line.Instruction = ".byte";
            line.Operand     = "'▒'";
            TestInstruction(line, 0x0001, 0x0001, new byte[] { 0xff });
        }