#include "./instruction.h" #include "../cpu_human.h" #include #include #include #include #include bool LogInstructionData(CpuInstructions instruction, ArgumentInfo arg1Info, ArgumentInfo arg2Info, r16_int arg1, r16_int arg2, r16_int arg1Val, r16_int arg2Val) { #ifdef LOG_INSTRUCTION_DATA char *hReadIns = CpuInstructionsHumanReadable[instruction], *hReadA1I = ArgumentInfoHumanReadable[arg1Info], *hReadA2I = ArgumentInfoHumanReadable[arg2Info], actArg1[32] = { 0 }, actArg2[32] = { 0 }, hReadA1[32] = { 0 }, hReadA2[32] = { 0 }; sprintf(actArg1, "0x%X", arg1Val.u); sprintf(actArg2, "0x%X", arg2Val.u); switch (arg1Info) { case value: hReadA1[0] = '~'; break; case valueInRam: sprintf(hReadA1, "0x%X", arg1.u); break; case valueInRegister: strncpy(hReadA1, CpuRegistersHumanReadable[arg1.u], 31); break; case pointerInRegister: sprintf(hReadA1, "%s ~ 0x%X", CpuRegistersHumanReadable[arg1.u], GetRegister(arg1.u).u); break; } switch (arg2Info) { case value: hReadA2[0] = '~'; break; case valueInRam: sprintf(hReadA2, "0x%X", arg2.u); break; case valueInRegister: strncpy(hReadA2, CpuRegistersHumanReadable[arg2.u], 31); break; case pointerInRegister: sprintf(hReadA2, "%s ~ 0x%X", CpuRegistersHumanReadable[arg2.u], GetRegister(arg2.u).u); break; } printf("%s :: (%s) %s -> %s, (%s) %s -> %s\n", hReadIns, hReadA1I, hReadA1, actArg1, hReadA2I, hReadA2, actArg2); return true; #else return false; #endif } 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; GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2); LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, actArg2); switch (instruction) { case HLT: printf("\nprogram HALTED!\n"); exit(0); case ADD: SetRegister(ACU, (r16_int){ actArg1.s + actArg2.s }); break; case SUB: SetRegister(ACU, (r16_int){ actArg1.s - actArg2.s }); break; case MUL: SetRegister(ACU, (r16_int){ actArg1.s * actArg2.s }); break; case DIV: if (actArg2.s == 0) { fprintf(stderr, "DIV by 0\n"); exit(-1); } SetRegister(ACU, (r16_int){ actArg1.s / actArg2.s }); break; case LBS: SetRegister(ACU, (r16_int){ actArg1.s << actArg2.s }); break; case RBS: SetRegister(ACU, (r16_int){ actArg1.s >> actArg2.s }); break; case BAN: SetRegister(ACU, (r16_int){ actArg1.u & actArg2.u }); break; case BOR: SetRegister(ACU, (r16_int){ actArg1.u | actArg2.u }); break; case BXO: SetRegister(ACU, (r16_int){ actArg1.u ^ actArg2.u }); break; case BNO: SetRegister(ACU, (r16_int){ ~ actArg1.u }); break; case PUS: StackPush(actArg1); break; case POP: SetRegister(ACU, StackPop()); break; case JMP: SetRegister(PC, GetArgVal(arg1Info, arg1)); break; case JEQ: if (actArg2.u == GetRegister(ACU).u) SetRegister(PC, actArg1); break; case JNZ: if (actArg2.s != 0) SetRegister(PC, actArg1); break; case CAL: StackPush(GetRegister(PC)); SetRegister(PC, actArg1); 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: SetValue(actArg1, actArg2); break; } }