cpu experimentation

This commit is contained in:
2026-03-23 17:08:26 -06:00
parent d4a1d5ad94
commit 3a6fc6cfb9
2 changed files with 195 additions and 7 deletions

View File

@@ -1,5 +1,14 @@
#include "CPU.hpp"
#include <spider/runtime/native/machine.hpp>
#include <spider/runtime/memory/RAM.hpp>
#include <spider/runtime/cpu/InstrReel.hpp>
#if __cplusplus >= 202002L
#include <bit>
#endif
namespace spider {
CPU::CPU()
@@ -9,9 +18,93 @@ namespace spider {
R6{}, R7{}, R8{}, R9{},
RF{}, RI{}, RS{}, RZ{},
RE{}, RN{}, RV{}, RM{},
ALU0{}, ALU1{}
{}
ALU0{}, ALU1{},
_ram(nullptr), _reel(nullptr) {
}
CPU::~CPU() {}
// Setup & Configuration //
void CPU::hookRAM(RAM* ram) {
this->_ram = ram;
}
void CPU::hookInstrReel(InstrReel* reel) {
this->_reel = reel;
}
constexpr u64 CPU::getFlag(u64 mask) {
if (!mask) return 0;
#if __cplusplus >= 202002L
return (RF & mask) >> std::countr_zero(mask);
#elif defined(SPIDER_COMPILER_GCC_LIKE)
return (RF & mask) >> __builtin_ctzll(mask);
#elif defined(SPIDER_COMPILER_MSVC)
return (RF & mask) >> _BitScanForward64(mask);
#else
// If you have reached this part,
// please come up with a better alternative.
u64 bits = RF & mask;
while (mask && (mask >>= 1)) bits >>= 1;
return bits;
#endif
}
// Addressing Modes //
/**
* Implied Addressing Mode
*/
void CPU::imp() {
// Nothing //
}
/**
* Immediate Addressing Mode
*/
void CPU::imm() {
u8 size = 2 << _size;
_next = &ALU0;
}
/**
* Absolute Addressing Mode
*/
void CPU::abs() {
u8 size = 2 << getFlag(CPU::FLAG_MEMORY_MODE);
}
/**
* Register Addressing Mode
*/
void CPU::reg() {
sizeof(CPU);
}
/**
* Indrect Addressing Mode
*/
void CPU::ind() {}
/**
* Pointer Addressing Mode
*/
void CPU::ptr() {}
/**
* Indexed Addressing Mode
*/
void CPU::idx() {}
/**
* Scaled Addressing Mode
*/
void CPU::sca() {}
/**
* Displaced Addressing Mode
*/
void CPU::dis() {}
}

View File

@@ -1,15 +1,28 @@
#pragma once
#include <spider/SpiderRuntime.hpp>
#include <spider/runtime/cpu/Register.hpp>
namespace spider {
class CPU {
public: // Flag Register Constants //
static constexpr const u64 FLAG_ENABLE = 0b0000000000000000000000000000000000000000000000000000000000000001;
static constexpr const u64 FLAG_INTERRUPT_SIGNAL = 0b0000000000000000000000000000000000000000000000000000000000000010;
static constexpr const u64 FLAG_INTERRUPT_REQUEST = 0b0000000000000000000000000000000000000000000000000000000000000100;
static constexpr const u64 FLAG_EXCEPTION = 0b0000000000000000000000000000000000000000000000000000000000001000;
static constexpr const u64 FLAG_MEMORY_MODE = 0b0000000000000000000000000000000000000000000000000000000000110000;
public: // General Purpose Registers
union {
register_t GPR[16];
struct {
register_t RA, RB, RC, RD,
RX, RY, R0, R1,
R2, R3, R4, R5,
R6, R7, R8, R9;
};
};
public: // System Registers
u64 RF;
@@ -31,6 +44,33 @@ namespace spider {
*/
register_t ALU0, ALU1;
private:
/**
* Pointer to the current RAM hooked into
* the CPU.
*
* It is unproved whether having the RAM directly
* into the CPU is better than not, or whether a
* virtual BUS is better.
*
* Alas, this way we can have a CPU state switch
* between memory and instruction banks.
*/
RAM* _ram;
/**
* Pointer to the current Instruction Reel
* hooked into the CPU.
*
* Ditto as RAM.
*/
InstrReel* _reel;
register_t* _next;
u8 _addrm : 6;
u8 _size : 2;
public:
CPU();
@@ -47,6 +87,61 @@ namespace spider {
CPU& operator=(CPU&& other) noexcept = default;
public:
void hookRAM(RAM* ram);
void hookInstrReel(InstrReel* reel);
constexpr u64 getFlag(u64 mask);
public: // Addressing Modes
/**
* Implied Addressing Mode
*/
void imp();
/**
* Immediate Addressing Mode
*/
void imm();
/**
* Absolute Addressing Mode
*/
void abs();
/**
* Register Addressing Mode
*/
void reg();
/**
* Indrect Addressing Mode
*/
void ind();
/**
* Pointer Addressing Mode
*/
void ptr();
/**
* Indexed Addressing Mode
*/
void idx();
/**
* Scaled Addressing Mode
*/
void sca();
/**
* Displaced Addressing Mode
*/
void dis();
public:
// <pygen-target name=cpu-instructions> //