#ifndef MACHINE_H #define MACHINE_H #include #include #include #include #include #include #include "constants.h" #include "device.h" #include "input_device.h" #include "output_device.h" #include "file_device.h" #include "opcode.h" #include "utils.h" using std::string; using std::cerr; using std::endl; using std::cout; class Machine { public: Machine(); Machine(int speedkHz) : Machine() { this->speedkHz = speedkHz; _instructionsTable = instructions; } ~Machine(); int getA() const { return A; } void setA(int value) { A = toSIC24(value); } int getB() const { return B; } void setB(int value) { B = toSIC24(value); } int getX() const { return X; } void setX(int value) { X = toSIC24(value); } int getL() const { return L; } void setL(int value) { L = toSIC24(value); } int getS() const { return S; } void setS(int value) { S = toSIC24(value); } int getT() const { return T; } void setT(int value) { T = toSIC24(value); } // PC is an address → don't mask to 24 unless you want 24-bit addressing int getPC() const { return PC; } void setPC(int value) { PC = value; } // status word: keep as-is int getSW() const { return SW; } void setSW(int value) { SW = value; } double getF() const { return F; } void setF(double value) { F = value; } int getReg(int regNum) const; void setReg(int regNum, int value); // Memory access methods int getByte(int address); void setByte(int address, int value); int getWord(int address); void setWord(int address, int value); double getFloat(int address); void setFloat(int address, double value); // Device access methods Device& getDevice(int num); void setDevice(int num, std::shared_ptr device); // Set a file device at index `num` using the provided filename. void setFileDevice(int num, const std::string &filename); // Fetch and execute instructions int fetch(); void execute(); // 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); void invalidOpcode(int opcode); void invalidAddressing(); 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; double F; // memory unsigned char memory[MEMORY_SIZE]; // devices std::vector> devices; // fallback device returned when device slot is empty/invalid Device fallbackDevice; // 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 }; #endif // MACHINE_H