CPU core still needs finishing
This commit is contained in:
2
.idea/discord.xml
generated
2
.idea/discord.xml
generated
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DiscordProjectSettings">
|
||||
<option name="show" value="ASK" />
|
||||
<option name="show" value="PROJECT_FILES" />
|
||||
<option name="description" value="" />
|
||||
</component>
|
||||
</project>
|
115
cpu/core.c
115
cpu/core.c
@@ -34,54 +34,53 @@ void step(CPU *cpu) {
|
||||
uint8_t reg1, reg2, imm, temp;
|
||||
uint32_t newPC, addrTemp;
|
||||
int32_t cmpResult;
|
||||
|
||||
switch (opcode) {
|
||||
case NOP:
|
||||
cpu->pc++;
|
||||
//Don't do anything
|
||||
break;
|
||||
|
||||
case BRK:
|
||||
cpu->pc++;
|
||||
//Pause CPU (for breakpoints)
|
||||
cpu->mode = Paused;
|
||||
break;
|
||||
|
||||
case INC_RN:
|
||||
cpu->pc++;
|
||||
reg1 = read_mem(cpu, cpu->pc++);
|
||||
if (reg1 >= REG_COUNT) {
|
||||
reg1 = REG_COUNT - 1;
|
||||
}
|
||||
//Increment register
|
||||
reg1 = read_reg(cpu);
|
||||
cpu->regs[reg1]++;
|
||||
|
||||
case INC_ADDR:
|
||||
cpu->pc++;
|
||||
imm = read_mem(cpu, cpu->pc++);
|
||||
write_mem(cpu, imm, read_mem(cpu, imm) + 1);
|
||||
//Increment address
|
||||
addrTemp = read_addr(cpu);
|
||||
write_mem(cpu, read_addr(cpu), read_mem(cpu, addrTemp) + 1);
|
||||
|
||||
case DEC_RN:
|
||||
cpu->pc++;
|
||||
reg1 = read_mem(cpu, cpu->pc++);
|
||||
//Decrement register
|
||||
reg1 = read_reg(cpu);
|
||||
cpu->regs[reg1]--;
|
||||
|
||||
case DEC_ADDR:
|
||||
cpu->pc++;
|
||||
imm = read_mem(cpu, cpu->pc++);
|
||||
write_mem(cpu, imm, read_mem(cpu, imm) - 1);
|
||||
//Decrement address
|
||||
addrTemp = read_addr(cpu);
|
||||
write_mem(cpu, addrTemp, read_mem(cpu, addrTemp) - 1);
|
||||
|
||||
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++);
|
||||
cpu->regs[reg1] = imm;
|
||||
break;
|
||||
|
||||
case MOV_RN_RM:
|
||||
reg1 = read_mem(cpu, cpu->pc++);
|
||||
reg2 = read_mem(cpu, cpu->pc++);
|
||||
reg1 = read_reg(cpu);
|
||||
reg2 = read_reg(cpu);
|
||||
cpu->regs[reg1] = cpu->regs[reg2];
|
||||
break;
|
||||
|
||||
case MOV_RN_ADDR:
|
||||
// Load from memory into register.
|
||||
reg1 = read_mem(cpu, cpu->pc++);
|
||||
reg1 = read_reg(cpu);
|
||||
imm = read_mem(cpu, cpu->pc++);
|
||||
cpu->regs[reg1] = read_mem(cpu, imm);
|
||||
break;
|
||||
@@ -89,14 +88,14 @@ void step(CPU *cpu) {
|
||||
case MOV_ADDR_RN:
|
||||
// Store from register into memory.
|
||||
imm = read_mem(cpu, cpu->pc++);
|
||||
reg1 = read_mem(cpu, cpu->pc++);
|
||||
reg1 = read_reg(cpu);
|
||||
write_mem(cpu, imm, cpu->regs[reg1]);
|
||||
break;
|
||||
|
||||
case SWAP: {
|
||||
// Swap contents of two registers.
|
||||
reg1 = read_mem(cpu, cpu->pc++);
|
||||
reg2 = read_mem(cpu, cpu->pc++);
|
||||
reg1 = read_reg(cpu);
|
||||
reg2 = read_reg(cpu);
|
||||
temp = cpu->regs[reg1];
|
||||
cpu->regs[reg1] = cpu->regs[reg2];
|
||||
cpu->regs[reg2] = temp;
|
||||
@@ -105,57 +104,57 @@ void step(CPU *cpu) {
|
||||
|
||||
case SWAPN: {
|
||||
// Swap the nibbles of a register.
|
||||
reg1 = read_mem(cpu, cpu->pc++);
|
||||
reg1 = read_reg(cpu);
|
||||
uint8_t val = (uint8_t) cpu->regs[reg1];
|
||||
cpu->regs[reg1] = ((val & 0x0F) << 4) | ((val & 0xF0) >> 4);
|
||||
break;
|
||||
}
|
||||
|
||||
case ADD_RN_RM:
|
||||
reg1 = read_mem(cpu, cpu->pc++);
|
||||
reg2 = read_mem(cpu, cpu->pc++);
|
||||
reg1 = read_reg(cpu);
|
||||
reg2 = read_reg(cpu);
|
||||
cpu->regs[reg1] += cpu->regs[reg2];
|
||||
set_flags(cpu, cpu->regs[reg1]);
|
||||
break;
|
||||
|
||||
case ADD_RN_IMM:
|
||||
reg1 = read_mem(cpu, cpu->pc++);
|
||||
reg1 = read_reg(cpu);
|
||||
imm = read_mem(cpu, cpu->pc++);
|
||||
cpu->regs[reg1] += imm;
|
||||
set_flags(cpu, cpu->regs[reg1]);
|
||||
break;
|
||||
|
||||
case SUB_RN_RM:
|
||||
reg1 = read_mem(cpu, cpu->pc++);
|
||||
reg2 = read_mem(cpu, cpu->pc++);
|
||||
reg1 = read_reg(cpu);
|
||||
reg2 = read_reg(cpu);
|
||||
cpu->regs[reg1] -= cpu->regs[reg2];
|
||||
set_flags(cpu, cpu->regs[reg1]);
|
||||
break;
|
||||
|
||||
case SUB_RN_IMM:
|
||||
reg1 = read_mem(cpu, cpu->pc++);
|
||||
reg1 = read_reg(cpu);
|
||||
imm = read_mem(cpu, cpu->pc++);
|
||||
cpu->regs[reg1] -= imm;
|
||||
set_flags(cpu, cpu->regs[reg1]);
|
||||
break;
|
||||
|
||||
case MUL_RN_RM:
|
||||
reg1 = read_mem(cpu, cpu->pc++);
|
||||
reg2 = read_mem(cpu, cpu->pc++);
|
||||
reg1 = read_reg(cpu);
|
||||
reg2 = read_reg(cpu);
|
||||
cpu->regs[reg1] *= cpu->regs[reg2];
|
||||
set_flags(cpu, cpu->regs[reg1]);
|
||||
break;
|
||||
|
||||
case MUL_RN_IMM:
|
||||
reg1 = read_mem(cpu, cpu->pc++);
|
||||
reg1 = read_reg(cpu);
|
||||
imm = read_mem(cpu, cpu->pc++);
|
||||
cpu->regs[reg1] *= imm;
|
||||
set_flags(cpu, cpu->regs[reg1]);
|
||||
break;
|
||||
|
||||
case DIV_RN_RM:
|
||||
reg1 = read_mem(cpu, cpu->pc++);
|
||||
reg2 = read_mem(cpu, cpu->pc++);
|
||||
reg1 = read_reg(cpu);
|
||||
reg2 = read_reg(cpu);
|
||||
if (cpu->regs[reg2] == 0) {
|
||||
printf("Error: Division by zero!\n");
|
||||
cpu->mode = Error;
|
||||
@@ -166,7 +165,7 @@ void step(CPU *cpu) {
|
||||
break;
|
||||
|
||||
case DIV_RN_IMM:
|
||||
reg1 = read_mem(cpu, cpu->pc++);
|
||||
reg1 = read_reg(cpu);
|
||||
imm = read_mem(cpu, cpu->pc++);
|
||||
if (imm == 0) {
|
||||
printf("Error: Division by zero!\n");
|
||||
@@ -178,8 +177,8 @@ void step(CPU *cpu) {
|
||||
break;
|
||||
|
||||
case MOD_RN_RM:
|
||||
reg1 = read_mem(cpu, cpu->pc++);
|
||||
reg2 = read_mem(cpu, cpu->pc++);
|
||||
reg1 = read_reg(cpu);
|
||||
reg2 = read_reg(cpu);
|
||||
if (cpu->regs[reg2] == 0) {
|
||||
printf("Error: Modulo by zero!\n");
|
||||
cpu->mode = Error;
|
||||
@@ -190,7 +189,7 @@ void step(CPU *cpu) {
|
||||
break;
|
||||
|
||||
case MOD_RN_IMM:
|
||||
reg1 = read_mem(cpu, cpu->pc++);
|
||||
reg1 = read_reg(cpu);
|
||||
imm = read_mem(cpu, cpu->pc++);
|
||||
if (imm == 0) {
|
||||
printf("Error: Modulo by zero!\n");
|
||||
@@ -202,75 +201,75 @@ void step(CPU *cpu) {
|
||||
break;
|
||||
|
||||
case NEG_RN:
|
||||
reg1 = read_mem(cpu, cpu->pc++);
|
||||
reg1 = read_reg(cpu);
|
||||
cpu->regs[reg1] = -((int32_t) cpu->regs[reg1]);
|
||||
set_flags(cpu, cpu->regs[reg1]);
|
||||
break;
|
||||
|
||||
case AND_RN_RM:
|
||||
reg1 = read_mem(cpu, cpu->pc++);
|
||||
reg2 = read_mem(cpu, cpu->pc++);
|
||||
reg1 = read_reg(cpu);
|
||||
reg2 = read_reg(cpu);
|
||||
cpu->regs[reg1] &= cpu->regs[reg2];
|
||||
set_flags(cpu, cpu->regs[reg1]);
|
||||
break;
|
||||
|
||||
case AND_RN_IMM:
|
||||
reg1 = read_mem(cpu, cpu->pc++);
|
||||
reg1 = read_reg(cpu);
|
||||
imm = read_mem(cpu, cpu->pc++);
|
||||
cpu->regs[reg1] &= imm;
|
||||
set_flags(cpu, cpu->regs[reg1]);
|
||||
break;
|
||||
|
||||
case OR_RN_RM:
|
||||
reg1 = read_mem(cpu, cpu->pc++);
|
||||
reg2 = read_mem(cpu, cpu->pc++);
|
||||
reg1 = read_reg(cpu);
|
||||
reg2 = read_reg(cpu);
|
||||
cpu->regs[reg1] |= cpu->regs[reg2];
|
||||
set_flags(cpu, cpu->regs[reg1]);
|
||||
break;
|
||||
|
||||
case OR_RN_IMM:
|
||||
reg1 = read_mem(cpu, cpu->pc++);
|
||||
reg1 = read_reg(cpu);
|
||||
imm = read_mem(cpu, cpu->pc++);
|
||||
cpu->regs[reg1] |= imm;
|
||||
set_flags(cpu, cpu->regs[reg1]);
|
||||
break;
|
||||
|
||||
case XOR_RN_RM:
|
||||
reg1 = read_mem(cpu, cpu->pc++);
|
||||
reg2 = read_mem(cpu, cpu->pc++);
|
||||
reg1 = read_reg(cpu);
|
||||
reg2 = read_reg(cpu);
|
||||
cpu->regs[reg1] ^= cpu->regs[reg2];
|
||||
set_flags(cpu, cpu->regs[reg1]);
|
||||
break;
|
||||
|
||||
case XOR_RN_IMM:
|
||||
reg1 = read_mem(cpu, cpu->pc++);
|
||||
reg1 = read_reg(cpu);
|
||||
imm = read_mem(cpu, cpu->pc++);
|
||||
cpu->regs[reg1] ^= imm;
|
||||
set_flags(cpu, cpu->regs[reg1]);
|
||||
break;
|
||||
|
||||
case NOT_RN:
|
||||
reg1 = read_mem(cpu, cpu->pc++);
|
||||
reg1 = read_reg(cpu);
|
||||
cpu->regs[reg1] = ~cpu->regs[reg1];
|
||||
set_flags(cpu, cpu->regs[reg1]);
|
||||
break;
|
||||
|
||||
case SHL_RN_IMM:
|
||||
reg1 = read_mem(cpu, cpu->pc++);
|
||||
reg1 = read_reg(cpu);
|
||||
imm = read_mem(cpu, cpu->pc++);
|
||||
cpu->regs[reg1] <<= imm;
|
||||
set_flags(cpu, cpu->regs[reg1]);
|
||||
break;
|
||||
|
||||
case SHR_RN_IMM:
|
||||
reg1 = read_mem(cpu, cpu->pc++);
|
||||
reg1 = read_reg(cpu);
|
||||
imm = read_mem(cpu, cpu->pc++);
|
||||
cpu->regs[reg1] >>= imm; // Logical right shift (assuming unsigned value)
|
||||
set_flags(cpu, cpu->regs[reg1]);
|
||||
break;
|
||||
|
||||
case SAR_RN_IMM:
|
||||
reg1 = read_mem(cpu, cpu->pc++);
|
||||
reg1 = read_reg(cpu);
|
||||
imm = read_mem(cpu, cpu->pc++);
|
||||
// Arithmetic right shift; cast to signed before shifting.
|
||||
cpu->regs[reg1] = ((int32_t) cpu->regs[reg1]) >> imm;
|
||||
@@ -290,8 +289,8 @@ void step(CPU *cpu) {
|
||||
|
||||
case CMP: {
|
||||
// Compare two registers: set flags (Zero, Negative)
|
||||
reg1 = read_mem(cpu, cpu->pc++);
|
||||
reg2 = read_mem(cpu, cpu->pc++);
|
||||
reg1 = read_reg(cpu);
|
||||
reg2 = read_reg(cpu);
|
||||
cmpResult = (int32_t) cpu->regs[reg1] - (int32_t) cpu->regs[reg2];
|
||||
set_flags(cpu, cmpResult);
|
||||
break;
|
||||
@@ -299,7 +298,7 @@ void step(CPU *cpu) {
|
||||
|
||||
case JE_BIT_RN: {
|
||||
// Jump if bit in register set
|
||||
reg1 = read_mem(cpu, cpu->pc++);
|
||||
reg1 = read_reg(cpu);
|
||||
if (reg1 >= REG_COUNT) {
|
||||
reg1 = REG_COUNT - 1;
|
||||
}
|
||||
@@ -343,7 +342,7 @@ void step(CPU *cpu) {
|
||||
|
||||
case JNE_BIT_RN: {
|
||||
// Jump if bit in register set
|
||||
reg1 = read_mem(cpu, cpu->pc++);
|
||||
reg1 = read_reg(cpu);
|
||||
if (reg1 >= REG_COUNT) {
|
||||
reg1 = REG_COUNT - 1;
|
||||
}
|
||||
@@ -438,14 +437,14 @@ void step(CPU *cpu) {
|
||||
|
||||
case PUSH: {
|
||||
// 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]);
|
||||
break;
|
||||
}
|
||||
|
||||
case POP: {
|
||||
// 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);
|
||||
break;
|
||||
}
|
||||
|
17
cpu/memory.c
17
cpu/memory.c
@@ -37,6 +37,23 @@ uint32_t read_mem32(CPU *cpu, uint32_t addr) {
|
||||
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 status = write_mem(cpu, addr, value & 0xFF);
|
||||
if (status) {
|
||||
|
@@ -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_addr(CPU *cpu);
|
||||
|
||||
uint8_t read_reg(CPU *cpu);
|
||||
|
||||
uint16_t read_mem16(CPU *cpu, uint32_t addr);
|
||||
|
||||
uint8_t read_mem(CPU *cpu, uint32_t addr);
|
||||
|
Reference in New Issue
Block a user