ready for addrm & instr

This commit is contained in:
2026-03-25 10:00:21 -06:00
parent 1c971a4e22
commit e24e8dfe2d
8 changed files with 245 additions and 20 deletions

View File

@@ -6,6 +6,8 @@
namespace spider {
const u32 RUNTIME_VERSION_NO = 0x00000000; // v0.1
const std::string RUNTIME_VERSION = "alpha v0.1";
}

View File

@@ -4,6 +4,9 @@
namespace spider {
extern const u32 RUNTIME_VERSION_NO;
extern const std::string RUNTIME_VERSION;
class Runtime;
class CPU;
class RAM;

View File

@@ -4,17 +4,33 @@ namespace spider {
// Constructors & Destructors //
Runtime::Runtime() : ram(0) {}
Runtime::Runtime() : Runtime(0) {}
Runtime::Runtime(u64 ramSize) : ram(ramSize) {}
Runtime::Runtime(u64 ramSize) : ram(ramSize), reel(nullptr) {
cpu.hookRAM(&ram);
}
Runtime::~Runtime() {}
Runtime::~Runtime() {
delete reel;
}
// Stepping/Running the Machine //
void Runtime::step() {}
void Runtime::step() {
cpu.fetchInstr();
// TODO: Call instruction
}
void Runtime::step(u64 n) {}
void Runtime::step(u64 n) {
while(n >= 4) {
step();
step();
step();
step();
n -= 4;
}
while (n--) step();
}
void Runtime::run() {}
@@ -26,4 +42,12 @@ namespace spider {
ram.resize(length);
}
/**
* Non-owning reel setup.
*/
void Runtime::hookReel(InstrReel* reel, bool own) {
cpu.hookInstrReel(reel);
if(own) this->reel = reel;
}
}

View File

@@ -1,8 +1,11 @@
#pragma once
#include <spider/runtime/cpu/CPU.hpp>
#include <spider/runtime/memory/RAM.hpp>
#include <spider/runtime/reel/InstrReel.hpp>
namespace spider {
/**
@@ -14,6 +17,7 @@ namespace spider {
CPU cpu;
RAM ram;
InstrReel* reel;
public:
@@ -68,6 +72,11 @@ namespace spider {
*/
void resizeRAM(u64 length);
/**
* Non-owning reel setup.
*/
void hookReel(InstrReel* reel, bool own = false);
};
}

View File

@@ -5,6 +5,7 @@
#include <deque>
#include <map>
#include <optional>
#include <string>
namespace spider {

View File

@@ -3,6 +3,7 @@
#include <spider/runtime/native/machine.hpp>
#include <spider/runtime/memory/RAM.hpp>
#include <spider/runtime/memory/Types.hpp>
#include <spider/runtime/reel/InstrReel.hpp>
@@ -14,13 +15,15 @@ namespace spider {
CPU::CPU()
: 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{},
RX{}, RY{}, R0{}, R1{},
R2{}, R3{}, R4{}, R5{},
R6{}, R7{}, R8{}, R9{},
RF{}, RI{}, RS{}, RZ{},
RE{}, RN{}, RV{}, RM{},
ALU0{}, ALU1{},
_dst(nullptr), _src(nullptr),
_instr(0), _addrm(0), _size(0),
_store(0), _post(&CPU::imp),
_ram(nullptr), _reel(nullptr) {
}
@@ -53,6 +56,44 @@ namespace spider {
#endif
}
// Interaction with Reel //
CPU::Fn CPU::addrModes[] = {
&CPU::imm, &CPU::abs,
&CPU::reg, &CPU::ind,
&CPU::ptr, &CPU::idx,
&CPU::sca, &CPU::dis
};
void CPU::fetchInstr() {
u16 i = _reel->readU16(RI);
_instr = (i >> 7) & 0x1FF;
_addrm = (i >> 2) & 0x1F;
_size = i & 0x3;
RI += 2;
}
void CPU::fetchOperDst() {
// Move the operand ptrs
_alu = &ALU0;
_opers[1] = _opers[0];
// call specific addressing mode
(this->*(CPU::addrModes[_addrm & 0x7]))();
}
void CPU::fetchOperSrc() {
// set ALU
_alu = &ALU1;
// call specific addressing mode
(this->*(CPU::addrModes[_addrm & 0x7]))();
// modify the _addrm register
_addrm >>= 3;
_addrm++;
}
// Addressing Modes //
/**
@@ -66,13 +107,67 @@ namespace spider {
* Immediate Addressing Mode
*/
void CPU::imm() {
switch(_size) {
case 0b00:
_alu->_u8 = _reel->readU8(RI);
break;
case 0b01:
_alu->_u16 = _reel->readU16(RI);
break;
case 0b10:
_alu->_u32 = _reel->readU32(RI);
break;
case 0b11:
_alu->_u64 = _reel->readU64(RI);
break;
}
_opers[0] = _alu;
_post = &CPU::imp;
RI += 1 << _size;
}
/**
* Absolute Addressing Mode
*/
void CPU::abs() {
u8 size = 2 << getFlag(CPU::FLAG_MEMORY_MODE);
void CPU::abs() { // TODO cache ptr size
u8 dat_size = 1 << _size;
u8 ptr_size = 1 << getFlag(CPU::FLAG_MEMORY_MODE);
u64 ptr = 0;
if(ptr_size + dat_size > _ram->size()) return; // TODO: avoid overflow
switch(ptr_size) {
case 1:
ptr = _reel->readU8(RI);
break;
case 2:
ptr = _reel->readU16(RI);
break;
case 4:
ptr = _reel->readU32(RI);
break;
case 8:
ptr = _reel->readU64(RI);
break;
}
switch(_size) {
case 0b00:
spider::loadLE(&_alu->_u8, &(*_ram)[ptr]);
break;
case 0b01:
spider::loadLE(&_alu->_u16, &(*_ram)[ptr]);
break;
case 0b10:
spider::loadLE(&_alu->_u32, &(*_ram)[ptr]);
break;
case 0b11:
spider::loadLE(&_alu->_u64, &(*_ram)[ptr]);
break;
}
RI += dat_size;
}
/**
@@ -107,4 +202,9 @@ namespace spider {
*/
void CPU::dis() {}
/**
* Post Write Action
*/
void CPU::psw() {}
}

View File

@@ -6,6 +6,9 @@
namespace spider {
class CPU {
public: // Helper types
using Fn = void (CPU::*)();
public: // Flag Register Constants //
static constexpr const u64 FLAG_ENABLE = 0b0000000000000000000000000000000000000000000000000000000000000001;
static constexpr const u64 FLAG_INTERRUPT_SIGNAL = 0b0000000000000000000000000000000000000000000000000000000000000010;
@@ -13,6 +16,10 @@ namespace spider {
static constexpr const u64 FLAG_EXCEPTION = 0b0000000000000000000000000000000000000000000000000000000000001000;
static constexpr const u64 FLAG_MEMORY_MODE = 0b0000000000000000000000000000000000000000000000000000000000110000;
public: // Map of addressing modes
static CPU::Fn addrModes[];
public: // General Purpose Registers
union {
register_t GPR[16];
@@ -42,16 +49,33 @@ namespace spider {
* This way we don't "write" into constant values, rather
* we write into a writeable var which is "hidden"
*/
register_t ALU0;
register_t ALU0, ALU1;
union {
struct {
register_t* _dst;
register_t* _src;
register_t* _alu;
};
register_t* _opers[2];
};
// Holds the current instruction opcode
u16 _instr : 9;
// Holds the current addressing modes,
// before they were used
u8 _addrm : 5;
// Holds the current instruction size.
u8 _size : 2;
// On _post that are not no-ops, it must
// write back DST to this memory location.
u64 _store;
// Post execution callback
CPU::Fn _post;
private:
@@ -99,13 +123,52 @@ namespace spider {
void hookInstrReel(InstrReel* reel);
constexpr u64 getFlag(u64 mask);
public:
/**
* Fetches the instruction from the
* reel, and advances IR by two.
*/
void fetchInstr();
/**
* Fetches the destination operand,
* by calling the appropriate addressing
* mode.
*
* Will read the bottom 3 bits.
* For instructions with two operands,
* call Src first.
*
* The internal variable _addrm
* will not be modified. It will
* be important when writing
* back the result.
*/
void fetchOperDst();
/**
* Fetches the source operand.
*
* For use in two operand instructions.
*
* Will read the bottom 3 bits. It will
* then shift the _addrm 3 spaces
* to ensure it aligns with the DST
* next.
*
* Additionally, it will add 1 to _addrm
* to account with
*/
void fetchOperSrc();
public: // Addressing Modes
/**
* Implied Addressing Mode
*/
void imp();
void imp(); // Kept as it is a no-op
/**
* Immediate Addressing Mode
@@ -147,6 +210,11 @@ namespace spider {
*/
void dis();
/**
* Post-Write Action
*/
void psw();
public:
// <pygen-target name=cpu-instructions> //

View File

@@ -1,5 +1,7 @@
#include "LiveDebug.hpp"
#include <spider/runtime/reel/InstrReelFixed.hpp>
#include <spider/runtime/Runtime.hpp>
#include <spider/runtime/util/Terminal.hpp>
#include <spider/runtime/native/distro.hpp>
@@ -122,7 +124,7 @@ namespace spider {
&cpu.R6, &cpu.R7, &cpu.R8, &cpu.R9,
//&cpu.RF, &cpu.RI, &cpu.RS, &cpu.RZ,
//&cpu.RE, &cpu.RN, &cpu.RV, &cpu.RM,
&cpu.ALU0, &cpu.ALU0
&cpu.ALU0, &cpu.ALU1
};
const u64* sys_regs[] = {
&cpu.RF, &cpu.RI, &cpu.RS, &cpu.RZ,
@@ -148,12 +150,12 @@ namespace spider {
t.move(r += 16, c);
r++;
for (i32 j = 0, i = 8; i < 12; j++, i++) {
for (i32 j = 0; j < 4; j++) {
t.style(alt[j & 1]);
t.move(r + j * 2, c);
printU64Hex(*sys_regs[i * 2]);
printU64Hex(*sys_regs[j * 2]);
t.move(r + j * 2, c + 17);
printU64Hex(*sys_regs[i * 2 + 1]);
printU64Hex(*sys_regs[j * 2 + 1]);
}
t.move(r += 8, c);
@@ -328,6 +330,17 @@ namespace spider {
int liveDebugMain() {
Terminal t;
Runtime runtime(1024);
InstrReelFixed fix(100);
runtime.ram[0] = 0xFF;
runtime.ram[1] = 0xEE;
runtime.ram[2] = 0xDD;
runtime.ram[3] = 0xCC;
runtime.ram[4] = 0xBB;
runtime.ram[5] = 0xAA;
runtime.ram[6] = 0x99;
runtime.ram[7] = 0x88;
fix.writeU16(0, 0b0000111);
runtime.hookReel(&fix, false);
bool running = true, update = true;
u64 ramScroll = 0;
@@ -372,6 +385,11 @@ namespace spider {
if (runtime.ram.size() >= 16 && ramScroll <= runtime.ram.size() - 16) ramScroll += 16;
update = true;
break;
case Terminal::ENTER:
update = true;
runtime.cpu.fetchInstr();
runtime.cpu.fetchOperDst();
break;
default:
break;
}