122 lines
4.1 KiB
C
122 lines
4.1 KiB
C
#include "./instruction.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
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;
|
|
}
|
|
} |