mirror of
https://github.com/Gehstock/Mist_FPGA.git
synced 2026-02-19 05:46:53 +00:00
4423 lines
120 KiB
Systemverilog
4423 lines
120 KiB
Systemverilog
module mc6801_core(
|
|
input logic clk,
|
|
input logic rst,
|
|
output logic rw,
|
|
output logic vma,
|
|
output logic[15:0]address,
|
|
input logic[7:0] data_in,
|
|
output logic[7:0] data_out,
|
|
input logic hold,
|
|
input logic halt,
|
|
input logic irq,
|
|
input logic nmi,
|
|
input logic irq_icf,
|
|
input logic irq_ocf,
|
|
input logic irq_tof,
|
|
input logic irq_sci,
|
|
output logic[15:0] test_alu,
|
|
output logic[7:0] test_cc
|
|
);
|
|
localparam SBIT = 7;
|
|
localparam XBIT = 6;
|
|
localparam HBIT = 5;
|
|
localparam IBIT = 4;
|
|
localparam NBIT = 3;
|
|
localparam ZBIT = 2;
|
|
localparam VBIT = 1;
|
|
localparam CBIT = 0;
|
|
|
|
typedef enum logic[5:0] {reset_state, fetch_state, decode_state,
|
|
extended_state, indexed_state, read8_state, read16_state, immediate16_state,
|
|
write8_state, write16_state,
|
|
execute_state, halt_state, error_state,
|
|
mul_state, mulea_state, muld_state,
|
|
mul0_state, mul1_state, mul2_state, mul3_state,
|
|
mul4_state, mul5_state, mul6_state, mul7_state,
|
|
jmp_state, jsr_state, jsr1_state,
|
|
branch_state, bsr_state, bsr1_state,
|
|
rts_hi_state, rts_lo_state,
|
|
int_pcl_state, int_pch_state,
|
|
int_ixl_state, int_ixh_state,
|
|
int_cc_state, int_acca_state, int_accb_state,
|
|
int_wai_state, int_mask_state,
|
|
rti_state, rti_cc_state, rti_acca_state, rti_accb_state,
|
|
rti_ixl_state, rti_ixh_state,
|
|
rti_pcl_state, rti_pch_state,
|
|
pula_state, psha_state, pulb_state, pshb_state,
|
|
pulx_lo_state, pulx_hi_state, pshx_lo_state, pshx_hi_state,
|
|
vect_lo_state, vect_hi_state } state_type;
|
|
typedef enum logic[5:0] {idle_ad, fetch_ad, read_ad, write_ad, push_ad, pull_ad, int_hi_ad, int_lo_ad } addr_type;
|
|
typedef enum logic[5:0] {md_lo_dout, md_hi_dout, acca_dout, accb_dout, ix_lo_dout, ix_hi_dout, cc_dout, pc_lo_dout, pc_hi_dout} dout_type;
|
|
typedef enum logic[2:0] {reset_op, fetch_op, latch_op } op_type;
|
|
typedef enum logic[5:0] {reset_acca, load_acca, load_hi_acca, pull_acca, latch_acca } acca_type;
|
|
typedef enum logic[5:0] {reset_accb, load_accb, pull_accb, latch_accb } accb_type;
|
|
typedef enum logic[5:0] {reset_cc, load_cc, pull_cc, latch_cc } cc_type;
|
|
typedef enum logic[5:0] {reset_ix, load_ix, pull_lo_ix, pull_hi_ix, latch_ix } ix_type;
|
|
typedef enum logic[5:0] {reset_sp, latch_sp, load_sp } sp_type;
|
|
typedef enum logic[5:0] {reset_pc, latch_pc, load_ea_pc, add_ea_pc, pull_lo_pc, pull_hi_pc, inc_pc } pc_type;
|
|
typedef enum logic[5:0] {reset_md, latch_md, load_md, fetch_first_md, fetch_next_md, shiftl_md } md_type;
|
|
typedef enum logic[5:0] {reset_ea, latch_ea, add_ix_ea, load_accb_ea, inc_ea, fetch_first_ea, fetch_next_ea } ea_type;
|
|
typedef enum logic[5:0] {reset_iv, latch_iv, swi_iv, nmi_iv, irq_iv, icf_iv, ocf_iv, tof_iv, sci_iv } iv_type;
|
|
typedef enum logic[5:0] {reset_nmi, set_nmi, latch_nmi } nmi_type;
|
|
typedef enum logic[5:0] {acca_left, accb_left, accd_left, md_left, ix_left, sp_left } left_type;
|
|
typedef enum logic[5:0] {md_right, zero_right, plus_one_right, accb_right } right_type;
|
|
typedef enum logic[5:0] {alu_add8, alu_sub8, alu_add16, alu_sub16, alu_adc, alu_sbc,
|
|
alu_and, alu_ora, alu_eor,
|
|
alu_tst, alu_inc, alu_dec, alu_clr, alu_neg, alu_com,
|
|
alu_inx, alu_dex,
|
|
alu_lsr16, alu_lsl16,
|
|
alu_ror8, alu_rol8,
|
|
alu_asr8, alu_asl8, alu_lsr8,
|
|
alu_sei, alu_cli, alu_sec, alu_clc, alu_sev, alu_clv, alu_tpa, alu_tap,
|
|
alu_ld8, alu_st8, alu_ld16, alu_st16, alu_nop, alu_daa } alu_type;
|
|
|
|
logic[7:0] op_code;
|
|
logic[7:0] acca;
|
|
logic[7:0] accb;
|
|
logic[7:0] cc;
|
|
logic[7:0] cc_out;
|
|
logic[15:0] xreg;
|
|
logic[15:0] sp;
|
|
logic[15:0] ea;
|
|
logic[15:0] pc;
|
|
logic[15:0] md;
|
|
logic[15:0] left;
|
|
logic[15:0] right;
|
|
logic[15:0] out_alu;
|
|
logic[2:0] iv;
|
|
logic nmi_req;
|
|
logic nmi_ack;
|
|
|
|
state_type state;
|
|
state_type next_state;
|
|
pc_type pc_ctrl;
|
|
ea_type ea_ctrl;
|
|
op_type op_ctrl;
|
|
md_type md_ctrl;
|
|
acca_type acca_ctrl;
|
|
accb_type accb_ctrl;
|
|
ix_type ix_ctrl;
|
|
cc_type cc_ctrl;
|
|
sp_type sp_ctrl;
|
|
iv_type iv_ctrl;
|
|
left_type left_ctrl;
|
|
right_type right_ctrl;
|
|
alu_type alu_ctrl;
|
|
addr_type addr_ctrl;
|
|
dout_type dout_ctrl;
|
|
nmi_type nmi_ctrl;
|
|
|
|
////////////////////////////////////
|
|
////
|
|
//// Address bus multiplexer
|
|
////
|
|
////////////////////////////////////
|
|
|
|
always_comb
|
|
begin
|
|
case(addr_ctrl)
|
|
idle_ad:
|
|
begin
|
|
address = 16'b1111111111111111;
|
|
vma = 1'b0;
|
|
rw = 1'b1;
|
|
end
|
|
fetch_ad:
|
|
begin
|
|
address = pc;
|
|
vma = 1'b1;
|
|
rw = 1'b1;
|
|
end
|
|
read_ad:
|
|
begin
|
|
address = ea;
|
|
vma = 1'b1;
|
|
rw = 1'b1;
|
|
end
|
|
write_ad:
|
|
begin
|
|
address = ea;
|
|
vma = 1'b1;
|
|
rw = 1'b0;
|
|
end
|
|
push_ad:
|
|
begin
|
|
address = sp;
|
|
vma = 1'b1;
|
|
rw = 1'b0;
|
|
end
|
|
pull_ad:
|
|
begin
|
|
address = sp;
|
|
vma = 1'b1;
|
|
rw = 1'b1;
|
|
end
|
|
int_hi_ad:
|
|
begin
|
|
address = {12'b111111111111, iv, 1'b0};
|
|
vma = 1'b1;
|
|
rw = 1'b1;
|
|
end
|
|
int_lo_ad:
|
|
begin
|
|
address = {12'b111111111111, iv, 1'b1};
|
|
vma = 1'b1;
|
|
rw = 1'b1;
|
|
end
|
|
default:
|
|
begin
|
|
address = 16'b1111111111111111;
|
|
vma = 1'b0;
|
|
rw = 1'b1;
|
|
end
|
|
endcase
|
|
end
|
|
|
|
//////////////////////////////////
|
|
////
|
|
//// Data Bus output
|
|
////
|
|
//////////////////////////////////
|
|
always_comb
|
|
begin
|
|
case (dout_ctrl)
|
|
md_hi_dout: //// alu output
|
|
data_out = md[15:8];
|
|
md_lo_dout:
|
|
data_out = md[7:0];
|
|
acca_dout: //// accumulator a
|
|
data_out = acca;
|
|
accb_dout: //// accumulator b
|
|
data_out = accb;
|
|
ix_lo_dout: //// index reg
|
|
data_out = xreg[7:0];
|
|
ix_hi_dout: //// index reg
|
|
data_out = xreg[15:8];
|
|
cc_dout: //// condition codes
|
|
data_out = cc;
|
|
pc_lo_dout: //// low order pc
|
|
data_out = pc[7:0];
|
|
pc_hi_dout: //// high order pc
|
|
data_out = pc[15:8];
|
|
default:
|
|
data_out = 8'b00000000;
|
|
endcase
|
|
end
|
|
|
|
|
|
////////////////////////////////////
|
|
////
|
|
//// Program Counter Control
|
|
////
|
|
////////////////////////////////////
|
|
|
|
logic[15:0] tempof;
|
|
logic[15:0] temppc;
|
|
always_comb
|
|
begin
|
|
case (pc_ctrl)
|
|
add_ea_pc:
|
|
begin
|
|
if (ea[7] == 0)
|
|
tempof = {8'b00000000, ea[7:0]};
|
|
else
|
|
tempof = {8'b11111111, ea[7:0]};
|
|
end
|
|
inc_pc:
|
|
tempof = 16'b0000000000000001;
|
|
default:
|
|
tempof = 16'b0000000000000000;
|
|
endcase
|
|
|
|
case (pc_ctrl)
|
|
reset_pc:
|
|
temppc = 16'b1111111111111110;
|
|
load_ea_pc:
|
|
temppc = ea;
|
|
pull_lo_pc:
|
|
begin
|
|
temppc[7:0] = data_in;
|
|
temppc[15:8] = pc[15:8];
|
|
end
|
|
pull_hi_pc:
|
|
begin
|
|
temppc[7:0] = pc[7:0];
|
|
temppc[15:8] = data_in;
|
|
end
|
|
default:
|
|
temppc = pc;
|
|
endcase
|
|
end
|
|
|
|
always_ff @(posedge clk)
|
|
begin
|
|
if (hold == 1'b1)
|
|
pc <= pc;
|
|
else
|
|
pc <= temppc + tempof;
|
|
end
|
|
|
|
////////////////////////////////////
|
|
////
|
|
//// Effective Address Control
|
|
////
|
|
////////////////////////////////////
|
|
|
|
logic[15:0] tempind;
|
|
logic[15:0] tempea;
|
|
always_comb
|
|
begin
|
|
case (ea_ctrl)
|
|
add_ix_ea:
|
|
tempind = {8'b00000000, ea[7:0]};
|
|
inc_ea:
|
|
tempind = 16'b0000000000000001;
|
|
default:
|
|
tempind = 16'b0000000000000000;
|
|
endcase
|
|
|
|
case (ea_ctrl)
|
|
reset_ea:
|
|
tempea = 16'b0000000000000000;
|
|
load_accb_ea:
|
|
tempea = {8'b00000000, accb[7:0]};
|
|
add_ix_ea:
|
|
tempea = xreg;
|
|
fetch_first_ea:
|
|
begin
|
|
tempea[7:0] = data_in;
|
|
tempea[15:8] = 8'b00000000;
|
|
end
|
|
fetch_next_ea:
|
|
begin
|
|
tempea[7:0] = data_in;
|
|
tempea[15:8] = ea[7:0];
|
|
end
|
|
default:
|
|
tempea = ea;
|
|
endcase
|
|
end
|
|
|
|
always_ff @(posedge clk)
|
|
begin
|
|
if (hold == 1'b1)
|
|
ea <= ea;
|
|
else
|
|
ea <= tempea + tempind;
|
|
end
|
|
|
|
//////////////////////////////////
|
|
////
|
|
//// Accumulator A
|
|
////
|
|
//////////////////////////////////
|
|
always_ff @(posedge clk)
|
|
begin
|
|
if (hold == 1'b1)
|
|
acca <= acca;
|
|
else
|
|
case (acca_ctrl)
|
|
reset_acca:
|
|
acca <= 8'b00000000;
|
|
load_acca:
|
|
acca <= out_alu[7:0];
|
|
load_hi_acca:
|
|
acca <= out_alu[15:8];
|
|
pull_acca:
|
|
acca <= data_in;
|
|
default:
|
|
// latch_acca:
|
|
acca <= acca;
|
|
endcase
|
|
end
|
|
|
|
//////////////////////////////////
|
|
////
|
|
//// Accumulator B
|
|
////
|
|
//////////////////////////////////
|
|
always_ff @(posedge clk)
|
|
begin
|
|
if (hold == 1'b1)
|
|
accb <= accb;
|
|
else
|
|
case (accb_ctrl)
|
|
reset_accb:
|
|
accb <= 8'b00000000;
|
|
load_accb:
|
|
accb <= out_alu[7:0];
|
|
pull_accb:
|
|
accb <= data_in;
|
|
default:
|
|
// latch_accb:
|
|
accb <= accb;
|
|
endcase
|
|
end
|
|
|
|
//////////////////////////////////
|
|
////
|
|
//// X Index register
|
|
////
|
|
//////////////////////////////////
|
|
always_ff @(posedge clk)
|
|
begin
|
|
if (hold == 1'b1)
|
|
xreg <= xreg;
|
|
else
|
|
case (ix_ctrl)
|
|
reset_ix:
|
|
xreg <= 16'b0000000000000000;
|
|
load_ix:
|
|
xreg <= out_alu[15:0];
|
|
pull_hi_ix:
|
|
xreg[15:8] <= data_in;
|
|
pull_lo_ix:
|
|
xreg[7:0] <= data_in;
|
|
default:
|
|
// latch_ix:
|
|
xreg <= xreg;
|
|
endcase
|
|
end
|
|
|
|
//////////////////////////////////
|
|
////
|
|
//// stack pointer
|
|
////
|
|
//////////////////////////////////
|
|
always_ff @(posedge clk)
|
|
begin
|
|
if (hold == 1'b1)
|
|
sp <= sp;
|
|
else
|
|
case (sp_ctrl)
|
|
reset_sp:
|
|
sp <= 16'b0000000000000000;
|
|
load_sp:
|
|
sp <= out_alu[15:0];
|
|
default:
|
|
// latch_sp:
|
|
sp <= sp;
|
|
endcase
|
|
end
|
|
|
|
//////////////////////////////////
|
|
////
|
|
//// Memory Data
|
|
////
|
|
//////////////////////////////////
|
|
always_ff @(posedge clk)
|
|
begin
|
|
if (hold == 1'b1)
|
|
md <= md;
|
|
else
|
|
case (md_ctrl)
|
|
reset_md:
|
|
md <= 16'b0000000000000000;
|
|
load_md:
|
|
md <= out_alu[15:0];
|
|
fetch_first_md:
|
|
begin
|
|
md[15:8] <= 8'b00000000;
|
|
md[7:0] <= data_in;
|
|
end
|
|
fetch_next_md:
|
|
begin
|
|
md[15:8] <= md[7:0];
|
|
md[7:0] <= data_in;
|
|
end
|
|
shiftl_md:
|
|
begin
|
|
md[15:1] <= md[14:0];
|
|
md[0] <= 1'b0;
|
|
end
|
|
default:
|
|
// latch_md:
|
|
md <= md;
|
|
endcase
|
|
end
|
|
|
|
|
|
////////////////////////////////////
|
|
////
|
|
//// Condition Codes
|
|
////
|
|
////////////////////////////////////
|
|
|
|
always_ff @(posedge clk)
|
|
begin
|
|
if (hold == 1'b1)
|
|
cc <= cc;
|
|
else
|
|
case (cc_ctrl)
|
|
reset_cc:
|
|
cc <= 8'b11000000;
|
|
load_cc:
|
|
cc <= cc_out;
|
|
pull_cc:
|
|
cc <= data_in;
|
|
default:
|
|
// latch_cc:
|
|
cc <= cc;
|
|
endcase
|
|
end
|
|
|
|
////////////////////////////////////
|
|
////
|
|
//// interrupt vector
|
|
////
|
|
////////////////////////////////////
|
|
|
|
always_ff @(posedge clk)
|
|
begin
|
|
if (hold == 1'b1)
|
|
iv <= iv;
|
|
else
|
|
case (iv_ctrl)
|
|
reset_iv:
|
|
iv <= 3'b111;
|
|
nmi_iv:
|
|
iv <= 3'b110;
|
|
swi_iv:
|
|
iv <= 3'b101;
|
|
irq_iv:
|
|
iv <= 3'b100;
|
|
icf_iv:
|
|
iv <= 3'b011;
|
|
ocf_iv:
|
|
iv <= 3'b010;
|
|
tof_iv:
|
|
iv <= 3'b001;
|
|
sci_iv:
|
|
iv <= 3'b000;
|
|
default:
|
|
iv <= iv;
|
|
endcase
|
|
end
|
|
|
|
////////////////////////////////////
|
|
////
|
|
//// op code fetch
|
|
////
|
|
////////////////////////////////////
|
|
|
|
always_ff @(posedge clk)
|
|
begin
|
|
if (hold == 1'b1)
|
|
op_code <= op_code;
|
|
else
|
|
case (op_ctrl)
|
|
reset_op:
|
|
op_code <= 8'b00000001; // nop
|
|
fetch_op:
|
|
op_code <= data_in;
|
|
default:
|
|
// latch_op:
|
|
op_code <= op_code;
|
|
endcase
|
|
end
|
|
|
|
////////////////////////////////////
|
|
////
|
|
//// Left Mux
|
|
////
|
|
////////////////////////////////////
|
|
|
|
always_comb
|
|
begin
|
|
case (left_ctrl)
|
|
acca_left:
|
|
begin
|
|
left[15:8] = 8'b00000000;
|
|
left[7:0] = acca;
|
|
end
|
|
accb_left:
|
|
begin
|
|
left[15:8] = 8'b00000000;
|
|
left[7:0] = accb;
|
|
end
|
|
accd_left:
|
|
begin
|
|
left[15:8] = acca;
|
|
left[7:0] = accb;
|
|
end
|
|
ix_left:
|
|
left = xreg;
|
|
sp_left:
|
|
left = sp;
|
|
default:
|
|
// md_left:
|
|
left = md;
|
|
endcase
|
|
end
|
|
////////////////////////////////////
|
|
////
|
|
//// Right Mux
|
|
////
|
|
////////////////////////////////////
|
|
|
|
always_comb
|
|
begin
|
|
case (right_ctrl)
|
|
zero_right:
|
|
right = 16'b0000000000000000;
|
|
plus_one_right:
|
|
right = 16'b0000000000000001;
|
|
accb_right:
|
|
right = {8'b00000000, accb};
|
|
default:
|
|
// md_right:
|
|
right = md;
|
|
endcase
|
|
end
|
|
|
|
////////////////////////////////////
|
|
////
|
|
//// Arithmetic Logic Unit
|
|
////
|
|
////////////////////////////////////
|
|
|
|
logic valid_lo, valid_hi;
|
|
logic carry_in;
|
|
logic[7:0] daa_reg;
|
|
always_comb
|
|
begin
|
|
|
|
case (alu_ctrl)
|
|
alu_adc, alu_sbc,
|
|
alu_rol8, alu_ror8:
|
|
carry_in = cc[CBIT];
|
|
default:
|
|
carry_in = 1'b0;
|
|
endcase
|
|
|
|
valid_lo = (left[3:0] <= 9);
|
|
valid_hi = (left[7:4] <= 9);
|
|
|
|
if (cc[CBIT] == 1'b0)
|
|
begin
|
|
if( cc[HBIT] == 1'b1 )
|
|
begin
|
|
if (valid_hi)
|
|
daa_reg = 8'b00000110;
|
|
else
|
|
daa_reg = 8'b01100110;
|
|
end
|
|
else
|
|
begin
|
|
if (valid_lo)
|
|
begin
|
|
if (valid_hi)
|
|
daa_reg = 8'b00000000;
|
|
else
|
|
daa_reg = 8'b01100000;
|
|
end
|
|
else
|
|
begin
|
|
if( left[7:4] <= 8 )
|
|
daa_reg = 8'b00000110;
|
|
else
|
|
daa_reg = 8'b01100110;
|
|
end
|
|
end
|
|
end
|
|
else
|
|
begin
|
|
if ( cc[HBIT] == 1'b1 )
|
|
daa_reg = 8'b01100110;
|
|
else
|
|
if (valid_lo)
|
|
daa_reg = 8'b01100000;
|
|
else
|
|
daa_reg = 8'b01100110;
|
|
end
|
|
|
|
case (alu_ctrl)
|
|
alu_add8, alu_inc, alu_add16, alu_inx, alu_adc:
|
|
out_alu = left + right + {15'b000000000000000, carry_in};
|
|
alu_sub8, alu_dec, alu_sub16, alu_dex, alu_sbc:
|
|
out_alu = left - right - {15'b000000000000000, carry_in};
|
|
alu_and:
|
|
out_alu = left & right; // and/bit
|
|
alu_ora:
|
|
out_alu = left | right; // or
|
|
alu_eor:
|
|
out_alu = left ^ right; // eor/xor
|
|
alu_lsl16, alu_asl8, alu_rol8:
|
|
out_alu = {left[14:0], carry_in}; // rol8/asl8/lsl16
|
|
alu_lsr16, alu_lsr8:
|
|
out_alu = {carry_in, left[15:1]}; // lsr
|
|
alu_ror8:
|
|
out_alu = {8'b00000000, carry_in, left[7:1]}; // ror
|
|
alu_asr8:
|
|
out_alu = {8'b00000000, left[7], left[7:1]}; // asr
|
|
alu_neg:
|
|
out_alu = right - left; // neg (right=0)
|
|
alu_com:
|
|
out_alu = ~left;
|
|
alu_clr, alu_ld8, alu_ld16:
|
|
out_alu = right; // clr, ld
|
|
alu_st8, alu_tst, alu_st16:
|
|
out_alu = left;
|
|
alu_daa:
|
|
out_alu = left + {8'b00000000, daa_reg};
|
|
alu_tpa:
|
|
out_alu = {8'b00000000, cc};
|
|
default:
|
|
out_alu = left; // nop
|
|
endcase
|
|
|
|
//
|
|
// carry bit
|
|
//
|
|
case (alu_ctrl)
|
|
alu_add8, alu_adc:
|
|
cc_out[CBIT] = (left[7] & right[7]) | (left[7] & ~out_alu[7]) | (right[7] & ~out_alu[7]);
|
|
alu_sub8, alu_sbc:
|
|
cc_out[CBIT] = ((~left[7]) & right[7]) | ((~left[7]) & out_alu[7]) | (right[7] & out_alu[7]);
|
|
alu_add16:
|
|
cc_out[CBIT] = (left[15] & right[15]) | (left[15] & ~out_alu[15]) | (right[15] & ~out_alu[15]);
|
|
alu_sub16:
|
|
cc_out[CBIT] = ((~left[15]) & right[15]) | ((~left[15]) & out_alu[15]) | (right[15] & out_alu[15]);
|
|
alu_ror8 , alu_lsr16, alu_lsr8, alu_asr8:
|
|
cc_out[CBIT] = left[0];
|
|
alu_rol8, alu_asl8:
|
|
cc_out[CBIT] = left[7];
|
|
alu_lsl16:
|
|
cc_out[CBIT] = left[15];
|
|
alu_com:
|
|
cc_out[CBIT] = 1'b1;
|
|
alu_neg, alu_clr:
|
|
cc_out[CBIT] = out_alu[7] | out_alu[6] | out_alu[5] | out_alu[4] | out_alu[3] | out_alu[2] | out_alu[1] | out_alu[0];
|
|
alu_daa:
|
|
begin
|
|
if ( daa_reg[7:4] == 4'b0110 )
|
|
cc_out[CBIT] = 1'b1;
|
|
else
|
|
cc_out[CBIT] = 1'b0;
|
|
end
|
|
alu_sec:
|
|
cc_out[CBIT] = 1'b1;
|
|
alu_clc, alu_tst:
|
|
cc_out[CBIT] = 1'b0;
|
|
alu_tap:
|
|
cc_out[CBIT] = left[CBIT];
|
|
default:
|
|
cc_out[CBIT] = cc[CBIT];
|
|
endcase
|
|
//
|
|
// Zero flag
|
|
//
|
|
case (alu_ctrl)
|
|
alu_add8 , alu_sub8 ,
|
|
alu_adc , alu_sbc ,
|
|
alu_and , alu_ora , alu_eor ,
|
|
alu_inc , alu_dec ,
|
|
alu_neg , alu_com , alu_clr ,
|
|
alu_rol8 , alu_ror8 , alu_asr8 , alu_asl8 , alu_lsr8 ,
|
|
alu_ld8 , alu_st8, alu_tst:
|
|
cc_out[ZBIT] = ~( out_alu[7] | out_alu[6] | out_alu[5] | out_alu[4] |
|
|
out_alu[3] | out_alu[2] | out_alu[1] | out_alu[0] );
|
|
alu_add16, alu_sub16,
|
|
alu_lsl16, alu_lsr16,
|
|
alu_inx, alu_dex,
|
|
alu_ld16, alu_st16:
|
|
cc_out[ZBIT] = ~( out_alu[15] | out_alu[14] | out_alu[13] | out_alu[12] |
|
|
out_alu[11] | out_alu[10] | out_alu[9] | out_alu[8] |
|
|
out_alu[7] | out_alu[6] | out_alu[5] | out_alu[4] |
|
|
out_alu[3] | out_alu[2] | out_alu[1] | out_alu[0] );
|
|
alu_tap:
|
|
cc_out[ZBIT] = left[ZBIT];
|
|
default:
|
|
cc_out[ZBIT] = cc[ZBIT];
|
|
endcase
|
|
|
|
//
|
|
// negative flag
|
|
//
|
|
case (alu_ctrl)
|
|
alu_add8, alu_sub8,
|
|
alu_adc, alu_sbc,
|
|
alu_and, alu_ora, alu_eor,
|
|
alu_rol8, alu_ror8, alu_asr8, alu_asl8, alu_lsr8,
|
|
alu_inc, alu_dec, alu_neg, alu_com, alu_clr,
|
|
alu_ld8 , alu_st8, alu_tst:
|
|
cc_out[NBIT] = out_alu[7];
|
|
alu_add16, alu_sub16,
|
|
alu_lsl16, alu_lsr16,
|
|
alu_ld16, alu_st16:
|
|
cc_out[NBIT] = out_alu[15];
|
|
alu_tap:
|
|
cc_out[NBIT] = left[NBIT];
|
|
default:
|
|
cc_out[NBIT] = cc[NBIT];
|
|
endcase
|
|
|
|
//
|
|
// Interrupt mask flag
|
|
//
|
|
case (alu_ctrl)
|
|
alu_sei:
|
|
cc_out[IBIT] = 1'b1; // set interrupt mask
|
|
alu_cli:
|
|
cc_out[IBIT] = 1'b0; // clear interrupt mask
|
|
alu_tap:
|
|
cc_out[IBIT] = left[IBIT];
|
|
default:
|
|
cc_out[IBIT] = cc[IBIT]; // interrupt mask
|
|
endcase
|
|
|
|
//
|
|
// Half Carry flag
|
|
//
|
|
case (alu_ctrl)
|
|
alu_add8, alu_adc:
|
|
cc_out[HBIT] = (left[3] & right[3]) |
|
|
(right[3] & ~out_alu[3]) |
|
|
(left[3] & ~out_alu[3]);
|
|
alu_tap:
|
|
cc_out[HBIT] = left[HBIT];
|
|
default:
|
|
cc_out[HBIT] = cc[HBIT];
|
|
endcase
|
|
|
|
//
|
|
// Overflow flag
|
|
//
|
|
case (alu_ctrl)
|
|
alu_add8, alu_adc:
|
|
cc_out[VBIT] = (left[7] & right[7] & (~out_alu[7])) |
|
|
((~left[7]) & (~right[7]) & out_alu[7]);
|
|
alu_sub8, alu_sbc:
|
|
cc_out[VBIT] = (left[7] & (~right[7]) & (~out_alu[7])) |
|
|
((~left[7]) & right[7] & out_alu[7]);
|
|
alu_add16:
|
|
cc_out[VBIT] = (left[15] & right[15] & (~out_alu[15])) |
|
|
((~left[15]) & (~right[15]) & out_alu[15]);
|
|
alu_sub16:
|
|
cc_out[VBIT] = (left[15] & (~right[15]) & (~out_alu[15])) |
|
|
((~left[15]) & right[15] & out_alu[15]);
|
|
alu_inc:
|
|
cc_out[VBIT] = ((~left[7]) & left[6] & left[5] & left[4] &
|
|
left[3] & left[2] & left[1] & left[0]);
|
|
alu_dec, alu_neg:
|
|
cc_out[VBIT] = (left[7] & (~left[6]) & (~left[5]) & (~left[4]) &
|
|
(~left[3]) & (~left[2]) & (~left[1]) & (~left[0]));
|
|
alu_asr8:
|
|
cc_out[VBIT] = left[0] ^ left[7];
|
|
alu_lsr8, alu_lsr16:
|
|
cc_out[VBIT] = left[0];
|
|
alu_ror8:
|
|
cc_out[VBIT] = left[0] ^ cc[CBIT];
|
|
alu_lsl16:
|
|
cc_out[VBIT] = left[15] ^ left[14];
|
|
alu_rol8, alu_asl8:
|
|
cc_out[VBIT] = left[7] ^ left[6];
|
|
alu_tap:
|
|
cc_out[VBIT] = left[VBIT];
|
|
alu_and, alu_ora, alu_eor, alu_com,
|
|
alu_st8, alu_tst, alu_st16, alu_ld8, alu_ld16,
|
|
alu_clv:
|
|
cc_out[VBIT] = 1'b0;
|
|
alu_sev:
|
|
cc_out[VBIT] = 1'b1;
|
|
default:
|
|
cc_out[VBIT] = cc[VBIT];
|
|
endcase
|
|
|
|
case (alu_ctrl)
|
|
alu_tap:
|
|
begin
|
|
cc_out[XBIT] = cc[XBIT] & left[XBIT];
|
|
cc_out[SBIT] = left[SBIT];
|
|
end
|
|
default:
|
|
begin
|
|
cc_out[XBIT] = cc[XBIT] & left[XBIT];
|
|
cc_out[SBIT] = cc[SBIT];
|
|
end
|
|
endcase
|
|
|
|
test_alu = out_alu;
|
|
test_cc = cc_out;
|
|
end
|
|
|
|
////////////////////////////////////
|
|
//
|
|
// Detect Edge of NMI interrupt
|
|
//
|
|
////////////////////////////////////
|
|
|
|
always_ff @(posedge clk)
|
|
begin
|
|
if (hold == 1'b1)
|
|
nmi_req <= nmi_req;
|
|
else if (rst==1'b1)
|
|
nmi_req <= 1'b0;
|
|
else if (nmi==1'b1 && nmi_ack==1'b0)
|
|
nmi_req <= 1'b1;
|
|
else if (nmi==1'b0 && nmi_ack==1'b1)
|
|
nmi_req <= 1'b0;
|
|
else
|
|
nmi_req <= nmi_req;
|
|
end
|
|
|
|
////////////////////////////////////
|
|
//
|
|
// Nmi mux
|
|
//
|
|
////////////////////////////////////
|
|
|
|
always_ff @(posedge clk)
|
|
begin
|
|
if (hold == 1'b1)
|
|
nmi_ack <= nmi_ack;
|
|
else
|
|
case (nmi_ctrl)
|
|
set_nmi:
|
|
nmi_ack <= 1'b1;
|
|
reset_nmi:
|
|
nmi_ack <= 1'b0;
|
|
default:
|
|
// when latch_nmi =>
|
|
nmi_ack <= nmi_ack;
|
|
endcase
|
|
end
|
|
|
|
////////////////////////////////////
|
|
//
|
|
// state sequencer
|
|
//
|
|
////////////////////////////////////
|
|
always_comb
|
|
begin
|
|
case (state)
|
|
reset_state: // released from reset
|
|
begin
|
|
// reset the registers
|
|
op_ctrl = reset_op;
|
|
acca_ctrl = reset_acca;
|
|
accb_ctrl = reset_accb;
|
|
ix_ctrl = reset_ix;
|
|
sp_ctrl = reset_sp;
|
|
pc_ctrl = reset_pc;
|
|
ea_ctrl = reset_ea;
|
|
md_ctrl = reset_md;
|
|
iv_ctrl = reset_iv;
|
|
nmi_ctrl = reset_nmi;
|
|
// idle the ALU
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = reset_cc;
|
|
// idle the bus
|
|
dout_ctrl = md_lo_dout;
|
|
addr_ctrl = idle_ad;
|
|
next_state = vect_hi_state;
|
|
end
|
|
|
|
//
|
|
// Jump via interrupt vector
|
|
// iv holds interrupt type
|
|
// fetch PC hi from vector location
|
|
//
|
|
vect_hi_state:
|
|
begin
|
|
// default the registers
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
md_ctrl = latch_md;
|
|
ea_ctrl = latch_ea;
|
|
iv_ctrl = latch_iv;
|
|
// idle the ALU
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
// fetch pc low interrupt vector
|
|
pc_ctrl = pull_hi_pc;
|
|
addr_ctrl = int_hi_ad;
|
|
dout_ctrl = pc_hi_dout;
|
|
next_state = vect_lo_state;
|
|
end
|
|
//
|
|
// jump via interrupt vector
|
|
// iv holds vector type
|
|
// fetch PC lo from vector location
|
|
//
|
|
vect_lo_state:
|
|
begin
|
|
// default the registers
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
md_ctrl = latch_md;
|
|
ea_ctrl = latch_ea;
|
|
iv_ctrl = latch_iv;
|
|
// idle the ALU
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
// fetch the vector low byte
|
|
pc_ctrl = pull_lo_pc;
|
|
addr_ctrl = int_lo_ad;
|
|
dout_ctrl = pc_lo_dout;
|
|
next_state = fetch_state;
|
|
end
|
|
|
|
//
|
|
// Here to fetch an instruction
|
|
// PC points to opcode
|
|
// Should service interrupt requests at this point
|
|
// either from the timer
|
|
// or from the external input.
|
|
//
|
|
fetch_state:
|
|
begin
|
|
case (op_code[7:4])
|
|
4'b0000,
|
|
4'b0001,
|
|
4'b0010, // branch conditional
|
|
4'b0011,
|
|
4'b0100, // acca single op
|
|
4'b0101, // accb single op
|
|
4'b0110, // indexed single op
|
|
4'b0111: // extended single op
|
|
begin
|
|
// idle ALU
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
|
|
4'b1000, // acca immediate
|
|
4'b1001, // acca direct
|
|
4'b1010, // acca indexed
|
|
4'b1011: // acca extended
|
|
begin
|
|
case (op_code[3:0])
|
|
4'b0000: // suba
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_sub8;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = load_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
4'b0001: // cmpa
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_sub8;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
4'b0010: // sbca
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_sbc;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = load_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
4'b0011: // subd
|
|
begin
|
|
left_ctrl = accd_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_sub16;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = load_hi_acca;
|
|
accb_ctrl = load_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
4'b0100: // anda
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_and;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = load_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
4'b0101: // bita
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_and;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
4'b0110: // ldaa
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_ld8;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = load_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
4'b0111: // staa
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_st8;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
4'b1000: // eora
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_eor;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = load_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
4'b1001: // adca
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_adc;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = load_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
4'b1010: // oraa
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_ora;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = load_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
4'b1011: // adda
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_add8;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = load_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
4'b1100: // cpx
|
|
begin
|
|
left_ctrl = ix_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_sub16;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
4'b1101: // bsr / jsr
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
4'b1110: // lds
|
|
begin
|
|
left_ctrl = sp_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_ld16;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = load_sp;
|
|
end
|
|
4'b1111: // sts
|
|
begin
|
|
left_ctrl = sp_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_st16;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
default:
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
endcase
|
|
end
|
|
4'b1100, // accb immediate
|
|
4'b1101, // accb direct
|
|
4'b1110, // accb indexed
|
|
4'b1111: // accb extended
|
|
begin
|
|
case (op_code[3:0])
|
|
4'b0000: // subb
|
|
begin
|
|
left_ctrl = accb_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_sub8;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = load_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
4'b0001: // cmpb
|
|
begin
|
|
left_ctrl = accb_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_sub8;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
4'b0010: // sbcb
|
|
begin
|
|
left_ctrl = accb_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_sbc;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = load_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
4'b0011: // addd
|
|
begin
|
|
left_ctrl = accd_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_add16;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = load_hi_acca;
|
|
accb_ctrl = load_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
4'b0100: // andb
|
|
begin
|
|
left_ctrl = accb_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_and;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = load_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
4'b0101: // bitb
|
|
begin
|
|
left_ctrl = accb_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_and;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
4'b0110: // ldab
|
|
begin
|
|
left_ctrl = accb_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_ld8;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = load_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
4'b0111: // stab
|
|
begin
|
|
left_ctrl = accb_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_st8;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
4'b1000: // eorb
|
|
begin
|
|
left_ctrl = accb_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_eor;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = load_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
4'b1001: // adcb
|
|
begin
|
|
left_ctrl = accb_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_adc;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = load_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
4'b1010: // orab
|
|
begin
|
|
left_ctrl = accb_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_ora;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = load_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
4'b1011: // addb
|
|
begin
|
|
left_ctrl = accb_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_add8;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = load_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
4'b1100: // ldd
|
|
begin
|
|
left_ctrl = accd_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_ld16;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = load_hi_acca;
|
|
accb_ctrl = load_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
4'b1101: // std
|
|
begin
|
|
left_ctrl = accd_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_st16;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
4'b1110: // ldx
|
|
begin
|
|
left_ctrl = ix_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_ld16;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = load_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
4'b1111: // stx
|
|
begin
|
|
left_ctrl = ix_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_st16;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
default:
|
|
begin
|
|
left_ctrl = accb_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
endcase
|
|
end
|
|
default:
|
|
begin
|
|
left_ctrl = accd_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
end
|
|
endcase
|
|
md_ctrl = latch_md;
|
|
// fetch the op code
|
|
op_ctrl = fetch_op;
|
|
ea_ctrl = reset_ea;
|
|
addr_ctrl = fetch_ad;
|
|
dout_ctrl = md_lo_dout;
|
|
iv_ctrl = latch_iv;
|
|
if (halt == 1'b1)
|
|
begin
|
|
pc_ctrl = latch_pc;
|
|
nmi_ctrl = latch_nmi;
|
|
next_state = halt_state;
|
|
end
|
|
// service non maskable interrupts
|
|
else if (nmi_req == 1'b1 && nmi_ack == 1'b0)
|
|
begin
|
|
pc_ctrl = latch_pc;
|
|
nmi_ctrl = set_nmi;
|
|
next_state = int_pcl_state;
|
|
end
|
|
// service maskable interrupts
|
|
else
|
|
begin
|
|
//
|
|
// nmi request is not cleared until nmi input goes low
|
|
//
|
|
if(nmi_req == 1'b0 && nmi_ack==1'b1)
|
|
nmi_ctrl = reset_nmi;
|
|
else
|
|
nmi_ctrl = latch_nmi;
|
|
//
|
|
// IRQ is level sensitive
|
|
//
|
|
if ((irq == 1'b1 || irq_icf == 1'b1 || irq_ocf == 1'b1 || irq_tof == 1'b1 || irq_sci == 1'b1) && cc[IBIT] == 1'b0)
|
|
begin
|
|
pc_ctrl = latch_pc;
|
|
next_state = int_pcl_state;
|
|
end
|
|
else
|
|
begin
|
|
// Advance the PC to fetch next instruction byte
|
|
pc_ctrl = inc_pc;
|
|
next_state = decode_state;
|
|
end
|
|
end
|
|
end
|
|
//
|
|
// Here to decode instruction
|
|
// and fetch next byte of intruction
|
|
// whether it be necessary or not
|
|
//
|
|
decode_state:
|
|
begin
|
|
// fetch first byte of address or immediate data
|
|
ea_ctrl = fetch_first_ea;
|
|
addr_ctrl = fetch_ad;
|
|
dout_ctrl = md_lo_dout;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
iv_ctrl = latch_iv;
|
|
case (op_code[7:4])
|
|
4'b0000:
|
|
begin
|
|
md_ctrl = fetch_first_md;
|
|
sp_ctrl = latch_sp;
|
|
pc_ctrl = latch_pc;
|
|
case (op_code[3:0])
|
|
4'b0001: // nop
|
|
begin
|
|
left_ctrl = accd_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
end
|
|
4'b0100: // lsrd
|
|
begin
|
|
left_ctrl = accd_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_lsr16;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = load_hi_acca;
|
|
accb_ctrl = load_accb;
|
|
ix_ctrl = latch_ix;
|
|
end
|
|
4'b0101: // lsld
|
|
begin
|
|
left_ctrl = accd_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_lsl16;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = load_hi_acca;
|
|
accb_ctrl = load_accb;
|
|
ix_ctrl = latch_ix;
|
|
end
|
|
4'b0110: // tap
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_tap;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
end
|
|
4'b0111: // tpa
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_tpa;
|
|
cc_ctrl = latch_cc;
|
|
acca_ctrl = load_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
end
|
|
4'b1000: // inx
|
|
begin
|
|
left_ctrl = ix_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_inx;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = load_ix;
|
|
end
|
|
4'b1001: // dex
|
|
begin
|
|
left_ctrl = ix_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_dex;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = load_ix;
|
|
end
|
|
4'b1010: // clv
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_clv;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
end
|
|
4'b1011: // sev
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_sev;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
end
|
|
4'b1100: // clc
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_clc;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
end
|
|
4'b1101: // sec
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_sec;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
end
|
|
4'b1110: // cli
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_cli;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
end
|
|
4'b1111: // sei
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_sei;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
end
|
|
default:
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
end
|
|
endcase
|
|
next_state = fetch_state;
|
|
end
|
|
// acca / accb inherent instructions
|
|
4'b0001:
|
|
begin
|
|
md_ctrl = fetch_first_md;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
pc_ctrl = latch_pc;
|
|
left_ctrl = acca_left;
|
|
right_ctrl = accb_right;
|
|
case (op_code[3:0])
|
|
4'b0000: // sba
|
|
begin
|
|
alu_ctrl = alu_sub8;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = load_acca;
|
|
accb_ctrl = latch_accb;
|
|
end
|
|
4'b0001: // cba
|
|
begin
|
|
alu_ctrl = alu_sub8;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
end
|
|
4'b0110: // tab
|
|
begin
|
|
alu_ctrl = alu_st8;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = load_accb;
|
|
end
|
|
4'b0111: // tba
|
|
begin
|
|
alu_ctrl = alu_ld8;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = load_acca;
|
|
accb_ctrl = latch_accb;
|
|
end
|
|
4'b1001: // daa
|
|
begin
|
|
alu_ctrl = alu_daa;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = load_acca;
|
|
accb_ctrl = latch_accb;
|
|
end
|
|
4'b1011: // aba
|
|
begin
|
|
alu_ctrl = alu_add8;
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = load_acca;
|
|
accb_ctrl = latch_accb;
|
|
end
|
|
default:
|
|
begin
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
end
|
|
endcase
|
|
next_state = fetch_state;
|
|
end
|
|
4'b0010: // branch conditional
|
|
begin
|
|
md_ctrl = fetch_first_md;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
// increment the pc
|
|
pc_ctrl = inc_pc;
|
|
case (op_code[3:0])
|
|
4'b0000: // bra
|
|
next_state = branch_state;
|
|
4'b0001: // brn
|
|
next_state = fetch_state;
|
|
4'b0010: // bhi
|
|
begin
|
|
if ((cc[CBIT] | cc[ZBIT]) == 1'b0)
|
|
next_state = branch_state;
|
|
else
|
|
next_state = fetch_state;
|
|
end
|
|
4'b0011: // bls
|
|
begin
|
|
if ((cc[CBIT] | cc[ZBIT]) == 1'b1)
|
|
next_state = branch_state;
|
|
else
|
|
next_state = fetch_state;
|
|
end
|
|
4'b0100: // bcc/bhs
|
|
begin
|
|
if (cc[CBIT] == 1'b0)
|
|
next_state = branch_state;
|
|
else
|
|
next_state = fetch_state;
|
|
end
|
|
4'b0101: // bcs/blo
|
|
begin
|
|
if (cc[CBIT] == 1'b1)
|
|
next_state = branch_state;
|
|
else
|
|
next_state = fetch_state;
|
|
end
|
|
4'b0110: // bne
|
|
begin
|
|
if (cc[ZBIT] == 1'b0)
|
|
next_state = branch_state;
|
|
else
|
|
next_state = fetch_state;
|
|
end
|
|
4'b0111: // beq
|
|
begin
|
|
if (cc[ZBIT] == 1'b1)
|
|
next_state = branch_state;
|
|
else
|
|
next_state = fetch_state;
|
|
end
|
|
4'b1000: // bvc
|
|
begin
|
|
if (cc[VBIT] == 1'b0)
|
|
next_state = branch_state;
|
|
else
|
|
next_state = fetch_state;
|
|
end
|
|
4'b1001: // bvs
|
|
begin
|
|
if (cc[VBIT] == 1'b1)
|
|
next_state = branch_state;
|
|
else
|
|
next_state = fetch_state;
|
|
end
|
|
4'b1010: // bpl
|
|
begin
|
|
if (cc[NBIT] == 1'b0)
|
|
next_state = branch_state;
|
|
else
|
|
next_state = fetch_state;
|
|
end
|
|
4'b1011: // bmi
|
|
begin
|
|
if (cc[NBIT] == 1'b1)
|
|
next_state = branch_state;
|
|
else
|
|
next_state = fetch_state;
|
|
end
|
|
4'b1100: // bge
|
|
begin
|
|
if ((cc[NBIT] ^ cc[VBIT]) == 1'b0)
|
|
next_state = branch_state;
|
|
else
|
|
next_state = fetch_state;
|
|
end
|
|
4'b1101: // blt
|
|
begin
|
|
if ((cc[NBIT] ^ cc[VBIT]) == 1'b1)
|
|
next_state = branch_state;
|
|
else
|
|
next_state = fetch_state;
|
|
end
|
|
4'b1110: // bgt
|
|
begin
|
|
if ((cc[ZBIT] | (cc[NBIT] ^ cc[VBIT])) == 1'b0)
|
|
next_state = branch_state;
|
|
else
|
|
next_state = fetch_state;
|
|
end
|
|
4'b1111: // ble
|
|
begin
|
|
if ((cc[ZBIT] | (cc[NBIT] ^ cc[VBIT])) == 1'b1)
|
|
next_state = branch_state;
|
|
else
|
|
next_state = fetch_state;
|
|
end
|
|
default:
|
|
next_state = fetch_state;
|
|
endcase
|
|
end
|
|
//
|
|
// Single byte stack operators
|
|
// Do not advance PC
|
|
//
|
|
4'b0011:
|
|
begin
|
|
md_ctrl = fetch_first_md;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
pc_ctrl = latch_pc;
|
|
case (op_code[3:0])
|
|
4'b0000: // tsx
|
|
begin
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_add16;
|
|
cc_ctrl = latch_cc;
|
|
ix_ctrl = load_ix;
|
|
sp_ctrl = latch_sp;
|
|
next_state = fetch_state;
|
|
end
|
|
4'b0001: // ins
|
|
begin
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_add16;
|
|
cc_ctrl = latch_cc;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = load_sp;
|
|
next_state = fetch_state;
|
|
end
|
|
4'b0010: // pula
|
|
begin
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_add16;
|
|
cc_ctrl = latch_cc;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = load_sp;
|
|
next_state = pula_state;
|
|
end
|
|
4'b0011: // pulb
|
|
begin
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_add16;
|
|
cc_ctrl = latch_cc;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = load_sp;
|
|
next_state = pulb_state;
|
|
end
|
|
4'b0100: // des
|
|
begin
|
|
// decrement sp
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_sub16;
|
|
cc_ctrl = latch_cc;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = load_sp;
|
|
next_state = fetch_state;
|
|
end
|
|
4'b0101: // txs
|
|
begin
|
|
left_ctrl = ix_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_sub16;
|
|
cc_ctrl = latch_cc;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = load_sp;
|
|
next_state = fetch_state;
|
|
end
|
|
4'b0110: // psha
|
|
begin
|
|
left_ctrl = sp_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
next_state = psha_state;
|
|
end
|
|
4'b0111: // pshb
|
|
begin
|
|
left_ctrl = sp_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
next_state = pshb_state;
|
|
end
|
|
4'b1000: // pulx
|
|
begin
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_add16;
|
|
cc_ctrl = latch_cc;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = load_sp;
|
|
next_state = pulx_hi_state;
|
|
end
|
|
4'b1001: // rts
|
|
begin
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_add16;
|
|
cc_ctrl = latch_cc;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = load_sp;
|
|
next_state = rts_hi_state;
|
|
end
|
|
4'b1010: // abx
|
|
begin
|
|
left_ctrl = ix_left;
|
|
right_ctrl = accb_right;
|
|
alu_ctrl = alu_add16;
|
|
cc_ctrl = latch_cc;
|
|
ix_ctrl = load_ix;
|
|
sp_ctrl = latch_sp;
|
|
next_state = fetch_state;
|
|
end
|
|
4'b1011: // rti
|
|
begin
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_add16;
|
|
cc_ctrl = latch_cc;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = load_sp;
|
|
next_state = rti_cc_state;
|
|
end
|
|
4'b1100: // pshx
|
|
begin
|
|
left_ctrl = sp_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
next_state = pshx_lo_state;
|
|
end
|
|
4'b1101: // mul
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = accb_right;
|
|
alu_ctrl = alu_add16;
|
|
cc_ctrl = latch_cc;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
next_state = mul_state;
|
|
end
|
|
4'b1110: // wai
|
|
begin
|
|
left_ctrl = sp_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
next_state = int_pcl_state;
|
|
end
|
|
4'b1111: // swi
|
|
begin
|
|
left_ctrl = sp_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
next_state = int_pcl_state;
|
|
end
|
|
default:
|
|
begin
|
|
left_ctrl = sp_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
next_state = fetch_state;
|
|
end
|
|
endcase
|
|
end
|
|
//
|
|
// Accumulator A Single operand
|
|
// source = Acc A dest = Acc A
|
|
// Do not advance PC
|
|
//
|
|
4'b0100: // acca single op
|
|
begin
|
|
md_ctrl = fetch_first_md;
|
|
accb_ctrl = latch_accb;
|
|
pc_ctrl = latch_pc;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
left_ctrl = acca_left;
|
|
case (op_code[3:0])
|
|
4'b0000: // neg
|
|
begin
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_neg;
|
|
acca_ctrl = load_acca;
|
|
cc_ctrl = load_cc;
|
|
end
|
|
4'b0011: // com
|
|
begin
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_com;
|
|
acca_ctrl = load_acca;
|
|
cc_ctrl = load_cc;
|
|
end
|
|
4'b0100: // lsr
|
|
begin
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_lsr8;
|
|
acca_ctrl = load_acca;
|
|
cc_ctrl = load_cc;
|
|
end
|
|
4'b0110: // ror
|
|
begin
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_ror8;
|
|
acca_ctrl = load_acca;
|
|
cc_ctrl = load_cc;
|
|
end
|
|
4'b0111: // asr
|
|
begin
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_asr8;
|
|
acca_ctrl = load_acca;
|
|
cc_ctrl = load_cc;
|
|
end
|
|
4'b1000: // asl
|
|
begin
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_asl8;
|
|
acca_ctrl = load_acca;
|
|
cc_ctrl = load_cc;
|
|
end
|
|
4'b1001: // rol
|
|
begin
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_rol8;
|
|
acca_ctrl = load_acca;
|
|
cc_ctrl = load_cc;
|
|
end
|
|
4'b1010: // dec
|
|
begin
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_dec;
|
|
acca_ctrl = load_acca;
|
|
cc_ctrl = load_cc;
|
|
end
|
|
4'b1011: // undefined
|
|
begin
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
acca_ctrl = latch_acca;
|
|
cc_ctrl = latch_cc;
|
|
end
|
|
4'b1100: // inc
|
|
begin
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_inc;
|
|
acca_ctrl = load_acca;
|
|
cc_ctrl = load_cc;
|
|
end
|
|
4'b1101: // tst
|
|
begin
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_tst;
|
|
acca_ctrl = latch_acca;
|
|
cc_ctrl = load_cc;
|
|
end
|
|
4'b1110: // jmp
|
|
begin
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
acca_ctrl = latch_acca;
|
|
cc_ctrl = latch_cc;
|
|
end
|
|
4'b1111: // clr
|
|
begin
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_clr;
|
|
acca_ctrl = load_acca;
|
|
cc_ctrl = load_cc;
|
|
end
|
|
default:
|
|
begin
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
acca_ctrl = latch_acca;
|
|
cc_ctrl = latch_cc;
|
|
end
|
|
endcase
|
|
next_state = fetch_state;
|
|
end
|
|
//
|
|
// single operand acc b
|
|
// Do not advance PC
|
|
//
|
|
4'b0101:
|
|
begin
|
|
md_ctrl = fetch_first_md;
|
|
acca_ctrl = latch_acca;
|
|
pc_ctrl = latch_pc;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
left_ctrl = accb_left;
|
|
case (op_code[3:0])
|
|
4'b0000: // neg
|
|
begin
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_neg;
|
|
accb_ctrl = load_accb;
|
|
cc_ctrl = load_cc;
|
|
end
|
|
4'b0011: // com
|
|
begin
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_com;
|
|
accb_ctrl = load_accb;
|
|
cc_ctrl = load_cc;
|
|
end
|
|
4'b0100: // lsr
|
|
begin
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_lsr8;
|
|
accb_ctrl = load_accb;
|
|
cc_ctrl = load_cc;
|
|
end
|
|
4'b0110: // ror
|
|
begin
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_ror8;
|
|
accb_ctrl = load_accb;
|
|
cc_ctrl = load_cc;
|
|
end
|
|
4'b0111: // asr
|
|
begin
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_asr8;
|
|
accb_ctrl = load_accb;
|
|
cc_ctrl = load_cc;
|
|
end
|
|
4'b1000: // asl
|
|
begin
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_asl8;
|
|
accb_ctrl = load_accb;
|
|
cc_ctrl = load_cc;
|
|
end
|
|
4'b1001: // rol
|
|
begin
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_rol8;
|
|
accb_ctrl = load_accb;
|
|
cc_ctrl = load_cc;
|
|
end
|
|
4'b1010: // dec
|
|
begin
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_dec;
|
|
accb_ctrl = load_accb;
|
|
cc_ctrl = load_cc;
|
|
end
|
|
4'b1011: // undefined
|
|
begin
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
accb_ctrl = latch_accb;
|
|
cc_ctrl = latch_cc;
|
|
end
|
|
4'b1100: // inc
|
|
begin
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_inc;
|
|
accb_ctrl = load_accb;
|
|
cc_ctrl = load_cc;
|
|
end
|
|
4'b1101: // tst
|
|
begin
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_tst;
|
|
accb_ctrl = latch_accb;
|
|
cc_ctrl = load_cc;
|
|
end
|
|
4'b1110: // jmp
|
|
begin
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
accb_ctrl = latch_accb;
|
|
cc_ctrl = latch_cc;
|
|
end
|
|
4'b1111: // clr
|
|
begin
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_clr;
|
|
accb_ctrl = load_accb;
|
|
cc_ctrl = load_cc;
|
|
end
|
|
default:
|
|
begin
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
accb_ctrl = latch_accb;
|
|
cc_ctrl = latch_cc;
|
|
end
|
|
endcase
|
|
next_state = fetch_state;
|
|
end
|
|
//
|
|
// Single operand indexed
|
|
// Two byte instruction so advance PC
|
|
// EA should hold index offset
|
|
//
|
|
4'b0110: // indexed single op
|
|
begin
|
|
md_ctrl = fetch_first_md;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
// increment the pc
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
pc_ctrl = inc_pc;
|
|
next_state = indexed_state;
|
|
end
|
|
//
|
|
// Single operand extended addressing
|
|
// three byte instruction so advance the PC
|
|
// Low order EA holds high order address
|
|
//
|
|
4'b0111: // extended single op
|
|
begin
|
|
md_ctrl = fetch_first_md;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
// increment the pc
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
pc_ctrl = inc_pc;
|
|
next_state = extended_state;
|
|
end
|
|
|
|
4'b1000: // acca immediate
|
|
begin
|
|
md_ctrl = fetch_first_md;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
// increment the pc
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
pc_ctrl = inc_pc;
|
|
case (op_code[3:0])
|
|
4'b0011, // subdd #
|
|
4'b1100, // cpx #
|
|
4'b1110: // lds #
|
|
next_state = immediate16_state;
|
|
4'b1101: // bsr
|
|
next_state = bsr_state;
|
|
default:
|
|
next_state = fetch_state;
|
|
endcase
|
|
end
|
|
|
|
4'b1001: // acca direct
|
|
begin
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
// increment the pc
|
|
pc_ctrl = inc_pc;
|
|
case (op_code[3:0])
|
|
4'b0111: // staa direct
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_st8;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = load_md;
|
|
next_state = write8_state;
|
|
end
|
|
4'b1111: // sts direct
|
|
begin
|
|
left_ctrl = sp_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_st16;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = load_md;
|
|
next_state = write16_state;
|
|
end
|
|
4'b1101: // jsr direct
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = fetch_first_md;
|
|
next_state = jsr_state;
|
|
end
|
|
default:
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = fetch_first_md;
|
|
next_state = read8_state;
|
|
end
|
|
endcase
|
|
end
|
|
|
|
4'b1010: // acca indexed
|
|
begin
|
|
md_ctrl = fetch_first_md;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
// increment the pc
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
pc_ctrl = inc_pc;
|
|
next_state = indexed_state;
|
|
end
|
|
|
|
4'b1011: // acca extended
|
|
begin
|
|
md_ctrl = fetch_first_md;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
// increment the pc
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
pc_ctrl = inc_pc;
|
|
next_state = extended_state;
|
|
end
|
|
|
|
4'b1100: // accb immediate
|
|
begin
|
|
md_ctrl = fetch_first_md;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
// increment the pc
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
pc_ctrl = inc_pc;
|
|
case (op_code[3:0])
|
|
4'b0011, // addd #
|
|
4'b1100, // ldd #
|
|
4'b1110: // ldx #
|
|
next_state = immediate16_state;
|
|
default:
|
|
next_state = fetch_state;
|
|
endcase
|
|
end
|
|
|
|
4'b1101: // accb direct
|
|
begin
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
// increment the pc
|
|
pc_ctrl = inc_pc;
|
|
case (op_code[3:0])
|
|
4'b0111: // stab direct
|
|
begin
|
|
left_ctrl = accb_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_st8;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = load_md;
|
|
next_state = write8_state;
|
|
end
|
|
4'b1101: // std direct
|
|
begin
|
|
left_ctrl = accd_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_st16;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = load_md;
|
|
next_state = write16_state;
|
|
end
|
|
4'b1111: // stx direct
|
|
begin
|
|
left_ctrl = ix_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_st16;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = load_md;
|
|
next_state = write16_state;
|
|
end
|
|
default:
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = fetch_first_md;
|
|
next_state = read8_state;
|
|
end
|
|
endcase
|
|
end
|
|
|
|
4'b1110: // accb indexed
|
|
begin
|
|
md_ctrl = fetch_first_md;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
// increment the pc
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
pc_ctrl = inc_pc;
|
|
next_state = indexed_state;
|
|
end
|
|
|
|
4'b1111: // accb extended
|
|
begin
|
|
md_ctrl = fetch_first_md;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
// increment the pc
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
pc_ctrl = inc_pc;
|
|
next_state = extended_state;
|
|
end
|
|
|
|
default:
|
|
begin
|
|
md_ctrl = fetch_first_md;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
// idle the pc
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
pc_ctrl = latch_pc;
|
|
next_state = fetch_state;
|
|
end
|
|
endcase
|
|
end
|
|
|
|
immediate16_state:
|
|
begin
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
op_ctrl = latch_op;
|
|
iv_ctrl = latch_iv;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
//ea_ctrl = fetch_next_ea; //steve
|
|
// increment pc
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
pc_ctrl = inc_pc;
|
|
// fetch next immediate byte
|
|
md_ctrl = fetch_next_md;
|
|
addr_ctrl = fetch_ad;
|
|
dout_ctrl = md_lo_dout;
|
|
next_state = fetch_state;
|
|
end
|
|
//
|
|
// ea holds 8 bit index offet
|
|
// calculate the effective memory address
|
|
// using the alu
|
|
//
|
|
indexed_state:
|
|
begin
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
pc_ctrl = latch_pc;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
// calculate effective address from index reg
|
|
// index offest is not sign extended
|
|
ea_ctrl = add_ix_ea;
|
|
// idle the bus
|
|
addr_ctrl = idle_ad;
|
|
dout_ctrl = md_lo_dout;
|
|
// work out next state
|
|
case (op_code[7:4])
|
|
4'b0110: // single op indexed
|
|
begin
|
|
md_ctrl = latch_md;
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
case (op_code[3:0])
|
|
4'b1011: // undefined
|
|
next_state = fetch_state;
|
|
4'b1110: // jmp
|
|
next_state = jmp_state;
|
|
default:
|
|
next_state = read8_state;
|
|
endcase
|
|
end
|
|
4'b1010: // acca indexed
|
|
begin
|
|
case (op_code[3:0])
|
|
4'b0111: // staa
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_st8;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = load_md;
|
|
next_state = write8_state;
|
|
end
|
|
4'b1101: // jsr
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = latch_md;
|
|
next_state = jsr_state;
|
|
end
|
|
4'b1111: // sts
|
|
begin
|
|
left_ctrl = sp_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_st16;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = load_md;
|
|
next_state = write16_state;
|
|
end
|
|
default:
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = latch_md;
|
|
next_state = read8_state;
|
|
end
|
|
endcase
|
|
end
|
|
4'b1110: // accb indexed
|
|
begin
|
|
case (op_code[3:0])
|
|
4'b0111: // stab direct
|
|
begin
|
|
left_ctrl = accb_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_st8;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = load_md;
|
|
next_state = write8_state;
|
|
end
|
|
4'b1101: // std direct
|
|
begin
|
|
left_ctrl = accd_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_st16;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = load_md;
|
|
next_state = write16_state;
|
|
end
|
|
4'b1111: // stx direct
|
|
begin
|
|
left_ctrl = ix_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_st16;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = load_md;
|
|
next_state = write16_state;
|
|
end
|
|
default:
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = latch_md;
|
|
next_state = read8_state;
|
|
end
|
|
endcase
|
|
end
|
|
default:
|
|
begin
|
|
md_ctrl = latch_md;
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
next_state = fetch_state;
|
|
end
|
|
endcase
|
|
end
|
|
//
|
|
// ea holds the low byte of the absolute address
|
|
// Move ea low byte into ea high byte
|
|
// load new ea low byte to for absolute 16 bit address
|
|
// advance the program counter
|
|
//
|
|
extended_state: // fetch ea low byte
|
|
begin
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
// increment pc
|
|
pc_ctrl = inc_pc;
|
|
// fetch next effective address bytes
|
|
ea_ctrl = fetch_next_ea;
|
|
addr_ctrl = fetch_ad;
|
|
dout_ctrl = md_lo_dout;
|
|
// work out the next state
|
|
case (op_code[7:4])
|
|
4'b0111: // single op extended
|
|
begin
|
|
md_ctrl = latch_md;
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
case (op_code[3:0])
|
|
4'b1011: // undefined
|
|
next_state = fetch_state;
|
|
4'b1110: // jmp
|
|
next_state = jmp_state;
|
|
default:
|
|
next_state = read8_state;
|
|
endcase
|
|
end
|
|
4'b1011: // acca extended
|
|
case (op_code[3:0])
|
|
4'b0111: // staa
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_st8;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = load_md;
|
|
next_state = write8_state;
|
|
end
|
|
4'b1101: // jsr
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = latch_md;
|
|
next_state = jsr_state;
|
|
end
|
|
4'b1111: // sts
|
|
begin
|
|
left_ctrl = sp_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_st16;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = load_md;
|
|
next_state = write16_state;
|
|
end
|
|
default:
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = latch_md;
|
|
next_state = read8_state;
|
|
end
|
|
endcase
|
|
4'b1111: // accb extended
|
|
case (op_code[3:0])
|
|
4'b0111: // stab
|
|
begin
|
|
left_ctrl = accb_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_st8;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = load_md;
|
|
next_state = write8_state;
|
|
end
|
|
4'b1101: // std
|
|
begin
|
|
left_ctrl = accd_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_st16;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = load_md;
|
|
next_state = write16_state;
|
|
end
|
|
4'b1111: // stx
|
|
begin
|
|
left_ctrl = ix_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_st16;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = load_md;
|
|
next_state = write16_state;
|
|
end
|
|
default:
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = latch_md;
|
|
next_state = read8_state;
|
|
end
|
|
endcase
|
|
default:
|
|
begin
|
|
md_ctrl = latch_md;
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
next_state = fetch_state;
|
|
end
|
|
endcase
|
|
end
|
|
//
|
|
// here if ea holds low byte (direct page)
|
|
// can enter here from extended addressing
|
|
// read memory location
|
|
// note that reads may be 8 or 16 bits
|
|
//
|
|
read8_state: // read data
|
|
begin
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
pc_ctrl = latch_pc;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
//
|
|
addr_ctrl = read_ad;
|
|
dout_ctrl = md_lo_dout;
|
|
case (op_code[7:4])
|
|
4'b0110, 4'b0111: // single operand
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = fetch_first_md;
|
|
ea_ctrl = latch_ea;
|
|
next_state = execute_state;
|
|
end
|
|
|
|
4'b1001, 4'b1010, 4'b1011: // acca
|
|
case (op_code[3:0])
|
|
4'b0011, // subd
|
|
4'b1110, // lds
|
|
4'b1100: // cpx
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = fetch_first_md;
|
|
// increment the effective address in case of 16 bit load
|
|
ea_ctrl = inc_ea;
|
|
next_state = read16_state;
|
|
end
|
|
default:
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = fetch_first_md;
|
|
ea_ctrl = latch_ea;
|
|
next_state = fetch_state;
|
|
end
|
|
endcase
|
|
|
|
4'b1101, 4'b1110, 4'b1111: // accb
|
|
case (op_code[3:0])
|
|
4'b0011, // addd
|
|
4'b1100, // ldd
|
|
4'b1110: // ldx
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = fetch_first_md;
|
|
// increment the effective address in case of 16 bit load
|
|
ea_ctrl = inc_ea;
|
|
next_state = read16_state;
|
|
end
|
|
default:
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = fetch_first_md;
|
|
ea_ctrl = latch_ea;
|
|
next_state = execute_state;
|
|
end
|
|
endcase
|
|
default:
|
|
begin
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = fetch_first_md;
|
|
ea_ctrl = latch_ea;
|
|
next_state = fetch_state;
|
|
end
|
|
endcase
|
|
end
|
|
|
|
read16_state: // read second data byte from ea
|
|
begin
|
|
// default
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
pc_ctrl = latch_pc;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
// idle the effective address
|
|
ea_ctrl = latch_ea;
|
|
// read the low byte of the 16 bit data
|
|
md_ctrl = fetch_next_md;
|
|
addr_ctrl = read_ad;
|
|
dout_ctrl = md_lo_dout;
|
|
next_state = fetch_state;
|
|
end
|
|
//
|
|
// 16 bit Write state
|
|
// write high byte of ALU output.
|
|
// EA hold address of memory to write to
|
|
// Advance the effective address in ALU
|
|
//
|
|
write16_state:
|
|
begin
|
|
// default
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
// increment the effective address
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
ea_ctrl = inc_ea;
|
|
// write the ALU hi byte to ea
|
|
addr_ctrl = write_ad;
|
|
dout_ctrl = md_hi_dout;
|
|
next_state = write8_state;
|
|
end
|
|
//
|
|
// 8 bit write
|
|
// Write low 8 bits of ALU output
|
|
//
|
|
write8_state:
|
|
begin
|
|
// default registers
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// idle the ALU
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
// write ALU low byte output
|
|
addr_ctrl = write_ad;
|
|
dout_ctrl = md_lo_dout;
|
|
next_state = fetch_state;
|
|
end
|
|
|
|
jmp_state:
|
|
begin
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// load PC with effective address
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
pc_ctrl = load_ea_pc;
|
|
// idle the bus
|
|
addr_ctrl = idle_ad;
|
|
dout_ctrl = md_lo_dout;
|
|
next_state = fetch_state;
|
|
end
|
|
|
|
jsr_state: // JSR
|
|
begin
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// decrement sp
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_sub16;
|
|
cc_ctrl = latch_cc;
|
|
sp_ctrl = load_sp;
|
|
// write pc low
|
|
addr_ctrl = push_ad;
|
|
dout_ctrl = pc_lo_dout;
|
|
next_state = jsr1_state;
|
|
end
|
|
|
|
jsr1_state: // JSR
|
|
begin
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// decrement sp
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_sub16;
|
|
cc_ctrl = latch_cc;
|
|
sp_ctrl = load_sp;
|
|
// write pc hi
|
|
addr_ctrl = push_ad;
|
|
dout_ctrl = pc_hi_dout;
|
|
next_state = jmp_state;
|
|
end
|
|
|
|
branch_state: // Bcc
|
|
begin
|
|
// default registers
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// calculate signed branch
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
pc_ctrl = add_ea_pc;
|
|
// idle the bus
|
|
addr_ctrl = idle_ad;
|
|
dout_ctrl = md_lo_dout;
|
|
next_state = fetch_state;
|
|
end
|
|
|
|
bsr_state: // BSR
|
|
begin
|
|
// default
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// decrement sp
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_sub16;
|
|
cc_ctrl = latch_cc;
|
|
sp_ctrl = load_sp;
|
|
// write pc low
|
|
addr_ctrl = push_ad;
|
|
dout_ctrl = pc_lo_dout;
|
|
next_state = bsr1_state;
|
|
end
|
|
|
|
bsr1_state: // BSR
|
|
begin
|
|
// default registers
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// decrement sp
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_sub16;
|
|
cc_ctrl = latch_cc;
|
|
sp_ctrl = load_sp;
|
|
// write pc hi
|
|
addr_ctrl = push_ad;
|
|
dout_ctrl = pc_hi_dout;
|
|
next_state = branch_state;
|
|
end
|
|
|
|
rts_hi_state: // RTS
|
|
begin
|
|
// default
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// increment the sp
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_add16;
|
|
cc_ctrl = latch_cc;
|
|
sp_ctrl = load_sp;
|
|
// read pc hi
|
|
pc_ctrl = pull_hi_pc;
|
|
addr_ctrl = pull_ad;
|
|
dout_ctrl = pc_hi_dout;
|
|
next_state = rts_lo_state;
|
|
end
|
|
|
|
rts_lo_state: // RTS1
|
|
begin
|
|
// default
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// idle the ALU
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
// read pc low
|
|
pc_ctrl = pull_lo_pc;
|
|
addr_ctrl = pull_ad;
|
|
dout_ctrl = pc_lo_dout;
|
|
next_state = fetch_state;
|
|
end
|
|
|
|
mul_state:
|
|
begin
|
|
// default
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
pc_ctrl = latch_pc;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// move acca to md
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_st16;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = load_md;
|
|
// idle bus
|
|
addr_ctrl = idle_ad;
|
|
dout_ctrl = md_lo_dout;
|
|
next_state = mulea_state;
|
|
end
|
|
|
|
mulea_state:
|
|
begin
|
|
// default
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
pc_ctrl = latch_pc;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
md_ctrl = latch_md;
|
|
// idle ALU
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
// move accb to ea
|
|
ea_ctrl = load_accb_ea;
|
|
// idle bus
|
|
addr_ctrl = idle_ad;
|
|
dout_ctrl = md_lo_dout;
|
|
next_state = muld_state;
|
|
end
|
|
|
|
muld_state:
|
|
begin
|
|
// default
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
pc_ctrl = latch_pc;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
md_ctrl = latch_md;
|
|
// clear accd
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_ld8;
|
|
cc_ctrl = latch_cc;
|
|
acca_ctrl = load_hi_acca;
|
|
accb_ctrl = load_accb;
|
|
// idle bus
|
|
addr_ctrl = idle_ad;
|
|
dout_ctrl = md_lo_dout;
|
|
next_state = mul0_state;
|
|
end
|
|
|
|
mul0_state:
|
|
begin
|
|
// default
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
pc_ctrl = latch_pc;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// if bit 0 of ea set, add accd to md
|
|
left_ctrl = accd_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_add16;
|
|
if (ea[0] == 1'b1)
|
|
begin
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = load_hi_acca;
|
|
accb_ctrl = load_accb;
|
|
end
|
|
else
|
|
begin
|
|
cc_ctrl = latch_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
end
|
|
md_ctrl = shiftl_md;
|
|
// idle bus
|
|
addr_ctrl = idle_ad;
|
|
dout_ctrl = md_lo_dout;
|
|
next_state = mul1_state;
|
|
end
|
|
|
|
mul1_state:
|
|
begin
|
|
// default
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
pc_ctrl = latch_pc;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// if bit 1 of ea set, add accd to md
|
|
left_ctrl = accd_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_add16;
|
|
if (ea[1] == 1'b1)
|
|
begin
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = load_hi_acca;
|
|
accb_ctrl = load_accb;
|
|
end
|
|
else
|
|
begin
|
|
cc_ctrl = latch_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
end
|
|
md_ctrl = shiftl_md;
|
|
// idle bus
|
|
addr_ctrl = idle_ad;
|
|
dout_ctrl = md_lo_dout;
|
|
next_state = mul2_state;
|
|
end
|
|
|
|
mul2_state:
|
|
begin
|
|
// default
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
pc_ctrl = latch_pc;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// if bit 2 of ea set, add accd to md
|
|
left_ctrl = accd_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_add16;
|
|
if (ea[2] == 1'b1)
|
|
begin
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = load_hi_acca;
|
|
accb_ctrl = load_accb;
|
|
end
|
|
else
|
|
begin
|
|
cc_ctrl = latch_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
end
|
|
md_ctrl = shiftl_md;
|
|
// idle bus
|
|
addr_ctrl = idle_ad;
|
|
dout_ctrl = md_lo_dout;
|
|
next_state = mul3_state;
|
|
end
|
|
|
|
mul3_state:
|
|
begin
|
|
// default
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
pc_ctrl = latch_pc;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// if bit 3 of ea set, add accd to md
|
|
left_ctrl = accd_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_add16;
|
|
if (ea[3] == 1'b1)
|
|
begin
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = load_hi_acca;
|
|
accb_ctrl = load_accb;
|
|
end
|
|
else
|
|
begin
|
|
cc_ctrl = latch_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
end
|
|
md_ctrl = shiftl_md;
|
|
// idle bus
|
|
addr_ctrl = idle_ad;
|
|
dout_ctrl = md_lo_dout;
|
|
next_state = mul4_state;
|
|
end
|
|
|
|
mul4_state:
|
|
begin
|
|
// default
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
pc_ctrl = latch_pc;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// if bit 4 of ea set, add accd to md
|
|
left_ctrl = accd_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_add16;
|
|
if (ea[4] == 1'b1)
|
|
begin
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = load_hi_acca;
|
|
accb_ctrl = load_accb;
|
|
end
|
|
else
|
|
begin
|
|
cc_ctrl = latch_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
end
|
|
md_ctrl = shiftl_md;
|
|
// idle bus
|
|
addr_ctrl = idle_ad;
|
|
dout_ctrl = md_lo_dout;
|
|
next_state = mul5_state;
|
|
end
|
|
|
|
mul5_state:
|
|
begin
|
|
// default
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
pc_ctrl = latch_pc;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// if bit 5 of ea set, add accd to md
|
|
left_ctrl = accd_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_add16;
|
|
if (ea[5] == 1'b1)
|
|
begin
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = load_hi_acca;
|
|
accb_ctrl = load_accb;
|
|
end
|
|
else
|
|
begin
|
|
cc_ctrl = latch_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
end
|
|
md_ctrl = shiftl_md;
|
|
// idle bus
|
|
addr_ctrl = idle_ad;
|
|
dout_ctrl = md_lo_dout;
|
|
next_state = mul6_state;
|
|
end
|
|
|
|
mul6_state:
|
|
begin
|
|
// default
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
pc_ctrl = latch_pc;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// if bit 6 of ea set, add accd to md
|
|
left_ctrl = accd_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_add16;
|
|
if (ea[6] == 1'b1)
|
|
begin
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = load_hi_acca;
|
|
accb_ctrl = load_accb;
|
|
end
|
|
else
|
|
begin
|
|
cc_ctrl = latch_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
end
|
|
md_ctrl = shiftl_md;
|
|
// idle bus
|
|
addr_ctrl = idle_ad;
|
|
dout_ctrl = md_lo_dout;
|
|
next_state = mul7_state;
|
|
end
|
|
|
|
mul7_state:
|
|
begin
|
|
// default
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
pc_ctrl = latch_pc;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// if bit 7 of ea set, add accd to md
|
|
left_ctrl = accd_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_add16;
|
|
if (ea[7] == 1'b1)
|
|
begin
|
|
cc_ctrl = load_cc;
|
|
acca_ctrl = load_hi_acca;
|
|
accb_ctrl = load_accb;
|
|
end
|
|
else
|
|
begin
|
|
cc_ctrl = latch_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
end
|
|
md_ctrl = shiftl_md;
|
|
// idle bus
|
|
addr_ctrl = idle_ad;
|
|
dout_ctrl = md_lo_dout;
|
|
next_state = fetch_state;
|
|
end
|
|
|
|
execute_state: // execute single operand instruction
|
|
begin
|
|
// default
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
case (op_code[7:4])
|
|
4'b0110, // indexed single op
|
|
4'b0111: // extended single op
|
|
begin
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
pc_ctrl = latch_pc;
|
|
iv_ctrl = latch_iv;
|
|
ea_ctrl = latch_ea;
|
|
// idle the bus
|
|
addr_ctrl = idle_ad;
|
|
dout_ctrl = md_lo_dout;
|
|
case (op_code[3:0])
|
|
4'b0000: // neg
|
|
begin
|
|
left_ctrl = md_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_neg;
|
|
cc_ctrl = load_cc;
|
|
md_ctrl = load_md;
|
|
next_state = write8_state;
|
|
end
|
|
4'b0011: // com
|
|
begin
|
|
left_ctrl = md_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_com;
|
|
cc_ctrl = load_cc;
|
|
md_ctrl = load_md;
|
|
next_state = write8_state;
|
|
end
|
|
4'b0100: // lsr
|
|
begin
|
|
left_ctrl = md_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_lsr8;
|
|
cc_ctrl = load_cc;
|
|
md_ctrl = load_md;
|
|
next_state = write8_state;
|
|
end
|
|
4'b0110: // ror
|
|
begin
|
|
left_ctrl = md_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_ror8;
|
|
cc_ctrl = load_cc;
|
|
md_ctrl = load_md;
|
|
next_state = write8_state;
|
|
end
|
|
4'b0111: // asr
|
|
begin
|
|
left_ctrl = md_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_asr8;
|
|
cc_ctrl = load_cc;
|
|
md_ctrl = load_md;
|
|
next_state = write8_state;
|
|
end
|
|
4'b1000: // asl
|
|
begin
|
|
left_ctrl = md_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_asl8;
|
|
cc_ctrl = load_cc;
|
|
md_ctrl = load_md;
|
|
next_state = write8_state;
|
|
end
|
|
4'b1001: // rol
|
|
begin
|
|
left_ctrl = md_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_rol8;
|
|
cc_ctrl = load_cc;
|
|
md_ctrl = load_md;
|
|
next_state = write8_state;
|
|
end
|
|
4'b1010: // dec
|
|
begin
|
|
left_ctrl = md_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_dec;
|
|
cc_ctrl = load_cc;
|
|
md_ctrl = load_md;
|
|
next_state = write8_state;
|
|
end
|
|
4'b1011: // undefined
|
|
begin
|
|
left_ctrl = md_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = latch_md;
|
|
next_state = fetch_state;
|
|
end
|
|
4'b1100: // inc
|
|
begin
|
|
left_ctrl = md_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_inc;
|
|
cc_ctrl = load_cc;
|
|
md_ctrl = load_md;
|
|
next_state = write8_state;
|
|
end
|
|
4'b1101: // tst
|
|
begin
|
|
left_ctrl = md_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_tst;
|
|
cc_ctrl = load_cc;
|
|
md_ctrl = latch_md;
|
|
next_state = fetch_state;
|
|
end
|
|
4'b1110: // jmp
|
|
begin
|
|
left_ctrl = md_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = latch_md;
|
|
next_state = fetch_state;
|
|
end
|
|
4'b1111: // clr
|
|
begin
|
|
left_ctrl = md_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_clr;
|
|
cc_ctrl = load_cc;
|
|
md_ctrl = load_md;
|
|
next_state = write8_state;
|
|
end
|
|
default:
|
|
begin
|
|
left_ctrl = md_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
md_ctrl = latch_md;
|
|
next_state = fetch_state;
|
|
end
|
|
endcase
|
|
end
|
|
|
|
default:
|
|
begin
|
|
left_ctrl = accd_left;
|
|
right_ctrl = md_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
ea_ctrl = latch_ea;
|
|
// idle the bus
|
|
addr_ctrl = idle_ad;
|
|
dout_ctrl = md_lo_dout;
|
|
next_state = fetch_state;
|
|
end
|
|
endcase
|
|
end
|
|
|
|
psha_state:
|
|
begin
|
|
// default registers
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// decrement sp
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_sub16;
|
|
cc_ctrl = latch_cc;
|
|
sp_ctrl = load_sp;
|
|
// write acca
|
|
addr_ctrl = push_ad;
|
|
dout_ctrl = acca_dout;
|
|
next_state = fetch_state;
|
|
end
|
|
|
|
pula_state:
|
|
begin
|
|
// default registers
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// idle sp
|
|
left_ctrl = sp_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
sp_ctrl = latch_sp;
|
|
// read acca
|
|
acca_ctrl = pull_acca;
|
|
addr_ctrl = pull_ad;
|
|
dout_ctrl = acca_dout;
|
|
next_state = fetch_state;
|
|
end
|
|
|
|
pshb_state:
|
|
begin
|
|
// default registers
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// decrement sp
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_sub16;
|
|
cc_ctrl = latch_cc;
|
|
sp_ctrl = load_sp;
|
|
// write accb
|
|
addr_ctrl = push_ad;
|
|
dout_ctrl = accb_dout;
|
|
next_state = fetch_state;
|
|
end
|
|
|
|
pulb_state:
|
|
begin
|
|
// default
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// idle sp
|
|
left_ctrl = sp_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
sp_ctrl = latch_sp;
|
|
// read accb
|
|
accb_ctrl = pull_accb;
|
|
addr_ctrl = pull_ad;
|
|
dout_ctrl = accb_dout;
|
|
next_state = fetch_state;
|
|
end
|
|
|
|
pshx_lo_state:
|
|
begin
|
|
// default
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// decrement sp
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_sub16;
|
|
cc_ctrl = latch_cc;
|
|
sp_ctrl = load_sp;
|
|
// write ix low
|
|
addr_ctrl = push_ad;
|
|
dout_ctrl = ix_lo_dout;
|
|
next_state = pshx_hi_state;
|
|
end
|
|
|
|
pshx_hi_state:
|
|
begin
|
|
// default registers
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// decrement sp
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_sub16;
|
|
cc_ctrl = latch_cc;
|
|
sp_ctrl = load_sp;
|
|
// write ix hi
|
|
addr_ctrl = push_ad;
|
|
dout_ctrl = ix_hi_dout;
|
|
next_state = fetch_state;
|
|
end
|
|
|
|
pulx_hi_state:
|
|
begin
|
|
// default
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// increment sp
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_add16;
|
|
cc_ctrl = latch_cc;
|
|
sp_ctrl = load_sp;
|
|
// pull ix hi
|
|
ix_ctrl = pull_hi_ix;
|
|
addr_ctrl = pull_ad;
|
|
dout_ctrl = ix_hi_dout;
|
|
next_state = pulx_lo_state;
|
|
end
|
|
|
|
pulx_lo_state:
|
|
begin
|
|
// default
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// idle sp
|
|
left_ctrl = sp_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
sp_ctrl = latch_sp;
|
|
// read ix low
|
|
ix_ctrl = pull_lo_ix;
|
|
addr_ctrl = pull_ad;
|
|
dout_ctrl = ix_lo_dout;
|
|
next_state = fetch_state;
|
|
end
|
|
|
|
//
|
|
// return from interrupt
|
|
// enter here from bogus interrupts
|
|
//
|
|
rti_state:
|
|
begin
|
|
// default registers
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// increment sp
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_add16;
|
|
sp_ctrl = load_sp;
|
|
// idle address bus
|
|
cc_ctrl = latch_cc;
|
|
addr_ctrl = idle_ad;
|
|
dout_ctrl = cc_dout;
|
|
next_state = rti_cc_state;
|
|
end
|
|
|
|
rti_cc_state:
|
|
begin
|
|
// default registers
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// increment sp
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_add16;
|
|
sp_ctrl = load_sp;
|
|
// read cc
|
|
cc_ctrl = pull_cc;
|
|
addr_ctrl = pull_ad;
|
|
dout_ctrl = cc_dout;
|
|
next_state = rti_accb_state;
|
|
end
|
|
|
|
rti_accb_state:
|
|
begin
|
|
// default registers
|
|
acca_ctrl = latch_acca;
|
|
ix_ctrl = latch_ix;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// increment sp
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_add16;
|
|
cc_ctrl = latch_cc;
|
|
sp_ctrl = load_sp;
|
|
// read accb
|
|
accb_ctrl = pull_accb;
|
|
addr_ctrl = pull_ad;
|
|
dout_ctrl = accb_dout;
|
|
next_state = rti_acca_state;
|
|
end
|
|
|
|
rti_acca_state:
|
|
begin
|
|
// default registers
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// increment sp
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_add16;
|
|
cc_ctrl = latch_cc;
|
|
sp_ctrl = load_sp;
|
|
// read acca
|
|
acca_ctrl = pull_acca;
|
|
addr_ctrl = pull_ad;
|
|
dout_ctrl = acca_dout;
|
|
next_state = rti_ixh_state;
|
|
end
|
|
|
|
rti_ixh_state:
|
|
begin
|
|
// default
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// increment sp
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_add16;
|
|
cc_ctrl = latch_cc;
|
|
sp_ctrl = load_sp;
|
|
// read ix hi
|
|
ix_ctrl = pull_hi_ix;
|
|
addr_ctrl = pull_ad;
|
|
dout_ctrl = ix_hi_dout;
|
|
next_state = rti_ixl_state;
|
|
end
|
|
|
|
rti_ixl_state:
|
|
begin
|
|
// default
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// increment sp
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_add16;
|
|
cc_ctrl = latch_cc;
|
|
sp_ctrl = load_sp;
|
|
// read ix low
|
|
ix_ctrl = pull_lo_ix;
|
|
addr_ctrl = pull_ad;
|
|
dout_ctrl = ix_lo_dout;
|
|
next_state = rti_pch_state;
|
|
end
|
|
|
|
rti_pch_state:
|
|
begin
|
|
// default
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// increment sp
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_add16;
|
|
cc_ctrl = latch_cc;
|
|
sp_ctrl = load_sp;
|
|
// pull pc hi
|
|
pc_ctrl = pull_hi_pc;
|
|
addr_ctrl = pull_ad;
|
|
dout_ctrl = pc_hi_dout;
|
|
next_state = rti_pcl_state;
|
|
end
|
|
|
|
rti_pcl_state:
|
|
begin
|
|
// default
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// idle sp
|
|
left_ctrl = sp_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
sp_ctrl = latch_sp;
|
|
// pull pc low
|
|
pc_ctrl = pull_lo_pc;
|
|
addr_ctrl = pull_ad;
|
|
dout_ctrl = pc_lo_dout;
|
|
next_state = fetch_state;
|
|
end
|
|
|
|
//
|
|
// here on interrupt
|
|
// iv register hold interrupt type
|
|
//
|
|
int_pcl_state:
|
|
begin
|
|
// default
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// decrement sp
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_sub16;
|
|
cc_ctrl = latch_cc;
|
|
sp_ctrl = load_sp;
|
|
// write pc low
|
|
addr_ctrl = push_ad;
|
|
dout_ctrl = pc_lo_dout;
|
|
next_state = int_pch_state;
|
|
end
|
|
|
|
int_pch_state:
|
|
begin
|
|
// default
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// decrement sp
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_sub16;
|
|
cc_ctrl = latch_cc;
|
|
sp_ctrl = load_sp;
|
|
// write pc hi
|
|
addr_ctrl = push_ad;
|
|
dout_ctrl = pc_hi_dout;
|
|
next_state = int_ixl_state;
|
|
end
|
|
|
|
int_ixl_state:
|
|
begin
|
|
// default
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// decrement sp
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_sub16;
|
|
cc_ctrl = latch_cc;
|
|
sp_ctrl = load_sp;
|
|
// write ix low
|
|
addr_ctrl = push_ad;
|
|
dout_ctrl = ix_lo_dout;
|
|
next_state = int_ixh_state;
|
|
end
|
|
|
|
int_ixh_state:
|
|
begin
|
|
// default
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// decrement sp
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_sub16;
|
|
cc_ctrl = latch_cc;
|
|
sp_ctrl = load_sp;
|
|
// write ix hi
|
|
addr_ctrl = push_ad;
|
|
dout_ctrl = ix_hi_dout;
|
|
next_state = int_acca_state;
|
|
end
|
|
|
|
int_acca_state:
|
|
begin
|
|
// default
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// decrement sp
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_sub16;
|
|
cc_ctrl = latch_cc;
|
|
sp_ctrl = load_sp;
|
|
// write acca
|
|
addr_ctrl = push_ad;
|
|
dout_ctrl = acca_dout;
|
|
next_state = int_accb_state;
|
|
end
|
|
|
|
|
|
int_accb_state:
|
|
begin
|
|
// default
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// decrement sp
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_sub16;
|
|
cc_ctrl = latch_cc;
|
|
sp_ctrl = load_sp;
|
|
// write accb
|
|
addr_ctrl = push_ad;
|
|
dout_ctrl = accb_dout;
|
|
next_state = int_cc_state;
|
|
end
|
|
|
|
int_cc_state:
|
|
begin
|
|
// default
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// decrement sp
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_sub16;
|
|
cc_ctrl = latch_cc;
|
|
sp_ctrl = load_sp;
|
|
// write cc
|
|
addr_ctrl = push_ad;
|
|
dout_ctrl = cc_dout;
|
|
nmi_ctrl = latch_nmi;
|
|
//
|
|
// nmi is edge triggered
|
|
// nmi_req is cleared when nmi goes low.
|
|
//
|
|
if (nmi_req == 1'b1)
|
|
begin
|
|
iv_ctrl = nmi_iv;
|
|
next_state = vect_hi_state;
|
|
end
|
|
else
|
|
begin
|
|
//
|
|
// IRQ is level sensitive
|
|
//
|
|
if ((irq == 1'b1) & (cc[IBIT] == 1'b0))
|
|
begin
|
|
iv_ctrl = irq_iv;
|
|
next_state = int_mask_state;
|
|
end
|
|
else if ((irq_icf == 1'b1) & (cc[IBIT] == 1'b0))
|
|
begin
|
|
iv_ctrl = icf_iv;
|
|
next_state = int_mask_state;
|
|
end
|
|
else if ((irq_ocf == 1'b1) & (cc[IBIT] == 1'b0))
|
|
begin
|
|
iv_ctrl = ocf_iv;
|
|
next_state = int_mask_state;
|
|
end
|
|
else if ((irq_tof == 1'b1) & (cc[IBIT] == 1'b0))
|
|
begin
|
|
iv_ctrl = tof_iv;
|
|
next_state = int_mask_state;
|
|
end
|
|
else if ((irq_sci == 1'b1) & (cc[IBIT] == 1'b0))
|
|
begin
|
|
iv_ctrl = sci_iv;
|
|
next_state = int_mask_state;
|
|
end
|
|
else
|
|
case (op_code)
|
|
8'b00111110: // WAI (wait for interrupt)
|
|
begin
|
|
iv_ctrl = latch_iv;
|
|
next_state = int_wai_state;
|
|
end
|
|
8'b00111111: // SWI (Software interrupt)
|
|
begin
|
|
iv_ctrl = swi_iv;
|
|
next_state = vect_hi_state;
|
|
end
|
|
default: // bogus interrupt (return)
|
|
begin
|
|
iv_ctrl = latch_iv;
|
|
next_state = rti_state;
|
|
end
|
|
endcase
|
|
end
|
|
end
|
|
|
|
int_wai_state:
|
|
begin
|
|
// default
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
op_ctrl = latch_op;
|
|
ea_ctrl = latch_ea;
|
|
// enable interrupts
|
|
left_ctrl = sp_left;
|
|
right_ctrl = plus_one_right;
|
|
alu_ctrl = alu_cli;
|
|
cc_ctrl = load_cc;
|
|
sp_ctrl = latch_sp;
|
|
// idle bus
|
|
addr_ctrl = idle_ad;
|
|
dout_ctrl = cc_dout;
|
|
if ((nmi_req == 1'b1) & (nmi_ack==1'b0))
|
|
begin
|
|
iv_ctrl = nmi_iv;
|
|
nmi_ctrl = set_nmi;
|
|
next_state = vect_hi_state;
|
|
end
|
|
else
|
|
begin
|
|
//
|
|
// nmi request is not cleared until nmi input goes low
|
|
//
|
|
if ((nmi_req == 1'b0) & (nmi_ack==1'b1))
|
|
nmi_ctrl = reset_nmi;
|
|
else
|
|
nmi_ctrl = latch_nmi;
|
|
//
|
|
// IRQ is level sensitive
|
|
//
|
|
if ((irq == 1'b1) & (cc[IBIT] == 1'b0))
|
|
begin
|
|
iv_ctrl = irq_iv;
|
|
next_state = int_mask_state;
|
|
end
|
|
else if ((irq_icf == 1'b1) & (cc[IBIT] == 1'b0))
|
|
begin
|
|
iv_ctrl = icf_iv;
|
|
next_state = int_mask_state;
|
|
end
|
|
else if ((irq_ocf == 1'b1) & (cc[IBIT] == 1'b0))
|
|
begin
|
|
iv_ctrl = ocf_iv;
|
|
next_state = int_mask_state;
|
|
end
|
|
else if ((irq_tof == 1'b1) & (cc[IBIT] == 1'b0))
|
|
begin
|
|
iv_ctrl = tof_iv;
|
|
next_state = int_mask_state;
|
|
end
|
|
else if ((irq_sci == 1'b1) & (cc[IBIT] == 1'b0))
|
|
begin
|
|
iv_ctrl = sci_iv;
|
|
next_state = int_mask_state;
|
|
end
|
|
else
|
|
begin
|
|
iv_ctrl = latch_iv;
|
|
next_state = int_wai_state;
|
|
end
|
|
end
|
|
end
|
|
|
|
int_mask_state:
|
|
begin
|
|
// default
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// Mask IRQ
|
|
left_ctrl = sp_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_sei;
|
|
cc_ctrl = load_cc;
|
|
sp_ctrl = latch_sp;
|
|
// idle bus cycle
|
|
addr_ctrl = idle_ad;
|
|
dout_ctrl = md_lo_dout;
|
|
next_state = vect_hi_state;
|
|
end
|
|
|
|
halt_state: // halt CPU.
|
|
begin
|
|
// default
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// do nothing in ALU
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
// idle bus cycle
|
|
addr_ctrl = idle_ad;
|
|
dout_ctrl = md_lo_dout;
|
|
if (halt == 1'b1)
|
|
next_state = halt_state;
|
|
else
|
|
next_state = fetch_state;
|
|
end
|
|
|
|
default: // error state halt on undefine states
|
|
begin
|
|
// default
|
|
acca_ctrl = latch_acca;
|
|
accb_ctrl = latch_accb;
|
|
ix_ctrl = latch_ix;
|
|
sp_ctrl = latch_sp;
|
|
pc_ctrl = latch_pc;
|
|
md_ctrl = latch_md;
|
|
iv_ctrl = latch_iv;
|
|
op_ctrl = latch_op;
|
|
nmi_ctrl = latch_nmi;
|
|
ea_ctrl = latch_ea;
|
|
// do nothing in ALU
|
|
left_ctrl = acca_left;
|
|
right_ctrl = zero_right;
|
|
alu_ctrl = alu_nop;
|
|
cc_ctrl = latch_cc;
|
|
// idle bus cycle
|
|
addr_ctrl = idle_ad;
|
|
dout_ctrl = md_lo_dout;
|
|
next_state = error_state;
|
|
end
|
|
endcase
|
|
end
|
|
|
|
////////////////////////////////
|
|
//
|
|
// state machine
|
|
//
|
|
////////////////////////////////
|
|
|
|
always_ff @(posedge clk)
|
|
begin
|
|
if (rst == 1'b1)
|
|
state <= reset_state;
|
|
else if (hold == 1'b1)
|
|
state <= state;
|
|
else
|
|
state <= next_state;
|
|
end
|
|
endmodule
|