diff --git a/src/spider/SpiderRuntime.cpp b/src/spider/SpiderRuntime.cpp index cffd95a..8c84608 100644 --- a/src/spider/SpiderRuntime.cpp +++ b/src/spider/SpiderRuntime.cpp @@ -6,6 +6,8 @@ namespace spider { + const u32 RUNTIME_VERSION_NO = 0x00000000; // v0.1 + const std::string RUNTIME_VERSION = "alpha v0.1"; } diff --git a/src/spider/SpiderRuntime.hpp b/src/spider/SpiderRuntime.hpp index 6f87fd0..744b6e2 100644 --- a/src/spider/SpiderRuntime.hpp +++ b/src/spider/SpiderRuntime.hpp @@ -4,6 +4,9 @@ namespace spider { + extern const u32 RUNTIME_VERSION_NO; + extern const std::string RUNTIME_VERSION; + class Runtime; class CPU; class RAM; diff --git a/src/spider/runtime/Runtime.cpp b/src/spider/runtime/Runtime.cpp index 461f093..e46bfc4 100644 --- a/src/spider/runtime/Runtime.cpp +++ b/src/spider/runtime/Runtime.cpp @@ -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; + } + } diff --git a/src/spider/runtime/Runtime.hpp b/src/spider/runtime/Runtime.hpp index 6541690..dba8bbc 100644 --- a/src/spider/runtime/Runtime.hpp +++ b/src/spider/runtime/Runtime.hpp @@ -1,8 +1,11 @@ #pragma once #include + #include +#include + 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); + }; } diff --git a/src/spider/runtime/common.hpp b/src/spider/runtime/common.hpp index 3507fc0..d8f3d61 100644 --- a/src/spider/runtime/common.hpp +++ b/src/spider/runtime/common.hpp @@ -5,6 +5,7 @@ #include #include #include +#include namespace spider { diff --git a/src/spider/runtime/cpu/CPU.cpp b/src/spider/runtime/cpu/CPU.cpp index 3c9d3f5..17366ff 100644 --- a/src/spider/runtime/cpu/CPU.cpp +++ b/src/spider/runtime/cpu/CPU.cpp @@ -3,6 +3,7 @@ #include #include +#include #include @@ -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() {} + } diff --git a/src/spider/runtime/cpu/CPU.hpp b/src/spider/runtime/cpu/CPU.hpp index fba9c8e..afc8984 100644 --- a/src/spider/runtime/cpu/CPU.hpp +++ b/src/spider/runtime/cpu/CPU.hpp @@ -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: // // diff --git a/src/spider/runtime/debug/LiveDebug.cpp b/src/spider/runtime/debug/LiveDebug.cpp index cfe94a4..8e80d5c 100644 --- a/src/spider/runtime/debug/LiveDebug.cpp +++ b/src/spider/runtime/debug/LiveDebug.cpp @@ -1,5 +1,7 @@ #include "LiveDebug.hpp" +#include + #include #include #include @@ -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; }