MICROCODE_EXECUTOR - retrotruestory/M1DEV GitHub Wiki
/**
- @file microcode_executor.h
- @brief Microcode execution engine for Magic-1 CPU */
#ifndef MAGIC1_MICROCODE_EXECUTOR_H #define MAGIC1_MICROCODE_EXECUTOR_H
#include #include #include #include "alu.h" #include "microcode.h"
namespace magic1 {
class CPU; class Memory;
/**
-
Microinstruction field definitions */ namespace MicroField { // NEXT_ADDR special values constexpr uint8_t NEXT_FETCH = 0x00; ///< Fetch next instruction constexpr uint8_t NEXT_IR = 0xFF; ///< Use IR as next address
// LATCH_REG field values (bits 7-4 of regCtrl) constexpr uint8_t LATCH_NONE = 0x00; ///< No register latch constexpr uint8_t LATCH_MSW = 0x10; ///< Latch MSW (flags only) constexpr uint8_t LATCH_C = 0x20; ///< Latch C register constexpr uint8_t LATCH_PC = 0x30; ///< Latch PC constexpr uint8_t LATCH_DP = 0x40; ///< Latch DP constexpr uint8_t LATCH_SP = 0x50; ///< Latch SP constexpr uint8_t LATCH_A = 0x60; ///< Latch A register constexpr uint8_t LATCH_B = 0x70; ///< Latch B register constexpr uint8_t LATCH_MDR = 0x80; ///< Latch MDR constexpr uint8_t LATCH_PTB = 0x90; ///< Latch PTB constexpr uint8_t LATCH_SSP = 0xA0; ///< Latch SSP constexpr uint8_t LATCH_TPC = 0xB0; ///< Latch TPC constexpr uint8_t LATCH_IR_REG = 0xF0;///< Latch IR_REG (IR[5:7])
// Other regCtrl bits constexpr uint8_t LMAR = 0x08; ///< Latch Memory Address Register constexpr uint8_t LMDRLO = 0x04; ///< Latch MDR low byte constexpr uint8_t LMDRHI = 0x02; ///< Latch MDR high byte constexpr uint8_t EMDRLO = 0x01; ///< Enable MDR low byte output
// miscCtrl bits and fields constexpr uint8_t EMDRHI = 0x80; ///< Enable MDR high byte output constexpr uint8_t PRIV = 0x40; ///< Privileged operation constexpr uint8_t LMODE = 0x20; ///< Latch mode bit constexpr uint8_t LPAGING = 0x10; ///< Latch paging enable bit
// MISC operation field values (bits 3-0 of miscCtrl) constexpr uint8_t M_NONE = 0x00; ///< No misc operation constexpr uint8_t M_RESET_FAULT = 0x01; ///< Reset fault status constexpr uint8_t M_HALT = 0x02; ///< Halt processor constexpr uint8_t M_ERROR = 0x03; ///< Error condition constexpr uint8_t M_TRAPO = 0x04; ///< Trap operation constexpr uint8_t M_LPTE = 0x05; ///< Latch page table entry constexpr uint8_t M_SET_FLAGS = 0x06; ///< Set flags constexpr uint8_t M_INIT_INST = 0x07; ///< Initialize instruction constexpr uint8_t M_RSHIFT = 0x08; ///< Right shift constexpr uint8_t M_MEMRQS = 0x09; ///< Memory request constexpr uint8_t M_LEI = 0x0A; ///< Latch interrupt enable constexpr uint8_t M_DO_BRANCH = 0x0B; ///< Perform branch operation constexpr uint8_t M_SYSCALL = 0x0C; ///< System call constexpr uint8_t M_BKPT = 0x0D; ///< Breakpoint constexpr uint8_t M_CLR_TRAP = 0x0E; ///< Clear trap constexpr uint8_t M_COMMIT = 0x0F; ///< Commit operation
// busCtrl fields
// L-bus source field (bits 7-4 of busCtrl) constexpr uint8_t E_L_MAR = 0x00; ///< Enable MAR to L-bus constexpr uint8_t E_L_MSW = 0x10; ///< Enable MSW to L-bus constexpr uint8_t E_L_C = 0x20; ///< Enable C register to L-bus constexpr uint8_t E_L_PC = 0x30; ///< Enable PC to L-bus constexpr uint8_t E_L_DP = 0x40; ///< Enable DP to L-bus constexpr uint8_t E_L_SP = 0x50; ///< Enable SP to L-bus constexpr uint8_t E_L_A = 0x60; ///< Enable A register to L-bus constexpr uint8_t E_L_B = 0x70; ///< Enable B register to L-bus constexpr uint8_t E_L_MDR = 0x80; ///< Enable MDR to L-bus constexpr uint8_t E_L_PTB = 0x90; ///< Enable PTB to L-bus constexpr uint8_t E_L_SSP = 0xA0; ///< Enable SSP to L-bus constexpr uint8_t E_L_TPC = 0xB0; ///< Enable TPC to L-bus constexpr uint8_t E_L_FCODE = 0xC0; ///< Enable fault code to L-bus constexpr uint8_t E_L_IR_BASE = 0xF0; ///< Enable IR_BASE to L-bus
// R-bus source field (bits 3-2 of busCtrl) constexpr uint8_t E_R_NONE = 0x00; ///< No R-bus source constexpr uint8_t E_R_IMM = 0x04; ///< Enable immediate value to R-bus constexpr uint8_t E_R_MDR = 0x08; ///< Enable MDR to R-bus constexpr uint8_t E_R_FCODE = 0x0C; ///< Enable fault code to R-bus
// IMMVAL field (bits 1-0 of busCtrl) constexpr uint8_t IMM_0 = 0x00; ///< Immediate value 0 constexpr uint8_t IMM_1 = 0x01; ///< Immediate value 1 constexpr uint8_t IMM_NEG2 = 0x02; ///< Immediate value -2 (0xFFFE) constexpr uint8_t IMM_NEG1 = 0x03; ///< Immediate value -1 (0xFFFF)
// aluCtrl fields and bits constexpr uint8_t ALUOP_SIZE_16 = 0x00; ///< 16-bit ALU operation constexpr uint8_t ALUOP_SIZE_8 = 0x80; ///< 8-bit ALU operation
// ALUOP field (bits 6-5 of aluCtrl) constexpr uint8_t OP_IR = 0x00; ///< Use IR to determine operation constexpr uint8_t OP_AND = 0x20; ///< AND operation constexpr uint8_t OP_SUB = 0x40; ///< SUB operation constexpr uint8_t OP_ADD = 0x60; ///< ADD operation
// Other aluCtrl bits constexpr uint8_t CARRY = 0x10; ///< Use carry in operation constexpr uint8_t L_SIZE = 0x08; ///< Latch size (0=byte, 1=word) constexpr uint8_t BR_SENSE = 0x04; ///< Branch sense (invert condition) constexpr uint8_t USER_PTB = 0x02; ///< User page table base constexpr uint8_t CODE_PTB = 0x01; ///< Code/data PTB select }
/**
-
Microcode executor class
-
This class is responsible for executing microcode instructions
-
for the Magic-1 CPU emulation. / class MicrocodeExecutor { public: /*
- Constructor
- @param cpu Reference to the CPU
- @param memory Reference to the Memory */ MicrocodeExecutor(CPU& cpu, Memory& memory);
/**
- Destructor */ ~MicrocodeExecutor();
/**
- Execute a microinstruction at the specified address
- @param microAddress Address of microinstruction to execute
- @return Next microinstruction address */ uint16_t executeMicroinstruction(uint16_t microAddress);
/**
- Load the microcode ROM */ void loadMicroROM();
/**
- Reset the executor state */ void reset();
/**
- Get reference to the microcode ROM
- @return Constant reference to microcode ROM */ const std::array<Microinstruction, 512>& getMicroROM() const;
private: CPU& m_cpu; ///< Reference to the CPU Memory& m_memory; ///< Reference to the memory std::unique_ptr m_alu; ///< ALU instance bool m_halt; ///< Halt flag uint16_t m_lBus; ///< L bus value uint16_t m_rBus; ///< R bus value uint16_t m_dBus; ///< D bus value std::array<Microinstruction, 512> microROM; ///< Microcode ROM
/**
* Process next address field
*
* @param inst Current microinstruction
* @return Next microinstruction address
*/
uint16_t processNextAddr(const Microinstruction& inst);
/**
* Process register control field
*
* @param inst Current microinstruction
* @return Status code (0=success)
*/
uint16_t processRegCtrl(const Microinstruction& inst);
/**
* Process miscellaneous control field
*
* @param inst Current microinstruction
* @return Status code (0=success)
*/
uint16_t processMiscCtrl(const Microinstruction& inst);
/**
* Process bus control field
*
* @param inst Current microinstruction
* @return Status code (0=success)
*/
uint16_t processBusCtrl(const Microinstruction& inst);
/**
* Process ALU control field
*
* @param inst Current microinstruction
* @return Status code (0=success)
*/
uint16_t processAluCtrl(const Microinstruction& inst);
/**
* Get L-bus source value
*
* @param source L-bus source selector
* @return Value from the selected source
*/
uint16_t getLBusSource(uint8_t source);
/**
* Get R-bus source value
*
* @param source R-bus source selector
* @return Value from the selected source
*/
uint16_t getRBusSource(uint8_t source);
/**
* Get immediate value
*
* @param immVal Immediate value selector
* @return Selected immediate value
*/
uint16_t getImmediateValue(uint8_t immVal);
/**
* Check for privilege violation
*
* @param inst Current microinstruction
* @return True if violation occurred
*/
bool checkPrivilegeViolation(const Microinstruction& inst);
/**
* Update CPU flags based on ALU result
*
* @param inst Current microinstruction
*/
void updateFlags(const Microinstruction& inst);
/**
* Handle miscellaneous operations
*
* @param miscOp Miscellaneous operation code
*/
void handleMiscOperation(uint8_t miscOp);
};
} // namespace magic1
#endif // MAGIC1_MICROCODE_EXECUTOR_H