public void Start() { SetBank(0); SetInstructionPointer(0); var context = new ExecutionContext(_program); try { while (true) { int address = GetCurrentInstructionAddress(); context.SetInstructionAddress(address); context.Opcode = (Opcode)context.GetNextByte(); context.ResultStatus = InstructionStatus.NotImplemented; ExecutionCycle(context); } } catch (McuException /*mex*/) { // TODO } }
private void Process_UNARY(ExecutionContext context) { const byte v = (byte)UnaryArg.V; bool useVar = ((byte)context.Opcode & v) == v; byte opArg = context.GetNextByte(); int value = useVar ? GetVariable(opArg) : GetMemoryByPointer(opArg); switch (context.Opcode) { case Opcode.RU_INC_V: case Opcode.RU_INC_M: value++; if (value > 255) { value %= 256; SetCarryBit(true); } else { SetCarryBit(false); } SetZeroBit(value == 0); context.ResultStatus = InstructionStatus.Normal; break; case Opcode.RU_DEC_V: case Opcode.RU_DEC_M: break; case Opcode.RU_NOT_V: case Opcode.RU_NOT_M: break; case Opcode.RU_ROL_V: case Opcode.RU_ROL_M: break; case Opcode.RU_ROR_V: case Opcode.RU_ROR_M: break; default: throw new McuException(); } if (useVar) { SetVariable(opArg, (byte)value); } else { SetMemoryByPointer(opArg, (byte)value); } }
private void Process_FLOW(ExecutionContext context) { switch (context.Opcode) { case Opcode.VO_NOP: context.ResultStatus = InstructionStatus.Normal; break; case Opcode.VO_STOP: break; case Opcode.VO_RET: break; case Opcode.UO_JMP_C: case Opcode.UO_JMP_V: case Opcode.BO_JMP_FAR: byte ip; switch ((FlowJumpAddress)((byte)context.Opcode - FlowCommand.JMP)) { case FlowJumpAddress.C: ip = context.GetNextByte(); break; case FlowJumpAddress.V: ip = GetVariable(context.GetNextByte()); break; case FlowJumpAddress.FAR: ip = context.GetNextByte(); SetBank(context.GetNextByte()); break; default: throw new McuException(); } SetInstructionPointer(ip); context.ResultStatus = InstructionStatus.Jumped; break; case Opcode.UO_JZ_C: case Opcode.UO_JZ_V: case Opcode.BO_JZ_FAR: break; case Opcode.UO_JNZ_C: case Opcode.UO_JNZ_V: case Opcode.BO_JNZ_FAR: break; case Opcode.UO_CALL_C: case Opcode.UO_CALL_V: case Opcode.BO_CALL_FAR: break; default: throw new McuException(); } }