module decoder ( input clk, input rst, input [7:0] instr, output logic [4:0] address_code, output logic [7:0] decoded ); `include "parameters.vh" wire [2:0] row = instr[7:5]; wire [2:0] column = instr[4:2]; wire [1:0] sector = instr[1:0]; wire sec_2_stp = (sector == 2) && ((column == 0 && row <= 3) || (column == 4)); wire sec_2_nop = (sector == 2) && ((column == 0 && (row == 4 || row == 6 || row == 7)) || (column == 6 && (row != 4 && row != 5))); always_comb begin address_code = 0; decoded = 0; if (rst) begin address_code = 8'h0; end else begin if (sector == 1) begin case (row) 0: decoded = I_ORA; 1: decoded = I_AND; 2: decoded = I_EOR; 3: decoded = I_ADC; 4: decoded = (column == 2 ? I_STA : I_NOP); 5: decoded = I_LDA; 6: decoded = I_CMP; 7: decoded = I_SBC; endcase address_code = column; end else if (sector == 2) begin case (row) 0: decoded = (sec_2_stp ? I_STP : (sec_2_nop ? I_NOP : I_ASL)); 1: decoded = (sec_2_stp ? I_STP : (sec_2_nop ? I_NOP : I_ROL)); 2: decoded = (sec_2_stp ? I_STP : (sec_2_nop ? I_NOP : I_LSR)); 3: decoded = (sec_2_stp ? I_STP : (sec_2_nop ? I_NOP : I_ROR)); 4: decoded = (sec_2_stp ? I_STP : (sec_2_nop ? I_NOP : (column[0] ? I_STX : I_TXA))); 5: decoded = (sec_2_stp ? I_STP : (column == 2 ? I_TAX : (column == 6 ? I_TSX : I_LDX))); 6: decoded = (sec_2_stp ? I_STP : (sec_2_nop ? I_NOP : (column == 2 ? I_DEX : I_DEC))); 7: decoded = (sec_2_stp ? I_STP : ((sec_2_nop || column == 2) ? I_NOP : I_INC)); endcase if (column > 0) begin address_code = column; end else begin address_code = ADDR_MODE_IMMEDIATE; end end else if (sector == 0) begin if (column == 0) begin case (row) 0: decoded = I_BRK; 1: decoded = I_JSR; 2: decoded = I_RTI; 3: decoded = I_RTS; 4: decoded = I_NOP; 5: decoded = I_LDY; 6: decoded = I_CPY; 7: decoded = I_CPX; endcase end else if (column == 1) begin case (row) 0: decoded = I_NOP; 1: decoded = I_BIT; 2: decoded = I_NOP; 3: decoded = I_NOP; 4: decoded = I_STY; 5: decoded = I_LDY; 6: decoded = I_CPY; 7: decoded = I_CPX; endcase end else if (column == 2) begin case (row) 0: decoded = I_PHP; 1: decoded = I_PLP; 2: decoded = I_PHA; 3: decoded = I_PLA; 4: decoded = I_DEY; 5: decoded = I_TAY; 6: decoded = I_INY; 7: decoded = I_INX; endcase end else if (column == 3) begin case (row) 0: decoded = I_NOP; 1: decoded = I_BIT; 2: decoded = I_JMP; 3: decoded = I_JMP; 4: decoded = I_STY; 5: decoded = I_LDY; 6: decoded = I_CPY; 7: decoded = I_CPX; endcase end else if (column == 4) begin case (row) 0: decoded = I_BPL; 1: decoded = I_BMI; 2: decoded = I_BVC; 3: decoded = I_BVS; 4: decoded = I_BCC; 5: decoded = I_BCS; 6: decoded = I_BNE; 7: decoded = I_BEQ; endcase end else if (column == 5) begin case (row) 0: decoded = I_NOP; 1: decoded = I_NOP; 2: decoded = I_NOP; 3: decoded = I_NOP; 4: decoded = I_STY; 5: decoded = I_LDY; 6: decoded = I_NOP; 7: decoded = I_NOP; endcase end else if (column == 6) begin case (row) 0: decoded = I_CLC; 1: decoded = I_SEC; 2: decoded = I_CLI; 3: decoded = I_SEI; 4: decoded = I_TYA; 5: decoded = I_CLV; 6: decoded = I_CLD; 7: decoded = I_SED; endcase end else if (column == 7) begin case (row) 0: decoded = I_NOP; 1: decoded = I_NOP; 2: decoded = I_NOP; 3: decoded = I_NOP; 4: decoded = I_SHY; 5: decoded = I_LDY; 6: decoded = I_NOP; 7: decoded = I_NOP; endcase end end if (sector == 0) begin if (column == 0) begin if (row == 0 || (row >= 2 && row <= 4)) begin address_code = ADDR_MODE_IMPLIED; end else if (row == 1) begin address_code = ADDR_MODE_ABSOLUTE; end else begin address_code = ADDR_MODE_IMMEDIATE; end end else if(column == 1) begin address_code = ADDR_MODE_ZP; end else if (column == 2) begin address_code = ADDR_MODE_IMPLIED; end else if (column == 3) begin if (row == 3) begin address_code = ADDR_MODE_ABSOLUTE; end else begin address_code = ADDR_MODE_INDEXED_ABSOLUTE; end end else if (column == 4) begin address_code = ADDR_MODE_RELATIVE; end else if (column == 5) begin address_code = ADDR_MODE_INDEXED_ZP; end else if (column == 6) begin address_code = ADDR_MODE_IMPLIED; end else if (column == 7) begin address_code = ADDR_MODE_INDEXED_ABSOLUTE; end end else if(sector == 1) begin if (column == 0) begin address_code = ADDR_MODE_PREINDEXED_INDIRECT; end else if (column == 1) begin address_code = ADDR_MODE_ZP; end else if (column == 2) begin address_code = ADDR_MODE_IMMEDIATE; end else if (column == 3) begin address_code = ADDR_MODE_ABSOLUTE; end else if (column == 4) begin address_code = ADDR_MODE_POSTINDEXED_INDIRECT; end else if (column == 5) begin address_code = ADDR_MODE_INDEXED_ZP; end else if (column == 6 || column == 7) begin address_code = ADDR_MODE_INDEXED_ABSOLUTE; end end else if(sector == 2) begin if (column == 0) begin address_code = ADDR_MODE_IMMEDIATE; end else if (column == 1) begin address_code = ADDR_MODE_ZP; end else if (column == 2 || column == 6) begin address_code = ADDR_MODE_IMPLIED; end else if (column == 3) begin address_code = ADDR_MODE_ABSOLUTE; end // column == 4 are invalid opcodes else if (column == 5) begin address_code = ADDR_MODE_INDEXED_ZP; end else if (column == 7) begin address_code = ADDR_MODE_INDEXED_ABSOLUTE; end end end end endmodule