ram, instr reel, runtime, etc

This commit is contained in:
2026-03-20 16:53:02 -06:00
parent 16fa0bf3ea
commit 5a4eb66c78
12 changed files with 390 additions and 20 deletions

Binary file not shown.

View File

@@ -7,5 +7,6 @@ namespace spider {
class Runtime; class Runtime;
class CPU; class CPU;
class RAM; class RAM;
class InstrReel;
} }

View File

@@ -0,0 +1,29 @@
#include "Runtime.hpp"
namespace spider {
// Constructors & Destructors //
Runtime::Runtime() : ram(0) {}
Runtime::Runtime(u64 ramSize) : ram(ramSize) {}
Runtime::~Runtime() {}
// Stepping/Running the Machine //
void Runtime::step() {}
void Runtime::step(u64 n) {}
void Runtime::run() {}
void Runtime::run(u64 n) {}
// Misc //
void Runtime::resizeRAM(u64 length) {
ram.resize(length);
}
}

View File

@@ -0,0 +1,73 @@
#pragma once
#include <spider/runtime/cpu/CPU.hpp>
#include <spider/runtime/memory/RAM.hpp>
namespace spider {
/**
* The main runtime class.
* This is where the Spider VM (Runtime) lives
*/
class Runtime {
private:
CPU cpu;
RAM ram;
public:
/**
* Creates a new runtime, with no memory.
*/
Runtime();
/**
* Creates a new runtime, with a specific
* amount of memory.
*/
Runtime(u64 ramSize);
/**
* Runtime Destructor.
*/
~Runtime();
public:
/**
* Steps the clock of the VM once.
*/
void step();
/**
* Steps n-times the clock of the VM.
*/
void step(u64 n);
public:
/**
* Sets the machine to run continously.
* If interrupts occur, they will be handled
* automatically.
*/
void run();
/**
* Runs this machine for a set amount of
* milliseconds.
*/
void run(u64 ms);
public:
/**
* Resizes the ram, which will preserve
* data inside the next length.
*/
void resizeRAM(u64 length);
};
}

View File

@@ -22,6 +22,7 @@ namespace spider {
u64 RM; u64 RM;
public: public:
/** /**
* These are private registers, which are only used * These are private registers, which are only used
* whenever constant things are used. * whenever constant things are used.
@@ -31,9 +32,21 @@ namespace spider {
register_t ALU0, ALU1; register_t ALU0, ALU1;
public: public:
CPU(); CPU();
CPU(const CPU& other) = default;
CPU(CPU&& other) noexcept = default;
~CPU(); ~CPU();
public:
CPU& operator=(const CPU& other) = default;
CPU& operator=(CPU&& other) noexcept = default;
public: public:
// <pygen-target name=cpu-instructions> // // <pygen-target name=cpu-instructions> //

View File

@@ -0,0 +1,29 @@
#include "InstrReel.hpp"
namespace spider {
InstrReel::InstrReel() {}
InstrReel::~InstrReel() {}
u16 InstrReel::instrAt(u64 ip) const {}
u8 InstrReel::dataAt(u64 ip) const {}
u8 InstrReel::feedNext(CPU& cpu) {}
// Static Utils //
u16 InstrReel::unpackInstr(u16 bcode) {
return (bcode >> 5) & 0x1FF;
}
u8 InstrReel::unpackAddrMode(u16 bcode) {
return (bcode >> 2) & 0x1F;
}
u8 InstrReel::unpackTypeSize(u16 bcode) {
return bcode & 0x3;
}
}

View File

@@ -0,0 +1,59 @@
#pragma once
#include <spider/SpiderRuntime.hpp>
namespace spider {
/**
* Implements an instruction reel.
*/
class InstrReel {
private:
public:
InstrReel();
~InstrReel();
public:
public:
/**
* Returns the two-byte instruction at the
* specific byte location.
*/
u16 instrAt(u64 ip) const;
/**
* Obtains a byte of data at
* the specific location.
*/
u8 dataAt(u64 ip) const;
public:
/**
* Fetches the data, and then
* feeds the instruction into the
* CPU.
*
* Returns how many steps it should
* move after.
*/
u8 feedNext(CPU& cpu);
public: // Static Utils //
static u16 unpackInstr(u16 bcode);
static u8 unpackAddrMode(u16 bcode);
static u8 unpackTypeSize(u16 bcode);
};
}

View File

@@ -0,0 +1,9 @@
#include <spider/runtime/cpu/CPU.hpp>
namespace spider {
void CPU::NOP() {
// No Operation //
}
}

View File

@@ -0,0 +1,114 @@
#include "RAM.hpp"
#include <cstring>
namespace spider {
// Constructors & Destructors //
RAM::RAM(u64 length) : _mem(nullptr), _size(length), _oob(0) {
if (_size > 0) {
_mem = new u8[_size];
std::memset(_mem, 0, _size);
}
}
RAM::RAM(const RAM& other) : _size(other._size), _oob(0) {
_mem = new u8[_size];
std::copy(other._mem, other._mem + _size, _mem);
}
RAM::RAM(RAM&& other) noexcept : _mem(other._mem), _size(other._size), _oob(0) {
other._mem = nullptr;
other._size = 0;
}
RAM::~RAM() {
delete[] _mem;
}
// Assign Operators //
RAM& RAM::operator=(const RAM& other) {
if (this == &other) return *this; // lock self
u8* new_mem = new u8[other._size];
std::copy(other._mem, other._mem + other._size, new_mem);
delete[] _mem;
_mem = new_mem;
_size = other._size;
return *this;
}
RAM& RAM::operator=(RAM&& other) noexcept {
if (this == &other) return *this; // lock self
delete[] _mem;
_mem = other._mem; // time to steal!
_size = other._size;
other._mem = nullptr; // leave as a husk
other._size = 0;
return *this;
}
// Unsafe Access //
u8& RAM::operator[](u64 i) { return _mem[i]; }
u8 RAM::operator[](u64 i) const { return _mem[i]; }
// Managed Access //
u8& RAM::at(u64 i) {
return (i < _size) ? _mem[i] : _oob;
}
u8 RAM::at(u64 i) const {
return (i < _size) ? _mem[i] : _oob;
}
// Misc //
void RAM::resize(u64 new_size) {
// Special case 1
if (new_size == _size) return;
// Special case 2
if (new_size == 0) {
delete[] _mem;
_mem = nullptr;
_size = 0;
return;
}
// 1. Allocate the new block
u8* new_mem = new u8[new_size];
// 2. Zero-initialize
std::memset(new_mem, 0, new_size);
// 3. Preserve data
// If shrinking, copy 'new_size' bytes. If growing, copy 'old_size' bytes.
u64 bytes_to_copy = (new_size < _size) ? new_size : _size;
// 3.1 Previous size could be zero, where _mem would be null
if (_mem != nullptr) {
std::copy(_mem, _mem + bytes_to_copy, new_mem);
}
// 4. Swap and Clean up
delete[] _mem;
_mem = new_mem;
_size = new_size;
}
u64 RAM::size() const {
return _size;
}
}

View File

@@ -12,13 +12,25 @@ namespace spider {
class RAM { class RAM {
private: private:
u8* _mem; u8* _mem;
u64 _size;
u8 _oob; // Out of bounds reference
public: public:
RAM(u64 length); RAM(u64 length);
RAM(const RAM& other);
RAM(RAM&& other) noexcept;
~RAM(); ~RAM();
public:
RAM& operator=(const RAM& other);
RAM& operator=(RAM&& other) noexcept;
public: // Unsafe access public: // Unsafe access
u8& operator[](u64 i); u8& operator[](u64 i);
@@ -31,6 +43,12 @@ namespace spider {
u8 at(u64 i) const; u8 at(u64 i) const;
public:
void resize(u64 new_size);
u64 size() const;
}; };
} }

View File

@@ -1,17 +1,5 @@
#pragma once #pragma once
// ========================================================== //
// Compiling or Writing? //
// ========================================================== //
#ifdef SPIDER_WRITING
#error "[Spider Distro] Please do not set this macro."
#endif
#ifndef SPIDER_COMPILING
#define SPIDER_WRITING
#endif
// ========================================================== // // ========================================================== //
// Distro // // Distro //
// ========================================================== // // ========================================================== //
@@ -43,11 +31,9 @@
#define SPIDER_DISTRO_DESKTOP #define SPIDER_DISTRO_DESKTOP
#define SPIDER_OS_LINUX #define SPIDER_OS_LINUX
#else #else
// ========================================================== // // === MUST be a microcontroller! === //
// MUST be a microcontroller! // #include <spider/runtime/native/distro_mcu.hpp>
// ========================================================== // #ifndef SPIDER_DISTRO_MICRO
#include <spider/config_mcu.hpp>
#ifdef SPIDER_DISTRO_MICRO
#error "[Spider Distro] Could not autodetect. Please select a distro and OS manually." #error "[Spider Distro] Could not autodetect. Please select a distro and OS manually."
#endif #endif
#endif #endif
@@ -107,8 +93,6 @@
#elif defined(SPIDER_DISTRO_MICRO) #elif defined(SPIDER_DISTRO_MICRO)
#include <spider/runtime/native/distro_mcu.hpp>
#define SPIDER_DISTRO_NAME "Micro" #define SPIDER_DISTRO_NAME "Micro"
#if !defined(SPIDER_USE_ICU) && !defined(SPIDER_NO_ICU) #if !defined(SPIDER_USE_ICU) && !defined(SPIDER_NO_ICU)
@@ -127,4 +111,5 @@
#endif #endif
// === Include Distro Defaults === //
#include <spider/runtime/native/distro_defs.hpp>

View File

@@ -0,0 +1,40 @@
#pragma once
// ========================================================== //
// SPIDER DEFAULT SETTINGS, PER DISTRO //
// ========================================================== //
// ================== MEMORY FOOTPRINT ================== //
/**
* Use a normal amount of memory, assuming there
* is like 100KB free of it.
*/
#define SPIDER_MEMFOOTPRINT_NORMAL 0
/**
* Attempt to reduce the memory footprint
* where possible, but without doing
* extreme adaptations.
*/
#define SPIDER_MEMFOOTPRINT_REDUCED 1
/**
* Will deliverately convert things from memory
* to functions in order to free as much memory
* as possible, even if it slows things down.
*/
#define SPIDER_MEMFOOTPRINT_MINIMAL 2
#ifndef SPIDER_MEMFOOTPRINT
#if defined(SPIDER_DISTRO_MOBILE) || defined(SPIDER_DISTRO_BROWSER)
#define SPIDER_MEMFOOTPRINT SPIDER_MEMFOOTPRINT_REDUCED
#elif defined(SPIDER_DISTRO_MICRO)
#define SPIDER_MEMFOOTPRINT SPIDER_MEMFOOTPRINT_MINIMAL
#else
#define SPIDER_MEMFOOTPRINT SPIDER_MEMFOOTPRINT_NORMAL
#endif
#endif
// ================== MISC ================== //