Files
RISC-B/cpu/core.h
2025-02-11 12:29:11 +01:00

137 lines
4.9 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//
// Created by bruno on 2.2.2025.
//
#ifndef RISCB_CORE_H
#define RISCB_CORE_H
#include <stdint.h>
#include "stdio.h"
#define MEM_SIZE 65535
// Register count (register names R0 to R7)
#define REG_COUNT 64
#define STACK_SIZE 255
#define CPU_FLAG_ZERO (1 << 0)
#define CPU_FLAG_NEGATIVE (1 << 1)
#define CPU_MODE_PAUSED (1 << 0)
#define CPU_MODE_HALTED (1 << 1)
#define CPU_MODE_ERROR (1 << 2)
#define CPU_MODE_LOOP (1 << 3)
#define CPU_MODE_STEP (1 << 4)
#define CPU_MODE_SECOND (1 << 5)
#define CPU_INSTRUCTION_SIZE 8 //Biggest instruction
// CPU state
typedef struct {
uint8_t regs[REG_COUNT];
uint8_t memory[MEM_SIZE];
uint32_t stack[STACK_SIZE]; // Stack pointer
uint32_t addrToLineMapper[MEM_SIZE / CPU_INSTRUCTION_SIZE];
uint32_t pc; // Program counter
uint32_t stack_ptr; // Stack pointer
uint8_t flags; // Status flags
uint32_t programEnd;
uint8_t mode;
uint32_t cycle;
} CPU;
void step(CPU *cpu);
void init_cpu(CPU *cpu);
// Helper function for setting flags in the CPU (here we assume bit0 is the Zero flag,
// and bit1 is the Negative flag).
static inline void set_flags(CPU *cpu, int32_t result);
// Opcode definitions (should match the CPUs enum)
typedef enum {
NOP, // NOP - No operation (does nothing, advances to next instruction)
BRK, // BRK - Pause CPU (halts execution until resumed)
HLT,
MOV_RN_IMM, // MOV Rn, Imm - Move immediate to register (Rn = Imm)
MOV_RN_RM, // MOV Rn, Rm - Move value from one register to another (Rn = Rm)
MOV_RN_ADDR, // MOV Rn, [Addr] - Load value from memory address into register (Rn = [Addr])
MOV_ADDR_RN, // MOV [Addr], Rn - Store register value into memory address ([Addr] = Rn)
SWAP, // SWAP Rn, Rm - Swap values between two registers (Rn <-> Rm)
SWAPN, // SWAPN Rn - Swap nibbles within a register (Rn high/low nibbles swapped)
ADD_RN_RM, // ADD Rn, Rm - Add values of two registers (Rn = Rn + Rm)
ADD_RN_IMM, // ADD Rn, Imm - Add immediate value to register (Rn = Rn + Imm)
SUB_RN_RM, // SUB Rn, Rm - Subtract one register from another (Rn = Rn - Rm)
SUB_RN_IMM, // SUB Rn, Imm - Subtract immediate value from register (Rn = Rn - Imm)
MUL_RN_RM, // MUL Rn, Rm - Multiply two registers (Rn = Rn * Rm)
MUL_RN_IMM, // MUL Rn, Imm - Multiply register by immediate (Rn = Rn * Imm)
DIV_RN_RM, // DIV Rn, Rm - Divide one register by another (Rn = Rn / Rm)
DIV_RN_IMM, // DIV Rn, Imm - Divide register by immediate (Rn = Rn / Imm)
MOD_RN_RM, // MOD Rn, Rm - Compute remainder of division (Rn = Rn % Rm)
MOD_RN_IMM, // MOD Rn, Imm - Compute remainder using immediate (Rn = Rn % Imm)
NEG_RN, // NEG Rn - Negate register value (Rn = -Rn)
AND_RN_RM, // AND Rn, Rm - Bitwise AND two registers (Rn = Rn & Rm)
AND_RN_IMM, // AND Rn, Imm - Bitwise AND register with immediate (Rn = Rn & Imm)
OR_RN_RM, // OR Rn, Rm - Bitwise OR two registers (Rn = Rn | Rm)
OR_RN_IMM, // OR Rn, Imm - Bitwise OR register with immediate (Rn = Rn | Imm)
XOR_RN_RM, // XOR Rn, Rm - Bitwise XOR two registers (Rn = Rn ^ Rm)
XOR_RN_IMM, // XOR Rn, Imm - Bitwise XOR register with immediate (Rn = Rn ^ Imm)
NOT_RN, // NOT Rn - Bitwise NOT (Rn = ~Rn)
SHL_RN_IMM, // SHL Rn, Imm - Logical shift left (Rn = Rn << Imm)
SHR_RN_IMM, // SHR Rn, Imm - Logical shift right (Rn = Rn >> Imm)
SAR_RN_IMM, // SAR Rn, Imm - Arithmetic shift right (Rn = Rn >> Imm with sign extension)
JMP, // JMP Addr - Jump to address (PC = Addr)
JMP_REL, // JMP Offset - relative jump (offset is signed)
INC_RN, //INC Rn - Increment register
INC_ADDR, //INC [Addr] - Increment address
DEC_RN, //DEC Rn - Increment register
DEC_ADDR, //DEC [Addr] - Increment address
CMP, // CMP Rn, Rm - Compare two registers (sets flags based on Rn - Rm)
JE, // JE Addr - Jump if equal (if zero flag set, PC = Addr)
JNE, // JNE Addr - Jump if not equal (if zero flag not set, PC = Addr)
JMP_BIT_SET_RN, // jump relative if a given bit in a register is set
JMP_BIT_SET_ADDR, // jump relative if a given bit in memory is set
JMP_BIT_CLEAR_RN, // jump relative if a given bit in a register is not set
JMP_BIT_CLEAR_ADDR, // jump relative if a given bit in memory is not set
JG, // JG Addr - Jump if greater (if greater flag set, PC = Addr)
JL, // JL Addr - Jump if less (if less flag set, PC = Addr)
JGE, // JGE Addr - Jump if greater or equal (if greater or zero flag set, PC = Addr)
JLE, // JLE Addr - Jump if less or equal (if less or zero flag set, PC = Addr)
CALL, // CALL Addr - Call subroutine (push PC, flags and registers to stack, PC = Addr)
RET, // RET - Return from subroutine (pop PC, flags and registers from stack)
} Opcode;
#endif //RISCB_CORE_H