Example #1
0
        public void ShouldGenerateRelativeInstructionsWithLabel()
        {
            string input = @"procedure Test
{
    php

backwardBranch:
    sec
    bvs backwardBranch
    lda #$03
    bra forwardBranch
    tax
    tay

forwardBranch:
    rts
}
";

            ZealCpuDriver driver = new ZealCpuDriver(input.ToMemoryStream());

            driver.Parse();

            MemoryStream     memoryStream = new MemoryStream(32);
            CpuCodeGenerator generator    = new CpuCodeGenerator(memoryStream);

            generator.Instructions = driver.GlobalScope.Children[0].Statements.Where(x => x is CpuInstructionStatement).Select(x => x as CpuInstructionStatement).ToList();
            generator.Scope        = driver.GlobalScope.Children[0];
            generator.Generate();

            Assert.Equal(0xFD, memoryStream.GetBuffer()[3]);
            Assert.Equal(0x02, memoryStream.GetBuffer()[7]);
        }
Example #2
0
        public void ShouldGenerateAbsoluteInstructionsWithLabel()
        {
            string input = @"procedure Test
{
    php

mainLoop:
    jmp mainLoop
}
";

            ZealCpuDriver driver = new ZealCpuDriver(input.ToMemoryStream());

            driver.Parse();

            RomHeader fakeHeader = new RomHeader();

            fakeHeader.MapMode  = MapMode.LoROM;
            fakeHeader.RomSpeed = RomSpeed.SlowROM;

            MemoryStream     memoryStream = new MemoryStream(32);
            CpuCodeGenerator generator    = new CpuCodeGenerator(memoryStream);

            generator.Instructions = driver.GlobalScope.Children[0].Statements.Where(x => x is CpuInstructionStatement).Select(x => x as CpuInstructionStatement).ToList();
            generator.Scope        = driver.GlobalScope.Children[0];
            generator.Header       = fakeHeader;
            generator.Generate();

            Assert.Equal(0x01, memoryStream.GetBuffer()[2]);
            Assert.Equal(0x80, memoryStream.GetBuffer()[3]);
        }
Example #3
0
        public void ShouldGenerateImmediateInstruction(CpuInstructions opcodeEnum, byte finalOpcode, int value)
        {
            CpuInstructionStatement instruction = new CpuInstructionStatement();

            instruction.AddressingMode = CpuAddressingMode.Immediate;
            instruction.Opcode         = opcodeEnum;
            if (value > byte.MaxValue)
            {
                instruction.Arguments.Add(new NumberInstructionArgument(value, ArgumentSize.Word));
            }
            else
            {
                instruction.Arguments.Add(new NumberInstructionArgument(value, ArgumentSize.Byte));
            }

            List <CpuInstructionStatement> instructions = new List <CpuInstructionStatement>();

            instructions.Add(instruction);

            MemoryStream     memoryStream = new MemoryStream(8);
            CpuCodeGenerator generator    = new CpuCodeGenerator(memoryStream);

            generator.Instructions = instructions;
            generator.Generate();

            Assert.Equal(finalOpcode, memoryStream.GetBuffer()[0]);
            Assert.Equal((byte)(value & 0xFF), memoryStream.GetBuffer()[1]);
            Assert.Equal((byte)(value >> 8), memoryStream.GetBuffer()[2]);
        }
Example #4
0
        public void ShouldGenerateImpliedInstruction(CpuInstructions opcodeEnum, byte finalOpcode)
        {
            CpuInstructionStatement instruction = new CpuInstructionStatement();

            instruction.AddressingMode = CpuAddressingMode.Implied;
            instruction.Opcode         = opcodeEnum;

            List <CpuInstructionStatement> instructions = new List <CpuInstructionStatement>();

            instructions.Add(instruction);

            MemoryStream     memoryStream = new MemoryStream(8);
            CpuCodeGenerator generator    = new CpuCodeGenerator(memoryStream);

            generator.Instructions = instructions;
            generator.Generate();

            Assert.Equal(finalOpcode, memoryStream.GetBuffer()[0]);
        }
Example #5
0
        static int Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.Error.WriteLine("No source file provided.");
                return(1);
            }

            if (Path.GetExtension(args[0]) != ".zcpu")
            {
                Console.Error.WriteLine("The source file is in the wrong format. The source file must ends with .zcpu.");
                return(1);
            }

            ZealCpuDriver driver = new ZealCpuDriver(args[0]);

            try
            {
                driver.Parse();
                driver.SecondPass();
            }
            catch (CompilerErrorException)
            {
                foreach (var error in driver.Errors)
                {
                    printErrorMessage(error);
                }

#if DEBUG
                Console.Read();
#endif

                return(1);
            }

            FileStream outputRom = new FileStream(Path.ChangeExtension(args[0], ".sfc"), FileMode.Create);

            CpuCodeGenerator codeGenerator = new CpuCodeGenerator(outputRom);
            codeGenerator.Header = driver.Header;

            foreach (var scope in driver.GlobalScope.Children)
            {
                codeGenerator.Scope = scope;

                List <CpuInstructionStatement> instructions = new List <CpuInstructionStatement>();

                foreach (var statement in scope.Statements)
                {
                    if (statement is CpuInstructionStatement)
                    {
                        instructions.Add((CpuInstructionStatement)statement);
                    }
                }

                codeGenerator.Instructions = instructions;
                codeGenerator.Generate();
            }

            SfcRomWriter romWriter = new SfcRomWriter(outputRom);
            romWriter.Driver = driver;
            romWriter.Write();

            outputRom.Close();

            using (FileStream newRom = new FileStream(Path.ChangeExtension(args[0], ".sfc"), FileMode.Open))
            {
                SfcRomWriter checksumWriter = new SfcRomWriter(newRom);
                checksumWriter.Driver = driver;
                checksumWriter.ComputeChecksum();
            }

            return(0);
        }