public void Generate()
{
foreach(var instruction in Instructions)
{
var opcodes = instruction.Opcode.GetAttributes<OpcodeAttribute>();
var opcode = opcodes.Where(x => x.AddressingMode == instruction.AddressingMode).First();
switch(instruction.AddressingMode)
{
// Instruction size of 1
case CpuAddressingMode.Implied:
_stream.WriteByte(opcode.Opcode);
break;
case CpuAddressingMode.Immediate:
case CpuAddressingMode.Direct:
case CpuAddressingMode.Absolute:
case CpuAddressingMode.Relative:
{
_stream.WriteByte(opcode.Opcode);
if (instruction.Arguments[0] is NumberInstructionArgument)
{
var numberArgument = instruction.Arguments[0] as NumberInstructionArgument;
if (numberArgument.Size == ArgumentSize.Word
|| numberArgument.Size == ArgumentSize.LongWord)
{
writeWord(numberArgument.Number);
}
else
{
_stream.WriteByte((byte)numberArgument.Number);
}
}
else if (instruction.Arguments[0] is LabelInstructionArgument)
{
var labelArgument = instruction.Arguments[0] as LabelInstructionArgument;
long labelPhysicalAddress = Scope.AddressFor(labelArgument.Label);
if (instruction.AddressingMode == CpuAddressingMode.Relative)
{
byte relativeAddress = Convert.ToByte((labelPhysicalAddress - (_stream.Position + 1)) & 0xFF);
_stream.WriteByte(relativeAddress);
}
else if (instruction.AddressingMode == CpuAddressingMode.Absolute)
{
int ramAddress = CpuAddressConverter.PhysicalToRAM((int)labelPhysicalAddress, Header.MapMode, Header.RomSpeed);
writeWord(ramAddress & 0xFFFF);
}
}
break;
}
}
}
}
public void ShouldGenerateAbsoluteInstruction(CpuInstructions opcodeEnum, byte finalOpcode, int value) { CpuInstructionStatement instruction = new CpuInstructionStatement(); instruction.AddressingMode = CpuAddressingMode.Absolute; instruction.Opcode = opcodeEnum; instruction.Arguments.Add(new NumberInstructionArgument(value, ArgumentSize.Word)); 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]); }