This commit is contained in:
Rose Apollo 2024-04-22 11:08:57 +00:00
parent 062b44b4f1
commit b30a4b1832
8 changed files with 171 additions and 3 deletions

View File

@ -1,6 +1,64 @@
#include "./instruction.h" #include "./instruction.h"
#include "../cpu_human.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <inttypes.h>
void LogInstructionData(CpuInstructions instruction, ArgumentInfo arg1Info,
ArgumentInfo arg2Info, r16_int arg1, r16_int arg2,
r16_int arg1Val, r16_int arg2Val)
{
char *hReadIns = CpuInstructionsHumanReadable[instruction],
*hReadA1I = ArgumentInfoHumanReadable[arg1Info],
*hReadA2I = ArgumentInfoHumanReadable[arg1Info],
*actArg1 = malloc(sizeof(char) * 32),
*actArg2 = malloc(sizeof(char) * 32),
*hReadA1 = malloc(sizeof(char) * 32),
*hReadA2 = malloc(sizeof(char) * 32);
sprintf(actArg1, "0x%X", arg2Val.u);
sprintf(actArg2, "0x%X", arg2Val.u);
switch (arg1Info)
{
case value:
hReadA1 = "~";
break;
case valueInRam:
sprintf(hReadA1, "0x%X", arg1.u);
break;
case valueInRegister:
hReadA1 = CpuRegistersHumanReadable[arg1.u];
break;
case pointerInRegister:
sprintf(hReadA1, "%s ~ 0x%X", CpuRegistersHumanReadable[arg1.u], GetRegister(arg1.u).u);
break;
}
switch (arg2Info)
{
case value:
hReadA2 = "~";
break;
case valueInRam:
sprintf(hReadA2, "0x%X", arg2.u);
break;
case valueInRegister:
hReadA2 = CpuRegistersHumanReadable[arg2.u];
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);
free(actArg1);
free(actArg2);
free(hReadA1);
free(hReadA2);
}
r16_int GetArgVal(ArgumentInfo argInfo, r16_int arg) r16_int GetArgVal(ArgumentInfo argInfo, r16_int arg)
{ {
@ -34,71 +92,91 @@ void ExecuteInstruction(CpuInstructions instruction, ArgumentInfo arg1Info,
{ {
case HLT: case HLT:
printf("\nprogram HALTED!\n"); printf("\nprogram HALTED!\n");
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, (r16_int){ 0 }, (r16_int){ 0 });
exit(0); exit(0);
case ADD: case ADD:
GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2); GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2);
SetRegister(ACU, (r16_int){ actArg1.s + actArg2.s }); SetRegister(ACU, (r16_int){ actArg1.s + actArg2.s });
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, actArg2);
break; break;
case SUB: case SUB:
GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2); GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2);
SetRegister(ACU, (r16_int){ actArg1.s - actArg2.s }); SetRegister(ACU, (r16_int){ actArg1.s - actArg2.s });
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, actArg2);
break; break;
case MUL: case MUL:
GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2); GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2);
SetRegister(ACU, (r16_int){ actArg1.s * actArg2.s }); SetRegister(ACU, (r16_int){ actArg1.s * actArg2.s });
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, actArg2);
break; break;
case DIV: case DIV:
GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2); GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2);
SetRegister(ACU, (r16_int){ actArg1.s / actArg2.s }); SetRegister(ACU, (r16_int){ actArg1.s / actArg2.s });
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, actArg2);
break; break;
case LBS: case LBS:
GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2); GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2);
SetRegister(ACU, (r16_int){ actArg1.s << actArg2.s }); SetRegister(ACU, (r16_int){ actArg1.s << actArg2.s });
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, actArg2);
break; break;
case RBS: case RBS:
GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2); GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2);
SetRegister(ACU, (r16_int){ actArg1.s >> actArg2.s }); SetRegister(ACU, (r16_int){ actArg1.s >> actArg2.s });
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, actArg2);
break; break;
case BAN: case BAN:
GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2); GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2);
SetRegister(ACU, (r16_int){ actArg1.u & actArg2.u }); SetRegister(ACU, (r16_int){ actArg1.u & actArg2.u });
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, actArg2);
break; break;
case BOR: case BOR:
GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2); GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2);
SetRegister(ACU, (r16_int){ actArg1.u | actArg2.u }); SetRegister(ACU, (r16_int){ actArg1.u | actArg2.u });
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, actArg2);
break; break;
case BXO: case BXO:
GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2); GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2);
SetRegister(ACU, (r16_int){ actArg1.u ^ actArg2.u }); SetRegister(ACU, (r16_int){ actArg1.u ^ actArg2.u });
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, actArg2);
break; break;
case BNO: case BNO:
SetRegister(ACU, (r16_int){ ~ GetArgVal(arg1Info, arg1).u }); actArg1 = GetArgVal(arg1Info, arg1);
SetRegister(ACU, (r16_int){ ~ actArg1.u });
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, (r16_int){ 0 });
break; break;
case PUS: case PUS:
StackPush(GetArgVal(arg1Info, arg1)); actArg1 = GetArgVal(arg1Info, arg1);
StackPush(actArg1);
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, (r16_int){ 0 });
break; break;
case POP: case POP:
SetRegister(ACU, StackPop()); SetRegister(ACU, StackPop());
break; break;
case JMP: case JMP:
SetRegister(PC, GetArgVal(arg1Info, arg1)); SetRegister(PC, GetArgVal(arg1Info, arg1));
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, (r16_int){ 0 }, (r16_int){ 0 });
break; break;
case JEQ: case JEQ:
GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2); GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2);
if (actArg2.u == GetRegister(ACU).u) if (actArg2.u == GetRegister(ACU).u)
SetRegister(PC, actArg1); SetRegister(PC, actArg1);
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, actArg2);
break; break;
case JNZ: case JNZ:
GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2); GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2);
if (actArg2.s != 0) if (actArg2.s != 0)
SetRegister(PC, actArg1); SetRegister(PC, actArg1);
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, actArg2);
break; break;
case CAL: case CAL:
actArg1 = GetArgVal(arg1Info, arg1);
StackPush(GetRegister(PC)); StackPush(GetRegister(PC));
SetRegister(PC, GetArgVal(arg1Info, arg1)); SetRegister(PC, actArg1);
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, (r16_int){ 0 });
break; break;
case RET: case RET:
SetRegister(PC, StackPop()); SetRegister(PC, StackPop());
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, (r16_int){ 0 }, (r16_int){ 0 });
break; break;
case REG: // TODO case REG: // TODO
case INT: // TODO case INT: // TODO
@ -106,9 +184,12 @@ void ExecuteInstruction(CpuInstructions instruction, ArgumentInfo arg1Info,
exit(-1); exit(-1);
case INP: case INP:
SetRegister(ACU, (r16_int){ getchar() }); SetRegister(ACU, (r16_int){ getchar() });
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, (r16_int){ 0 }, (r16_int){ 0 });
break; break;
case OUT: case OUT:
actArg1 = GetArgVal(arg1Info, arg1);
putchar((char)(GetArgVal(arg1Info, arg1).u)); putchar((char)(GetArgVal(arg1Info, arg1).u));
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, (r16_int){ 0 });
break; break;
case DIN: // TODO case DIN: // TODO
case DOT: // TODO case DOT: // TODO
@ -117,6 +198,7 @@ void ExecuteInstruction(CpuInstructions instruction, ArgumentInfo arg1Info,
case MOV: case MOV:
GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2); GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2);
SetValue(actArg1, actArg2); SetValue(actArg1, actArg2);
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, actArg2);
break; break;
} }
} }

View File

@ -8,5 +8,8 @@
void ExecuteInstruction(CpuInstructions instruction, ArgumentInfo arg1Info, void ExecuteInstruction(CpuInstructions instruction, ArgumentInfo arg1Info,
ArgumentInfo arg2Info, r16_int arg1, r16_int arg2); ArgumentInfo arg2Info, r16_int arg1, r16_int arg2);
void LogInstructionData(CpuInstructions instruction, ArgumentInfo arg1Info,
ArgumentInfo arg2Info, r16_int arg1, r16_int arg2,
r16_int arg1Val, r16_int arg2Val);
#endif #endif

View File

@ -1,8 +1,15 @@
#include "./register.h" #include "./register.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h>
r16_int r0, r1, r2, r3, acu, pc, sp; r16_int r0, r1, r2, r3, acu, pc, sp;
void LogRegisters()
{
printf(" r0: 0x%X\n r1: 0x%X\n r2: 0x%X\n r3: 0x%X\nACU: 0x%X\n PC: 0x%X\n SP: 0x%X\n",
r0.u, r1.u, r2.u, r3.u, acu.u, pc.u, sp.u);
}
r16_int *GetRegPoint(CpuRegisters reg) r16_int *GetRegPoint(CpuRegisters reg)
{ {
switch (reg) switch (reg)

View File

@ -4,6 +4,7 @@
#include "../cpu_const.h" #include "../cpu_const.h"
#include "./ram.h" #include "./ram.h"
void LogRegisters();
r16_int GetRegister(CpuRegisters reg); r16_int GetRegister(CpuRegisters reg);
void SetRegister(CpuRegisters reg, r16_int value); void SetRegister(CpuRegisters reg, r16_int value);

View File

@ -1,6 +1,20 @@
#include "./stack.h" #include "./stack.h"
#include "./register.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <stdbool.h>
void LogStack(bool onlyUpToSP, bool pointOutSP)
{
char *pointer = "->";
char *nointer = " ";
for (int i = 0; i < (onlyUpToSP ? GetRegister(SP).u : STACK_SIZE); i++)
{
printf("%s 0x%x: 0x%x\n", ((pointOutSP && i == GetRegister(SP).u) ? pointer : nointer),
i, GetValue((r16_int){ STACK_LOCATION + i }).u);
}
}
r16_int StackPop() r16_int StackPop()
{ {

View File

@ -55,4 +55,8 @@ typedef enum
#define INSTRUCTION_ARG_1_INFO_MASK 0b0011000000000000 #define INSTRUCTION_ARG_1_INFO_MASK 0b0011000000000000
#define INSTRUCTION_ARG_2_INFO_MASK 0b1100000000000000 #define INSTRUCTION_ARG_2_INFO_MASK 0b1100000000000000
#define R16 "Reduced 16 bit CPU"
#define R16_AUTHOR "Rose Apollo"
#define R16_STANDARD "r16_0 version 1"
#endif #endif

53
emu/cpu_human.h Normal file
View File

@ -0,0 +1,53 @@
#ifndef EMU_CPU_HUMAN_H
#define EMU_CPU_HUMAN_H
char CpuRegistersHumanReadable[9][4] =
{
"R0",
"R1",
"R2",
"R3",
"R4",
"ACU",
"PC",
"SP"
};
char ArgumentInfoHumanReadable[4][21] =
{
"Value",
"Value in register",
"Value in ram",
"Pointer in register"
};
char CpuInstructionsHumanReadable[25][4] =
{
"HLT",
"ADD",
"SUB",
"MUL",
"DIV",
"LBS",
"RBS",
"BAN",
"BOR",
"BXO",
"BNO",
"PUS",
"POP",
"JMP",
"JEQ",
"JNZ",
"CAL",
"RET",
"REG",
"INT",
"INP",
"OUT",
"DIN",
"DOT",
"MOV"
};
#endif

View File

@ -8,7 +8,11 @@
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
printf("R16 " R16 "\n" R16_STANDARD "\n(c) " R16_AUTHOR "\n");
carg_parse_data* args = carg_parse(argc, argv); carg_parse_data* args = carg_parse(argc, argv);
carg_parse_free(args); carg_parse_free(args);
return 0;
} }