module nes6502states (Op, BRK, current, read, LoadIR, IncPC, MUXBusA, AluOp, write, LoadPCH, LoadPCL, LoadSP, IncSP, DecSP, MUXAddr, MUXDO, LoadF_N, LoadF_V, LoadF_B, LoadF_D, LoadF_I, LoadF_Z, LoadF_C, LoadA, LoadX, LoadY, LoadTEMP, LoadTEMPH); input [7:0] Op; input [3:0] current; output BRK; output read; output LoadIR; output IncPC; output [2:0] MUXBusA; output [3:0] AluOp; output write; output LoadPCH; output LoadPCL; output LoadSP; output IncSP; output DecSP; output [1:0] MUXAddr; output MUXDO; output LoadF_N; output LoadF_V; output LoadF_B; output LoadF_D; output LoadF_I; output LoadF_Z; output LoadF_C; output LoadA; output LoadX; output LoadY; output LoadTEMP; output LoadTEMPH; wire [7:0] Op; wire [3:0] current; reg BRK; // Has nothing to do with #$00 .. reg read; reg LoadIR; reg IncPC; reg [2:0] MUXBusA; `define BusAPCL 0 `define BusAPCH 1 `define BusAA 2 `define BusASP 3 `define BusAX 4 `define BusAY 5 reg [3:0] AluOp; `define AluPassA 0 `define AluPassB 1 `define AluPassS 2 `define AluLoadS 3 `define AluAndAB 4 `define AluOraAB 5 `define AluEorAB 6 `define AluShift 7 `define AluAddA1 8 `define AluSubA1 9 `define AluAddAB 10 `define AluSubAB 11 `define AluAddABC 12 `define AluSubABC 13 reg write; reg LoadPCH; reg LoadPCL; reg LoadSP; reg IncSP; reg DecSP; reg [1:0] MUXAddr; `define AddrPC 0 `define AddrSP 1 `define AddrV 2 `define AddrT 3 reg LoadF_N; reg LoadF_V; reg LoadF_B; reg LoadF_D; reg LoadF_I; reg LoadF_Z; reg LoadF_C; reg LoadA; reg LoadX; reg LoadY; reg LoadTEMP; reg LoadTEMPH; always @(current, Op) begin //Some Signals are sampled on next clock.. //////////////////////////////////////////////// //// INITIALS //////////////////////////////////////////////// BRK = 0; read = 0; LoadIR = 0; IncPC = 0; MUXBusA = 0; AluOp = 0; write = 0; LoadPCH = 0; LoadPCL = 0; LoadSP = 0; IncSP = 0; DecSP = 0; MUXAddr = 0; MUXDO = 0; LoadF_N = 0; LoadF_V = 0; LoadF_B = 0; LoadF_D = 0; LoadF_I = 0; LoadF_Z = 0; LoadF_C = 0; LoadA = 0; LoadX = 0; LoadY = 0; LoadTEMP = 0; LoadTEMPH = 0; // Fetch if(current == 1) {read, LoadIR, IncPC} = {1'b1, 1'b1, 1'b1}; //////////////////////////////////////////////// //// MICROCODE //////////////////////////////////////////////// case(Op) default: begin case(current) 2: BRK = 1; default: ; endcase end // IMPLIED 8'h00: begin // BRK case(current) 2: IncPC = 1; 3: begin AluOp = `AluPassA; // Push PCH MUXBusA = `BusAPCH; write = 1; MUXAddr = `AddrSP; DecSP = 1; end 4: begin AluOp = `AluPassA; // Push PCL MUXBusA = `BusAPCL; write = 1; MUXAddr = `AddrSP; DecSP = 1; end 5: begin AluOp = `AluPassS; // Push S write = 1; MUXAddr = `AddrSP; DecSP = 1; end 6: begin LoadPCL = 1; AluOp = `AluPassB; read = 1; MUXAddr = `AddrV; end 7: begin LoadPCH = 1; AluOp = `AluPassB; read = 1; MUXAddr = `AddrV; LoadF_B = 1; BRK = 1; end default: ; endcase end 8'h40: begin // RTI case(current) 2: begin IncSP = 1; IncPC = 1; end 3: begin // Pop S MUXAddr = `AddrSP; AluOp = `AluPassB; read = 1; IncSP = 1; LoadF_N = 1; LoadF_V = 1; LoadF_B = 1; LoadF_D = 1; LoadF_I = 1; LoadF_Z = 1; LoadF_C = 1; end 4: begin // Pop PCL MUXAddr = `AddrSP; LoadPCL = 1; AluOp = `AluPassB; read = 1; IncSP = 1; end 5: begin // Pop PCH MUXAddr = `AddrSP; LoadPCH = 1; AluOp = `AluPassB; read = 1; end 6: BRK = 1; default: ; endcase end 8'h60: begin // RTS case(current) 2: begin IncSP = 1; IncPC = 1; end 3: begin // Pop PCL MUXAddr = `AddrSP; LoadPCL = 1; AluOp = `AluPassB; read = 1; IncSP = 1; end 4: begin // Pop PCH MUXAddr = `AddrSP; LoadPCH = 1; AluOp = `AluPassB; read = 1; end 5: IncPC = 1; 6: BRK = 1; default: ; endcase end 8'h48, 8'h08: begin // PHA, PHP case(current) 2: begin IncPC = 1; end 3: begin if(Op[6]) AluOp = `AluPassA; else AluOp = `AluPassS; MUXBusA = `BusAA; write = 1; MUXAddr = `AddrSP; DecSP = 1; BRK = 1; end default: ; endcase end 8'h68, 8'h28: begin // PLA, PLP case(current) 2: begin IncPC = 1; IncSP = 1; end 3: begin MUXAddr = `AddrSP; if(Op[6]) begin AluOp = `AluPassB; LoadA = 1; end else begin AluOp = `AluLoadS; LoadF_V = 1; LoadF_B = 1; LoadF_D = 1; LoadF_I = 1; LoadF_C = 1; end LoadF_N = 1; LoadF_Z = 1; read = 1; IncSP = 1; end 4: BRK = 1; default: ; endcase end 8'hAA, 8'hA8, 8'hBA, 8'h8A, 8'h9A, 8'h98: begin // TAX, TAY, TSX, TXS, TXA, TYA case(current) 2: begin case(Op) 8'hAA: begin // TAX - NZ LoadX = 1; LoadF_Z = 1; LoadF_N = 1; MUXBusA = `BusAA; AluOp = `AluPassA; end 8'hA8: begin // TAY - NZ LoadY = 1; LoadF_Z = 1; LoadF_N = 1; MUXBusA = `BusAA; AluOp = `AluPassA; end 8'hBA: begin // TSX - NZ LoadX = 1; LoadF_Z = 1; LoadF_N = 1; MUXBusA = `BusASP; AluOp = `AluPassA; end 8'h8A: begin // TXA - NZ LoadA = 1; LoadF_Z = 1; LoadF_N = 1; MUXBusA = `BusAX; AluOp = `AluPassA; end 8'h9A: begin // TXS LoadSP = 1; MUXBusA = `BusAX; AluOp = `AluPassA; end 8'h98: begin // TYA - NZ LoadA = 1; LoadF_Z = 1; LoadF_N = 1; MUXBusA = `BusAY; AluOp = `AluPassA; end default: ; endcase BRK = 1; end default: ; endcase end 8'hE8, 8'hC8, 8'hCA, 8'h88: begin // INX, INY, DEX, DEY case(current) 2: begin if(Op == 8'hE8 || Op == 8'hC8) begin AluOp = `AluAddA1; end else begin AluOp = `AluSubA1; end if(Op[5] || Op[1]) begin MUXBusA = `BusAX; LoadX = 1; end else begin MUXBusA = `BusAY; LoadY = 1; end LoadF_Z = 1; LoadF_N = 1; BRK = 1; end default: ; endcase end // IMMEDIATE 8'hA9, 8'hA2, 8'hA0: begin // LDA, LDX, LDY case(current) 2: begin AluOp = `AluPassB; LoadF_Z = 1; LoadF_N = 1; IncPC = 1; if(Op[0]) LoadA = 1; else if(Op[1]) LoadX = 1; else LoadY = 1; read = 1; BRK = 1; end default: ; endcase end 8'hC9, 8'hE0, 8'hC0: begin // CMP CPX CPY case(current) 2: begin if(Op == 8'hC9) MUXBusA = `BusAA; else if(Op == 8'hE0) MUXBusA = `BusAX; else MUXBusA = `BusAY; AluOp = `AluSubAB; LoadF_Z = 1; LoadF_N = 1; LoadF_C = 1; IncPC = 1; read = 1; BRK = 1; end default: ; endcase end 8'h69, 8'hE9, 8'h29, 8'h09, 8'h49: begin // ADC SBC AND ORA EOR case(current) 2: begin if(Op[7:4] == 4'h6) begin AluOp = `AluAddABC; LoadF_C = 1; LoadF_V = 1; end else if(Op[7:4] == 4'hE) begin AluOp = `AluSubABC; LoadF_C = 1; LoadF_V = 1; end else if(Op[7:4] == 4'h2) begin AluOp = `AluAndAB; end else if(Op[7:4] == 4'h0) begin AluOp = `AluOraAB; end else if(Op[7:4] == 4'h4) begin AluOp = `AluEorAB; end MUXBusA = `BusAA; LoadF_Z = 1; LoadF_N = 1; LoadA = 1; IncPC = 1; read = 1; BRK = 1; end default: ; endcase end // ABSOLUTE 8'h4C: begin // JMP case(current) 2: begin AluOp = `AluPassB; LoadTEMP = 1; IncPC = 1; read = 1; end 3: begin AluOp = `AluPassB; LoadPCH = 1; LoadPCL = 1; read = 1; BRK = 1; end default: ; endcase end 8'h8C, 8'h8D, 8'h8E: begin // STY STA STX case(current) 2: begin AluOp = `AluPassB; LoadTEMP = 1; IncPC = 1; read = 1; end 3: begin AluOp = `AluPassB; LoadTEMPH = 1; IncPC = 1; read = 1; end 4: begin AluOp = `AluPassA; if(Op[3:0] == 4'hC) MUXBusA = `BusAY; else if (Op[3:0] == 4'hD) MUXBusA = `BusAA; else MUXBusA = `BusAX; MUXAddr = `AddrT; write = 1; BRK = 1; end default: ; endcase end // ACCUMULATOR 8'h0A, 8'h4A, 8'h2A, 8'h6A: begin // ASL LSR ROL ROR case(current) 2: begin AluOp = `AluShift; MUXBusA = `BusAA; LoadF_Z = 1; LoadF_N = 1; LoadF_C = 1; LoadA = 1; BRK = 1; end default: ; endcase end endcase end endmodule