#include "./instruction.h" #include #include r16_int GetArgVal(ArgumentInfo argInfo, r16_int arg) { switch (argInfo) { case value: return arg; case valueInRegister: return GetRegister((CpuRegisters)arg.u); case valueInRam: return GetValue(arg); case pointerInRegister: return GetValue(GetRegister((CpuRegisters)arg.u)); } } void GetAllArgVal(ArgumentInfo arg1Info, ArgumentInfo arg2Info, r16_int arg1, r16_int arg2, r16_int *arg1Out, r16_int *arg2Out) { *arg1Out = GetArgVal(arg1Info, arg1); *arg2Out = GetArgVal(arg2Info, arg2); } void ExecuteInstruction(CpuInstructions instruction, ArgumentInfo arg1Info, ArgumentInfo arg2Info, r16_int arg1, r16_int arg2) { r16_int actArg1, actArg2; switch (instruction) { case HLT: printf("\nprogram HALTED!\n"); exit(0); case ADD: GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2); SetRegister(ACU, (r16_int){ actArg1.s + actArg2.s }); break; case SUB: GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2); SetRegister(ACU, (r16_int){ actArg1.s - actArg2.s }); break; case MUL: GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2); SetRegister(ACU, (r16_int){ actArg1.s * actArg2.s }); break; case DIV: GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2); SetRegister(ACU, (r16_int){ actArg1.s / actArg2.s }); break; case LBS: GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2); SetRegister(ACU, (r16_int){ actArg1.s << actArg2.s }); break; case RBS: GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2); SetRegister(ACU, (r16_int){ actArg1.s >> actArg2.s }); break; case BAN: GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2); SetRegister(ACU, (r16_int){ actArg1.u & actArg2.u }); break; case BOR: GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2); SetRegister(ACU, (r16_int){ actArg1.u | actArg2.u }); break; case BXO: GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2); SetRegister(ACU, (r16_int){ actArg1.u ^ actArg2.u }); break; case BNO: SetRegister(ACU, (r16_int){ ~ GetArgVal(arg1Info, arg1).u }); break; case PUS: StackPush(GetArgVal(arg1Info, arg1)); break; case POP: SetRegister(ACU, StackPop()); break; case JMP: SetRegister(PC, GetArgVal(arg1Info, arg1)); break; case JEQ: GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2); if (actArg2.u == GetRegister(ACU).u) SetRegister(PC, actArg1); break; case JNZ: GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2); if (actArg2.s != 0) SetRegister(PC, actArg1); break; case CAL: StackPush(GetRegister(PC)); SetRegister(PC, GetArgVal(arg1Info, arg1)); break; case RET: SetRegister(PC, StackPop()); break; case REG: // TODO case INT: // TODO fprintf(stderr, "INTS NOT IMPLEMENTED YET\n"); exit(-1); case INP: SetRegister(ACU, (r16_int){ getchar() }); break; case OUT: putchar((char)(GetArgVal(arg1Info, arg1).u)); break; case DIN: // TODO case DOT: // TODO fprintf(stderr, "DISK NOT IMPLEMENTED YET\n"); exit(-1); case MOV: GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2); SetValue(actArg1, actArg2); break; } }