#pragma once #include #include enum ctlreg { DATA_INSTRUCTION_FIELD_BUFFER, // (df << 3) | if_buffer DATA_INSTRUCTION_FIELD_SAVED, // (df_saved << 3) | if_saved HALTED, INT_ENABLE, // (int_enable_delay << 1) | int_enable TT_INPUT, // (tti_flag << 8) | tti_buffer TT_INPUT_INT_ENABLE, TT_OUTPUT, // {tto_flag_old, tto_flag, tto_tx, tto_data} TT_OUTPUT_INT_ENABLE, NUM_CTLREGS, }; struct instruction_context { // Known statically at decode time bool need_indirect_load = false; // final_address = mem[init_address] bool need_autoinc_store = false; // mem[init_address] += 1 bool need_exec_load = false; // data = mem[final_address] bool need_read_acc = false; // acc = %acc bool need_read_link = false; // link = %link bool need_read_mq = false; // mq = %mq std::optional read_ctlreg; // ctlval = %[read_ctlreg] bool need_write_acc = false; // %acc = acc bool need_write_link = false; // %link = link bool need_write_mq = false; // %mq = mq std::optional write_ctlreg; // %[write_ctlreg] = ctlval bool need_exec_store = false; // mem[final_address] = data bool possibly_redirects = false; // %pc = next_pc std::function ef; void execute() { ef(*this); } // May change over the lifetime of the instruction execution unsigned int next_pc; // includes IF std::optional init_address; // includes DF std::optional final_address; // includes DF std::optional ctlval; std::optional data; std::optional acc; std::optional link; std::optional mq; }; instruction_context decode(unsigned int df, unsigned int pc, unsigned int bits, bool interrupt);