ready for addrm & instr
This commit is contained in:
@@ -6,6 +6,8 @@
|
||||
|
||||
namespace spider {
|
||||
|
||||
const u32 RUNTIME_VERSION_NO = 0x00000000; // v0.1
|
||||
const std::string RUNTIME_VERSION = "alpha v0.1";
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
|
||||
namespace spider {
|
||||
|
||||
extern const u32 RUNTIME_VERSION_NO;
|
||||
extern const std::string RUNTIME_VERSION;
|
||||
|
||||
class Runtime;
|
||||
class CPU;
|
||||
class RAM;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
namespace spider {
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -19,8 +20,10 @@ namespace spider {
|
||||
R6{}, R7{}, R8{}, R9{},
|
||||
RF{}, RI{}, RS{}, RZ{},
|
||||
RE{}, RN{}, RV{}, RM{},
|
||||
ALU0{},
|
||||
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() {}
|
||||
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -100,12 +124,51 @@ namespace spider {
|
||||
|
||||
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> //
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user