module decoder ( input clk, input rst, input [7:0] instr, output reg [3:0] address_code, output reg [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 @* begin if (rst) begin address_code <= 0; 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 if (column > 0) begin address_code <= column; end else begin if (row >= 4) begin address_code <= ADDR_MODE_IMMEDIATE; end else begin address_code <= ADDR_MODE_ABSOLUTE; end end end end end endmodule