working changes
This commit is contained in:
+169
-14
@@ -1,5 +1,16 @@
|
||||
#include "CPU.hpp"
|
||||
|
||||
#include <spider/runtime/native/machine.hpp>
|
||||
|
||||
#include <spider/runtime/memory/RAM.hpp>
|
||||
#include <spider/runtime/memory/Types.hpp>
|
||||
|
||||
#include <spider/runtime/reel/InstrReel.hpp>
|
||||
|
||||
#if __cplusplus >= 202002L
|
||||
#include <bit>
|
||||
#endif
|
||||
|
||||
namespace spider {
|
||||
|
||||
CPU::CPU()
|
||||
@@ -8,26 +19,170 @@ namespace spider {
|
||||
R2{}, R3{}, R4{}, R5{},
|
||||
R6{}, R7{}, R8{}, R9{},
|
||||
RF{}, RI{}, RS{}, RZ{},
|
||||
RE{}, RN{}, RV{}, RM{}
|
||||
{}
|
||||
RE{}, RN{}, RV{}, RM{},
|
||||
ALU0{}, ALU1{},
|
||||
_dst(nullptr), _src(nullptr),
|
||||
_opcode(0), _addrm(0), _size(0),
|
||||
_store(0), _post(&CPU::imp),
|
||||
_ram(nullptr), _reel(nullptr) {
|
||||
}
|
||||
|
||||
CPU::~CPU() {}
|
||||
|
||||
// Setup & Configuration //
|
||||
|
||||
void CPU::hookRAM(RAM* ram) {
|
||||
this->_ram = ram;
|
||||
}
|
||||
|
||||
void CPU::hookInstrReel(InstrReel* reel) {
|
||||
this->_reel = reel;
|
||||
}
|
||||
|
||||
constexpr u64 CPU::getFlag(u64 mask) {
|
||||
if (!mask) return 0;
|
||||
#if __cplusplus >= 202002L
|
||||
return (RF & mask) >> std::countr_zero(mask);
|
||||
#elif defined(SPIDER_COMPILER_GCC_LIKE)
|
||||
return (RF & mask) >> __builtin_ctzll(mask);
|
||||
#elif defined(SPIDER_COMPILER_MSVC)
|
||||
return (RF & mask) >> _BitScanForward64(mask);
|
||||
#else
|
||||
// If you have reached this part,
|
||||
// please come up with a better alternative.
|
||||
u64 bits = RF & mask;
|
||||
while (mask && (mask >>= 1)) bits >>= 1;
|
||||
return bits;
|
||||
#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);
|
||||
const u16 oc = (i >> 7);
|
||||
_opcode = oc & 0x1FF; // GCC WHY!
|
||||
_addrm = static_cast<u8>((i >> 2) & 0x1F);
|
||||
_size = static_cast<u8>(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 & 0b111]))(); // mask added here too
|
||||
}
|
||||
|
||||
void CPU::fetchOperSrc() {
|
||||
// set ALU
|
||||
_alu = &ALU1;
|
||||
|
||||
// call specific addressing mode
|
||||
(this->*(CPU::addrModes[_addrm & 0b111]))(); // mask keeps index within 0-7
|
||||
|
||||
// modify the _addrm register
|
||||
_addrm = static_cast<u8>((_addrm >> 3) & 0x1F);
|
||||
_addrm++;
|
||||
}
|
||||
|
||||
|
||||
void CPU::execute() {
|
||||
(this->*(CPU::instrMap[_opcode]))(); // no null check needed
|
||||
if(_post) (this->*_post)();
|
||||
}
|
||||
|
||||
|
||||
// Addressing Modes //
|
||||
|
||||
/**
|
||||
* @brief BRAD (0xF7) - Memory Integrity Checksum
|
||||
* Escanea los primeros 256 bytes de memoria y valida contra una firma de seguridad.
|
||||
* Implementado por Bradley Vergara Lara - Estancia 2026.
|
||||
* Implied Addressing Mode
|
||||
*/
|
||||
void CPU::BRAD() {
|
||||
u32 checksum = 0;
|
||||
const u32 MAGIC_SIGNATURE = 0x504944; // Firma de integridad "PID"
|
||||
|
||||
// Recorre la memoria base del sistema
|
||||
for (u16 i = 0; i < 256; i++) {
|
||||
checksum += memory.read8(i);
|
||||
void CPU::imp() {
|
||||
// Nothing //
|
||||
}
|
||||
|
||||
// Si el checksum coincide, RA = 1 (OK), si no RA = 0 (Error)
|
||||
RA = (checksum == MAGIC_SIGNATURE) ? 1 : 0;
|
||||
/**
|
||||
* Immediate Addressing Mode
|
||||
*/
|
||||
void CPU::imm() {
|
||||
_reel->loadRegister(RI, _size, _alu);
|
||||
_opers[0] = _alu;
|
||||
_post = &CPU::imp;
|
||||
RI += 1 << _size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Absolute Addressing Mode
|
||||
*/
|
||||
void CPU::abs() {
|
||||
// Load the actual ptr into the ALU
|
||||
u8 mm = u8(getFlag(CPU::FLAG_MEMORY_MODE));
|
||||
_reel->loadRegister(RI, mm, _alu);
|
||||
RI += 1 << mm;
|
||||
|
||||
// read the memory from RAM
|
||||
_store = _alu->_u64;
|
||||
_ram->loadRegister(_store, _size, _alu);
|
||||
_post = &CPU::psw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register Addressing Mode
|
||||
*/
|
||||
void CPU::reg() { // NOT FINISHED
|
||||
// Two consecutive registers can be declared
|
||||
// Shift if the top part will become .reg too
|
||||
u8 sh = ((_addrm & 0b11000) == 0b11000) * 4;
|
||||
u8 use = 1 - (sh >> 2); // (sh / 4)
|
||||
|
||||
// get byte
|
||||
u8 reg = (_reel->readU8(RI) >> sh) & 0xF;
|
||||
_alu = &GPR[reg];
|
||||
_opers[0] = _alu; // explicitly sets _opers[0] = _dst
|
||||
RI += use;
|
||||
|
||||
// store no-op
|
||||
_post = &CPU::imp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indrect Addressing Mode
|
||||
*/
|
||||
void CPU::ind() {}
|
||||
|
||||
/**
|
||||
* Pointer Addressing Mode
|
||||
*/
|
||||
void CPU::ptr() {}
|
||||
|
||||
/**
|
||||
* Indexed Addressing Mode
|
||||
*/
|
||||
void CPU::idx() {}
|
||||
|
||||
/**
|
||||
* Scaled Addressing Mode
|
||||
*/
|
||||
void CPU::sca() {}
|
||||
|
||||
/**
|
||||
* Displaced Addressing Mode
|
||||
*/
|
||||
void CPU::dis() {}
|
||||
|
||||
/**
|
||||
* Post Write Action
|
||||
*/
|
||||
void CPU::psw() {}
|
||||
|
||||
}
|
||||
@@ -893,6 +893,13 @@ namespace spider {
|
||||
// Operation: Writes "IN KAABA SPIDER" one char per GP register
|
||||
void DGANT();
|
||||
|
||||
/**
|
||||
* @brief BRAD (0xF7) - Memory Integrity Checksum
|
||||
* Escanea los primeros 256 bytes de memoria y valida contra una firma de seguridad.
|
||||
* Implementado por Bradley Vergara Lara - Estancia 2026.
|
||||
*/
|
||||
void BRAD();
|
||||
|
||||
// </pygen-target> //
|
||||
|
||||
};
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
#include "CPU.hpp"
|
||||
|
||||
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{}
|
||||
{}
|
||||
|
||||
CPU::~CPU() {}
|
||||
|
||||
// Stubs for testing
|
||||
void CPU::fetchOperDst() { /* _dst already set manually in tests */ }
|
||||
void CPU::fetchOperSrc() { /* _src already set manually in tests */ }
|
||||
void CPU::imp() { /* no-op post action */ }
|
||||
void CPU::hookRAM(RAM*) {}
|
||||
void CPU::hookInstrReel(InstrReel*) {}
|
||||
void CPU::fetchInstr() {}
|
||||
void CPU::execute() {}
|
||||
void CPU::psw() {}
|
||||
}
|
||||
@@ -13,13 +13,17 @@ namespace spider {
|
||||
fetchOperDst();
|
||||
switch(_size){
|
||||
case 0b00: //byte
|
||||
_dst->_u8 |= (1 << _src->_u8);
|
||||
_dst->_u8 |= (u64(1) << _src->_u8);
|
||||
break;
|
||||
case 0b01: //short
|
||||
_dst->_u16 |= (1 << _src->_u16);
|
||||
_dst->_u16 |= (u64(1) << _src->_u16);
|
||||
break;
|
||||
case 0b10: //int
|
||||
_dst->_u32 |= (1 << _src->_u32);
|
||||
_dst->_u32 |= (u64(1) << _src->_u32);
|
||||
break;
|
||||
case 0b11: //long
|
||||
_dst->_u64 |= (1 << _src->_u64);
|
||||
_dst->_u64 |= (u64(1) << _src->_u64);
|
||||
break;
|
||||
}
|
||||
(this->*_post)();
|
||||
}
|
||||
@@ -30,13 +34,17 @@ namespace spider {
|
||||
fetchOperDst();
|
||||
switch(_size){
|
||||
case 0b00: //byte
|
||||
_dst->_u8 &= ~(1 << _src->_u8);
|
||||
_dst->_u8 &= ~u8(u64(1) << _src->_u8);
|
||||
break;
|
||||
case 0b01: //short
|
||||
_dst->_u16 &= ~(1 << _src->_u16);
|
||||
_dst->_u16 &= ~u16(u64(1) << _src->_u16);
|
||||
break;
|
||||
case 0b10: //int
|
||||
_dst->_u32 &= ~(1 << _src->_u32);
|
||||
_dst->_u32 &= ~u32(u64(1) << _src->_u32);
|
||||
break;
|
||||
case 0b11: //long
|
||||
_dst->_u64 &= ~(1 << _src->_u64);
|
||||
_dst->_u64 &= ~(u64(1) << _src->_u64);
|
||||
break;
|
||||
}
|
||||
(this->*_post)();
|
||||
}
|
||||
@@ -49,34 +57,34 @@ namespace spider {
|
||||
case 0b00: //byte
|
||||
switch (((RF >> _src->_u8) & 1) != ((_dst->_u8 >> _src->_u8) & 1)){
|
||||
case 1:
|
||||
RF |= (1 << _src->_u8);
|
||||
RF |= (u64(1) << _src->_u8);
|
||||
|
||||
case 0:
|
||||
RF &= ~(1 << _src->_u8);
|
||||
RF &= ~(u64(1) << _src->_u8);
|
||||
}
|
||||
case 0b01: //short
|
||||
switch (((RF >> _src->_u16) & 1) != ((_dst->_u16 >> _src->_u16) & 1)){
|
||||
case 1:
|
||||
RF |= (1 << _src->_u16);
|
||||
RF |= (u64(1) << _src->_u16);
|
||||
|
||||
case 0:
|
||||
RF &= ~(1 << _src->_u16);
|
||||
RF &= ~(u64(1) << _src->_u16);
|
||||
}
|
||||
case 0b10: //int
|
||||
switch (((RF >> _src->_u32) & 1) != ((_dst->_u32 >> _src->_u32) & 1)){
|
||||
case 1:
|
||||
RF |= (1 << _src->_u32);
|
||||
RF |= (u64(1) << _src->_u32);
|
||||
|
||||
case 0:
|
||||
RF &= ~(1 << _src->_u32);
|
||||
RF &= ~(u64(1) << _src->_u32);
|
||||
}
|
||||
case 0b11: //long
|
||||
switch (((RF >> _src->_u64) & 1) != ((_dst->_u64 >> _src->_u64) & 1)){
|
||||
case 1:
|
||||
RF |= (1 << _src->_u64);
|
||||
RF |= (u64(1) << _src->_u64);
|
||||
|
||||
case 0:
|
||||
RF &= ~(1 << _src->_u64);
|
||||
RF &= ~(u64(1) << _src->_u64);
|
||||
}
|
||||
}
|
||||
(this->*_post)();
|
||||
@@ -88,12 +96,16 @@ namespace spider {
|
||||
switch(_size){
|
||||
case 0b00: //byte
|
||||
_dst->_u8 = _dst != 0;
|
||||
break;
|
||||
case 0b01: //short
|
||||
_dst->_u16 = _dst != 0;
|
||||
break;
|
||||
case 0b10: //int
|
||||
_dst->_u32 = _dst != 0;
|
||||
break;
|
||||
case 0b11: //long
|
||||
_dst->_u64 = _dst != 0;
|
||||
break;
|
||||
}
|
||||
(this->*_post)();
|
||||
}
|
||||
|
||||
@@ -52,4 +52,22 @@ namespace spider {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief BRAD (0xF7) - Memory Integrity Checksum
|
||||
* Escanea los primeros 256 bytes de memoria y valida contra una firma de seguridad.
|
||||
* Implementado por Bradley Vergara Lara - Estancia 2026.
|
||||
*/
|
||||
void CPU::BRAD() {
|
||||
u32 checksum = 0;
|
||||
const u32 MAGIC_SIGNATURE = 0x504944; // Firma de integridad "PID"
|
||||
|
||||
// Recorre la memoria base del sistema
|
||||
for (u16 i = 0; i < 256; i++) {
|
||||
checksum += _ram->at(i);
|
||||
}
|
||||
|
||||
// Si el checksum coincide, RA = 1 (OK), si no RA = 0 (Error)
|
||||
RA._u8 = (checksum == MAGIC_SIGNATURE) ? 1 : 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user