diff --git a/docs/Spider Instructions.xlsx b/docs/Spider Instructions.xlsx index 1ff5eba..e664320 100644 Binary files a/docs/Spider Instructions.xlsx and b/docs/Spider Instructions.xlsx differ diff --git a/src/spider/SpiderRuntime.hpp b/src/spider/SpiderRuntime.hpp index 99afe03..6f87fd0 100644 --- a/src/spider/SpiderRuntime.hpp +++ b/src/spider/SpiderRuntime.hpp @@ -7,5 +7,6 @@ namespace spider { class Runtime; class CPU; class RAM; + class InstrReel; } diff --git a/src/spider/runtime/Runtime.cpp b/src/spider/runtime/Runtime.cpp new file mode 100644 index 0000000..461f093 --- /dev/null +++ b/src/spider/runtime/Runtime.cpp @@ -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); + } + +} diff --git a/src/spider/runtime/Runtime.hpp b/src/spider/runtime/Runtime.hpp new file mode 100644 index 0000000..c4dc9c8 --- /dev/null +++ b/src/spider/runtime/Runtime.hpp @@ -0,0 +1,73 @@ +#pragma once + +#include +#include + +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); + + }; + +} diff --git a/src/spider/runtime/cpu/CPU.hpp b/src/spider/runtime/cpu/CPU.hpp index 2bcb302..0431c1f 100644 --- a/src/spider/runtime/cpu/CPU.hpp +++ b/src/spider/runtime/cpu/CPU.hpp @@ -22,6 +22,7 @@ namespace spider { u64 RM; public: + /** * These are private registers, which are only used * whenever constant things are used. @@ -31,9 +32,21 @@ namespace spider { register_t ALU0, ALU1; public: + CPU(); + + CPU(const CPU& other) = default; + + CPU(CPU&& other) noexcept = default; + ~CPU(); + public: + + CPU& operator=(const CPU& other) = default; + + CPU& operator=(CPU&& other) noexcept = default; + public: // // diff --git a/src/spider/runtime/cpu/InstrReel.cpp b/src/spider/runtime/cpu/InstrReel.cpp new file mode 100644 index 0000000..3a6cfaa --- /dev/null +++ b/src/spider/runtime/cpu/InstrReel.cpp @@ -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; + } + +} diff --git a/src/spider/runtime/cpu/InstrReel.hpp b/src/spider/runtime/cpu/InstrReel.hpp new file mode 100644 index 0000000..5e2175f --- /dev/null +++ b/src/spider/runtime/cpu/InstrReel.hpp @@ -0,0 +1,59 @@ +#pragma once + +#include + +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); + + }; + +} diff --git a/src/spider/runtime/instr/Instr_00-1F.cpp b/src/spider/runtime/instr/Instr_00-1F.cpp new file mode 100644 index 0000000..0d40cc9 --- /dev/null +++ b/src/spider/runtime/instr/Instr_00-1F.cpp @@ -0,0 +1,9 @@ +#include + +namespace spider { + + void CPU::NOP() { + // No Operation // + } + +} diff --git a/src/spider/runtime/memory/RAM.cpp b/src/spider/runtime/memory/RAM.cpp index e69de29..c47d7f2 100644 --- a/src/spider/runtime/memory/RAM.cpp +++ b/src/spider/runtime/memory/RAM.cpp @@ -0,0 +1,114 @@ +#include "RAM.hpp" + +#include + +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; + } + +} diff --git a/src/spider/runtime/memory/RAM.hpp b/src/spider/runtime/memory/RAM.hpp index 9d07316..6df9cdc 100644 --- a/src/spider/runtime/memory/RAM.hpp +++ b/src/spider/runtime/memory/RAM.hpp @@ -12,13 +12,25 @@ namespace spider { class RAM { private: u8* _mem; + u64 _size; + u8 _oob; // Out of bounds reference public: RAM(u64 length); + RAM(const RAM& other); + + RAM(RAM&& other) noexcept; + ~RAM(); + public: + + RAM& operator=(const RAM& other); + + RAM& operator=(RAM&& other) noexcept; + public: // Unsafe access u8& operator[](u64 i); @@ -31,6 +43,12 @@ namespace spider { u8 at(u64 i) const; + public: + + void resize(u64 new_size); + + u64 size() const; + }; } \ No newline at end of file diff --git a/src/spider/runtime/native/distro.hpp b/src/spider/runtime/native/distro.hpp index 3c490ed..1e691a2 100644 --- a/src/spider/runtime/native/distro.hpp +++ b/src/spider/runtime/native/distro.hpp @@ -1,17 +1,5 @@ #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 // // ========================================================== // @@ -43,11 +31,9 @@ #define SPIDER_DISTRO_DESKTOP #define SPIDER_OS_LINUX #else - // ========================================================== // - // MUST be a microcontroller! // - // ========================================================== // - #include - #ifdef SPIDER_DISTRO_MICRO + // === MUST be a microcontroller! === // + #include + #ifndef SPIDER_DISTRO_MICRO #error "[Spider Distro] Could not autodetect. Please select a distro and OS manually." #endif #endif @@ -107,8 +93,6 @@ #elif defined(SPIDER_DISTRO_MICRO) - #include - #define SPIDER_DISTRO_NAME "Micro" #if !defined(SPIDER_USE_ICU) && !defined(SPIDER_NO_ICU) @@ -127,4 +111,5 @@ #endif - +// === Include Distro Defaults === // +#include diff --git a/src/spider/runtime/native/distro_defs.hpp b/src/spider/runtime/native/distro_defs.hpp new file mode 100644 index 0000000..8e7544d --- /dev/null +++ b/src/spider/runtime/native/distro_defs.hpp @@ -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 ================== // + +