CPU core still needs finishing

This commit is contained in:
2025-02-04 23:16:19 +01:00
parent e6f241bcae
commit de77a0a9f5
4 changed files with 79 additions and 59 deletions

2
.idea/discord.xml generated
View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="DiscordProjectSettings"> <component name="DiscordProjectSettings">
<option name="show" value="ASK" /> <option name="show" value="PROJECT_FILES" />
<option name="description" value="" /> <option name="description" value="" />
</component> </component>
</project> </project>

View File

@@ -34,54 +34,53 @@ void step(CPU *cpu) {
uint8_t reg1, reg2, imm, temp; uint8_t reg1, reg2, imm, temp;
uint32_t newPC, addrTemp; uint32_t newPC, addrTemp;
int32_t cmpResult; int32_t cmpResult;
switch (opcode) { switch (opcode) {
case NOP: case NOP:
cpu->pc++; //Don't do anything
break; break;
case BRK: case BRK:
cpu->pc++; //Pause CPU (for breakpoints)
cpu->mode = Paused; cpu->mode = Paused;
break; break;
case INC_RN: case INC_RN:
cpu->pc++; //Increment register
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
if (reg1 >= REG_COUNT) {
reg1 = REG_COUNT - 1;
}
cpu->regs[reg1]++; cpu->regs[reg1]++;
case INC_ADDR: case INC_ADDR:
cpu->pc++; //Increment address
imm = read_mem(cpu, cpu->pc++); addrTemp = read_addr(cpu);
write_mem(cpu, imm, read_mem(cpu, imm) + 1); write_mem(cpu, read_addr(cpu), read_mem(cpu, addrTemp) + 1);
case DEC_RN: case DEC_RN:
cpu->pc++; //Decrement register
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
cpu->regs[reg1]--; cpu->regs[reg1]--;
case DEC_ADDR: case DEC_ADDR:
cpu->pc++; //Decrement address
imm = read_mem(cpu, cpu->pc++); addrTemp = read_addr(cpu);
write_mem(cpu, imm, read_mem(cpu, imm) - 1); write_mem(cpu, addrTemp, read_mem(cpu, addrTemp) - 1);
case MOV_RN_IMM: case MOV_RN_IMM:
reg1 = read_mem(cpu, cpu->pc++); //Load from immediate to register
reg1 = read_reg(cpu);
imm = read_mem(cpu, cpu->pc++); imm = read_mem(cpu, cpu->pc++);
cpu->regs[reg1] = imm; cpu->regs[reg1] = imm;
break; break;
case MOV_RN_RM: case MOV_RN_RM:
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
reg2 = read_mem(cpu, cpu->pc++); reg2 = read_reg(cpu);
cpu->regs[reg1] = cpu->regs[reg2]; cpu->regs[reg1] = cpu->regs[reg2];
break; break;
case MOV_RN_ADDR: case MOV_RN_ADDR:
// Load from memory into register. // Load from memory into register.
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
imm = read_mem(cpu, cpu->pc++); imm = read_mem(cpu, cpu->pc++);
cpu->regs[reg1] = read_mem(cpu, imm); cpu->regs[reg1] = read_mem(cpu, imm);
break; break;
@@ -89,14 +88,14 @@ void step(CPU *cpu) {
case MOV_ADDR_RN: case MOV_ADDR_RN:
// Store from register into memory. // Store from register into memory.
imm = read_mem(cpu, cpu->pc++); imm = read_mem(cpu, cpu->pc++);
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
write_mem(cpu, imm, cpu->regs[reg1]); write_mem(cpu, imm, cpu->regs[reg1]);
break; break;
case SWAP: { case SWAP: {
// Swap contents of two registers. // Swap contents of two registers.
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
reg2 = read_mem(cpu, cpu->pc++); reg2 = read_reg(cpu);
temp = cpu->regs[reg1]; temp = cpu->regs[reg1];
cpu->regs[reg1] = cpu->regs[reg2]; cpu->regs[reg1] = cpu->regs[reg2];
cpu->regs[reg2] = temp; cpu->regs[reg2] = temp;
@@ -105,57 +104,57 @@ void step(CPU *cpu) {
case SWAPN: { case SWAPN: {
// Swap the nibbles of a register. // Swap the nibbles of a register.
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
uint8_t val = (uint8_t) cpu->regs[reg1]; uint8_t val = (uint8_t) cpu->regs[reg1];
cpu->regs[reg1] = ((val & 0x0F) << 4) | ((val & 0xF0) >> 4); cpu->regs[reg1] = ((val & 0x0F) << 4) | ((val & 0xF0) >> 4);
break; break;
} }
case ADD_RN_RM: case ADD_RN_RM:
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
reg2 = read_mem(cpu, cpu->pc++); reg2 = read_reg(cpu);
cpu->regs[reg1] += cpu->regs[reg2]; cpu->regs[reg1] += cpu->regs[reg2];
set_flags(cpu, cpu->regs[reg1]); set_flags(cpu, cpu->regs[reg1]);
break; break;
case ADD_RN_IMM: case ADD_RN_IMM:
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
imm = read_mem(cpu, cpu->pc++); imm = read_mem(cpu, cpu->pc++);
cpu->regs[reg1] += imm; cpu->regs[reg1] += imm;
set_flags(cpu, cpu->regs[reg1]); set_flags(cpu, cpu->regs[reg1]);
break; break;
case SUB_RN_RM: case SUB_RN_RM:
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
reg2 = read_mem(cpu, cpu->pc++); reg2 = read_reg(cpu);
cpu->regs[reg1] -= cpu->regs[reg2]; cpu->regs[reg1] -= cpu->regs[reg2];
set_flags(cpu, cpu->regs[reg1]); set_flags(cpu, cpu->regs[reg1]);
break; break;
case SUB_RN_IMM: case SUB_RN_IMM:
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
imm = read_mem(cpu, cpu->pc++); imm = read_mem(cpu, cpu->pc++);
cpu->regs[reg1] -= imm; cpu->regs[reg1] -= imm;
set_flags(cpu, cpu->regs[reg1]); set_flags(cpu, cpu->regs[reg1]);
break; break;
case MUL_RN_RM: case MUL_RN_RM:
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
reg2 = read_mem(cpu, cpu->pc++); reg2 = read_reg(cpu);
cpu->regs[reg1] *= cpu->regs[reg2]; cpu->regs[reg1] *= cpu->regs[reg2];
set_flags(cpu, cpu->regs[reg1]); set_flags(cpu, cpu->regs[reg1]);
break; break;
case MUL_RN_IMM: case MUL_RN_IMM:
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
imm = read_mem(cpu, cpu->pc++); imm = read_mem(cpu, cpu->pc++);
cpu->regs[reg1] *= imm; cpu->regs[reg1] *= imm;
set_flags(cpu, cpu->regs[reg1]); set_flags(cpu, cpu->regs[reg1]);
break; break;
case DIV_RN_RM: case DIV_RN_RM:
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
reg2 = read_mem(cpu, cpu->pc++); reg2 = read_reg(cpu);
if (cpu->regs[reg2] == 0) { if (cpu->regs[reg2] == 0) {
printf("Error: Division by zero!\n"); printf("Error: Division by zero!\n");
cpu->mode = Error; cpu->mode = Error;
@@ -166,7 +165,7 @@ void step(CPU *cpu) {
break; break;
case DIV_RN_IMM: case DIV_RN_IMM:
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
imm = read_mem(cpu, cpu->pc++); imm = read_mem(cpu, cpu->pc++);
if (imm == 0) { if (imm == 0) {
printf("Error: Division by zero!\n"); printf("Error: Division by zero!\n");
@@ -178,8 +177,8 @@ void step(CPU *cpu) {
break; break;
case MOD_RN_RM: case MOD_RN_RM:
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
reg2 = read_mem(cpu, cpu->pc++); reg2 = read_reg(cpu);
if (cpu->regs[reg2] == 0) { if (cpu->regs[reg2] == 0) {
printf("Error: Modulo by zero!\n"); printf("Error: Modulo by zero!\n");
cpu->mode = Error; cpu->mode = Error;
@@ -190,7 +189,7 @@ void step(CPU *cpu) {
break; break;
case MOD_RN_IMM: case MOD_RN_IMM:
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
imm = read_mem(cpu, cpu->pc++); imm = read_mem(cpu, cpu->pc++);
if (imm == 0) { if (imm == 0) {
printf("Error: Modulo by zero!\n"); printf("Error: Modulo by zero!\n");
@@ -202,75 +201,75 @@ void step(CPU *cpu) {
break; break;
case NEG_RN: case NEG_RN:
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
cpu->regs[reg1] = -((int32_t) cpu->regs[reg1]); cpu->regs[reg1] = -((int32_t) cpu->regs[reg1]);
set_flags(cpu, cpu->regs[reg1]); set_flags(cpu, cpu->regs[reg1]);
break; break;
case AND_RN_RM: case AND_RN_RM:
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
reg2 = read_mem(cpu, cpu->pc++); reg2 = read_reg(cpu);
cpu->regs[reg1] &= cpu->regs[reg2]; cpu->regs[reg1] &= cpu->regs[reg2];
set_flags(cpu, cpu->regs[reg1]); set_flags(cpu, cpu->regs[reg1]);
break; break;
case AND_RN_IMM: case AND_RN_IMM:
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
imm = read_mem(cpu, cpu->pc++); imm = read_mem(cpu, cpu->pc++);
cpu->regs[reg1] &= imm; cpu->regs[reg1] &= imm;
set_flags(cpu, cpu->regs[reg1]); set_flags(cpu, cpu->regs[reg1]);
break; break;
case OR_RN_RM: case OR_RN_RM:
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
reg2 = read_mem(cpu, cpu->pc++); reg2 = read_reg(cpu);
cpu->regs[reg1] |= cpu->regs[reg2]; cpu->regs[reg1] |= cpu->regs[reg2];
set_flags(cpu, cpu->regs[reg1]); set_flags(cpu, cpu->regs[reg1]);
break; break;
case OR_RN_IMM: case OR_RN_IMM:
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
imm = read_mem(cpu, cpu->pc++); imm = read_mem(cpu, cpu->pc++);
cpu->regs[reg1] |= imm; cpu->regs[reg1] |= imm;
set_flags(cpu, cpu->regs[reg1]); set_flags(cpu, cpu->regs[reg1]);
break; break;
case XOR_RN_RM: case XOR_RN_RM:
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
reg2 = read_mem(cpu, cpu->pc++); reg2 = read_reg(cpu);
cpu->regs[reg1] ^= cpu->regs[reg2]; cpu->regs[reg1] ^= cpu->regs[reg2];
set_flags(cpu, cpu->regs[reg1]); set_flags(cpu, cpu->regs[reg1]);
break; break;
case XOR_RN_IMM: case XOR_RN_IMM:
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
imm = read_mem(cpu, cpu->pc++); imm = read_mem(cpu, cpu->pc++);
cpu->regs[reg1] ^= imm; cpu->regs[reg1] ^= imm;
set_flags(cpu, cpu->regs[reg1]); set_flags(cpu, cpu->regs[reg1]);
break; break;
case NOT_RN: case NOT_RN:
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
cpu->regs[reg1] = ~cpu->regs[reg1]; cpu->regs[reg1] = ~cpu->regs[reg1];
set_flags(cpu, cpu->regs[reg1]); set_flags(cpu, cpu->regs[reg1]);
break; break;
case SHL_RN_IMM: case SHL_RN_IMM:
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
imm = read_mem(cpu, cpu->pc++); imm = read_mem(cpu, cpu->pc++);
cpu->regs[reg1] <<= imm; cpu->regs[reg1] <<= imm;
set_flags(cpu, cpu->regs[reg1]); set_flags(cpu, cpu->regs[reg1]);
break; break;
case SHR_RN_IMM: case SHR_RN_IMM:
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
imm = read_mem(cpu, cpu->pc++); imm = read_mem(cpu, cpu->pc++);
cpu->regs[reg1] >>= imm; // Logical right shift (assuming unsigned value) cpu->regs[reg1] >>= imm; // Logical right shift (assuming unsigned value)
set_flags(cpu, cpu->regs[reg1]); set_flags(cpu, cpu->regs[reg1]);
break; break;
case SAR_RN_IMM: case SAR_RN_IMM:
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
imm = read_mem(cpu, cpu->pc++); imm = read_mem(cpu, cpu->pc++);
// Arithmetic right shift; cast to signed before shifting. // Arithmetic right shift; cast to signed before shifting.
cpu->regs[reg1] = ((int32_t) cpu->regs[reg1]) >> imm; cpu->regs[reg1] = ((int32_t) cpu->regs[reg1]) >> imm;
@@ -290,8 +289,8 @@ void step(CPU *cpu) {
case CMP: { case CMP: {
// Compare two registers: set flags (Zero, Negative) // Compare two registers: set flags (Zero, Negative)
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
reg2 = read_mem(cpu, cpu->pc++); reg2 = read_reg(cpu);
cmpResult = (int32_t) cpu->regs[reg1] - (int32_t) cpu->regs[reg2]; cmpResult = (int32_t) cpu->regs[reg1] - (int32_t) cpu->regs[reg2];
set_flags(cpu, cmpResult); set_flags(cpu, cmpResult);
break; break;
@@ -299,7 +298,7 @@ void step(CPU *cpu) {
case JE_BIT_RN: { case JE_BIT_RN: {
// Jump if bit in register set // Jump if bit in register set
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
if (reg1 >= REG_COUNT) { if (reg1 >= REG_COUNT) {
reg1 = REG_COUNT - 1; reg1 = REG_COUNT - 1;
} }
@@ -343,7 +342,7 @@ void step(CPU *cpu) {
case JNE_BIT_RN: { case JNE_BIT_RN: {
// Jump if bit in register set // Jump if bit in register set
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
if (reg1 >= REG_COUNT) { if (reg1 >= REG_COUNT) {
reg1 = REG_COUNT - 1; reg1 = REG_COUNT - 1;
} }
@@ -438,14 +437,14 @@ void step(CPU *cpu) {
case PUSH: { case PUSH: {
// Push register value onto the stack. // Push register value onto the stack.
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
write_mem(cpu, cpu->sp--, (uint8_t) cpu->regs[reg1]); write_mem(cpu, cpu->sp--, (uint8_t) cpu->regs[reg1]);
break; break;
} }
case POP: { case POP: {
// Pop a value from the stack into a register. // Pop a value from the stack into a register.
reg1 = read_mem(cpu, cpu->pc++); reg1 = read_reg(cpu);
cpu->regs[reg1] = read_mem(cpu, ++cpu->sp); cpu->regs[reg1] = read_mem(cpu, ++cpu->sp);
break; break;
} }

View File

@@ -37,6 +37,23 @@ uint32_t read_mem32(CPU *cpu, uint32_t addr) {
return read_mem16(cpu, addr) | (read_mem16(cpu, addr + 2) << 16); return read_mem16(cpu, addr) | (read_mem16(cpu, addr + 2) << 16);
} }
uint32_t read_addr(CPU *cpu) {
uint32_t out = read_mem16(cpu, cpu->pc) | (read_mem16(cpu, cpu->pc + 2) << 16);
cpu->pc += 4;
if (out >= MEM_SIZE) {
out = MEM_SIZE - 1;
}
return out;
}
uint8_t read_reg(CPU *cpu) {
uint8_t out = read_mem(cpu, cpu->pc++);
if (out >= REG_COUNT) {
out = REG_COUNT - 1;
}
return out;
}
uint8_t write_mem16(CPU *cpu, uint32_t addr, uint16_t value) { uint8_t write_mem16(CPU *cpu, uint32_t addr, uint16_t value) {
uint8_t status = write_mem(cpu, addr, value & 0xFF); uint8_t status = write_mem(cpu, addr, value & 0xFF);
if (status) { if (status) {

View File

@@ -14,6 +14,10 @@ uint8_t write_mem16(CPU *cpu, uint32_t addr, uint16_t value);
uint32_t read_mem32(CPU *cpu, uint32_t addr); uint32_t read_mem32(CPU *cpu, uint32_t addr);
uint32_t read_addr(CPU *cpu);
uint8_t read_reg(CPU *cpu);
uint16_t read_mem16(CPU *cpu, uint32_t addr); uint16_t read_mem16(CPU *cpu, uint32_t addr);
uint8_t read_mem(CPU *cpu, uint32_t addr); uint8_t read_mem(CPU *cpu, uint32_t addr);