diff --git a/src/spider/runtime/Runtime.cpp b/src/spider/runtime/Runtime.cpp index ddb008e..7188517 100644 --- a/src/spider/runtime/Runtime.cpp +++ b/src/spider/runtime/Runtime.cpp @@ -17,8 +17,10 @@ namespace spider { // Stepping/Running the Machine // void Runtime::step() { + // fetchInstr() decodes the opcode, addressing mode and type siz cpu.fetchInstr(); - // TODO: Call instruction + // execute() completes the fetch-decode-execute cycle by calling the correct instruction method based on the opcode. + cpu.execute(); } void Runtime::step(u64 n) { diff --git a/src/spider/runtime/cpu/CPU.hpp b/src/spider/runtime/cpu/CPU.hpp index a2e8aa5..46bb324 100644 --- a/src/spider/runtime/cpu/CPU.hpp +++ b/src/spider/runtime/cpu/CPU.hpp @@ -15,6 +15,14 @@ namespace spider { static constexpr const u64 FLAG_INTERRUPT_REQUEST = 0b0000000000000000000000000000000000000000000000000000000000000100; static constexpr const u64 FLAG_EXCEPTION = 0b0000000000000000000000000000000000000000000000000000000000001000; static constexpr const u64 FLAG_MEMORY_MODE = 0b0000000000000000000000000000000000000000000000000000000000110000; + static constexpr const u64 FLAG_EXT_INT_DISABLE = 0b0000000000000000000000000000000000000000000000000000000010000000; // bit 7 + static constexpr const u64 FLAG_EQUAL = 0b0000000000000000000000000000000000000000000000000000010000000000; // bit 10 + static constexpr const u64 FLAG_EPSILON_ENABLE = 0b0000000000000000000000000000000000000000000000000001000000000000; // bit 12 + static constexpr const u64 FLAG_HOTSWAP_SIGNAL = 0b0000000000000000000000000000000000000000000000010000000000000000; // bit 16 + static constexpr const u64 FLAG_USER_A = 0b0000000000000000000000000000000000000000000100000000000000000000; // bit 20 + static constexpr const u64 FLAG_USER_B = 0b0000000000000000000000000000000000000000001000000000000000000000; // bit 21 + static constexpr const u64 FLAG_USER_C = 0b0000000000000000000000000000000000000000010000000000000000000000; // bit 22 + static constexpr const u64 FLAG_USER_D = 0b0000000000000000000000000000000000000000100000000000000000000000; // bit 23 public: // Map of addressing modes & Instructions @@ -876,6 +884,11 @@ namespace spider { // Operation: void UPY(); + // [Easter Eggs] 0x0F6 — DGANT: "In kaaba Spider" (Yucatec Maya: My name is Spider) + // Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00 + // Operation: Writes "IN KAABA SPIDER" one char per GP register + void DGANT(); + // // }; diff --git a/src/spider/runtime/instr/InstrMap.cpp b/src/spider/runtime/instr/InstrMap.cpp index 6d3e5de..83305f8 100644 --- a/src/spider/runtime/instr/InstrMap.cpp +++ b/src/spider/runtime/instr/InstrMap.cpp @@ -281,7 +281,7 @@ CPU::Fn CPU::instrMap[] = { nullptr, // 0x0F3 nullptr, // 0x0F4 nullptr, // 0x0F5 - nullptr, // 0x0F6 + &CPU::DGANT, // 0x0F6 nullptr, // 0x0F7 nullptr, // 0x0F8 nullptr, // 0x0F9 diff --git a/src/spider/runtime/instr/Instr_020-03F.cpp b/src/spider/runtime/instr/Instr_020-03F.cpp index 58a8805..0ab818f 100644 --- a/src/spider/runtime/instr/Instr_020-03F.cpp +++ b/src/spider/runtime/instr/Instr_020-03F.cpp @@ -154,20 +154,63 @@ namespace spider { // TODO: Implement JIF } + // ── 0x03C — JMR: Dst + Instruction Register -> Instruction Register ── void CPU::JMR() { - // TODO: Implement JMR + fetchOperDst(); + i64 offset; + switch (_size) { + case 0b00: offset = static_cast(_dst->_i8); break; // 1 byte + case 0b01: offset = static_cast(_dst->_i16); break; // 2 bytes + case 0b10: offset = static_cast(_dst->_i32); break; // 4 bytes + case 0b11: offset = _dst->_i64; break; // 8 bytes + } + RI = static_cast(static_cast(RI) + offset); } + // ── 0x03D — JER: Dst + Instruction Register -> Instruction Register IF Flags.EQ ── void CPU::JER() { - // TODO: Implement JER + fetchOperDst(); + if (RF & CPU::FLAG_EQUAL) { + i64 offset; + switch (_size) { + case 0b00: offset = static_cast(_dst->_i8); break; + case 0b01: offset = static_cast(_dst->_i16); break; + case 0b10: offset = static_cast(_dst->_i32); break; + case 0b11: offset = _dst->_i64; break; + } + RI = static_cast(static_cast(RI) + offset); + } } + // ── 0x03E — JNR: Dst + Instruction Register -> Instruction Register IF NOT Flags.EQ ── void CPU::JNR() { - // TODO: Implement JNR + fetchOperDst(); + if (!(RF & CPU::FLAG_EQUAL)) { + i64 offset; + switch (_size) { + case 0b00: offset = static_cast(_dst->_i8); break; + case 0b01: offset = static_cast(_dst->_i16); break; + case 0b10: offset = static_cast(_dst->_i32); break; + case 0b11: offset = _dst->_i64; break; + } + RI = static_cast(static_cast(RI) + offset); + } } + // ── 0x03F — JIR: Dst + Instruction Register -> Instruction Register IF Src ── void CPU::JIR() { - // TODO: Implement JIR + fetchOperSrc(); + fetchOperDst(); + if (_src->_u64 != 0) { + i64 offset; + switch (_size) { + case 0b00: offset = static_cast(_dst->_i8); break; + case 0b01: offset = static_cast(_dst->_i16); break; + case 0b10: offset = static_cast(_dst->_i32); break; + case 0b11: offset = _dst->_i64; break; + } + RI = static_cast(static_cast(RI) + offset); + } } } diff --git a/src/spider/runtime/instr/Instr_040-05F.cpp b/src/spider/runtime/instr/Instr_040-05F.cpp index 153ab96..87d0231 100644 --- a/src/spider/runtime/instr/Instr_040-05F.cpp +++ b/src/spider/runtime/instr/Instr_040-05F.cpp @@ -4,73 +4,195 @@ */ #include +#include #include // provides std::fmod, std::fma and cast support namespace spider { + // ── 0x040 — SFB: Store (User) Flag Bit ────────────────────────────── void CPU::SFB() { - // TODO: Implement SFB + fetchOperSrc(); + fetchOperDst(); + u8 flag_idx = _dst->_u8 & 0x3; + u64 flag_bit = CPU::FLAG_USER_A << flag_idx; + if (_src->_u64 != 0) { + RF |= flag_bit; + } else { + RF &= ~flag_bit; + } } + // ── 0x041 — LFB: Load (User) Flag Bit ────────────────────────────── void CPU::LFB() { - // TODO: Implement LFB + fetchOperSrc(); + fetchOperDst(); + u8 flag_idx = _src->_u8 & 0x3; + u64 flag_bit = CPU::FLAG_USER_A << flag_idx; + _dst->_u64 = (RF & flag_bit) ? 1 : 0; + (this->*_post)(); } + // ── 0x042 — JUF: Jump to absolute position, if user flag is true ──── void CPU::JUF() { - // TODO: Implement JUF + fetchOperSrc(); + fetchOperDst(); + u8 flag_idx = _src->_u8 & 0x3; + u64 flag_bit = CPU::FLAG_USER_A << flag_idx; + if (RF & flag_bit) { + RI = _dst->_u64; + } } + // ── 0x043 — JUR: Jump to relative position, if user flag is true ──── void CPU::JUR() { - // TODO: Implement JUR + fetchOperSrc(); + fetchOperDst(); + u8 flag_idx = _src->_u8 & 0x3; + u64 flag_bit = CPU::FLAG_USER_A << flag_idx; + if (RF & flag_bit) { + i64 offset; + switch (_size) { + case 0b00: offset = static_cast(_dst->_i8); break; + case 0b01: offset = static_cast(_dst->_i16); break; + case 0b10: offset = static_cast(_dst->_i32); break; + case 0b11: offset = _dst->_i64; break; + default: offset = 0; break; + } + RI = static_cast(static_cast(RI) + offset); + } } + // ── 0x044 — PUSH: Dst -> pushed into stack ────────────────────────── void CPU::PUSH() { - // TODO: Implement PUSH + fetchOperDst(); + u8 bytes = 1 << _size; + for (u8 i = 0; i < bytes; i++) { + _ram->at(RS + i) = (*_dst)[i]; + } + RS += bytes; } + // ── 0x045 — POP: popped from stack -> Dst ─────────────────────────── void CPU::POP() { - // TODO: Implement POP + fetchOperDst(); + u8 bytes = 1 << _size; + RS -= bytes; + _ram->loadRegister(RS, _size, _dst); + (this->*_post)(); } + // ── 0x046 — ALLOC: Dst -> heap ptr of size Dst ────────────────────── void CPU::ALLOC() { - // TODO: Implement ALLOC + fetchOperDst(); + // TODO: Proper heap allocation with gap tracking. + _dst->_u64 = 0; + (this->*_post)(); } + // ── 0x047 — HFREE: Frees heap ptr in Dst ──────────────────────────── void CPU::HFREE() { - // TODO: Implement HFREE + fetchOperDst(); + // TODO: Proper heap deallocation. } + // ── 0x04A — CALL: Performs a function call, step XX ────────────────── void CPU::CALL() { - // TODO: Implement CALL + fetchOperDst(); + u64 target = _dst->_u64; + + register_t rz_save; + rz_save._u64 = RZ; + for (u8 i = 0; i < 8; i++) { + _ram->at(RS + i) = rz_save[i]; + } + RS += 8; + + register_t ri_save; + ri_save._u64 = RI; + for (u8 i = 0; i < 8; i++) { + _ram->at(RS + i) = ri_save[i]; + } + RS += 8; + + RZ = RS; + RI = target; } + // ── 0x04B — RET: Undoes a function call, step XX ──────────────────── void CPU::RET() { - // TODO: Implement RET + RS = RZ; + + RS -= 8; + register_t ri_restore; + _ram->loadRegister(RS, 0b11, &ri_restore); + RI = ri_restore._u64; + + RS -= 8; + register_t rz_restore; + _ram->loadRegister(RS, 0b11, &rz_restore); + RZ = rz_restore._u64; } + // ── 0x04C — EDI: bool( Dst ) -> Enable External Interrupts Bit ───── void CPU::EDI() { - // TODO: Implement EDI + fetchOperDst(); + if (_dst->_u64 != 0) { + RF &= ~CPU::FLAG_EXT_INT_DISABLE; + } else { + RF |= CPU::FLAG_EXT_INT_DISABLE; + } } + // ── 0x04D — SHSS: bool( Dst ) -> Hot Swap Signal Bit ──────────────── void CPU::SHSS() { - // TODO: Implement SHSS + fetchOperDst(); + if (_dst->_u64 != 0) { + RF |= CPU::FLAG_HOTSWAP_SIGNAL; + } else { + RF &= ~CPU::FLAG_HOTSWAP_SIGNAL; + } } + // ── 0x050 — FLI: Float Load Immediate ─────────────────────────────── void CPU::FLI() { - // TODO: Implement FLI + fetchOperDst(); + (this->*_post)(); } + // ── 0x051 — FNEG: - Dst -> Dst ────────────────────────────────────── void CPU::FNEG() { - // TODO: Implement FNEG + fetchOperDst(); + switch (_size) { + case 0b10: _dst->_f32 = -_dst->_f32; break; + case 0b11: _dst->_f64 = -_dst->_f64; break; + default: break; + } + (this->*_post)(); } + // ── 0x052 — FADD: Dst + Src -> Dst ────────────────────────────────── void CPU::FADD() { - // TODO: Implement FADD + fetchOperSrc(); + fetchOperDst(); + switch (_size) { + case 0b10: _dst->_f32 += _src->_f32; break; + case 0b11: _dst->_f64 += _src->_f64; break; + default: break; + } + (this->*_post)(); } + // ── 0x053 — FSUB: Dst - Src -> Dst ────────────────────────────────── void CPU::FSUB() { - // TODO: Implement FSUB + fetchOperSrc(); + fetchOperDst(); + switch (_size) { + case 0b10: _dst->_f32 -= _src->_f32; break; + case 0b11: _dst->_f64 -= _src->_f64; break; + default: break; + } + (this->*_post)(); } // ── 0x054 — FMUL: Float Multiplication ─────────────────────────────────── diff --git a/src/spider/runtime/instr/Instr_0E0-0FF.cpp b/src/spider/runtime/instr/Instr_0E0-0FF.cpp index c305616..f043a49 100644 --- a/src/spider/runtime/instr/Instr_0E0-0FF.cpp +++ b/src/spider/runtime/instr/Instr_0E0-0FF.cpp @@ -4,6 +4,7 @@ */ #include +#include namespace spider { @@ -11,4 +12,44 @@ namespace spider { // TODO: Implement UPY } + // ── 0x0F6 — DGANT: "I'm SpiderLang" in a spider web ──────────── + void CPU::DGANT() { + const char art[] = + R"(\ | //)" + R"( \-+-// )" + R"( -- + --)" + R"( //-+-\ )" + R"(// | \)" + R"( )" + R"( I ' M )" + R"( SPIDER )" + R"( LANG )" + R"( )" + R"(\ | //)" + R"( \-+-// )" + R"(-- + -- )" + R"( /-+-\ )" + R"(/ | \ )" + R"( || )" + R"( || )" + R"( || )" + R"(\ | / )" + R"( \-+-/ )" + R"(-- + -- )" + R"( /-+-\ )" + R"(/ | \ )" + R"( || )" + R"( || )" + R"( || )" + R"(\ | / )" + R"( \-+-/ )" + R"(-- + -- )" + R"( /-+-\ )" + R"(/ | \ )" + R"( || )"; + for (u16 i = 0; i < sizeof(art) - 1; i++) { + _ram->at(i) = static_cast(art[i]); + } + } + }