#ifndef FOOT_EMULATOR #define FOOT_EMULATOR #include #include #include #include namespace foot { struct Operand { Operand(uint8_t bits); enum class AddressingMode { Immediate = 0, Direct, IndirectAutoIncrement, Indirect } addressing_mode; uint8_t register_index; }; class Device { friend class Emulator; public: virtual ~Device() = default; virtual bool update() = 0; virtual uint16_t mapped_memory_size() const { return assigned_memory_size; } protected: Device(uint16_t size); uint32_t& memory(uint16_t index); private: uint32_t* assigned_memory_base; uint32_t assigned_memory_size; }; class Emulator { public: static constexpr uint8_t PC = 31; static constexpr uint8_t LC = 30; Emulator(); void run(const std::vector& program); void map_device(std::unique_ptr&& device); uint32_t& memory_at(uint16_t address); uint32_t& decode_operand(Operand operand); uint32_t& register_at(uint8_t index); void run_instruction(); private: std::array memory; std::array registers; enum class Status { Less, Equal, Greater } status_register; uint32_t instruction; uint32_t configuration; uint32_t dummy_value; std::vector> devices; uint16_t mapped_base; bool keep_running; void read_instruction(); void CNST(); void CMPR(); void BWNG(); void ARNG(); void LONG(); void CONF(); void BWOR(); void BAND(); void BXOR(); void SRSH(); void ZLSH(); void CLSH(); void ADDI(); void SUBT(); void MULT(); void DIVI(); void MODU(); bool repeats() const; uint8_t simd_elements() const; uint8_t shift() const; uint32_t apply_many_unary(uint32_t a, uint32_t (Emulator::*fn)(uint32_t a) const) const; uint32_t apply_many_binary(uint32_t a, uint32_t b, uint32_t (Emulator::*fn)(uint32_t a, uint32_t b) const) const; uint32_t op_arithmetic_negate(uint32_t a) const; uint32_t op_logical_negate(uint32_t a) const; uint32_t op_signed_right_shift(uint32_t a, uint32_t b) const; uint32_t op_pad_zero_left_shift(uint32_t a, uint32_t b) const; uint32_t op_circular_left_shift(uint32_t a, uint32_t b) const; uint32_t op_add(uint32_t a, uint32_t b) const; uint32_t op_sub(uint32_t a, uint32_t b) const; uint32_t op_mul(uint32_t a, uint32_t b) const; uint32_t op_div(uint32_t a, uint32_t b) const; uint32_t op_mod(uint32_t a, uint32_t b) const; }; } #endif//FOOT_EMULATOR