cpu experimentation
This commit is contained in:
@@ -1,5 +1,14 @@
|
|||||||
#include "CPU.hpp"
|
#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 {
|
namespace spider {
|
||||||
|
|
||||||
CPU::CPU()
|
CPU::CPU()
|
||||||
@@ -9,9 +18,93 @@ namespace spider {
|
|||||||
R6{}, R7{}, R8{}, R9{},
|
R6{}, R7{}, R8{}, R9{},
|
||||||
RF{}, RI{}, RS{}, RZ{},
|
RF{}, RI{}, RS{}, RZ{},
|
||||||
RE{}, RN{}, RV{}, RM{},
|
RE{}, RN{}, RV{}, RM{},
|
||||||
ALU0{}, ALU1{}
|
ALU0{}, ALU1{},
|
||||||
{}
|
_ram(nullptr), _reel(nullptr) {
|
||||||
|
}
|
||||||
|
|
||||||
CPU::~CPU() {}
|
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() {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,28 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <spider/SpiderRuntime.hpp>
|
||||||
#include <spider/runtime/cpu/Register.hpp>
|
#include <spider/runtime/cpu/Register.hpp>
|
||||||
|
|
||||||
namespace spider {
|
namespace spider {
|
||||||
|
|
||||||
class CPU {
|
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
|
public: // General Purpose Registers
|
||||||
|
union {
|
||||||
|
register_t GPR[16];
|
||||||
|
struct {
|
||||||
register_t RA, RB, RC, RD,
|
register_t RA, RB, RC, RD,
|
||||||
RX, RY, R0, R1,
|
RX, RY, R0, R1,
|
||||||
R2, R3, R4, R5,
|
R2, R3, R4, R5,
|
||||||
R6, R7, R8, R9;
|
R6, R7, R8, R9;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
public: // System Registers
|
public: // System Registers
|
||||||
u64 RF;
|
u64 RF;
|
||||||
@@ -31,6 +44,33 @@ namespace spider {
|
|||||||
*/
|
*/
|
||||||
register_t ALU0, ALU1;
|
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:
|
public:
|
||||||
|
|
||||||
CPU();
|
CPU();
|
||||||
@@ -47,6 +87,61 @@ namespace spider {
|
|||||||
|
|
||||||
CPU& operator=(CPU&& other) noexcept = default;
|
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:
|
public:
|
||||||
|
|
||||||
// <pygen-target name=cpu-instructions> //
|
// <pygen-target name=cpu-instructions> //
|
||||||
|
|||||||
Reference in New Issue
Block a user