diff --git a/.idea/discord.xml b/.idea/discord.xml index 30bab2a..d8e9561 100644 --- a/.idea/discord.xml +++ b/.idea/discord.xml @@ -1,7 +1,7 @@ - \ No newline at end of file diff --git a/cpu/core.c b/cpu/core.c index a712bd8..027c8d8 100644 --- a/cpu/core.c +++ b/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; } diff --git a/cpu/memory.c b/cpu/memory.c index aed42c1..9c0c8b5 100644 --- a/cpu/memory.c +++ b/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) { diff --git a/cpu/memory.h b/cpu/memory.h index 9655b78..229e632 100644 --- a/cpu/memory.h +++ b/cpu/memory.h @@ -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);