diff --git a/src/spider/runtime/cpu/CPU.cpp b/src/spider/runtime/cpu/CPU.cpp index e9b456e..cc92778 100644 --- a/src/spider/runtime/cpu/CPU.cpp +++ b/src/spider/runtime/cpu/CPU.cpp @@ -1,17 +1,110 @@ #include "CPU.hpp" +#include + +#include +#include + +#if __cplusplus >= 202002L +#include +#endif + namespace spider { CPU::CPU() - : RA{}, RB{}, RC{}, RD{}, + : RA{}, RB{}, RC{}, RD{}, RX{}, RY{}, R0{}, R1{}, R2{}, R3{}, R4{}, R5{}, 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() {} + } diff --git a/src/spider/runtime/cpu/CPU.hpp b/src/spider/runtime/cpu/CPU.hpp index 0431c1f..7bba16f 100644 --- a/src/spider/runtime/cpu/CPU.hpp +++ b/src/spider/runtime/cpu/CPU.hpp @@ -1,15 +1,28 @@ #pragma once +#include #include 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 - register_t RA, RB, RC, RD, - RX, RY, R0, R1, - R2, R3, R4, R5, - R6, R7, R8, R9; + 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: // //