rendered paste bodymodule 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