// // Created by bruno on 2.2.2025. // #ifndef RISCB_CORE_H #define RISCB_CORE_H #include #include "stdio.h" enum Mode { Paused, Done, Error, EverySecond, EveryFrame, MaxSpeed }; #define MEM_SIZE 8192 // Register count (register names R0 to R7) #define REG_COUNT 32 // CPU state typedef struct { uint32_t regs[REG_COUNT]; uint8_t memory[MEM_SIZE]; uint32_t pc; // Program counter uint32_t sp; // Stack pointer uint8_t flags; // Status flags enum Mode mode; } 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 CPU’s enum) typedef enum { NOP, // NOP - No operation (does nothing, advances to next instruction) BRK, // BRK - Pause CPU (halts execution until resumed) INC_RN, //INC Rn - Increment register INC_ADDR, //INC [Addr] - Increment address DEC_RN, //DEC Rn - Increment register DEC_ADDR, //DEC [Addr] - Increment address 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) 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) JE_BIT_RN, // jump relative if a given bit in a register is set JE_BIT_ADDR, // jump relative if a given bit in memory is set JNE, // JNE Addr - Jump if not equal (if zero flag not set, PC = Addr) JNE_BIT_RN, // jump relative if a given bit in a register is not set JNE_BIT_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 to stack, PC = Addr) RET, // RET - Return from subroutine (pop PC from stack) PUSH, // PUSH Rn - Push register onto stack (stack[top] = Rn) POP, // POP Rn - Pop value from stack into register (Rn = stack[top]) PUSHF, // PUSHF - Push flags onto stack (stack[top] = flags) POPF // POPF - Pop flags from stack (flags = stack[top]) } Opcode; #endif //RISCB_CORE_H