NOP, CMP, JMP ok. JEQ maybe not

This commit is contained in:
xamidev
2024-10-18 23:32:44 +02:00
parent 68bda98d1a
commit 14e8802497
2 changed files with 63 additions and 26 deletions

74
cpu.c
View File

@@ -24,6 +24,7 @@
typedef enum typedef enum
{ {
// TODO: Bitwise operations (OR, AND, XOR, NOT, ...) // TODO: Bitwise operations (OR, AND, XOR, NOT, ...)
NOP = 0,
MOV = 1, MOV = 1,
ADD, ADD,
SUB, SUB,
@@ -47,6 +48,7 @@ typedef struct
uint16_t pc; uint16_t pc;
bool halted; bool halted;
bool equal_flag; bool equal_flag;
int flag_clear_delay;
} CPU_t; } CPU_t;
CPU_t cpu; CPU_t cpu;
@@ -59,6 +61,8 @@ void cpu_init()
{ {
cpu.pc = 0; cpu.pc = 0;
cpu.halted = false; cpu.halted = false;
cpu.equal_flag = false;
cpu.flag_clear_delay = 0;
for (size_t i=0; i<NUM_REGISTERS; i++) for (size_t i=0; i<NUM_REGISTERS; i++)
{ {
cpu.reg[i] = 0; cpu.reg[i] = 0;
@@ -73,8 +77,19 @@ void cpu_exec(uint8_t opcode)
{ {
uint8_t reg1, reg2, addr; uint8_t reg1, reg2, addr;
if (cpu.flag_clear_delay > 0)
{
cpu.flag_clear_delay--;
if (cpu.flag_clear_delay == 0)
{
cpu.equal_flag = false;
}
}
switch (opcode) switch (opcode)
{ {
case NOP:
break;
case MOV: case MOV:
reg1 = cpu.memory[cpu.pc++]; reg1 = cpu.memory[cpu.pc++];
reg2 = cpu.memory[cpu.pc++]; reg2 = cpu.memory[cpu.pc++];
@@ -93,6 +108,7 @@ void cpu_exec(uint8_t opcode)
cpu.pc = addr; cpu.pc = addr;
break; break;
case JEQ: case JEQ:
reg1 = cpu.memory[cpu.pc++];
addr = cpu.memory[cpu.pc++]; addr = cpu.memory[cpu.pc++];
if (cpu.equal_flag) { if (cpu.equal_flag) {
cpu.pc = addr; cpu.pc = addr;
@@ -101,11 +117,8 @@ void cpu_exec(uint8_t opcode)
case CMP: case CMP:
reg1 = cpu.memory[cpu.pc++]; reg1 = cpu.memory[cpu.pc++];
reg2 = cpu.memory[cpu.pc++]; reg2 = cpu.memory[cpu.pc++];
if (cpu.reg[reg1] == cpu.reg[reg2]) { cpu.equal_flag = (cpu.reg[reg1] == cpu.reg[reg2]);
cpu.equal_flag = true; cpu.flag_clear_delay = 2;
} else {
cpu.equal_flag = false;
}
break; break;
// TODO: complete instruction set // TODO: complete instruction set
default: default:
@@ -147,47 +160,64 @@ void assemble(const char* filename)
while (fgets(line, sizeof(line), fp)) while (fgets(line, sizeof(line), fp))
{ {
char instruction[10]; char instruction[10] = {0};
int reg1, reg2, addr; char reg1[10] = {0};
char reg2[10] = {0};
int addr;
if (strncmp(line, ";", 1) == 0) if (strncmp(line, ";", 1) == 0)
{ {
// comment, ignore // comment, ignore
continue; continue;
} }
else if (sscanf(line, "%s %d %d", instruction, &reg1, &reg2) == 3) else if (sscanf(line, "%s %[^,], %s", instruction, reg1, reg2) == 3)
{ {
int reg1_n = reg1[1] - '0';
int reg2_n = reg2[1] - '0';
if (strncmp(instruction, "MOV", 3) == 0) if (strncmp(instruction, "MOV", 3) == 0)
{ {
cpu.memory[mem_index++] = MOV; cpu.memory[mem_index++] = MOV;
cpu.memory[mem_index++] = reg1; cpu.memory[mem_index++] = reg1_n;
cpu.memory[mem_index++] = reg2; cpu.memory[mem_index++] = reg2_n;
} else if (strncmp(instruction, "ADD", 3) == 0) } else if (strncmp(instruction, "ADD", 3) == 0)
{ {
cpu.memory[mem_index++] = ADD; cpu.memory[mem_index++] = ADD;
cpu.memory[mem_index++] = reg1; cpu.memory[mem_index++] = reg1_n;
cpu.memory[mem_index++] = reg2; cpu.memory[mem_index++] = reg2_n;
} else if (strncmp(instruction, "CMP", 3) == 0) } else if (strncmp(instruction, "CMP", 3) == 0)
{ {
cpu.memory[mem_index++] = CMP; cpu.memory[mem_index++] = CMP;
cpu.memory[mem_index++] = reg1; cpu.memory[mem_index++] = reg1_n;
cpu.memory[mem_index++] = reg2; cpu.memory[mem_index++] = reg2_n;
} }
} else if (sscanf(line, "%s %d", instruction, &addr) == 2) } else if (sscanf(line, "%s %[^,], %d", instruction, reg1, &addr) == 2)
{
int reg1_n = reg1[1] - '0';
if (strncmp(instruction, "JEQ", 3) == 0)
{
cpu.memory[mem_index++] = JEQ;
cpu.memory[mem_index++] = reg1_n;
cpu.memory[mem_index++] = addr;
}
else if (sscanf(line, "%s %d", instruction, &addr) == 2)
{ {
if (strncmp(instruction, "JMP", 3) == 0) if (strncmp(instruction, "JMP", 3) == 0)
{ {
cpu.memory[mem_index++] = JMP; cpu.memory[mem_index++] = JMP;
cpu.memory[mem_index++] = addr; cpu.memory[mem_index++] = addr;
} else if (strncmp(instruction, "JEQ", 3) == 0)
{
cpu.memory[mem_index++] = JEQ;
cpu.memory[mem_index++] = reg1;
cpu.memory[mem_index++] = addr;
} }
} else if (strncmp(line, "HLT", 3) == 0) }
}
else if (strncmp(line, "HLT", 3) == 0)
{ {
cpu.memory[mem_index++] = HLT; cpu.memory[mem_index++] = HLT;
} }
else if (strncmp(line, "NOP", 3) == 0)
{
cpu.memory[mem_index++] = NOP;
}
} }
fclose(fp); fclose(fp);
} }
@@ -211,7 +241,7 @@ void cpu_run()
void cpu_dump() void cpu_dump()
{ {
printf("\n*** CPU state dump ***\nPC: 0x%x\nHalted: %d\n\n", cpu.pc, cpu.halted); printf("\n*** CPU state dump ***\nPC: 0x%x\nEqual flag: %d\nHalted: %d\n\n", cpu.pc, cpu.equal_flag, cpu.halted);
for (size_t i=0; i<NUM_REGISTERS; i++) for (size_t i=0; i<NUM_REGISTERS; i++)
{ {

View File

@@ -1,6 +1,13 @@
;this is a comment ;this is a comment
JMP 5 ; this is one too JMP 4
MOV 1 2 ; hellooo?
MOV 3 2 ; should jump here, R1 should be untouched
HLT
NOP
MOV R1, R2 ; hellooo?
;MOV R3, R2 ; should jump here, R1 should be untouched
CMP R1, R2
JEQ R1, 2
ADD R1, R2
HLT HLT