/// <summary> /// Reads the value stored in memory at address into reg. /// </summary> /// <param name="reg"></param> /// <param name="literal"></param> void Read(Register_t reg, uint16_t literal) { MoveL(Register.MLR, registers.SizeOf(reg)); MoveL(Register.MAR, literal); ReadMemory(); MoveR(reg, Register.MDR); }
/// <summary> /// Reads the value stored in memory at address in regB into regA. /// </summary> /// <param name="regA">Destination of data</param> /// <param name="regB">Memory address</param> void Read(Register_t regA, Register_t regB) { MoveL(Register.MLR, registers.SizeOf(regA)); MoveR(Register.MAR, regB); ReadMemory(); MoveR(regA, Register.MDR); }
void Write(Register_t address, uint16_t value) { MoveR(Register.MAR, address); MoveL(Register.MLR, 2); MoveL(Register.MDR, value); WriteMemory(); }
/// <summary> /// Writes the value in reg to address in literal /// </summary> /// <param name="reg"></param> /// <param name="literal"></param> void Write(uint16_t address, Register_t value) { MoveL(Register.MAR, address); MoveL(Register.MLR, registers.SizeOf(value)); MoveR(Register.MDR, value); WriteMemory(); }
protected override void Decode() { if (!cycleException) { try { operation = opcodes[opcode.Code]; } catch (KeyNotFoundException) { cycleException = true; // TODO: Interrupt with an invalid opcode } if (opcode.Flags.HasFlag(OpcodeFlags.Register1)) { operandA = new Register_t(opcode.OperandA); } if (opcode.Flags.HasFlag(OpcodeFlags.Register2)) { operandB = new Register_t(opcode.OperandB); } if (opcode.Flags.HasFlag(OpcodeFlags.Literal1)) { operandA = opcode.OperandA; } if (opcode.Flags.HasFlag(OpcodeFlags.Literal2)) { operandB = opcode.OperandB; } } }
void sair(Register_t index) { MoveR(Register.AEI, index); MoveR(Register.AEP, index); Multiply(Register.AEP, Register.AEL); Add(Register.AEP, Register.ABP); }
void PushRegister(Register_t reg) { int size = registers.SizeOf(reg); switch (size) { case 8: uint64_t value64 = registers.Read <uint64_t>(reg); System.Diagnostics.Debug.Assert(value64 != null); stack.Push(value64); break; case 4: uint32_t value32 = registers.Read <uint32_t>(reg); System.Diagnostics.Debug.Assert(value32 != null); stack.Push(value32); break; case 2: uint16_t value16 = registers.Read <uint16_t>(reg); System.Diagnostics.Debug.Assert(value16 != null); stack.Push(value16); break; case 1: uint8_t value8 = registers.Read <uint8_t>(reg); System.Diagnostics.Debug.Assert(value8 != null); stack.Push(value8); break; } }
void PushRegister(Register_t reg) { int size = registers.SizeOf(reg); switch (size) { case 8: uint64_t value64 = registers.Read <uint64_t>(reg); stack.Push(value64); break; case 4: uint32_t value32 = registers.Read <uint32_t>(reg); stack.Push(value32); break; case 2: uint16_t value16 = registers.Read <uint16_t>(reg); stack.Push(value16); break; case 1: uint8_t value8 = registers.Read <uint8_t>(reg); stack.Push(value8); break; } }
void ALUOperation(Register_t a, ALU.ALUOperationUnary op) { byte[] opA = registers.Read(a); byte[] result = op(opA); registers.Write(a, result); ALUCopyFlags(); }
void Compare(Register_t a, uint16_t b) { byte[] opA = registers.Read(a); byte[] opB = b.ToBinary(); alu.Compare(opA, opB); ALUCopyCompareFlags(); }
void Compare(Register_t a, Register_t b) { byte[] opA = registers.Read(a); byte[] opB = registers.Read(b); alu.Compare(opA, opB); ALUCopyCompareFlags(); }
void ALUOperation(Register_t a, uint16_t b, ALU.ALUOperation op) { byte[] opA = registers.Read(a); byte[] opB = b.ToBinary(); bool overflow; byte[] result = op(opA, opB, out overflow); registers.Write(a, result); ALUCopyFlags(); }
void Pop(Register_t reg) { ushort size = registers.SizeOf(reg); if (stack.Peek().Length > size) { // Throw a value indicating that the source value is larger than the destination register throw new Exception("Source larger than destination."); } else { registers.Write(reg, stack.Pop().ToBinary()); } }
void Divide(Register_t a, uint16_t b) { ALUOperation(a, b, new ALU.ALUOperation(alu.Divide)); }
void intr(Register_t r) { uint16_t value = registers.Read <uint16_t>(r); Interrupt(value.Value); }
void Mod(Register_t a, Register_t b) { ALUOperation(a, b, new ALU.ALUOperation(alu.Mod)); }
void sarr(Register_t baseAddress, Register_t elementSize) { sall(registers.Read <uint32_t>(baseAddress).CastTo <uint16_t>(), registers.Read <uint32_t>(elementSize).CastTo <uint16_t>()); }
void Or(Register_t a, Register_t b) { ALUOperation(a, b, new ALU.ALUOperation(alu.Or)); }
void And(Register_t a, uint16_t b) { ALUOperation(a, b, new ALU.ALUOperation(alu.And)); }
void Not(Register_t a) { ALUOperation(a, new ALU.ALUOperationUnary(alu.Not)); }
void LeftShift(Register_t a, uint16_t b) { ALUOperation(a, b, new ALU.ALUOperation(alu.LeftShift)); }
/// <summary> /// Moves a value from one register to another. /// </summary> /// <param name="to"></param> /// <param name="from"></param> void MoveR(Register_t to, Register_t from) { registers.Move(to, from); }
/// <summary> /// Moves a literal into a register. /// </summary> /// <param name="to"></param> /// <param name="literal"></param> void MoveL(Register_t to, uint16_t literal) { registers.Write(to, literal); }
/// <summary> /// Dereferences the pointer in literal and stores the result in reg /// </summary> /// <param name="reg"></param> /// <param name="literal"></param> void Deref(Register_t reg, uint16_t literal) { MoveL(reg, literal); Read(reg, reg); }
/// <summary> /// Dereferences the pointer in regB and stores the result in regA /// </summary> /// <param name="regA"></param> /// <param name="regB"></param> void Deref(Register_t regA, Register_t regB) { MoveR(regA, regB); Read(regA, regA); }
void Subtract(Register_t a, uint16_t b) { ALUOperation(a, b, new ALU.ALUOperation(alu.Subtract)); }
void Multiply(Register_t a, uint16_t b) { ALUOperation(a, b, new ALU.ALUOperation(alu.Multiply)); }
void Xor(Register_t a, uint16_t b) { ALUOperation(a, b, new ALU.ALUOperation(alu.Xor)); }
void RightShift(Register_t a, Register_t b) { ALUOperation(a, b, new ALU.ALUOperation(alu.RightShift)); }
void Neg(Register_t a) { ALUOperation(a, new ALU.ALUOperationUnary(alu.Negate)); }