diff --git a/simulator_SIC_XE/include/constants.h b/simulator_SIC_XE/include/constants.h index 9c8988c..3698665 100644 --- a/simulator_SIC_XE/include/constants.h +++ b/simulator_SIC_XE/include/constants.h @@ -35,4 +35,9 @@ constexpr int BP_DIRECT_MASK = 0b00; constexpr int BIT_E_MASK = 0x10; // mask for e bit in F4 and F3 instructions +//SIC/XE/XE +constexpr bool USE_EXTENDED_MODE = true; +constexpr int VECTOR_REG_SIZE = 4; + + #endif // CONSTANTS_H \ No newline at end of file diff --git a/simulator_SIC_XE/include/instructions.h b/simulator_SIC_XE/include/instructions.h index 61cc452..5bef303 100644 --- a/simulator_SIC_XE/include/instructions.h +++ b/simulator_SIC_XE/include/instructions.h @@ -12,6 +12,7 @@ void hio_handler(Machine& m); void norm_handler(Machine& m); void sio_handler(Machine& m); void tio_handler(Machine& m); +void nop_handler(Machine& m); /* IDEJE ZA SIC_XE_XE :)*/ // void nop(Machine& m); @@ -75,4 +76,26 @@ void tix_handler(Machine& m, int ea, AddressingMode mode); void wd_handler(Machine& m, int ea, AddressingMode mode); +// SIC/XE/XE Extended instruction handlers +void xexe_handler(Machine& m); +void halt_handler(Machine& m); +void nop_handler(Machine& m); + +void vaddr_handler(Machine& m, int r1, int r2); +void vsubr_handler(Machine& m, int r1, int r2); +void vmulr_handler(Machine& m, int r1, int r2); +void vdivr_handler(Machine& m, int r1, int r2); + +void vadd_handler(Machine& m, int ea, AddressingMode mode); +void vsub_handler(Machine& m, int ea, AddressingMode mode); +void vmul_handler(Machine& m, int ea, AddressingMode mode); +void vdiv_handler(Machine& m, int ea, AddressingMode mode); +void stva_handler(Machine& m, int ea, AddressingMode mode); +void stvs_handler(Machine& m, int ea, AddressingMode mode); +void stvt_handler(Machine& m, int ea, AddressingMode mode); +void ldva_handler(Machine& m, int ea, AddressingMode mode); +void ldvs_handler(Machine& m, int ea, AddressingMode mode); +void ldvt_handler(Machine& m, int ea, AddressingMode mode); + + #endif // INSTRUCTIONS_H \ No newline at end of file diff --git a/simulator_SIC_XE/include/machine.h b/simulator_SIC_XE/include/machine.h index b92934e..8e80669 100644 --- a/simulator_SIC_XE/include/machine.h +++ b/simulator_SIC_XE/include/machine.h @@ -26,7 +26,7 @@ using std::cout; class Machine { public: Machine(); - Machine(int speedkHz) : Machine() { this->speedkHz = speedkHz; } + Machine(int speedkHz) : Machine() { this->speedkHz = speedkHz; _instructionsTable = instructions; } ~Machine(); int getA() const { return A; } @@ -82,16 +82,13 @@ public: int fetch(); void execute(); - bool execF1(int opcode); - bool execF2(int opcode, int operand); - bool execSICF3F4(int opcode, int ni, int x, int b, int p, int e, int operand); - // Execution and speed control int getSpeed() const; void setSpeed(int kHz); void start(); void stop(); void tick(); + void halt(); // error handling methods void notImplemented(string mnemonic); @@ -100,6 +97,22 @@ public: void divisionByZero(int opcode); void undefinedHandler(int opcode); + bool getExtendedMode() const { return _exex_mode; } + void enableExtendedMode(); + void disableExtendedMode(); + + + int* getVectorRegister(int regNum); + void setVectorRegister(int regNum, const int* values); + + const int* getVA() const { return VA; } + const int* getVS() const { return VS; } + const int* getVT() const { return VT; } + void setVA(const int* values); + void setVS(const int* values); + void setVT(const int* values); + + private: // registers int A, B, X, L, S, T, PC, SW; @@ -116,6 +129,17 @@ private: // Execution control std::atomic running{false}; std::atomic speedkHz{1}; // Default 1 kHz + + bool execF1(int opcode); + bool execF2(int opcode, int operand); + bool execSICF3F4(int opcode, int ni, int x, int b, int p, int e, int operand); + + + // Extended mode + bool _stopped{false}; + bool _exex_mode{false}; + InstructionInfo* _instructionsTable; + int VA[VECTOR_REG_SIZE], VS[VECTOR_REG_SIZE], VT[VECTOR_REG_SIZE]; // vector operation registers }; diff --git a/simulator_SIC_XE/include/opcode.h b/simulator_SIC_XE/include/opcode.h index 071e1bf..a467488 100644 --- a/simulator_SIC_XE/include/opcode.h +++ b/simulator_SIC_XE/include/opcode.h @@ -66,6 +66,28 @@ #define TIXR 0xB8 #define WD 0xDC +// ============================== +// Extended opcodes (SIC/XE/XE) +// ============================== +#define NOP 0xF1 +#define HALT 0xF2 +#define XEXE 0xEE // Enable extended mode +#define VADD 0x18 +#define VADDR 0x90 +#define VSUB 0x1C +#define VSUBR 0x94 +#define VMUL 0x20 +#define VMULR 0x98 +#define VDIV 0x24 +#define VDIVR 0x9C +#define STVA 0x0C +#define STVS 0x7C +#define STVT 0x84 +#define LDVA 0x00 +#define LDVS 0x68 +#define LDVT 0x04 + + enum class InstructionType { TYPE1, @@ -86,6 +108,7 @@ struct InstructionInfo { }; extern InstructionInfo instructions[]; +extern InstructionInfo instructionsEXEX[]; // Initialize the instruction table void loadInstructionSet(); diff --git a/simulator_SIC_XE/src/instructions.cpp b/simulator_SIC_XE/src/instructions.cpp index 5286311..9a88a68 100644 --- a/simulator_SIC_XE/src/instructions.cpp +++ b/simulator_SIC_XE/src/instructions.cpp @@ -412,3 +412,177 @@ void wd_handler(Machine &m, int ea, AddressingMode mode) // Write rightmost byte of A register to device device.write(static_cast(m.getA() & 0xFF)); } + +void xexe_handler(Machine &m) +{ + m.enableExtendedMode(); + m.execute(); + m.disableExtendedMode(); +} + +void halt_handler(Machine &m) +{ + m.halt(); +} + +void nop_handler(Machine &m) +{ + // Do nothing +} + +void vaddr_handler(Machine &m, int r1, int r2) +{ + int result[VECTOR_REG_SIZE]; + for (int i = 0; i < VECTOR_REG_SIZE; ++i) { + result[i] = m.getVectorRegister(r1)[i] + m.getVectorRegister(r2)[i]; + } + m.setVectorRegister(r2, result); +} + +void vsubr_handler(Machine &m, int r1, int r2) +{ + int result[VECTOR_REG_SIZE]; + for (int i = 0; i < VECTOR_REG_SIZE; ++i) { + result[i] = m.getVectorRegister(r2)[i] - m.getVectorRegister(r1)[i]; + } + m.setVectorRegister(r2, result); +} + +void vmulr_handler(Machine &m, int r1, int r2) +{ + int result[VECTOR_REG_SIZE]; + for (int i = 0; i < VECTOR_REG_SIZE; ++i) { + result[i] = m.getVectorRegister(r1)[i] * m.getVectorRegister(r2)[i]; + } + m.setVectorRegister(r2, result); +} + +void vdivr_handler(Machine &m, int r1, int r2) +{ + int result[VECTOR_REG_SIZE]; + for (int i = 0; i < VECTOR_REG_SIZE; ++i) { + if (m.getVectorRegister(r1)[i] == 0) { + m.divisionByZero(VDIVR); + return; + } + result[i] = m.getVectorRegister(r2)[i] / m.getVectorRegister(r1)[i]; + } + m.setVT(result); +} + +void vadd_handler(Machine &m, int ea, AddressingMode mode) +{ + int baseAddr = resolveWordOperand(m, ea, mode); + int vec[VECTOR_REG_SIZE]; + for (int i = 0; i < VECTOR_REG_SIZE; ++i) { + vec[i] = m.getWord(baseAddr + i * 3); + } + int result[VECTOR_REG_SIZE]; + for (int i = 0; i < VECTOR_REG_SIZE; ++i) { + result[i] = m.getVA()[i] + vec[i]; + } + m.setVA(result); +} + +void vsub_handler(Machine &m, int ea, AddressingMode mode) +{ + int baseAddr = resolveWordOperand(m, ea, mode); + int vec[VECTOR_REG_SIZE]; + for (int i = 0; i < VECTOR_REG_SIZE; ++i) { + vec[i] = m.getWord(baseAddr + i * 3); + } + int result[VECTOR_REG_SIZE]; + for (int i = 0; i < VECTOR_REG_SIZE; ++i) { + result[i] = m.getVA()[i] - vec[i]; + } + m.setVA(result); +} + +void vmul_handler(Machine &m, int ea, AddressingMode mode) +{ + int baseAddr = resolveWordOperand(m, ea, mode); + int vec[VECTOR_REG_SIZE]; + for (int i = 0; i < VECTOR_REG_SIZE; ++i) { + vec[i] = m.getWord(baseAddr + i * 3); + } + int result[VECTOR_REG_SIZE]; + for (int i = 0; i < VECTOR_REG_SIZE; ++i) { + result[i] = m.getVA()[i] * vec[i]; + } + m.setVA(result); +} + +void vdiv_handler(Machine &m, int ea, AddressingMode mode) +{ + int baseAddr = resolveWordOperand(m, ea, mode); + int vec[VECTOR_REG_SIZE]; + for (int i = 0; i < VECTOR_REG_SIZE; ++i) { + vec[i] = m.getWord(baseAddr + i * 3); + } + int result[VECTOR_REG_SIZE]; + for (int i = 0; i < VECTOR_REG_SIZE; ++i) { + if (vec[i] == 0) { + m.divisionByZero(VDIV); + return; + } + result[i] = m.getVA()[i] / vec[i]; + } + m.setVA(result); +} + +void stva_handler(Machine &m, int ea, AddressingMode mode) +{ + int baseAddr = resolveWordOperand(m, ea, mode); + const int* vec = m.getVA(); + for (int i = 0; i < VECTOR_REG_SIZE; ++i) { + m.setWord(baseAddr + i * 3, vec[i]); + } +} + +void stvs_handler(Machine &m, int ea, AddressingMode mode) +{ + int baseAddr = resolveWordOperand(m, ea, mode); + const int* vec = m.getVS(); + for (int i = 0; i < VECTOR_REG_SIZE; ++i) { + m.setWord(baseAddr + i * 3, vec[i]); + } +} + +void stvt_handler(Machine &m, int ea, AddressingMode mode) +{ + int baseAddr = resolveWordOperand(m, ea, mode); + const int* vec = m.getVT(); + for (int i = 0; i < VECTOR_REG_SIZE; ++i) { + m.setWord(baseAddr + i * 3, vec[i]); + } +} + +void ldva_handler(Machine &m, int ea, AddressingMode mode) +{ + int baseAddr = resolveWordOperand(m, ea, mode); + int vec[VECTOR_REG_SIZE]; + for (int i = 0; i < VECTOR_REG_SIZE; ++i) { + vec[i] = m.getWord(baseAddr + i * 3); + } + m.setVA(vec); +} + +void ldvs_handler(Machine &m, int ea, AddressingMode mode) +{ + int baseAddr = resolveWordOperand(m, ea, mode); + int vec[VECTOR_REG_SIZE]; + for (int i = 0; i < VECTOR_REG_SIZE; ++i) { + vec[i] = m.getWord(baseAddr + i * 3); + } + m.setVS(vec); +} + +void ldvt_handler(Machine &m, int ea, AddressingMode mode) +{ + int baseAddr = resolveWordOperand(m, ea, mode); + int vec[VECTOR_REG_SIZE]; + for (int i = 0; i < VECTOR_REG_SIZE; ++i) { + vec[i] = m.getWord(baseAddr + i * 3); + } + m.setVT(vec); +} diff --git a/simulator_SIC_XE/src/machine.cpp b/simulator_SIC_XE/src/machine.cpp index e4ee364..9570054 100644 --- a/simulator_SIC_XE/src/machine.cpp +++ b/simulator_SIC_XE/src/machine.cpp @@ -21,6 +21,8 @@ Machine::Machine() devices[1] = make_shared(std::cout); // device 2: standard error devices[2] = make_shared(std::cerr); + _exex_mode = false; + _instructionsTable = instructions; } Machine::~Machine() @@ -67,6 +69,62 @@ void Machine::undefinedHandler(int opcode) cout << prefix << "Undefined handler for opcode: " << opcode << endl; } +void Machine::enableExtendedMode() +{ + if(!USE_EXTENDED_MODE) return; + _exex_mode = true; + _instructionsTable = instructionsEXEX; +} + +void Machine::disableExtendedMode() +{ + if(!USE_EXTENDED_MODE) return; + _exex_mode = false; + _instructionsTable = instructions; +} + +int *Machine::getVectorRegister(int regNum) +{ + switch (regNum) { + case 0: return VA; + case 4: return VS; + case 5: return VT; + default: + cerr << prefix << "Invalid register number: " << regNum << endl; + return nullptr; + } +} + +void Machine::setVectorRegister(int regNum, const int *values) +{ + int* targetReg = getVectorRegister(regNum); + if (targetReg == nullptr) return; + for (int i = 0; i < VECTOR_REG_SIZE; i++) { + targetReg[i] = toSIC24(values[i]); + } +} + +void Machine::setVA(const int *values) +{ + for (int i = 0; i < VECTOR_REG_SIZE; i++) { + VA[i] = toSIC24(values[i]); + } +} + +void Machine::setVS(const int *values) +{ + for (int i = 0; i < VECTOR_REG_SIZE; i++) { + VS[i] = toSIC24(values[i]); + } +} + +void Machine::setVT(const int *values) +{ + for (int i = 0; i < VECTOR_REG_SIZE; i++) { + VT[i] = toSIC24(values[i]); + } +} + void Machine::tick() { const int speed = speedkHz.load(); @@ -76,6 +134,11 @@ void Machine::tick() std::this_thread::sleep_for(delay); } +void Machine::halt() +{ + _stopped = true; +} + int Machine::getReg(int regNum) const { switch (regNum) { @@ -289,14 +352,16 @@ int Machine::fetch() } void Machine::execute() { + if (_stopped) return; int b1 = fetch(); - InstructionInfo &info = instructions[b1]; + + InstructionInfo &info = _instructionsTable[b1]; if (info.type == InstructionType::TYPE1) { execF1(b1); return; } if (info.type == InstructionType::TYPE2) { execF2(b1, fetch()); return; } int opcode = b1 & TYPE3_4_SIC_MASK; - InstructionInfo &info34 = instructions[opcode]; + InstructionInfo &info34 = _instructionsTable[opcode]; int ni = b1 & NI_MASK; if (info34.type == InstructionType::TYPE3_4) { @@ -329,8 +394,8 @@ void Machine::execute() { bool Machine::execF1(int opcode) { - if (instructions[opcode].handler) { - auto handler = reinterpret_cast(instructions[opcode].handler); + if (_instructionsTable[opcode].handler) { + auto handler = reinterpret_cast(_instructionsTable[opcode].handler); handler(*this); return true; } @@ -343,8 +408,8 @@ bool Machine::execF2(int opcode, int operand) int r1 = (operand >> 4) & 0xF; int r2 = operand & 0xF; - if (instructions[opcode].handler) { - auto handler = reinterpret_cast(instructions[opcode].handler); + if (_instructionsTable[opcode].handler) { + auto handler = reinterpret_cast(_instructionsTable[opcode].handler); handler(*this, r1, r2); return true; } @@ -362,8 +427,8 @@ bool Machine::execSICF3F4(int opcode, int ni, int x, int b, int p, int e, int op // --- PURE SIC --- if (mode == AddressingMode::SIC_DIRECT) { int ea = ea_part + (x ? getX() : 0); - if (instructions[opcode].handler) { - auto h = reinterpret_cast(instructions[opcode].handler); + if (_instructionsTable[opcode].handler) { + auto h = reinterpret_cast(_instructionsTable[opcode].handler); h(*this, ea, mode); return true; } @@ -386,8 +451,8 @@ bool Machine::execSICF3F4(int opcode, int ni, int x, int b, int p, int e, int op // format 4 (e=1): b/p ignored, ea_part is 20-bit absolute int ea = base + ea_part + (x ? getX() : 0); - if (instructions[opcode].handler) { - auto h = reinterpret_cast(instructions[opcode].handler); + if (_instructionsTable[opcode].handler) { + auto h = reinterpret_cast(_instructionsTable[opcode].handler); h(*this, ea, mode); return true; } diff --git a/simulator_SIC_XE/src/main.cpp b/simulator_SIC_XE/src/main.cpp index 16dcd0c..2d9662a 100644 --- a/simulator_SIC_XE/src/main.cpp +++ b/simulator_SIC_XE/src/main.cpp @@ -9,11 +9,16 @@ using std::cout; using std::endl; +struct VectorAddProgram { + int x, y; +}; + + + int main() { loadInstructionSet(); Machine machine; - cout << "SIC/XE Program: Accumulator Loop" << endl; const int TEMP_ADDR = 0x50; @@ -21,61 +26,67 @@ int main() // clear TEMP machine.setByte(TEMP_ADDR, 0); + loadInstructionSet(); - // Program (addresses): - // 0x00 LDA #1 - // 0x03 LDB TEMP - // 0x06 ADDR A,B - // 0x08 RMO B,A - // 0x0A STA TEMP - // 0x0D J LOOP + cout << "SIC/XE Program: Vector add test" << endl; - // LDA #1 - machine.setByte(0x00, 0x01); - machine.setByte(0x01, 0x00); - machine.setByte(0x02, 0x01); + const int VA_ADDR = 0x100; // source vector A + const int VB_ADDR = 0x200; // source vector B + const int VR_ADDR = 0x300; // result store (STVA) - // LDB TEMP - machine.setByte(0x03, 0x6B); - machine.setByte(0x04, 0x00); - machine.setByte(0x05, TEMP_ADDR); + // Prepare two 4-element vectors (WORD = 3 bytes) for VA and VB + int a_vals[VECTOR_REG_SIZE] = {1,2,3,4}; + int b_vals[VECTOR_REG_SIZE] = {5,6,7,8}; - // ADDR A,B - machine.setByte(0x06, 0x90); - machine.setByte(0x07, 0x03); + for (int i = 0; i < VECTOR_REG_SIZE; ++i) { + machine.setWord(VA_ADDR + i * 3, a_vals[i]); + machine.setWord(VB_ADDR + i * 3, b_vals[i]); + } - // RMO B,A - machine.setByte(0x08, 0xAC); - machine.setByte(0x09, 0x30); + // Assemble program at address 0x000 (we use XEXE before each extended op) + // Offsets and bytes (hex): + // 0x00: XEXE -> 0xEE + // 0x01: LDVA (format 4) -> b1=0x03 (LDVA|ni=0x00|0x03), b2=0x10 (e=1), b3=0x01, b4=0x00 (addr 0x100) + // 0x05: XEXE -> 0xEE + // 0x06: LDVS (format 4) -> b1=0x6B (0x68|0x03), b2=0x10, b3=0x02, b4=0x00 (addr 0x200) + // 0x0A: XEXE -> 0xEE + // 0x0B: VADDR B->A (type 2) -> opcode 0x90, operand r1=4 (VS), r2=0 (VA) => operand=(4<<4)|0=0x40 + // 0x0D: XEXE -> 0xEE + // 0x0E: STVA (format4) -> b1=0x0F (0x0C|0x03), b2=0x10, b3=0x03, b4=0x00 (addr 0x300) + // 0x12: J (format4) to self -> b1=0x3F (0x3C|0x03), b2=0x10, b3=0x00, b4=0x12 - // STA TEMP - machine.setByte(0x0A, 0x0F); - machine.setByte(0x0B, 0x00); - machine.setByte(0x0C, TEMP_ADDR); + unsigned char prog[] = { + 0xEE, + 0x01, 0x10, 0x01, 0x00, // LDVA (format 4) with ni=IMMEDIATE -> b1=0x01 + 0xEE, + 0x69, 0x10, 0x02, 0x00, // LDVS (format 4) with ni=IMMEDIATE -> b1=0x69 (0x68|0x01) + 0xEE, + 0x90, 0x40, // VADDR VS->VA (type2) + 0xEE, + 0x0D, 0x10, 0x03, 0x00, // STVA (format4) with ni=IMMEDIATE -> b1=0x0D + 0x3F, 0x10, 0x00, 0x12 // J (format4) loop to 0x12 + }; - // J LOOP - machine.setByte(0x0D, 0x3F); - machine.setByte(0x0E, 0x00); - machine.setByte(0x0F, LOOP_ADDR); + const int PROG_START = 0x00; + for (size_t i = 0; i < sizeof(prog); ++i) { + machine.setByte(PROG_START + static_cast(i), prog[i]); + } - machine.setPC(0x00); + machine.setPC(PROG_START); - cout << "Program loaded. TEMP at 0x" << std::hex << TEMP_ADDR << std::dec << endl; + cout << "Program loaded. VA@0x" << std::hex << VA_ADDR << " VB@0x" << VB_ADDR << " -> store@0x" << VR_ADDR << std::dec << endl; - // run a few iterations - for (int i = 0; i < 10; ++i) { - cout << "Iter " << (i + 1) << ": A=" << machine.getA() - << " B=" << machine.getB() - << " TEMP=" << machine.getByte(TEMP_ADDR); + + const int MAX_STEPS = 100; + for (int i = 0; i < MAX_STEPS; ++i) { + machine.execute(); + } - // advance the program by executing the next 6 instructions - for (int k = 0; k < 6; ++k) machine.execute(); - - cout << " -> A=" << machine.getA() - << " B=" << machine.getB() - << " TEMP=" << machine.getByte(TEMP_ADDR) << "\n"; - - std::this_thread::sleep_for(std::chrono::milliseconds(100)); + // Read back result vector stored at VR_ADDR + cout << "Result vector at 0x" << std::hex << VR_ADDR << std::dec << ": "; + for (int i = 0; i < VECTOR_REG_SIZE; ++i) { + int val = machine.getWord(VR_ADDR + i * 3); + cout << val << (i + 1 < VECTOR_REG_SIZE ? ", " : "\n"); } return 0; diff --git a/simulator_SIC_XE/src/opcode.cpp b/simulator_SIC_XE/src/opcode.cpp index f5d63cf..0b63ce8 100644 --- a/simulator_SIC_XE/src/opcode.cpp +++ b/simulator_SIC_XE/src/opcode.cpp @@ -4,74 +4,96 @@ #include InstructionInfo instructions[0xff]; +InstructionInfo instructionsEXEX[0xff]; void loadInstructionSet() { - instructions[ADD] = {"ADD", InstructionType::TYPE3_4, reinterpret_cast(add_handler)}; - instructions[ADDF] = {"ADDF", InstructionType::TYPE3_4, reinterpret_cast(addf_handler)}; - instructions[ADDR] = {"ADDR", InstructionType::TYPE2, reinterpret_cast(addr_handler)}; - instructions[AND] = {"AND", InstructionType::TYPE3_4, reinterpret_cast(and_handler)}; - instructions[CLEAR] = {"CLEAR", InstructionType::TYPE2, reinterpret_cast(clear_handler)}; - instructions[COMP] = {"COMP", InstructionType::TYPE3_4, reinterpret_cast(comp_handler)}; - instructions[COMPF] = {"COMPF", InstructionType::TYPE3_4, reinterpret_cast(compf_handler)}; - instructions[COMPR] = {"COMPR", InstructionType::TYPE2, reinterpret_cast(compr_handler)}; - instructions[DIV] = {"DIV", InstructionType::TYPE3_4, reinterpret_cast(div_handler)}; - instructions[DIVF] = {"DIVF", InstructionType::TYPE3_4, reinterpret_cast(divf_handler)}; - instructions[DIVR] = {"DIVR", InstructionType::TYPE2, reinterpret_cast(divr_handler)}; - instructions[FIX] = {"FIX", InstructionType::TYPE1, reinterpret_cast(fix_handler)}; - instructions[FLOAT] = {"FLOAT", InstructionType::TYPE1, reinterpret_cast(float_handler)}; - instructions[HIO] = {"HIO", InstructionType::TYPE1, nullptr}; - instructions[J] = {"J", InstructionType::TYPE3_4, reinterpret_cast(j_handler)}; - instructions[JEQ] = {"JEQ", InstructionType::TYPE3_4, reinterpret_cast(jeq_handler)}; - instructions[JGT] = {"JGT", InstructionType::TYPE3_4, reinterpret_cast(jgt_handler)}; - instructions[JLT] = {"JLT", InstructionType::TYPE3_4, reinterpret_cast(jlt_handler)}; - instructions[JSUB] = {"JSUB", InstructionType::TYPE3_4, reinterpret_cast(jsub_handler)}; - instructions[LDA] = {"LDA", InstructionType::TYPE3_4, reinterpret_cast(lda_handler)}; - instructions[LDB] = {"LDB", InstructionType::TYPE3_4, reinterpret_cast(ldb_handler)}; - instructions[LDCH] = {"LDCH", InstructionType::TYPE3_4, reinterpret_cast(ldch_handler)}; - instructions[LDF] = {"LDF", InstructionType::TYPE3_4, reinterpret_cast(ldf_handler)}; - instructions[LDL] = {"LDL", InstructionType::TYPE3_4, reinterpret_cast(ldl_handler)}; - instructions[LDS] = {"LDS", InstructionType::TYPE3_4, reinterpret_cast(lds_handler)}; - instructions[LDT] = {"LDT", InstructionType::TYPE3_4, reinterpret_cast(ldt_handler)}; - instructions[LDX] = {"LDX", InstructionType::TYPE3_4, reinterpret_cast(ldx_handler)}; - instructions[LPS] = {"LPS", InstructionType::TYPE3_4, nullptr}; - instructions[MUL] = {"MUL", InstructionType::TYPE3_4, reinterpret_cast(mul_handler)}; - instructions[MULF] = {"MULF", InstructionType::TYPE3_4, reinterpret_cast(mulf_handler)}; - instructions[MULR] = {"MULR", InstructionType::TYPE2, reinterpret_cast(mulr_handler)}; - instructions[NORM] = {"NORM", InstructionType::TYPE1, reinterpret_cast(norm_handler)}; - instructions[OR] = {"OR", InstructionType::TYPE3_4, reinterpret_cast(or_handler)}; - instructions[RD] = {"RD", InstructionType::TYPE3_4, reinterpret_cast(rd_handler)}; - instructions[RMO] = {"RMO", InstructionType::TYPE2, reinterpret_cast(rmo_handler)}; - instructions[RSUB] = {"RSUB", InstructionType::TYPE3_4, reinterpret_cast(rsub_handler)}; - instructions[SHIFTL] = {"SHIFTL", InstructionType::TYPE2, reinterpret_cast(shiftl_handler)}; - instructions[SHIFTR] = {"SHIFTR", InstructionType::TYPE2, reinterpret_cast(shiftr_handler)}; - instructions[SIO] = {"SIO", InstructionType::TYPE1, nullptr}; - instructions[SSK] = {"SSK", InstructionType::TYPE3_4, nullptr}; - instructions[STA] = {"STA", InstructionType::TYPE3_4, reinterpret_cast(sta_handler)}; - instructions[STB] = {"STB", InstructionType::TYPE3_4, reinterpret_cast(stb_handler)}; - instructions[STCH] = {"STCH", InstructionType::TYPE3_4, reinterpret_cast(stch_handler)}; - instructions[STF] = {"STF", InstructionType::TYPE3_4, reinterpret_cast(stf_handler)}; - instructions[STI] = {"STI", InstructionType::TYPE3_4, nullptr}; - instructions[STL] = {"STL", InstructionType::TYPE3_4, reinterpret_cast(stl_handler)}; - instructions[STS] = {"STS", InstructionType::TYPE3_4, reinterpret_cast(sts_handler)}; - instructions[STSW] = {"STSW", InstructionType::TYPE3_4, reinterpret_cast(stsw_handler)}; - instructions[STT] = {"STT", InstructionType::TYPE3_4, reinterpret_cast(stt_handler)}; - instructions[STX] = {"STX", InstructionType::TYPE3_4, reinterpret_cast(stx_handler)}; - instructions[SUB] = {"SUB", InstructionType::TYPE3_4, reinterpret_cast(sub_handler)}; - instructions[SUBF] = {"SUBF", InstructionType::TYPE3_4, reinterpret_cast(subf_handler)}; - instructions[SUBR] = {"SUBR", InstructionType::TYPE2, reinterpret_cast(subr_handler)}; - instructions[SVC] = {"SVC", InstructionType::TYPE2, reinterpret_cast(svc_handler)}; - instructions[TIXR] = {"TIXR", InstructionType::TYPE2, reinterpret_cast(tixr_handler)}; - instructions[TD] = {"TD", InstructionType::TYPE3_4, reinterpret_cast(td_handler)}; - instructions[TIX] = {"TIX", InstructionType::TYPE3_4, reinterpret_cast(tix_handler)}; - instructions[TIO] = {"TIO", InstructionType::TYPE1, nullptr}; - instructions[WD] = {"WD", InstructionType::TYPE3_4, reinterpret_cast(wd_handler)}; + instructions[ADD] = {"ADD", InstructionType::TYPE3_4, reinterpret_cast(add_handler)}; + instructions[ADDF] = {"ADDF", InstructionType::TYPE3_4, reinterpret_cast(addf_handler)}; + instructions[ADDR] = {"ADDR", InstructionType::TYPE2, reinterpret_cast(addr_handler)}; + instructions[AND] = {"AND", InstructionType::TYPE3_4, reinterpret_cast(and_handler)}; + instructions[CLEAR] = {"CLEAR", InstructionType::TYPE2, reinterpret_cast(clear_handler)}; + instructions[COMP] = {"COMP", InstructionType::TYPE3_4, reinterpret_cast(comp_handler)}; + instructions[COMPF] = {"COMPF", InstructionType::TYPE3_4, reinterpret_cast(compf_handler)}; + instructions[COMPR] = {"COMPR", InstructionType::TYPE2, reinterpret_cast(compr_handler)}; + instructions[DIV] = {"DIV", InstructionType::TYPE3_4, reinterpret_cast(div_handler)}; + instructions[DIVF] = {"DIVF", InstructionType::TYPE3_4, reinterpret_cast(divf_handler)}; + instructions[DIVR] = {"DIVR", InstructionType::TYPE2, reinterpret_cast(divr_handler)}; + instructions[FIX] = {"FIX", InstructionType::TYPE1, reinterpret_cast(fix_handler)}; + instructions[FLOAT] = {"FLOAT", InstructionType::TYPE1, reinterpret_cast(float_handler)}; + instructions[HIO] = {"HIO", InstructionType::TYPE1, nullptr}; + instructions[J] = {"J", InstructionType::TYPE3_4, reinterpret_cast(j_handler)}; + instructions[JEQ] = {"JEQ", InstructionType::TYPE3_4, reinterpret_cast(jeq_handler)}; + instructions[JGT] = {"JGT", InstructionType::TYPE3_4, reinterpret_cast(jgt_handler)}; + instructions[JLT] = {"JLT", InstructionType::TYPE3_4, reinterpret_cast(jlt_handler)}; + instructions[JSUB] = {"JSUB", InstructionType::TYPE3_4, reinterpret_cast(jsub_handler)}; + instructions[LDA] = {"LDA", InstructionType::TYPE3_4, reinterpret_cast(lda_handler)}; + instructions[LDB] = {"LDB", InstructionType::TYPE3_4, reinterpret_cast(ldb_handler)}; + instructions[LDCH] = {"LDCH", InstructionType::TYPE3_4, reinterpret_cast(ldch_handler)}; + instructions[LDF] = {"LDF", InstructionType::TYPE3_4, reinterpret_cast(ldf_handler)}; + instructions[LDL] = {"LDL", InstructionType::TYPE3_4, reinterpret_cast(ldl_handler)}; + instructions[LDS] = {"LDS", InstructionType::TYPE3_4, reinterpret_cast(lds_handler)}; + instructions[LDT] = {"LDT", InstructionType::TYPE3_4, reinterpret_cast(ldt_handler)}; + instructions[LDX] = {"LDX", InstructionType::TYPE3_4, reinterpret_cast(ldx_handler)}; + instructions[LPS] = {"LPS", InstructionType::TYPE3_4, nullptr}; + instructions[MUL] = {"MUL", InstructionType::TYPE3_4, reinterpret_cast(mul_handler)}; + instructions[MULF] = {"MULF", InstructionType::TYPE3_4, reinterpret_cast(mulf_handler)}; + instructions[MULR] = {"MULR", InstructionType::TYPE2, reinterpret_cast(mulr_handler)}; + instructions[NORM] = {"NORM", InstructionType::TYPE1, reinterpret_cast(norm_handler)}; + instructions[OR] = {"OR", InstructionType::TYPE3_4, reinterpret_cast(or_handler)}; + instructions[RD] = {"RD", InstructionType::TYPE3_4, reinterpret_cast(rd_handler)}; + instructions[RMO] = {"RMO", InstructionType::TYPE2, reinterpret_cast(rmo_handler)}; + instructions[RSUB] = {"RSUB", InstructionType::TYPE3_4, reinterpret_cast(rsub_handler)}; + instructions[SHIFTL] = {"SHIFTL", InstructionType::TYPE2, reinterpret_cast(shiftl_handler)}; + instructions[SHIFTR] = {"SHIFTR", InstructionType::TYPE2, reinterpret_cast(shiftr_handler)}; + instructions[SIO] = {"SIO", InstructionType::TYPE1, nullptr}; + instructions[SSK] = {"SSK", InstructionType::TYPE3_4, nullptr}; + instructions[STA] = {"STA", InstructionType::TYPE3_4, reinterpret_cast(sta_handler)}; + instructions[STB] = {"STB", InstructionType::TYPE3_4, reinterpret_cast(stb_handler)}; + instructions[STCH] = {"STCH", InstructionType::TYPE3_4, reinterpret_cast(stch_handler)}; + instructions[STF] = {"STF", InstructionType::TYPE3_4, reinterpret_cast(stf_handler)}; + instructions[STI] = {"STI", InstructionType::TYPE3_4, nullptr}; + instructions[STL] = {"STL", InstructionType::TYPE3_4, reinterpret_cast(stl_handler)}; + instructions[STS] = {"STS", InstructionType::TYPE3_4, reinterpret_cast(sts_handler)}; + instructions[STSW] = {"STSW", InstructionType::TYPE3_4, reinterpret_cast(stsw_handler)}; + instructions[STT] = {"STT", InstructionType::TYPE3_4, reinterpret_cast(stt_handler)}; + instructions[STX] = {"STX", InstructionType::TYPE3_4, reinterpret_cast(stx_handler)}; + instructions[SUB] = {"SUB", InstructionType::TYPE3_4, reinterpret_cast(sub_handler)}; + instructions[SUBF] = {"SUBF", InstructionType::TYPE3_4, reinterpret_cast(subf_handler)}; + instructions[SUBR] = {"SUBR", InstructionType::TYPE2, reinterpret_cast(subr_handler)}; + instructions[SVC] = {"SVC", InstructionType::TYPE2, reinterpret_cast(svc_handler)}; + instructions[TIXR] = {"TIXR", InstructionType::TYPE2, reinterpret_cast(tixr_handler)}; + instructions[TD] = {"TD", InstructionType::TYPE3_4, reinterpret_cast(td_handler)}; + instructions[TIX] = {"TIX", InstructionType::TYPE3_4, reinterpret_cast(tix_handler)}; + instructions[TIO] = {"TIO", InstructionType::TYPE1, nullptr}; + instructions[WD] = {"WD", InstructionType::TYPE3_4, reinterpret_cast(wd_handler)}; - // Mark uninitialized opcodes as INVALID + // Load SIC/XE/XE extended instructions + if (USE_EXTENDED_MODE) { + // Still in main table + instructions[NOP] = {"NOP", InstructionType::TYPE1, reinterpret_cast(nop_handler)}; + instructions[HALT] = {"HALT", InstructionType::TYPE1, reinterpret_cast(halt_handler)}; + instructions[XEXE] = {"XEXE", InstructionType::TYPE1, reinterpret_cast(xexe_handler)}; + + instructionsEXEX[VADD] = {"VADD", InstructionType::TYPE3_4, reinterpret_cast(vadd_handler)}; + instructionsEXEX[VADDR] = {"VADDR", InstructionType::TYPE2, reinterpret_cast(vaddr_handler)}; + instructionsEXEX[VSUB] = {"VSUB", InstructionType::TYPE3_4, reinterpret_cast(vsub_handler)}; + instructionsEXEX[VSUBR] = {"VSUBR", InstructionType::TYPE2, reinterpret_cast(vsubr_handler)}; + instructionsEXEX[VMUL] = {"VMUL", InstructionType::TYPE3_4, reinterpret_cast(vmul_handler)}; + instructionsEXEX[VMULR] = {"VMULR", InstructionType::TYPE2, reinterpret_cast(vmulr_handler)}; + instructionsEXEX[VDIV] = {"VDIV", InstructionType::TYPE3_4, reinterpret_cast(vdiv_handler)}; + instructionsEXEX[VDIVR] = {"VDIVR", InstructionType::TYPE2, reinterpret_cast(vdivr_handler)}; + instructionsEXEX[STVA] = {"STVA", InstructionType::TYPE3_4, reinterpret_cast(stva_handler)}; + instructionsEXEX[STVS] = {"STVS", InstructionType::TYPE3_4, reinterpret_cast(stvs_handler)}; + instructionsEXEX[STVT] = {"STVT", InstructionType::TYPE3_4, reinterpret_cast(stvt_handler)}; + instructionsEXEX[LDVA] = {"LDVA", InstructionType::TYPE3_4, reinterpret_cast(ldva_handler)}; + instructionsEXEX[LDVS] = {"LDVS", InstructionType::TYPE3_4, reinterpret_cast(ldvs_handler)}; + instructionsEXEX[LDVT] = {"LDVT", InstructionType::TYPE3_4, reinterpret_cast(ldvt_handler)}; + } + // Mark uninitialized opcodes as INVALID for (int i = 0; i < 0xff; ++i) { - if (instructions[i].name == nullptr) { - instructions[i] = {"INVALID", InstructionType::INVALID, nullptr}; - } + if (instructions[i].name == nullptr) instructions[i] = {"INVALID", InstructionType::INVALID, nullptr}; + if (instructionsEXEX[i].name == nullptr) instructionsEXEX[i] = {"INVALID", InstructionType::INVALID, nullptr}; } }