URL
https://opencores.org/ocsvn/System09/System09/trunk
Subversion Repositories System09
Compare Revisions
- This comparison shows the changes necessary to convert path
/System09/tags/V10/rtl
- from Rev 3 to Rev 66
- ↔ Reverse comparison
Rev 3 → Rev 66
/vhdl/cpu09.vhd
0,0 → 1,9535
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ iv_ctrl <= latch_iv;
+ nmi_ctrl <= latch_nmi;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ case ea(6 downto 5) is
+ when "00" =>
+ left_ctrl <= ix_left;
+ when "01" =>
+ left_ctrl <= iy_left;
+ when "10" =>
+ left_ctrl <= up_left;
+ when others =>
+ -- when "11" =>
+ left_ctrl <= sp_left;
+ end case;
+ -- ea = index reg + md
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_add16;
+ ea_ctrl <= load_ea;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ -- return to previous state
+ if ea(4) = '0' then
+ st_ctrl <= pull_st;
+ return_state <= fetch_state;
+ next_state <= saved_state;
+ else
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= indirect_state;
+ end if;
+ --
+ -- pc relative with 8 bit signed offest
+ -- md holds signed offset
+ --
+ when pcrel8_state =>
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ iv_ctrl <= latch_iv;
+ nmi_ctrl <= latch_nmi;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ -- ea = pc + signed md
+ left_ctrl <= pc_left;
+ right_ctrl <= md_sign8_right;
+ alu_ctrl <= alu_add16;
+ ea_ctrl <= load_ea;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ -- return to previous state
+ if ea(4) = '0' then
+ st_ctrl <= pull_st;
+ return_state <= fetch_state;
+ next_state <= saved_state;
+ else
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= indirect_state;
+ end if;
+
+ -- pc relative addressing with 16 bit offset
+ -- pick up the low byte of the offset in md
+ -- advance the pc
+ when pcrel16_state =>
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ iv_ctrl <= latch_iv;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- advance pc
+ left_ctrl <= pc_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ pc_ctrl <= incr_pc;
+ -- fetch low byte
+ ea_ctrl <= latch_ea;
+ md_ctrl <= fetch_next_md;
+ addr_ctrl <= fetch_ad;
+ dout_ctrl <= md_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= pcrel16_2_state;
+
+ -- pc relative with16 bit signed offest
+ -- md holds signed offset
+ when pcrel16_2_state =>
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ iv_ctrl <= latch_iv;
+ nmi_ctrl <= latch_nmi;
+ pc_ctrl <= latch_pc;
+ -- ea = pc + md
+ left_ctrl <= pc_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_add16;
+ ea_ctrl <= load_ea;
+ md_ctrl <= latch_md;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ -- return to previous state
+ if ea(4) = '0' then
+ st_ctrl <= pull_st;
+ return_state <= fetch_state;
+ next_state <= saved_state;
+ else
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= indirect_state;
+ end if;
+
+ -- indexed to absolute address
+ -- md holds address
+ -- ea hold indexing mode byte
+ when indexaddr2_state =>
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ iv_ctrl <= latch_iv;
+ nmi_ctrl <= latch_nmi;
+ pc_ctrl <= latch_pc;
+ -- ea = md
+ left_ctrl <= pc_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_ld16;
+ ea_ctrl <= load_ea;
+ md_ctrl <= latch_md;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ -- return to previous state
+ if ea(4) = '0' then
+ st_ctrl <= pull_st;
+ return_state <= fetch_state;
+ next_state <= saved_state;
+ else
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= indirect_state;
+ end if;
+
+ -- indexed to address
+ -- pick up the low byte of the address
+ -- advance the pc
+ when indexaddr_state =>
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- advance pc
+ left_ctrl <= pc_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ pc_ctrl <= incr_pc;
+ -- fetch low byte
+ md_ctrl <= fetch_next_md;
+ addr_ctrl <= read_ad;
+ dout_ctrl <= md_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= indexaddr2_state;
+ --
+ -- load md with high byte of indirect address
+ -- pointed to by ea
+ -- increment ea
+ --
+ when indirect_state =>
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ pc_ctrl <= latch_pc;
+ -- increment ea
+ left_ctrl <= ea_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ ea_ctrl <= load_ea;
+ -- fetch high byte
+ md_ctrl <= fetch_first_md;
+ addr_ctrl <= read_ad;
+ dout_ctrl <= md_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= indirect2_state;
+ --
+ -- load md with low byte of indirect address
+ -- pointed to by ea
+ -- ea has previously been incremented
+ --
+ when indirect2_state =>
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ pc_ctrl <= latch_pc;
+ -- idle ea
+ left_ctrl <= ea_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ ea_ctrl <= latch_ea;
+ -- fetch high byte
+ md_ctrl <= fetch_next_md;
+ addr_ctrl <= read_ad;
+ dout_ctrl <= md_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= indirect3_state;
+ --
+ -- complete idirect addressing
+ -- by loading ea with md
+ --
+ when indirect3_state =>
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ pc_ctrl <= latch_pc;
+ -- load ea with md
+ left_ctrl <= ea_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_ld16;
+ ea_ctrl <= load_ea;
+ -- idle cycle
+ md_ctrl <= latch_md;
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ -- return to previous state
+ st_ctrl <= pull_st;
+ return_state <= fetch_state;
+ next_state <= saved_state;
+
+ --
+ -- 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
+ --
+ when extended_state => -- fetch ea low byte
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ dp_ctrl <= latch_dp;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ -- increment pc
+ left_ctrl <= pc_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ pc_ctrl <= incr_pc;
+ -- fetch next effective address bytes
+ ea_ctrl <= fetch_next_ea;
+ addr_ctrl <= fetch_ad;
+ dout_ctrl <= md_lo_dout;
+ -- return to previous state
+ st_ctrl <= pull_st;
+ return_state <= fetch_state;
+ next_state <= saved_state;
+
+ when lea_state => -- here on load effective address
+ op_ctrl <= latch_op;
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ iv_ctrl <= latch_iv;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ md_ctrl <= latch_md;
+ ea_ctrl <= latch_ea;
+ pc_ctrl <= latch_pc;
+ -- load index register with effective address
+ left_ctrl <= pc_left;
+ right_ctrl <= ea_right;
+ alu_ctrl <= alu_ld16;
+ case op_code(3 downto 0) is
+ when "0000" => -- leax
+ ix_ctrl <= load_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ when "0001" => -- leay
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= load_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ when "0010" => -- leas
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= load_sp;
+ when "0011" => -- leau
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= load_up;
+ sp_ctrl <= latch_sp;
+ when others =>
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ end case;
+ -- idle the bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= fetch_state;
+
+ --
+ -- jump to subroutine
+ -- (sp)=pc_lo
+ -- sp=sp-1
+ -- call push_return_hi_state to save hi pc
+ -- return to jmp_state
+ --
+ when jsr_state =>
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ md_ctrl <= latch_md;
+ ea_ctrl <= latch_ea;
+ pc_ctrl <= latch_pc;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- write pc lo byte
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= pc_lo_dout;
+ -- call second half of push_return_state
+ st_ctrl <= push_st;
+ return_state <= jmp_state;
+ next_state <= push_return_hi_state;
+
+ --
+ -- Load pc with ea
+ -- (JMP)
+ --
+ when jmp_state =>
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ md_ctrl <= latch_md;
+ ea_ctrl <= latch_ea;
+ -- load PC with effective address
+ left_ctrl <= pc_left;
+ right_ctrl <= ea_right;
+ alu_ctrl <= alu_ld16;
+ pc_ctrl <= load_pc;
+ -- idle the bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= fetch_state;
+
+ --
+ -- long branch or branch to subroutine
+ -- pick up next md byte
+ -- md_hi = md_lo
+ -- md_lo = (pc)
+ -- pc=pc+1
+ -- if a lbsr push return address
+ -- continue to sbranch_state
+ -- to evaluate conditional branches
+ --
+ when lbranch_state =>
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ --
+ left_ctrl <= pc_left;
+ right_ctrl <= ea_right;
+ alu_ctrl <= alu_ld16;
+ pc_ctrl <= incr_pc;
+ -- fetch the next byte into md_lo
+ md_ctrl <= fetch_next_md;
+ addr_ctrl <= fetch_ad;
+ dout_ctrl <= md_lo_dout;
+ -- if lbsr - push return address
+ -- then continue on to short branch
+ if op_code = "00010111" then
+ st_ctrl <= push_st;
+ return_state <= sbranch_state;
+ next_state <= push_return_lo_state;
+ else
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= sbranch_state;
+ end if;
+
+ --
+ -- here to execute conditional branch
+ -- short conditional branch md = signed 8 bit offset
+ -- long branch md = 16 bit offset
+ --
+ when sbranch_state =>
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ md_ctrl <= latch_md;
+ --
+ left_ctrl <= pc_left;
+ right_ctrl <= md_right;
+ alu_ctrl <= alu_add16;
+ --
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= fetch_state;
+ if op_code(7 downto 4) = "0010" then -- conditional branch
+ case op_code(3 downto 0) is
+ when "0000" => -- bra
+ cond_true := (1 = 1);
+ when "0001" => -- brn
+ cond_true := (1 = 0);
+ when "0010" => -- bhi
+ cond_true := ((cc(CBIT) or cc(ZBIT)) = '0');
+ when "0011" => -- bls
+ cond_true := ((cc(CBIT) or cc(ZBIT)) = '1');
+ when "0100" => -- bcc/bhs
+ cond_true := (cc(CBIT) = '0');
+ when "0101" => -- bcs/blo
+ cond_true := (cc(CBIT) = '1');
+ when "0110" => -- bne
+ cond_true := (cc(ZBIT) = '0');
+ when "0111" => -- beq
+ cond_true := (cc(ZBIT) = '1');
+ when "1000" => -- bvc
+ cond_true := (cc(VBIT) = '0');
+ when "1001" => -- bvs
+ cond_true := (cc(VBIT) = '1');
+ when "1010" => -- bpl
+ cond_true := (cc(NBIT) = '0');
+ when "1011" => -- bmi
+ cond_true := (cc(NBIT) = '1');
+ when "1100" => -- bge
+ cond_true := ((cc(NBIT) xor cc(VBIT)) = '0');
+ when "1101" => -- blt
+ cond_true := ((cc(NBIT) xor cc(VBIT)) = '1');
+ when "1110" => -- bgt
+ cond_true := ((cc(ZBIT) or (cc(NBIT) xor cc(VBIT))) = '0');
+ when "1111" => -- ble
+ cond_true := ((cc(ZBIT) or (cc(NBIT) xor cc(VBIT))) = '1');
+ when others =>
+ cond_true := (1 = 1);
+ end case;
+ else
+ cond_true := (1 = 1); -- lbra, lbsr, bsr
+ end if;
+ if cond_true then
+ pc_ctrl <= load_pc;
+ else
+ pc_ctrl <= latch_pc;
+ end if;
+
+ --
+ -- push return address onto the S stack
+ --
+ -- (sp) = pc_lo
+ -- sp = sp - 1
+ --
+ when push_return_lo_state =>
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ dp_ctrl <= latch_dp;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement the sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ cc_ctrl <= latch_cc;
+ sp_ctrl <= load_sp;
+ -- write PC low
+ pc_ctrl <= latch_pc;
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= pc_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= push_return_hi_state;
+
+ --
+ -- push program counter hi byte onto the stack
+ -- (sp) = pc_hi
+ -- sp = sp
+ -- return to originating state
+ --
+ when push_return_hi_state =>
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ dp_ctrl <= latch_dp;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- idle the SP
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ cc_ctrl <= latch_cc;
+ sp_ctrl <= latch_sp;
+ -- write pc hi bytes
+ pc_ctrl <= latch_pc;
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= pc_hi_dout;
+ --
+ st_ctrl <= pull_st;
+ return_state <= fetch_state;
+ next_state <= saved_state;
+
+ when pull_return_hi_state =>
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ dp_ctrl <= latch_dp;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment the sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ cc_ctrl <= latch_cc;
+ sp_ctrl <= load_sp;
+ -- read pc hi
+ pc_ctrl <= pull_hi_pc;
+ addr_ctrl <= pulls_ad;
+ dout_ctrl <= pc_hi_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= pull_return_lo_state;
+
+ when pull_return_lo_state =>
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ dp_ctrl <= latch_dp;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment the SP
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ cc_ctrl <= latch_cc;
+ sp_ctrl <= load_sp;
+ -- read pc low
+ pc_ctrl <= pull_lo_pc;
+ addr_ctrl <= pulls_ad;
+ dout_ctrl <= pc_lo_dout;
+ --
+ st_ctrl <= pull_st;
+ return_state <= fetch_state;
+ next_state <= saved_state;
+
+ when andcc_state =>
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ iv_ctrl <= latch_iv;
+ dp_ctrl <= latch_dp;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ md_ctrl <= latch_md;
+ -- AND CC with md
+ left_ctrl <= md_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_andcc;
+ cc_ctrl <= load_cc;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ --
+ st_ctrl <= pull_st;
+ return_state <= fetch_state;
+ next_state <= saved_state;
+
+ when orcc_state =>
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ iv_ctrl <= latch_iv;
+ dp_ctrl <= latch_dp;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ md_ctrl <= latch_md;
+ -- OR CC with md
+ left_ctrl <= md_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_orcc;
+ cc_ctrl <= load_cc;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ --
+ st_ctrl <= pull_st;
+ return_state <= fetch_state;
+ next_state <= saved_state;
+
+ when tfr_state =>
+ -- default
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ md_ctrl <= latch_md;
+ -- select source register
+ case md(7 downto 4) is
+ when "0000" =>
+ left_ctrl <= accd_left;
+ when "0001" =>
+ left_ctrl <= ix_left;
+ when "0010" =>
+ left_ctrl <= iy_left;
+ when "0011" =>
+ left_ctrl <= up_left;
+ when "0100" =>
+ left_ctrl <= sp_left;
+ when "0101" =>
+ left_ctrl <= pc_left;
+ when "1000" =>
+ left_ctrl <= acca_left;
+ when "1001" =>
+ left_ctrl <= accb_left;
+ when "1010" =>
+ left_ctrl <= cc_left;
+ when "1011" =>
+ left_ctrl <= dp_left;
+ when others =>
+ left_ctrl <= md_left;
+ end case;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_tfr;
+ -- select destination register
+ case md(3 downto 0) is
+ when "0000" => -- accd
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= latch_dp;
+ when "0001" => -- ix
+ ix_ctrl <= load_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= latch_dp;
+ when "0010" => -- iy
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= load_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= latch_dp;
+ when "0011" => -- up
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= load_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= latch_dp;
+ when "0100" => -- sp
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= load_sp;
+ pc_ctrl <= latch_pc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= latch_dp;
+ when "0101" => -- pc
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= load_pc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= latch_dp;
+ when "1000" => -- acca
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ acca_ctrl <= load_acca;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= latch_dp;
+ when "1001" => -- accb
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= load_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= latch_dp;
+ when "1010" => -- cc
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= load_cc;
+ dp_ctrl <= latch_dp;
+ when "1011" => --dp
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= load_dp;
+ when others =>
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= latch_dp;
+ end case;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ --
+ st_ctrl <= pull_st;
+ return_state <= fetch_state;
+ next_state <= saved_state;
+
+ when exg_state =>
+ -- default
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ md_ctrl <= latch_md;
+ -- save destination register
+ case md(3 downto 0) is
+ when "0000" =>
+ left_ctrl <= accd_left;
+ when "0001" =>
+ left_ctrl <= ix_left;
+ when "0010" =>
+ left_ctrl <= iy_left;
+ when "0011" =>
+ left_ctrl <= up_left;
+ when "0100" =>
+ left_ctrl <= sp_left;
+ when "0101" =>
+ left_ctrl <= pc_left;
+ when "1000" =>
+ left_ctrl <= acca_left;
+ when "1001" =>
+ left_ctrl <= accb_left;
+ when "1010" =>
+ left_ctrl <= cc_left;
+ when "1011" =>
+ left_ctrl <= dp_left;
+ when others =>
+ left_ctrl <= md_left;
+ end case;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_tfr;
+ ea_ctrl <= load_ea;
+
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= latch_dp;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ -- call tranfer microcode
+ st_ctrl <= push_st;
+ return_state <= exg1_state;
+ next_state <= tfr_state;
+
+ when exg1_state =>
+ -- default
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ md_ctrl <= latch_md;
+ -- restore destination
+ left_ctrl <= ea_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_tfr;
+ -- save as source register
+ case md(7 downto 4) is
+ when "0000" => -- accd
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= latch_dp;
+ when "0001" => -- ix
+ ix_ctrl <= load_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= latch_dp;
+ when "0010" => -- iy
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= load_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= latch_dp;
+ when "0011" => -- up
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= load_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= latch_dp;
+ when "0100" => -- sp
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= load_sp;
+ pc_ctrl <= latch_pc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= latch_dp;
+ when "0101" => -- pc
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= load_pc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= latch_dp;
+ when "1000" => -- acca
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ acca_ctrl <= load_acca;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= latch_dp;
+ when "1001" => -- accb
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= load_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= latch_dp;
+ when "1010" => -- cc
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= load_cc;
+ dp_ctrl <= latch_dp;
+ when "1011" => --dp
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= load_dp;
+ when others =>
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ cc_ctrl <= latch_cc;
+ dp_ctrl <= latch_dp;
+ end case;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= fetch_state;
+
+ when mul_state =>
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ iv_ctrl <= latch_iv;
+ dp_ctrl <= latch_dp;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ 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;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= mulea_state;
+
+ when mulea_state =>
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ iv_ctrl <= latch_iv;
+ dp_ctrl <= latch_dp;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ md_ctrl <= latch_md;
+ -- move accb to ea
+ left_ctrl <= accb_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_st16;
+ cc_ctrl <= latch_cc;
+ ea_ctrl <= load_ea;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= muld_state;
+
+ when muld_state =>
+ -- default
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ iv_ctrl <= latch_iv;
+ dp_ctrl <= latch_dp;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ 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;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= mul0_state;
+
+ when mul0_state =>
+ -- default
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ iv_ctrl <= latch_iv;
+ dp_ctrl <= latch_dp;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ 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' then
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ else
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ end if;
+ md_ctrl <= shiftl_md;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= mul1_state;
+
+ when mul1_state =>
+ -- default
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ iv_ctrl <= latch_iv;
+ dp_ctrl <= latch_dp;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ 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' then
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ else
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ end if;
+ md_ctrl <= shiftl_md;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= mul2_state;
+
+ when mul2_state =>
+ -- default
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ iv_ctrl <= latch_iv;
+ dp_ctrl <= latch_dp;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ 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' then
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ else
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ end if;
+ md_ctrl <= shiftl_md;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= mul3_state;
+
+ when mul3_state =>
+ -- default
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ iv_ctrl <= latch_iv;
+ dp_ctrl <= latch_dp;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ 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' then
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ else
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ end if;
+ md_ctrl <= shiftl_md;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= mul4_state;
+
+ when mul4_state =>
+ -- default
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ iv_ctrl <= latch_iv;
+ dp_ctrl <= latch_dp;
+ op_ctrl <= latch_op;
+ nmi_ctrl <= latch_nmi;
+ pre_ctrl <= latch_pre;
+ 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' then
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ else
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ end if;
+ md_ctrl <= shiftl_md;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= mul5_state;
+
+ when mul5_state =>
+ -- default
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ iv_ctrl <= latch_iv;
+ dp_ctrl <= latch_dp;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ 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' then
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ else
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ end if;
+ md_ctrl <= shiftl_md;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= mul6_state;
+
+ when mul6_state =>
+ -- default
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ iv_ctrl <= latch_iv;
+ dp_ctrl <= latch_dp;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ 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' then
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ else
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ end if;
+ md_ctrl <= shiftl_md;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= mul7_state;
+
+ when mul7_state =>
+ -- default
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ iv_ctrl <= latch_iv;
+ dp_ctrl <= latch_dp;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ 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' then
+ cc_ctrl <= load_cc;
+ acca_ctrl <= load_hi_acca;
+ accb_ctrl <= load_accb;
+ else
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ end if;
+ md_ctrl <= shiftl_md;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= fetch_state;
+
+ --
+ -- Enter here on pushs
+ -- ea holds post byte
+ --
+ when pshs_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ dp_ctrl <= latch_dp;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp if any registers to be pushed
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ if ea(7 downto 0) = "00000000" then
+ sp_ctrl <= latch_sp;
+ else
+ sp_ctrl <= load_sp;
+ end if;
+ -- write idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if ea(7) = '1' then
+ next_state <= pshs_pcl_state;
+ elsif ea(6) = '1' then
+ next_state <= pshs_upl_state;
+ elsif ea(5) = '1' then
+ next_state <= pshs_iyl_state;
+ elsif ea(4) = '1' then
+ next_state <= pshs_ixl_state;
+ elsif ea(3) = '1' then
+ next_state <= pshs_dp_state;
+ elsif ea(2) = '1' then
+ next_state <= pshs_accb_state;
+ elsif ea(1) = '1' then
+ next_state <= pshs_acca_state;
+ elsif ea(0) = '1' then
+ next_state <= pshs_cc_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+ when pshs_pcl_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ dp_ctrl <= latch_dp;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- write pc low
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= pc_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= pshs_pch_state;
+
+ when pshs_pch_state =>
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ dp_ctrl <= latch_dp;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ if ea(6 downto 0) = "0000000" then
+ sp_ctrl <= latch_sp;
+ else
+ sp_ctrl <= load_sp;
+ end if;
+ -- write pc hi
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= pc_hi_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if ea(6) = '1' then
+ next_state <= pshs_upl_state;
+ elsif ea(5) = '1' then
+ next_state <= pshs_iyl_state;
+ elsif ea(4) = '1' then
+ next_state <= pshs_ixl_state;
+ elsif ea(3) = '1' then
+ next_state <= pshs_dp_state;
+ elsif ea(2) = '1' then
+ next_state <= pshs_accb_state;
+ elsif ea(1) = '1' then
+ next_state <= pshs_acca_state;
+ elsif ea(0) = '1' then
+ next_state <= pshs_cc_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+
+ when pshs_upl_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- write pc low
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= up_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= pshs_uph_state;
+
+ when pshs_uph_state =>
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ if ea(5 downto 0) = "000000" then
+ sp_ctrl <= latch_sp;
+ else
+ sp_ctrl <= load_sp;
+ end if;
+ -- write pc hi
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= up_hi_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if ea(5) = '1' then
+ next_state <= pshs_iyl_state;
+ elsif ea(4) = '1' then
+ next_state <= pshs_ixl_state;
+ elsif ea(3) = '1' then
+ next_state <= pshs_dp_state;
+ elsif ea(2) = '1' then
+ next_state <= pshs_accb_state;
+ elsif ea(1) = '1' then
+ next_state <= pshs_acca_state;
+ elsif ea(0) = '1' then
+ next_state <= pshs_cc_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+ when pshs_iyl_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- write iy low
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= iy_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= pshs_iyh_state;
+
+ when pshs_iyh_state =>
+ -- default registers
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ if ea(4 downto 0) = "00000" then
+ sp_ctrl <= latch_sp;
+ else
+ sp_ctrl <= load_sp;
+ end if;
+ -- write iy hi
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= iy_hi_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if ea(4) = '1' then
+ next_state <= pshs_ixl_state;
+ elsif ea(3) = '1' then
+ next_state <= pshs_dp_state;
+ elsif ea(2) = '1' then
+ next_state <= pshs_accb_state;
+ elsif ea(1) = '1' then
+ next_state <= pshs_acca_state;
+ elsif ea(0) = '1' then
+ next_state <= pshs_cc_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+ when pshs_ixl_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- write ix low
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= ix_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= pshs_ixh_state;
+
+ when pshs_ixh_state =>
+ -- default registers
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ if ea(3 downto 0) = "0000" then
+ sp_ctrl <= latch_sp;
+ else
+ sp_ctrl <= load_sp;
+ end if;
+ -- write ix hi
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= ix_hi_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if ea(3) = '1' then
+ next_state <= pshs_dp_state;
+ elsif ea(2) = '1' then
+ next_state <= pshs_accb_state;
+ elsif ea(1) = '1' then
+ next_state <= pshs_acca_state;
+ elsif ea(0) = '1' then
+ next_state <= pshs_cc_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+ when pshs_dp_state =>
+ -- default registers
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ if ea(2 downto 0) = "000" then
+ sp_ctrl <= latch_sp;
+ else
+ sp_ctrl <= load_sp;
+ end if;
+ -- write dp
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= dp_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if ea(2) = '1' then
+ next_state <= pshs_accb_state;
+ elsif ea(1) = '1' then
+ next_state <= pshs_acca_state;
+ elsif ea(0) = '1' then
+ next_state <= pshs_cc_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+ when pshs_accb_state =>
+ -- default registers
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ if ea(1 downto 0) = "00" then
+ sp_ctrl <= latch_sp;
+ else
+ sp_ctrl <= load_sp;
+ end if;
+ -- write accb
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= accb_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if ea(1) = '1' then
+ next_state <= pshs_acca_state;
+ elsif ea(0) = '1' then
+ next_state <= pshs_cc_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+ when pshs_acca_state =>
+ -- default registers
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ if ea(0) = '1' then
+ sp_ctrl <= load_sp;
+ else
+ sp_ctrl <= latch_sp;
+ end if;
+ -- write acca
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= acca_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if ea(0) = '1' then
+ next_state <= pshs_cc_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+ when pshs_cc_state =>
+ -- default registers
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- idle sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_nop;
+ sp_ctrl <= latch_sp;
+ -- write cc
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= cc_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= fetch_state;
+
+ --
+ -- enter here on PULS
+ -- ea hold register mask
+ --
+ when puls_state =>
+ -- default registers
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- idle SP
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= latch_sp;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if ea(0) = '1' then
+ next_state <= puls_cc_state;
+ elsif ea(1) = '1' then
+ next_state <= puls_acca_state;
+ elsif ea(2) = '1' then
+ next_state <= puls_accb_state;
+ elsif ea(3) = '1' then
+ next_state <= puls_dp_state;
+ elsif ea(4) = '1' then
+ next_state <= puls_ixh_state;
+ elsif ea(5) = '1' then
+ next_state <= puls_iyh_state;
+ elsif ea(6) = '1' then
+ next_state <= puls_uph_state;
+ elsif ea(7) = '1' then
+ next_state <= puls_pch_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+ when puls_cc_state =>
+ -- default registers
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- Increment SP
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read cc
+ cc_ctrl <= pull_cc;
+ addr_ctrl <= pulls_ad;
+ dout_ctrl <= cc_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if ea(1) = '1' then
+ next_state <= puls_acca_state;
+ elsif ea(2) = '1' then
+ next_state <= puls_accb_state;
+ elsif ea(3) = '1' then
+ next_state <= puls_dp_state;
+ elsif ea(4) = '1' then
+ next_state <= puls_ixh_state;
+ elsif ea(5) = '1' then
+ next_state <= puls_iyh_state;
+ elsif ea(6) = '1' then
+ next_state <= puls_uph_state;
+ elsif ea(7) = '1' then
+ next_state <= puls_pch_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+ when puls_acca_state =>
+ -- default registers
+ cc_ctrl <= latch_cc;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- Increment SP
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read acca
+ acca_ctrl <= pull_acca;
+ addr_ctrl <= pulls_ad;
+ dout_ctrl <= acca_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if ea(2) = '1' then
+ next_state <= puls_accb_state;
+ elsif ea(3) = '1' then
+ next_state <= puls_dp_state;
+ elsif ea(4) = '1' then
+ next_state <= puls_ixh_state;
+ elsif ea(5) = '1' then
+ next_state <= puls_iyh_state;
+ elsif ea(6) = '1' then
+ next_state <= puls_uph_state;
+ elsif ea(7) = '1' then
+ next_state <= puls_pch_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+ when puls_accb_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- Increment SP
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read accb
+ accb_ctrl <= pull_accb;
+ addr_ctrl <= pulls_ad;
+ dout_ctrl <= accb_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if ea(3) = '1' then
+ next_state <= puls_dp_state;
+ elsif ea(4) = '1' then
+ next_state <= puls_ixh_state;
+ elsif ea(5) = '1' then
+ next_state <= puls_iyh_state;
+ elsif ea(6) = '1' then
+ next_state <= puls_uph_state;
+ elsif ea(7) = '1' then
+ next_state <= puls_pch_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+ when puls_dp_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- idle sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read dp
+ dp_ctrl <= pull_dp;
+ addr_ctrl <= pulls_ad;
+ dout_ctrl <= dp_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if ea(4) = '1' then
+ next_state <= puls_ixh_state;
+ elsif ea(5) = '1' then
+ next_state <= puls_iyh_state;
+ elsif ea(6) = '1' then
+ next_state <= puls_uph_state;
+ elsif ea(7) = '1' then
+ next_state <= puls_pch_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+ when puls_ixh_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- pull ix hi
+ ix_ctrl <= pull_hi_ix;
+ addr_ctrl <= pulls_ad;
+ dout_ctrl <= ix_hi_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= puls_ixl_state;
+
+ when puls_ixl_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- idle sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read ix low
+ ix_ctrl <= pull_lo_ix;
+ addr_ctrl <= pulls_ad;
+ dout_ctrl <= ix_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if ea(5) = '1' then
+ next_state <= puls_iyh_state;
+ elsif ea(6) = '1' then
+ next_state <= puls_uph_state;
+ elsif ea(7) = '1' then
+ next_state <= puls_pch_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+ when puls_iyh_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- pull iy hi
+ iy_ctrl <= pull_hi_iy;
+ addr_ctrl <= pulls_ad;
+ dout_ctrl <= iy_hi_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= puls_iyl_state;
+
+ when puls_iyl_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read iy low
+ iy_ctrl <= pull_lo_iy;
+ addr_ctrl <= pulls_ad;
+ dout_ctrl <= iy_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if ea(6) = '1' then
+ next_state <= puls_uph_state;
+ elsif ea(7) = '1' then
+ next_state <= puls_pch_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+ when puls_uph_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- pull up hi
+ up_ctrl <= pull_hi_up;
+ addr_ctrl <= pulls_ad;
+ dout_ctrl <= up_hi_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= puls_upl_state;
+
+ when puls_upl_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read up low
+ up_ctrl <= pull_lo_up;
+ addr_ctrl <= pulls_ad;
+ dout_ctrl <= up_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if ea(7) = '1' then
+ next_state <= puls_pch_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+ when puls_pch_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- pull pc hi
+ pc_ctrl <= pull_hi_pc;
+ addr_ctrl <= pulls_ad;
+ dout_ctrl <= pc_hi_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= puls_pcl_state;
+
+ when puls_pcl_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read pc low
+ pc_ctrl <= pull_lo_pc;
+ addr_ctrl <= pulls_ad;
+ dout_ctrl <= pc_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= fetch_state;
+
+ --
+ -- Enter here on pshu
+ -- ea holds post byte
+ --
+ when pshu_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ dp_ctrl <= latch_dp;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp if any registers to be pushed
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ if ea(7 downto 0) = "00000000" then
+ up_ctrl <= latch_up;
+ else
+ up_ctrl <= load_up;
+ end if;
+ -- write idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if ea(7) = '1' then
+ next_state <= pshu_pcl_state;
+ elsif ea(6) = '1' then
+ next_state <= pshu_spl_state;
+ elsif ea(5) = '1' then
+ next_state <= pshu_iyl_state;
+ elsif ea(4) = '1' then
+ next_state <= pshu_ixl_state;
+ elsif ea(3) = '1' then
+ next_state <= pshu_dp_state;
+ elsif ea(2) = '1' then
+ next_state <= pshu_accb_state;
+ elsif ea(1) = '1' then
+ next_state <= pshu_acca_state;
+ elsif ea(0) = '1' then
+ next_state <= pshu_cc_state;
+ else
+ next_state <= fetch_state;
+ end if;
+ --
+ -- push PC onto U stack
+ --
+ when pshu_pcl_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ up_ctrl <= load_up;
+ -- write pc low
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= pc_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= pshu_pch_state;
+
+ when pshu_pch_state =>
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ if ea(6 downto 0) = "0000000" then
+ up_ctrl <= latch_up;
+ else
+ up_ctrl <= load_up;
+ end if;
+ -- write pc hi
+ addr_ctrl <= pushu_ad;
+ dout_ctrl <= pc_hi_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if ea(6) = '1' then
+ next_state <= pshu_spl_state;
+ elsif ea(5) = '1' then
+ next_state <= pshu_iyl_state;
+ elsif ea(4) = '1' then
+ next_state <= pshu_ixl_state;
+ elsif ea(3) = '1' then
+ next_state <= pshu_dp_state;
+ elsif ea(2) = '1' then
+ next_state <= pshu_accb_state;
+ elsif ea(1) = '1' then
+ next_state <= pshu_acca_state;
+ elsif ea(0) = '1' then
+ next_state <= pshu_cc_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+ when pshu_spl_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ up_ctrl <= load_up;
+ -- write pc low
+ addr_ctrl <= pushu_ad;
+ dout_ctrl <= sp_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= pshu_sph_state;
+
+ when pshu_sph_state =>
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ if ea(5 downto 0) = "000000" then
+ up_ctrl <= latch_up;
+ else
+ up_ctrl <= load_up;
+ end if;
+ -- write sp hi
+ addr_ctrl <= pushu_ad;
+ dout_ctrl <= sp_hi_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if ea(5) = '1' then
+ next_state <= pshu_iyl_state;
+ elsif ea(4) = '1' then
+ next_state <= pshu_ixl_state;
+ elsif ea(3) = '1' then
+ next_state <= pshu_dp_state;
+ elsif ea(2) = '1' then
+ next_state <= pshu_accb_state;
+ elsif ea(1) = '1' then
+ next_state <= pshu_acca_state;
+ elsif ea(0) = '1' then
+ next_state <= pshu_cc_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+ when pshu_iyl_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ up_ctrl <= load_up;
+ -- write iy low
+ addr_ctrl <= pushu_ad;
+ dout_ctrl <= iy_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= pshu_iyh_state;
+
+ when pshu_iyh_state =>
+ -- default registers
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ if ea(4 downto 0) = "00000" then
+ up_ctrl <= latch_up;
+ else
+ up_ctrl <= load_up;
+ end if;
+ -- write iy hi
+ addr_ctrl <= pushu_ad;
+ dout_ctrl <= iy_hi_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if ea(4) = '1' then
+ next_state <= pshu_ixl_state;
+ elsif ea(3) = '1' then
+ next_state <= pshu_dp_state;
+ elsif ea(2) = '1' then
+ next_state <= pshu_accb_state;
+ elsif ea(1) = '1' then
+ next_state <= pshu_acca_state;
+ elsif ea(0) = '1' then
+ next_state <= pshu_cc_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+ when pshu_ixl_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ up_ctrl <= load_up;
+ -- write ix low
+ addr_ctrl <= pushu_ad;
+ dout_ctrl <= ix_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= pshu_ixh_state;
+
+ when pshu_ixh_state =>
+ -- default registers
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ if ea(3 downto 0) = "0000" then
+ up_ctrl <= latch_up;
+ else
+ up_ctrl <= load_up;
+ end if;
+ -- write ix hi
+ addr_ctrl <= pushu_ad;
+ dout_ctrl <= ix_hi_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if ea(3) = '1' then
+ next_state <= pshu_dp_state;
+ elsif ea(2) = '1' then
+ next_state <= pshu_accb_state;
+ elsif ea(1) = '1' then
+ next_state <= pshu_acca_state;
+ elsif ea(0) = '1' then
+ next_state <= pshu_cc_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+ when pshu_dp_state =>
+ -- default registers
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ if ea(2 downto 0) = "000" then
+ up_ctrl <= latch_up;
+ else
+ up_ctrl <= load_up;
+ end if;
+ -- write accb
+ addr_ctrl <= pushu_ad;
+ dout_ctrl <= dp_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if ea(2) = '1' then
+ next_state <= pshu_accb_state;
+ elsif ea(1) = '1' then
+ next_state <= pshu_acca_state;
+ elsif ea(0) = '1' then
+ next_state <= pshu_cc_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+ when pshu_accb_state =>
+ -- default registers
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ if ea(1 downto 0) = "00" then
+ up_ctrl <= latch_up;
+ else
+ up_ctrl <= load_up;
+ end if;
+ -- write accb
+ addr_ctrl <= pushu_ad;
+ dout_ctrl <= accb_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if ea(1) = '1' then
+ next_state <= pshu_acca_state;
+ elsif ea(0) = '1' then
+ next_state <= pshu_cc_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+ when pshu_acca_state =>
+ -- default registers
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ if ea(0) = '0' then
+ up_ctrl <= latch_up;
+ else
+ up_ctrl <= load_up;
+ end if;
+ -- write acca
+ addr_ctrl <= pushu_ad;
+ dout_ctrl <= acca_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if ea(0) = '1' then
+ next_state <= pshu_cc_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+ when pshu_cc_state =>
+ -- default registers
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- idle sp
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ cc_ctrl <= latch_cc;
+ alu_ctrl <= alu_nop;
+ up_ctrl <= latch_up;
+ -- write cc
+ addr_ctrl <= pushu_ad;
+ dout_ctrl <= cc_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= fetch_state;
+
+ --
+ -- enter here on PULU
+ -- ea hold register mask
+ --
+ when pulu_state =>
+ -- default registers
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- idle UP
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ up_ctrl <= latch_up;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if ea(0) = '1' then
+ next_state <= pulu_cc_state;
+ elsif ea(1) = '1' then
+ next_state <= pulu_acca_state;
+ elsif ea(2) = '1' then
+ next_state <= pulu_accb_state;
+ elsif ea(3) = '1' then
+ next_state <= pulu_dp_state;
+ elsif ea(4) = '1' then
+ next_state <= pulu_ixh_state;
+ elsif ea(5) = '1' then
+ next_state <= pulu_iyh_state;
+ elsif ea(6) = '1' then
+ next_state <= pulu_sph_state;
+ elsif ea(7) = '1' then
+ next_state <= pulu_pch_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+ when pulu_cc_state =>
+ -- default registers
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ up_ctrl <= load_up;
+ -- read cc
+ cc_ctrl <= pull_cc;
+ addr_ctrl <= pullu_ad;
+ dout_ctrl <= cc_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if ea(1) = '1' then
+ next_state <= pulu_acca_state;
+ elsif ea(2) = '1' then
+ next_state <= pulu_accb_state;
+ elsif ea(3) = '1' then
+ next_state <= pulu_dp_state;
+ elsif ea(4) = '1' then
+ next_state <= pulu_ixh_state;
+ elsif ea(5) = '1' then
+ next_state <= pulu_iyh_state;
+ elsif ea(6) = '1' then
+ next_state <= pulu_sph_state;
+ elsif ea(7) = '1' then
+ next_state <= pulu_pch_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+ when pulu_acca_state =>
+ -- default registers
+ cc_ctrl <= latch_cc;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ up_ctrl <= load_up;
+ -- read acca
+ acca_ctrl <= pull_acca;
+ addr_ctrl <= pullu_ad;
+ dout_ctrl <= acca_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if ea(2) = '1' then
+ next_state <= pulu_accb_state;
+ elsif ea(3) = '1' then
+ next_state <= pulu_dp_state;
+ elsif ea(4) = '1' then
+ next_state <= pulu_ixh_state;
+ elsif ea(5) = '1' then
+ next_state <= pulu_iyh_state;
+ elsif ea(6) = '1' then
+ next_state <= pulu_sph_state;
+ elsif ea(7) = '1' then
+ next_state <= pulu_pch_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+ when pulu_accb_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ up_ctrl <= load_up;
+ -- read accb
+ accb_ctrl <= pull_accb;
+ addr_ctrl <= pullu_ad;
+ dout_ctrl <= accb_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if ea(3) = '1' then
+ next_state <= pulu_dp_state;
+ elsif ea(4) = '1' then
+ next_state <= pulu_ixh_state;
+ elsif ea(5) = '1' then
+ next_state <= pulu_iyh_state;
+ elsif ea(6) = '1' then
+ next_state <= pulu_sph_state;
+ elsif ea(7) = '1' then
+ next_state <= pulu_pch_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+ when pulu_dp_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ up_ctrl <= load_up;
+ -- read dp
+ dp_ctrl <= pull_dp;
+ addr_ctrl <= pullu_ad;
+ dout_ctrl <= dp_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if ea(4) = '1' then
+ next_state <= pulu_ixh_state;
+ elsif ea(5) = '1' then
+ next_state <= pulu_iyh_state;
+ elsif ea(6) = '1' then
+ next_state <= pulu_sph_state;
+ elsif ea(7) = '1' then
+ next_state <= pulu_pch_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+ when pulu_ixh_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ iy_ctrl <= latch_iy;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ up_ctrl <= load_up;
+ -- pull ix hi
+ ix_ctrl <= pull_hi_ix;
+ addr_ctrl <= pullu_ad;
+ dout_ctrl <= ix_hi_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= pulu_ixl_state;
+
+ when pulu_ixl_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ iy_ctrl <= latch_iy;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ up_ctrl <= load_up;
+ -- read ix low
+ ix_ctrl <= pull_lo_ix;
+ addr_ctrl <= pullu_ad;
+ dout_ctrl <= ix_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if ea(5) = '1' then
+ next_state <= pulu_iyh_state;
+ elsif ea(6) = '1' then
+ next_state <= pulu_sph_state;
+ elsif ea(7) = '1' then
+ next_state <= pulu_pch_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+ when pulu_iyh_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ up_ctrl <= load_up;
+ -- pull iy hi
+ iy_ctrl <= pull_hi_iy;
+ addr_ctrl <= pullu_ad;
+ dout_ctrl <= iy_hi_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= pulu_iyl_state;
+
+ when pulu_iyl_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ up_ctrl <= load_up;
+ -- read iy low
+ iy_ctrl <= pull_lo_iy;
+ addr_ctrl <= pullu_ad;
+ dout_ctrl <= iy_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if ea(6) = '1' then
+ next_state <= pulu_sph_state;
+ elsif ea(7) = '1' then
+ next_state <= pulu_pch_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+ when pulu_sph_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ up_ctrl <= load_up;
+ -- pull sp hi
+ sp_ctrl <= pull_hi_sp;
+ addr_ctrl <= pullu_ad;
+ dout_ctrl <= up_hi_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= pulu_spl_state;
+
+ when pulu_spl_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ up_ctrl <= load_up;
+ -- read sp low
+ sp_ctrl <= pull_lo_sp;
+ addr_ctrl <= pullu_ad;
+ dout_ctrl <= up_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if ea(7) = '1' then
+ next_state <= pulu_pch_state;
+ else
+ next_state <= fetch_state;
+ end if;
+
+ when pulu_pch_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ sp_ctrl <= latch_sp;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ up_ctrl <= load_up;
+ -- pull pc hi
+ pc_ctrl <= pull_hi_pc;
+ addr_ctrl <= pullu_ad;
+ dout_ctrl <= pc_hi_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= pulu_pcl_state;
+
+ when pulu_pcl_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ sp_ctrl <= latch_sp;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment up
+ left_ctrl <= up_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ up_ctrl <= load_up;
+ -- read pc low
+ pc_ctrl <= pull_lo_pc;
+ addr_ctrl <= pullu_ad;
+ dout_ctrl <= pc_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= fetch_state;
+
+ when rti_cc_state =>
+ -- default registers
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read cc
+ cc_ctrl <= pull_cc;
+ addr_ctrl <= pulls_ad;
+ dout_ctrl <= cc_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ --
+ -- CC is clocked at the end of this cycle
+ -- so this test tests the current state
+ -- of the condition codes, not the popped value
+ -- Mind you, the Entire flag is set before
+ -- the registers are pushed, so it should not matter
+ --
+ if cc(EBIT) = '1' then
+ next_state <= rti_acca_state;
+ else
+ next_state <= rti_pch_state;
+ end if;
+
+ when rti_acca_state =>
+ -- default registers
+ cc_ctrl <= latch_cc;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read acca
+ acca_ctrl <= pull_acca;
+ addr_ctrl <= pulls_ad;
+ dout_ctrl <= acca_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= rti_accb_state;
+
+ when rti_accb_state =>
+ -- default registers
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read accb
+ accb_ctrl <= pull_accb;
+ addr_ctrl <= pulls_ad;
+ dout_ctrl <= accb_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= rti_dp_state;
+
+ when rti_dp_state =>
+ -- default registers
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read dp
+ dp_ctrl <= pull_dp;
+ addr_ctrl <= pulls_ad;
+ dout_ctrl <= dp_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= rti_ixh_state;
+
+ when rti_ixh_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read ix hi
+ ix_ctrl <= pull_hi_ix;
+ addr_ctrl <= pulls_ad;
+ dout_ctrl <= ix_hi_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= rti_ixl_state;
+
+ when rti_ixl_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read ix low
+ ix_ctrl <= pull_lo_ix;
+ addr_ctrl <= pulls_ad;
+ dout_ctrl <= ix_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= rti_iyh_state;
+
+ when rti_iyh_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read iy hi
+ iy_ctrl <= pull_hi_iy;
+ addr_ctrl <= pulls_ad;
+ dout_ctrl <= iy_hi_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= rti_iyl_state;
+
+ when rti_iyl_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read iy low
+ iy_ctrl <= pull_lo_iy;
+ addr_ctrl <= pulls_ad;
+ dout_ctrl <= iy_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= rti_uph_state;
+
+
+ when rti_uph_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read up hi
+ up_ctrl <= pull_hi_up;
+ addr_ctrl <= pulls_ad;
+ dout_ctrl <= up_hi_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= rti_upl_state;
+
+ when rti_upl_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ iy_ctrl <= latch_iy;
+ ix_ctrl <= latch_ix;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- read up low
+ up_ctrl <= pull_lo_up;
+ addr_ctrl <= pulls_ad;
+ dout_ctrl <= up_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= rti_pch_state;
+
+ when rti_pch_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- pull pc hi
+ pc_ctrl <= pull_hi_pc;
+ addr_ctrl <= pulls_ad;
+ dout_ctrl <= pc_hi_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= rti_pcl_state;
+
+ when rti_pcl_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- increment sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_add16;
+ sp_ctrl <= load_sp;
+ -- pull pc low
+ pc_ctrl <= pull_lo_pc;
+ addr_ctrl <= pulls_ad;
+ dout_ctrl <= pc_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= fetch_state;
+
+ --
+ -- here on IRQ, NMI or FIRQ interrupt
+ -- pre decrement the sp
+ --
+ when int_decr_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= pc_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= int_entire_state;
+
+ --
+ -- set Entire Flag on SWI, SWI2, SWI3 and CWAI, IRQ and NMI
+ -- clear Entire Flag on FIRQ
+ -- before stacking all registers
+ --
+ when int_entire_state =>
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ --
+ left_ctrl <= sp_left;
+ right_ctrl <= zero_right;
+ if iv = FIRQ_VEC then
+ -- clear entire flag
+ alu_ctrl <= alu_cle;
+ else
+ -- set entire flag
+ alu_ctrl <= alu_see;
+ end if;
+ cc_ctrl <= load_cc;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= pc_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= int_pcl_state;
+
+ when int_pcl_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- write pc low
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= pc_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= int_pch_state;
+
+ when int_pch_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- write pc hi
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= pc_hi_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ if cc(EBIT) = '1' then
+ next_state <= int_upl_state;
+ else
+ next_state <= int_cc_state;
+ end if;
+
+ when int_upl_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- write up low
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= up_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= int_uph_state;
+
+ when int_uph_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- write ix hi
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= up_hi_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= int_iyl_state;
+
+ when int_iyl_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- write ix low
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= iy_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= int_iyh_state;
+
+ when int_iyh_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- write ix hi
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= iy_hi_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= int_ixl_state;
+
+ when int_ixl_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- write ix low
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= ix_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= int_ixh_state;
+
+ when int_ixh_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- write ix hi
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= ix_hi_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= int_dp_state;
+
+ when int_dp_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- write accb
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= dp_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= int_accb_state;
+
+ when int_accb_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- write accb
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= accb_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= int_acca_state;
+
+ when int_acca_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- decrement sp
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_sub16;
+ sp_ctrl <= load_sp;
+ -- write acca
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= acca_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= int_cc_state;
+
+ when int_cc_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ iv_ctrl <= latch_iv;
+ ea_ctrl <= latch_ea;
+ -- idle sp
+ left_ctrl <= sp_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ sp_ctrl <= latch_sp;
+ -- write cc
+ addr_ctrl <= pushs_ad;
+ dout_ctrl <= cc_dout;
+ nmi_ctrl <= latch_nmi;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ case iv is
+ when NMI_VEC =>
+ next_state <= int_mask_state;
+ when SWI_VEC =>
+ next_state <= int_mask_state;
+ when IRQ_VEC =>
+ next_state <= int_mask_state;
+ when SWI2_VEC =>
+ next_state <= vect_hi_state;
+ when FIRQ_VEC =>
+ next_state <= int_mask_state;
+ when SWI3_VEC =>
+ next_state <= vect_hi_state;
+ when others =>
+ if op_code = "00111100" then -- CWAI
+ next_state <= int_cwai_state;
+ else
+ next_state <= rti_state;
+ end if;
+ end case;
+
+ --
+ -- wait here for an inteerupt
+ --
+ when int_cwai_state =>
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ ea_ctrl <= latch_ea;
+ --
+ left_ctrl <= sp_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_nop;
+ cc_ctrl <= latch_cc;
+ sp_ctrl <= latch_sp;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= cc_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ --
+ if (nmi_req = '1') and (nmi_ack='0') then
+ iv_ctrl <= nmi_iv;
+ nmi_ctrl <= set_nmi;
+ next_state <= vect_hi_state;
+ else
+ --
+ -- nmi request is not cleared until nmi input goes low
+ --
+ if (nmi_req = '0') and (nmi_ack='1') then
+ nmi_ctrl <= reset_nmi;
+ else
+ nmi_ctrl <= latch_nmi;
+ end if;
+ --
+ -- IRQ is level sensitive
+ --
+ if (irq = '1') and (cc(IBIT) = '0') then
+ iv_ctrl <= irq_iv;
+ next_state <= int_mask_state;
+ elsif (firq = '1') and (cc(FBIT) = '0') then
+ --
+ -- FIRQ is level sensitive
+ --
+ iv_ctrl <= firq_iv;
+ next_state <= int_mask_state;
+ else
+ iv_ctrl <= latch_iv;
+ next_state <= int_cwai_state;
+ end if;
+ end if;
+
+ when int_mask_state =>
+ -- default
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- Mask IRQ and FIRQ
+ left_ctrl <= sp_left;
+ right_ctrl <= zero_right;
+ --
+ -- FIRQ can interrupt an IRQ service routine
+ --
+ if iv = IRQ_VEC then
+ alu_ctrl <= alu_sei;
+ else
+ alu_ctrl <= alu_seif;
+ end if;
+ cc_ctrl <= load_cc;
+ sp_ctrl <= latch_sp;
+ -- idle bus cycle
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= vect_hi_state;
+
+ when sync_state =>
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ ea_ctrl <= latch_ea;
+ --
+ left_ctrl <= pc_left;
+ right_ctrl <= one_right;
+ alu_ctrl <= alu_nop;
+ -- idle bus
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= cc_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ --
+ if (nmi_req = '1') and (nmi_ack='0') then
+ iv_ctrl <= nmi_iv;
+ nmi_ctrl <= set_nmi;
+ next_state <= fetch_state;
+ else
+ --
+ -- nmi request is not cleared until nmi input goes low
+ --
+ if (nmi_req = '0') and (nmi_ack='1') then
+ nmi_ctrl <= reset_nmi;
+ else
+ nmi_ctrl <= latch_nmi;
+ end if;
+ --
+ -- IRQ is level sensitive
+ --
+ if (irq = '1') and (cc(IBIT) = '0') then
+ iv_ctrl <= irq_iv;
+ next_state <= fetch_state;
+ elsif (firq = '1') and (cc(FBIT) = '0') then
+ --
+ -- FIRQ is level sensitive
+ --
+ iv_ctrl <= firq_iv;
+ next_state <= fetch_state;
+ else
+ iv_ctrl <= latch_iv;
+ next_state <= sync_state;
+ end if;
+ end if;
+
+
+ when halt_state =>
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- idle ALU
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ sp_ctrl <= latch_sp;
+ -- idle bus cycle
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ --
+ if halt <= '1' then
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= halt_state;
+ else
+ st_ctrl <= pull_st;
+ return_state <= fetch_state;
+ next_state <= saved_state;
+ end if;
+
+ when others => -- halt on undefine states
+ -- default
+ cc_ctrl <= latch_cc;
+ acca_ctrl <= latch_acca;
+ accb_ctrl <= latch_accb;
+ dp_ctrl <= latch_dp;
+ ix_ctrl <= latch_ix;
+ iy_ctrl <= latch_iy;
+ up_ctrl <= latch_up;
+ sp_ctrl <= latch_sp;
+ pc_ctrl <= latch_pc;
+ md_ctrl <= latch_md;
+ iv_ctrl <= latch_iv;
+ op_ctrl <= latch_op;
+ pre_ctrl <= latch_pre;
+ nmi_ctrl <= latch_nmi;
+ ea_ctrl <= latch_ea;
+ -- do nothing in ALU
+ left_ctrl <= acca_left;
+ right_ctrl <= zero_right;
+ alu_ctrl <= alu_nop;
+ -- idle bus cycle
+ addr_ctrl <= idle_ad;
+ dout_ctrl <= md_lo_dout;
+ --
+ st_ctrl <= idle_st;
+ return_state <= fetch_state;
+ next_state <= error_state;
+ end case;
+end process;
+
+end CPU_ARCH;
+
--===========================================================================---- |
-- |
-- S Y N T H E Z I A B L E CPU09 - 6809 compatible CPU Core |
-- |
-- www.OpenCores.Org - September 2003 |
-- This core adheres to the GNU public license |
-- |
-- File name : cpu09.vhd |
-- |
-- Purpose : 6809 CPU core |
-- |
-- Dependencies : ieee.Std_Logic_1164 |
-- ieee.std_logic_unsigned |
-- |
-- Uses : None |
-- |
-- Author : John E. Kent |
-- dilbert57@opencores.org |
-- |
--===========================================================================---- |
-- |
-- Revision History: |
--===========================================================================-- |
-- |
-- Version 0.1 - 26 June 2003 - John Kent |
-- Added extra level in state stack |
-- fixed some calls to the extended addressing state |
-- |
-- Version 0.2 - 5 Sept 2003 - John Kent |
-- Fixed 16 bit indexed offset (was doing read rather than fetch) |
-- Added/Fixed STY and STS instructions. |
-- ORCC_STATE ANDed CC state rather than ORed it - Now fixed |
-- CMPX Loaded ACCA and ACCB - Now fixed |
-- |
-- Version 1.0 - 6 Sep 2003 - John Kent |
-- Initial release to Open Cores |
-- reversed clock edge |
-- |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
|
entity cpu09 is |
port ( |
clk: in std_logic; |
rst: in std_logic; |
rw: out std_logic; |
vma: out std_logic; |
address: out std_logic_vector(15 downto 0); |
data_in: in std_logic_vector(7 downto 0); |
data_out: out std_logic_vector(7 downto 0); |
halt: in std_logic; |
hold: in std_logic; |
irq: in std_logic; |
firq: in std_logic; |
nmi: in std_logic; |
test_alu: out std_logic_vector(15 downto 0); |
test_cc: out std_logic_vector(7 downto 0) |
); |
end; |
|
architecture CPU_ARCH of cpu09 is |
|
constant EBIT : integer := 7; |
constant FBIT : integer := 6; |
constant HBIT : integer := 5; |
constant IBIT : integer := 4; |
constant NBIT : integer := 3; |
constant ZBIT : integer := 2; |
constant VBIT : integer := 1; |
constant CBIT : integer := 0; |
|
-- |
-- Interrupt vector modifiers |
-- |
constant RST_VEC : std_logic_vector(2 downto 0) := "111"; |
constant NMI_VEC : std_logic_vector(2 downto 0) := "110"; |
constant SWI_VEC : std_logic_vector(2 downto 0) := "101"; |
constant IRQ_VEC : std_logic_vector(2 downto 0) := "100"; |
constant FIRQ_VEC : std_logic_vector(2 downto 0) := "011"; |
constant SWI2_VEC : std_logic_vector(2 downto 0) := "010"; |
constant SWI3_VEC : std_logic_vector(2 downto 0) := "001"; |
constant RESV_VEC : std_logic_vector(2 downto 0) := "000"; |
|
type state_type is (-- Start off in Reset |
reset_state, |
-- Fetch Interrupt Vectors (including reset) |
vect_lo_state, vect_hi_state, |
-- Fetch Instruction Cycle |
fetch_state, |
-- Decode Instruction Cycles |
decode1_state, decode2_state, decode3_state, |
-- Calculate Effective Address |
imm16_state, |
indexed_state, index8_state, index16_state, index16_2_state, |
pcrel8_state, pcrel16_state, pcrel16_2_state, |
indexaddr_state, indexaddr2_state, |
postincr1_state, postincr2_state, |
indirect_state, indirect2_state, indirect3_state, |
extended_state, |
-- single ops |
single_op_read_state, |
single_op_exec_state, |
single_op_write_state, |
-- Dual op states |
dual_op_read8_state, dual_op_read16_state, dual_op_read16_2_state, |
dual_op_write8_state, dual_op_write16_state, |
-- |
sync_state, halt_state, error_state, |
-- |
andcc_state, orcc_state, |
tfr_state, exg_state, exg1_state, |
lea_state, |
-- Multiplication |
mul_state, mulea_state, muld_state, |
mul0_state, mul1_state, mul2_state, mul3_state, |
mul4_state, mul5_state, mul6_state, mul7_state, |
-- Branches |
lbranch_state, sbranch_state, |
-- Jumps, Subroutine Calls and Returns |
jsr_state, jmp_state, |
push_return_hi_state, push_return_lo_state, |
pull_return_hi_state, pull_return_lo_state, |
-- Interrupt cycles |
int_decr_state, |
int_entire_state, |
int_pcl_state, int_pch_state, |
int_upl_state, int_uph_state, |
int_iyl_state, int_iyh_state, |
int_ixl_state, int_ixh_state, |
int_cc_state, |
int_acca_state, int_accb_state, |
int_dp_state, |
int_cwai_state, int_mask_state, |
-- Return From Interrupt |
rti_state, |
rti_acca_state, rti_accb_state, |
rti_cc_state, rti_dp_state, |
rti_ixl_state, rti_ixh_state, |
rti_iyl_state, rti_iyh_state, |
rti_upl_state, rti_uph_state, |
rti_pcl_state, rti_pch_state, |
-- Push Registers using SP |
pshs_state, |
pshs_pcl_state, pshs_pch_state, |
pshs_upl_state, pshs_uph_state, |
pshs_iyl_state, pshs_iyh_state, |
pshs_ixl_state, pshs_ixh_state, |
pshs_dp_state, |
pshs_acca_state, pshs_accb_state, |
pshs_cc_state, |
-- Pull Registers using SP |
puls_state, |
puls_cc_state, |
puls_acca_state, puls_accb_state, |
puls_dp_state, |
puls_ixl_state, puls_ixh_state, |
puls_iyl_state, puls_iyh_state, |
puls_upl_state, puls_uph_state, |
puls_pcl_state, puls_pch_state, |
-- Push Registers using UP |
pshu_state, |
pshu_pcl_state, pshu_pch_state, |
pshu_spl_state, pshu_sph_state, |
pshu_iyl_state, pshu_iyh_state, |
pshu_ixl_state, pshu_ixh_state, |
pshu_dp_state, |
pshu_acca_state, pshu_accb_state, |
pshu_cc_state, |
-- Pull Registers using UP |
pulu_state, |
pulu_cc_state, |
pulu_acca_state, pulu_accb_state, |
pulu_dp_state, |
pulu_ixl_state, pulu_ixh_state, |
pulu_iyl_state, pulu_iyh_state, |
pulu_spl_state, pulu_sph_state, |
pulu_pcl_state, pulu_pch_state ); |
|
type stack_type is array(2 downto 0) of state_type; |
type st_type is (idle_st, push_st, pull_st ); |
type addr_type is (idle_ad, fetch_ad, read_ad, write_ad, pushu_ad, pullu_ad, pushs_ad, pulls_ad, int_hi_ad, int_lo_ad ); |
type dout_type is (cc_dout, acca_dout, accb_dout, dp_dout, |
ix_lo_dout, ix_hi_dout, iy_lo_dout, iy_hi_dout, |
up_lo_dout, up_hi_dout, sp_lo_dout, sp_hi_dout, |
pc_lo_dout, pc_hi_dout, md_lo_dout, md_hi_dout ); |
type op_type is (reset_op, fetch_op, latch_op ); |
type pre_type is (reset_pre, fetch_pre, latch_pre ); |
type cc_type is (reset_cc, load_cc, pull_cc, latch_cc ); |
type acca_type is (reset_acca, load_acca, load_hi_acca, pull_acca, latch_acca ); |
type accb_type is (reset_accb, load_accb, pull_accb, latch_accb ); |
type dp_type is (reset_dp, load_dp, pull_dp, latch_dp ); |
type ix_type is (reset_ix, load_ix, pull_lo_ix, pull_hi_ix, latch_ix ); |
type iy_type is (reset_iy, load_iy, pull_lo_iy, pull_hi_iy, latch_iy ); |
type sp_type is (reset_sp, latch_sp, load_sp, pull_hi_sp, pull_lo_sp ); |
type up_type is (reset_up, latch_up, load_up, pull_hi_up, pull_lo_up ); |
type pc_type is (reset_pc, latch_pc, load_pc, pull_lo_pc, pull_hi_pc, incr_pc ); |
type md_type is (reset_md, latch_md, load_md, fetch_first_md, fetch_next_md, shiftl_md ); |
type ea_type is (reset_ea, latch_ea, load_ea, fetch_first_ea, fetch_next_ea ); |
type iv_type is (reset_iv, latch_iv, nmi_iv, irq_iv, firq_iv, swi_iv, swi2_iv, swi3_iv, resv_iv); |
type nmi_type is (reset_nmi, set_nmi, latch_nmi ); |
type left_type is (cc_left, acca_left, accb_left, dp_left, |
ix_left, iy_left, up_left, sp_left, |
accd_left, md_left, pc_left, ea_left ); |
type right_type is (ea_right, zero_right, one_right, two_right, |
acca_right, accb_right, accd_right, |
md_right, md_sign5_right, md_sign8_right ); |
type alu_type is (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_andcc, alu_orcc, alu_sex, alu_tfr, |
alu_seif, alu_sei, alu_see, alu_cle, |
alu_ld8, alu_st8, alu_ld16, alu_st16, alu_nop, alu_daa ); |
|
signal op_code: std_logic_vector(7 downto 0); |
signal pre_code: std_logic_vector(7 downto 0); |
signal acca: std_logic_vector(7 downto 0); |
signal accb: std_logic_vector(7 downto 0); |
signal cc: std_logic_vector(7 downto 0); |
signal cc_out: std_logic_vector(7 downto 0); |
signal dp: std_logic_vector(7 downto 0); |
signal xreg: std_logic_vector(15 downto 0); |
signal yreg: std_logic_vector(15 downto 0); |
signal sp: std_logic_vector(15 downto 0); |
signal up: std_logic_vector(15 downto 0); |
signal ea: std_logic_vector(15 downto 0); |
signal pc: std_logic_vector(15 downto 0); |
signal md: std_logic_vector(15 downto 0); |
signal left: std_logic_vector(15 downto 0); |
signal right: std_logic_vector(15 downto 0); |
signal out_alu: std_logic_vector(15 downto 0); |
signal iv: std_logic_vector(2 downto 0); |
signal nmi_req: std_logic; |
signal nmi_ack: std_logic; |
|
signal state: state_type; |
signal next_state: state_type; |
signal saved_state: state_type; |
signal return_state: state_type; |
signal state_stack: stack_type; |
signal st_ctrl: st_type; |
signal pc_ctrl: pc_type; |
signal ea_ctrl: ea_type; |
signal op_ctrl: op_type; |
signal pre_ctrl: pre_type; |
signal md_ctrl: md_type; |
signal acca_ctrl: acca_type; |
signal accb_ctrl: accb_type; |
signal ix_ctrl: ix_type; |
signal iy_ctrl: iy_type; |
signal cc_ctrl: cc_type; |
signal dp_ctrl: dp_type; |
signal sp_ctrl: sp_type; |
signal up_ctrl: up_type; |
signal iv_ctrl: iv_type; |
signal left_ctrl: left_type; |
signal right_ctrl: right_type; |
signal alu_ctrl: alu_type; |
signal addr_ctrl: addr_type; |
signal dout_ctrl: dout_type; |
signal nmi_ctrl: nmi_type; |
|
|
begin |
|
---------------------------------- |
-- |
-- State machine stack |
-- |
---------------------------------- |
state_stack_proc: process( clk, st_ctrl, state_stack, return_state, hold ) |
begin |
if clk'event and clk = '0' then |
if hold= '1' then |
state_stack(0) <= state_stack(0); |
state_stack(1) <= state_stack(1); |
state_stack(2) <= state_stack(2); |
else |
case st_ctrl is |
when idle_st => |
state_stack(0) <= state_stack(0); |
state_stack(1) <= state_stack(1); |
state_stack(2) <= state_stack(2); |
when push_st => |
state_stack(0) <= return_state; |
state_stack(1) <= state_stack(0); |
state_stack(2) <= state_stack(1); |
when pull_st => |
state_stack(0) <= state_stack(1); |
state_stack(1) <= state_stack(2); |
state_stack(2) <= fetch_state; |
when others => |
state_stack(0) <= state_stack(0); |
state_stack(1) <= state_stack(1); |
state_stack(2) <= state_stack(2); |
end case; |
end if; |
end if; |
saved_state <= state_stack(0); |
end process; |
|
---------------------------------- |
-- |
-- Program Counter Control |
-- |
---------------------------------- |
|
pc_reg: process( clk, pc_ctrl, hold, pc, out_alu, data_in ) |
begin |
if clk'event and clk = '0' then |
if hold= '1' then |
pc <= pc; |
else |
case pc_ctrl is |
when reset_pc => |
pc <= "0000000000000000"; |
when load_pc => |
pc <= out_alu(15 downto 0); |
when pull_lo_pc => |
pc(7 downto 0) <= data_in; |
when pull_hi_pc => |
pc(15 downto 8) <= data_in; |
when incr_pc => |
pc <= pc + 1; |
when others => |
-- when latch_pc => |
pc <= pc; |
end case; |
end if; |
end if; |
end process; |
|
---------------------------------- |
-- |
-- Effective Address Control |
-- |
---------------------------------- |
|
ea_reg: process( clk, ea_ctrl, hold, ea, out_alu, data_in, dp ) |
begin |
|
if clk'event and clk = '0' then |
if hold= '1' then |
ea <= ea; |
else |
case ea_ctrl is |
when reset_ea => |
ea <= "0000000000000000"; |
when fetch_first_ea => |
ea(7 downto 0) <= data_in; |
ea(15 downto 8) <= dp; |
when fetch_next_ea => |
ea(15 downto 8) <= ea(7 downto 0); |
ea(7 downto 0) <= data_in; |
when load_ea => |
ea <= out_alu(15 downto 0); |
when others => |
-- when latch_ea => |
ea <= ea; |
end case; |
end if; |
end if; |
end process; |
|
-------------------------------- |
-- |
-- Accumulator A |
-- |
-------------------------------- |
acca_reg : process( clk, acca_ctrl, hold, out_alu, acca, data_in ) |
begin |
if clk'event and clk = '0' then |
if hold= '1' then |
acca <= acca; |
else |
case acca_ctrl is |
when reset_acca => |
acca <= "00000000"; |
when load_acca => |
acca <= out_alu(7 downto 0); |
when load_hi_acca => |
acca <= out_alu(15 downto 8); |
when pull_acca => |
acca <= data_in; |
when others => |
-- when latch_acca => |
acca <= acca; |
end case; |
end if; |
end if; |
end process; |
|
-------------------------------- |
-- |
-- Accumulator B |
-- |
-------------------------------- |
accb_reg : process( clk, accb_ctrl, hold, out_alu, accb, data_in ) |
begin |
if clk'event and clk = '0' then |
if hold= '1' then |
accb <= accb; |
else |
case accb_ctrl is |
when reset_accb => |
accb <= "00000000"; |
when load_accb => |
accb <= out_alu(7 downto 0); |
when pull_accb => |
accb <= data_in; |
when others => |
-- when latch_accb => |
accb <= accb; |
end case; |
end if; |
end if; |
end process; |
|
-------------------------------- |
-- |
-- X Index register |
-- |
-------------------------------- |
ix_reg : process( clk, ix_ctrl, hold, out_alu, xreg, data_in ) |
begin |
if clk'event and clk = '0' then |
if hold= '1' then |
xreg <= xreg; |
else |
case ix_ctrl is |
when reset_ix => |
xreg <= "0000000000000000"; |
when load_ix => |
xreg <= out_alu(15 downto 0); |
when pull_hi_ix => |
xreg(15 downto 8) <= data_in; |
when pull_lo_ix => |
xreg(7 downto 0) <= data_in; |
when others => |
-- when latch_ix => |
xreg <= xreg; |
end case; |
end if; |
end if; |
end process; |
|
-------------------------------- |
-- |
-- Y Index register |
-- |
-------------------------------- |
iy_reg : process( clk, iy_ctrl, hold, out_alu, yreg, data_in ) |
begin |
if clk'event and clk = '0' then |
if hold= '1' then |
yreg <= yreg; |
else |
case iy_ctrl is |
when reset_iy => |
yreg <= "0000000000000000"; |
when load_iy => |
yreg <= out_alu(15 downto 0); |
when pull_hi_iy => |
yreg(15 downto 8) <= data_in; |
when pull_lo_iy => |
yreg(7 downto 0) <= data_in; |
when others => |
-- when latch_iy => |
yreg <= yreg; |
end case; |
end if; |
end if; |
end process; |
|
-------------------------------- |
-- |
-- S stack pointer |
-- |
-------------------------------- |
sp_reg : process( clk, sp_ctrl, hold, sp, out_alu, data_in ) |
begin |
if clk'event and clk = '0' then |
if hold= '1' then |
sp <= sp; |
else |
case sp_ctrl is |
when reset_sp => |
sp <= "0000000000000000"; |
when load_sp => |
sp <= out_alu(15 downto 0); |
when pull_hi_sp => |
sp(15 downto 8) <= data_in; |
when pull_lo_sp => |
sp(7 downto 0) <= data_in; |
when others => |
-- when latch_sp => |
sp <= sp; |
end case; |
end if; |
end if; |
end process; |
|
-------------------------------- |
-- |
-- U stack pointer |
-- |
-------------------------------- |
up_reg : process( clk, up_ctrl, hold, up, out_alu, data_in ) |
begin |
if clk'event and clk = '0' then |
if hold= '1' then |
up <= up; |
else |
case up_ctrl is |
when reset_up => |
up <= "0000000000000000"; |
when load_up => |
up <= out_alu(15 downto 0); |
when pull_hi_up => |
up(15 downto 8) <= data_in; |
when pull_lo_up => |
up(7 downto 0) <= data_in; |
when others => |
-- when latch_up => |
up <= up; |
end case; |
end if; |
end if; |
end process; |
|
-------------------------------- |
-- |
-- Memory Data |
-- |
-------------------------------- |
md_reg : process( clk, md_ctrl, hold, out_alu, data_in, md ) |
begin |
if clk'event and clk = '0' then |
if hold= '1' then |
md <= md; |
else |
case md_ctrl is |
when reset_md => |
md <= "0000000000000000"; |
when load_md => |
md <= out_alu(15 downto 0); |
when fetch_first_md => -- sign extend md for branches |
md(15 downto 8) <= data_in(7) & data_in(7) & data_in(7) & data_in(7) & |
data_in(7) & data_in(7) & data_in(7) & data_in(7) ; |
md(7 downto 0) <= data_in; |
when fetch_next_md => |
md(15 downto 8) <= md(7 downto 0); |
md(7 downto 0) <= data_in; |
when shiftl_md => |
md(15 downto 1) <= md(14 downto 0); |
md(0) <= '0'; |
when others => |
-- when latch_md => |
md <= md; |
end case; |
end if; |
end if; |
end process; |
|
|
---------------------------------- |
-- |
-- Condition Codes |
-- |
---------------------------------- |
|
cc_reg: process( clk, cc_ctrl, hold, cc_out, cc, data_in ) |
begin |
if clk'event and clk = '0' then |
if hold= '1' then |
cc <= cc; |
else |
case cc_ctrl is |
when reset_cc => |
cc <= "11010000"; -- set EBIT, FBIT & IBIT |
when load_cc => |
cc <= cc_out; |
when pull_cc => |
cc <= data_in; |
when others => |
-- when latch_cc => |
cc <= cc; |
end case; |
end if; |
end if; |
end process; |
|
---------------------------------- |
-- |
-- Direct Page register |
-- |
---------------------------------- |
|
dp_reg: process( clk, dp_ctrl, hold, out_alu, dp, data_in ) |
begin |
if clk'event and clk = '0' then |
if hold= '1' then |
dp <= dp; |
else |
case dp_ctrl is |
when reset_dp => |
dp <= "00000000"; |
when load_dp => |
dp <= out_alu(7 downto 0); |
when pull_dp => |
dp <= data_in; |
when others => |
-- when latch_dp => |
dp <= dp; |
end case; |
end if; |
end if; |
end process; |
|
---------------------------------- |
-- |
-- interrupt vector |
-- |
---------------------------------- |
|
iv_mux: process( clk, iv_ctrl, hold, iv ) |
begin |
if clk'event and clk = '0' then |
if hold= '1' then |
iv <= iv; |
else |
case iv_ctrl is |
when reset_iv => |
iv <= RST_VEC; |
when nmi_iv => |
iv <= NMI_VEC; |
when swi_iv => |
iv <= SWI_VEC; |
when irq_iv => |
iv <= IRQ_VEC; |
when firq_iv => |
iv <= FIRQ_VEC; |
when swi2_iv => |
iv <= SWI2_VEC; |
when swi3_iv => |
iv <= SWI3_VEC; |
when resv_iv => |
iv <= RESV_VEC; |
when others => |
iv <= iv; |
end case; |
end if; |
end if; |
end process; |
|
|
---------------------------------- |
-- |
-- op code register |
-- |
---------------------------------- |
|
op_reg: process( clk, op_ctrl, hold, op_code, data_in ) |
begin |
if clk'event and clk = '0' then |
if hold= '1' then |
op_code <= op_code; |
else |
case op_ctrl is |
when reset_op => |
op_code <= "00010010"; |
when fetch_op => |
op_code <= data_in; |
when others => |
-- when latch_op => |
op_code <= op_code; |
end case; |
end if; |
end if; |
end process; |
|
|
---------------------------------- |
-- |
-- pre byte op code register |
-- |
---------------------------------- |
|
pre_reg: process( clk, pre_ctrl, hold, pre_code, data_in ) |
begin |
if clk'event and clk = '0' then |
if hold= '1' then |
pre_code <= pre_code; |
else |
case pre_ctrl is |
when reset_pre => |
pre_code <= "00000000"; |
when fetch_pre => |
pre_code <= data_in; |
when others => |
-- when latch_pre => |
pre_code <= pre_code; |
end case; |
end if; |
end if; |
end process; |
|
-------------------------------- |
-- |
-- state machine |
-- |
-------------------------------- |
|
change_state: process( clk, rst, state, hold, next_state ) |
begin |
if clk'event and clk = '0' then |
if rst = '1' then |
state <= reset_state; |
else |
if hold = '1' then |
state <= state; |
else |
state <= next_state; |
end if; |
end if; |
end if; |
end process; |
-- output |
|
------------------------------------ |
-- |
-- Nmi register |
-- |
------------------------------------ |
|
nmi_reg: process( clk, nmi_ctrl, hold, nmi_ack ) |
begin |
if clk'event and clk='0' then |
if hold = '1' then |
nmi_ack <= nmi_ack; |
else |
case nmi_ctrl is |
when set_nmi => |
nmi_ack <= '1'; |
when reset_nmi => |
nmi_ack <= '0'; |
when others => |
-- when latch_nmi => |
nmi_ack <= nmi_ack; |
end case; |
end if; |
end if; |
end process; |
|
------------------------------------ |
-- |
-- Detect Edge of NMI interrupt |
-- |
------------------------------------ |
|
nmi_handler : process( clk, rst, nmi, nmi_ack, nmi_req ) |
begin |
if clk'event and clk='0' then |
if rst='1' then |
nmi_req <= '0'; |
else |
if (nmi='1') and (nmi_ack='0') then |
nmi_req <= '1'; |
else |
if (nmi='0') and (nmi_ack='1') then |
nmi_req <= '0'; |
else |
nmi_req <= nmi_req; |
end if; |
end if; |
end if; |
end if; |
end process; |
|
|
---------------------------------- |
-- |
-- Address output multiplexer |
-- |
---------------------------------- |
|
addr_mux: process( addr_ctrl, pc, ea, up, sp, iv ) |
begin |
case addr_ctrl is |
when idle_ad => |
address <= "1111111111111111"; |
vma <= '0'; |
rw <= '1'; |
when fetch_ad => |
address <= pc; |
vma <= '1'; |
rw <= '1'; |
when read_ad => |
address <= ea; |
vma <= '1'; |
rw <= '1'; |
when write_ad => |
address <= ea; |
vma <= '1'; |
rw <= '0'; |
when pushs_ad => |
address <= sp; |
vma <= '1'; |
rw <= '0'; |
when pulls_ad => |
address <= sp; |
vma <= '1'; |
rw <= '1'; |
when pushu_ad => |
address <= up; |
vma <= '1'; |
rw <= '0'; |
when pullu_ad => |
address <= up; |
vma <= '1'; |
rw <= '1'; |
when int_hi_ad => |
address <= "111111111111" & iv & "0"; |
vma <= '1'; |
rw <= '1'; |
when int_lo_ad => |
address <= "111111111111" & iv & "1"; |
vma <= '1'; |
rw <= '1'; |
when others => |
address <= "1111111111111111"; |
vma <= '0'; |
rw <= '1'; |
end case; |
end process; |
|
-------------------------------- |
-- |
-- Data Bus output |
-- |
-------------------------------- |
dout_mux : process( dout_ctrl, md, acca, accb, dp, xreg, yreg, sp, up, pc, cc ) |
begin |
case dout_ctrl is |
when md_hi_dout => -- alu output |
data_out <= md(15 downto 8); |
when md_lo_dout => -- alu output |
data_out <= md(7 downto 0); |
when acca_dout => -- accumulator a |
data_out <= acca; |
when accb_dout => -- accumulator b |
data_out <= accb; |
when ix_lo_dout => -- index reg |
data_out <= xreg(7 downto 0); |
when ix_hi_dout => -- index reg |
data_out <= xreg(15 downto 8); |
when iy_lo_dout => -- index reg |
data_out <= yreg(7 downto 0); |
when iy_hi_dout => -- index reg |
data_out <= yreg(15 downto 8); |
when sp_lo_dout => -- s stack pointer |
data_out <= sp(7 downto 0); |
when sp_hi_dout => -- s stack pointer |
data_out <= sp(15 downto 8); |
when up_lo_dout => -- u stack pointer |
data_out <= up(7 downto 0); |
when up_hi_dout => -- u stack pointer |
data_out <= up(15 downto 8); |
when cc_dout => -- condition code register |
data_out <= cc; |
when dp_dout => -- direct page register |
data_out <= dp; |
when pc_lo_dout => -- low order pc |
data_out <= pc(7 downto 0); |
when pc_hi_dout => -- high order pc |
data_out <= pc(15 downto 8); |
when others => |
data_out <= "00000000"; |
end case; |
end process; |
|
---------------------------------- |
-- |
-- Left Mux |
-- |
---------------------------------- |
|
left_mux: process( left_ctrl, acca, accb, cc, dp, xreg, yreg, up, sp, pc, ea, md ) |
begin |
case left_ctrl is |
when cc_left => |
left(15 downto 8) <= "00000000"; |
left(7 downto 0) <= cc; |
when acca_left => |
left(15 downto 8) <= "00000000"; |
left(7 downto 0) <= acca; |
when accb_left => |
left(15 downto 8) <= "00000000"; |
left(7 downto 0) <= accb; |
when dp_left => |
left(15 downto 8) <= "00000000"; |
left(7 downto 0) <= dp; |
when accd_left => |
left(15 downto 8) <= acca; |
left(7 downto 0) <= accb; |
when md_left => |
left <= md; |
when ix_left => |
left <= xreg; |
when iy_left => |
left <= yreg; |
when sp_left => |
left <= sp; |
when up_left => |
left <= up; |
when pc_left => |
left <= pc; |
when others => |
-- when ea_left => |
left <= ea; |
end case; |
end process; |
|
---------------------------------- |
-- |
-- Right Mux |
-- |
---------------------------------- |
|
right_mux: process( right_ctrl, md, acca, accb, ea ) |
begin |
case right_ctrl is |
when ea_right => |
right <= ea; |
when zero_right => |
right <= "0000000000000000"; |
when one_right => |
right <= "0000000000000001"; |
when two_right => |
right <= "0000000000000010"; |
when acca_right => |
right <= "00000000" & acca; |
when accb_right => |
right <= "00000000" & accb; |
when accd_right => |
right <= acca & accb; |
when md_sign5_right => |
if md(4) = '0' then |
right <= "00000000000" & md(4 downto 0); |
else |
right <= "11111111111" & md(4 downto 0); |
end if; |
when md_sign8_right => |
if md(7) = '0' then |
right <= "00000000" & md(7 downto 0); |
else |
right <= "11111111" & md(7 downto 0); |
end if; |
when others => |
-- when md_right => |
right <= md; |
end case; |
end process; |
|
---------------------------------- |
-- |
-- Arithmetic Logic Unit |
-- |
---------------------------------- |
|
alu: process( alu_ctrl, cc, left, right, out_alu, cc_out ) |
variable valid_lo, valid_hi : boolean; |
variable carry_in : std_logic; |
variable daa_reg : std_logic_vector(7 downto 0); |
begin |
|
case alu_ctrl is |
when alu_adc | alu_sbc | |
alu_rol8 | alu_ror8 => |
carry_in := cc(CBIT); |
when others => |
carry_in := '0'; |
end case; |
|
valid_lo := left(3 downto 0) <= 9; |
valid_hi := left(7 downto 4) <= 9; |
|
if (cc(CBIT) = '0') then |
if( cc(HBIT) = '1' ) then |
if valid_hi then |
daa_reg := "00000110"; |
else |
daa_reg := "01100110"; |
end if; |
else |
if valid_lo then |
if valid_hi then |
daa_reg := "00000000"; |
else |
daa_reg := "01100000"; |
end if; |
else |
if( left(7 downto 4) <= 8 ) then |
daa_reg := "00000110"; |
else |
daa_reg := "01100110"; |
end if; |
end if; |
end if; |
else |
if ( cc(HBIT) = '1' )then |
daa_reg := "01100110"; |
else |
if valid_lo then |
daa_reg := "01100000"; |
else |
daa_reg := "01100110"; |
end if; |
end if; |
end if; |
|
case alu_ctrl is |
when alu_add8 | alu_inc | |
alu_add16 | alu_inx | |
alu_adc => |
out_alu <= left + right + ("000000000000000" & carry_in); |
when alu_sub8 | alu_dec | |
alu_sub16 | alu_dex | |
alu_sbc => |
out_alu <= left - right - ("000000000000000" & carry_in); |
when alu_and => |
out_alu <= left and right; -- and/bit |
when alu_ora => |
out_alu <= left or right; -- or |
when alu_eor => |
out_alu <= left xor right; -- eor/xor |
when alu_lsl16 | alu_asl8 | alu_rol8 => |
out_alu <= left(14 downto 0) & carry_in; -- rol8/asl8/lsl16 |
when alu_lsr16 | alu_lsr8 => |
out_alu <= carry_in & left(15 downto 1); -- lsr |
when alu_ror8 => |
out_alu <= "00000000" & carry_in & left(7 downto 1); -- ror |
when alu_asr8 => |
out_alu <= "00000000" & left(7) & left(7 downto 1); -- asr |
when alu_neg => |
out_alu <= right - left; -- neg (right=0) |
when alu_com => |
out_alu <= not left; |
when alu_clr | alu_ld8 | alu_ld16 => |
out_alu <= right; -- clr, ld |
when alu_st8 | alu_st16 | alu_andcc | alu_orcc => |
out_alu <= left; |
when alu_daa => |
out_alu <= left + ("00000000" & daa_reg); |
when alu_sex => |
if left(7) = '0' then |
out_alu <= "00000000" & left(7 downto 0); |
else |
out_alu <= "11111111" & left(7 downto 0); |
end if; |
when others => |
out_alu <= left; -- nop, tfr |
end case; |
|
-- |
-- carry bit |
-- |
case alu_ctrl is |
when alu_add8 | alu_adc => |
cc_out(CBIT) <= (left(7) and right(7)) or |
(left(7) and not out_alu(7)) or |
(right(7) and not out_alu(7)); |
when alu_sub8 | alu_sbc => |
cc_out(CBIT) <= ((not left(7)) and right(7)) or |
((not left(7)) and out_alu(7)) or |
(right(7) and out_alu(7)); |
when alu_add16 => |
cc_out(CBIT) <= (left(15) and right(15)) or |
(left(15) and not out_alu(15)) or |
(right(15) and not out_alu(15)); |
when alu_sub16 => |
cc_out(CBIT) <= ((not left(15)) and right(15)) or |
((not left(15)) and out_alu(15)) or |
(right(15) and out_alu(15)); |
when alu_ror8 | alu_lsr16 | alu_lsr8 | alu_asr8 => |
cc_out(CBIT) <= left(0); |
when alu_rol8 | alu_asl8 => |
cc_out(CBIT) <= left(7); |
when alu_lsl16 => |
cc_out(CBIT) <= left(15); |
when alu_com => |
cc_out(CBIT) <= '1'; |
when alu_neg | alu_clr => |
cc_out(CBIT) <= out_alu(7) or out_alu(6) or out_alu(5) or out_alu(4) or |
out_alu(3) or out_alu(2) or out_alu(1) or out_alu(0); |
when alu_daa => |
if ( daa_reg(7 downto 4) = "0110" ) then |
cc_out(CBIT) <= '1'; |
else |
cc_out(CBIT) <= '0'; |
end if; |
when alu_andcc => |
cc_out(CBIT) <= left(CBIT) and cc(CBIT); |
when alu_orcc => |
cc_out(CBIT) <= left(CBIT) or cc(CBIT); |
when alu_tfr => |
cc_out(CBIT) <= left(CBIT); |
when others => |
cc_out(CBIT) <= cc(CBIT); |
end case; |
-- |
-- Zero flag |
-- |
case alu_ctrl is |
when 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_sex => |
cc_out(ZBIT) <= not( out_alu(7) or out_alu(6) or out_alu(5) or out_alu(4) or |
out_alu(3) or out_alu(2) or out_alu(1) or out_alu(0) ); |
when alu_add16 | alu_sub16 | |
alu_lsl16 | alu_lsr16 | |
alu_inx | alu_dex | |
alu_ld16 | alu_st16 => |
cc_out(ZBIT) <= not( out_alu(15) or out_alu(14) or out_alu(13) or out_alu(12) or |
out_alu(11) or out_alu(10) or out_alu(9) or out_alu(8) or |
out_alu(7) or out_alu(6) or out_alu(5) or out_alu(4) or |
out_alu(3) or out_alu(2) or out_alu(1) or out_alu(0) ); |
when alu_andcc => |
cc_out(ZBIT) <= left(ZBIT) and cc(ZBIT); |
when alu_orcc => |
cc_out(ZBIT) <= left(ZBIT) or cc(ZBIT); |
when alu_tfr => |
cc_out(ZBIT) <= left(ZBIT); |
when others => |
cc_out(ZBIT) <= cc(ZBIT); |
end case; |
|
-- |
-- negative flag |
-- |
case alu_ctrl is |
when 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_sex => |
cc_out(NBIT) <= out_alu(7); |
when alu_add16 | alu_sub16 | |
alu_lsl16 | alu_lsr16 | |
alu_ld16 | alu_st16 => |
cc_out(NBIT) <= out_alu(15); |
when alu_andcc => |
cc_out(NBIT) <= left(NBIT) and cc(NBIT); |
when alu_orcc => |
cc_out(NBIT) <= left(NBIT) or cc(NBIT); |
when alu_tfr => |
cc_out(NBIT) <= left(NBIT); |
when others => |
cc_out(NBIT) <= cc(NBIT); |
end case; |
|
-- |
-- Interrupt mask flag |
-- |
case alu_ctrl is |
when alu_andcc => |
cc_out(IBIT) <= left(IBIT) and cc(IBIT); |
when alu_orcc => |
cc_out(IBIT) <= left(IBIT) or cc(IBIT); |
when alu_seif | alu_sei => |
cc_out(IBIT) <= '1'; |
when alu_tfr => |
cc_out(IBIT) <= left(IBIT); |
when others => |
cc_out(IBIT) <= cc(IBIT); -- interrupt mask |
end case; |
|
-- |
-- Half Carry flag |
-- |
case alu_ctrl is |
when alu_add8 | alu_adc => |
cc_out(HBIT) <= (left(3) and right(3)) or |
(right(3) and not out_alu(3)) or |
(left(3) and not out_alu(3)); |
when alu_andcc => |
cc_out(HBIT) <= left(HBIT) and cc(HBIT); |
when alu_orcc => |
cc_out(HBIT) <= left(HBIT) or cc(HBIT); |
when alu_tfr => |
cc_out(HBIT) <= left(HBIT); |
when others => |
cc_out(HBIT) <= cc(HBIT); |
end case; |
|
-- |
-- Overflow flag |
-- |
case alu_ctrl is |
when alu_add8 | alu_adc => |
cc_out(VBIT) <= (left(7) and right(7) and (not out_alu(7))) or |
((not left(7)) and (not right(7)) and out_alu(7)); |
when alu_sub8 | alu_sbc => |
cc_out(VBIT) <= (left(7) and (not right(7)) and (not out_alu(7))) or |
((not left(7)) and right(7) and out_alu(7)); |
when alu_add16 => |
cc_out(VBIT) <= (left(15) and right(15) and (not out_alu(15))) or |
((not left(15)) and (not right(15)) and out_alu(15)); |
when alu_sub16 => |
cc_out(VBIT) <= (left(15) and (not right(15)) and (not out_alu(15))) or |
((not left(15)) and right(15) and out_alu(15)); |
when alu_inc => |
cc_out(VBIT) <= ((not left(7)) and left(6) and left(5) and left(4) and |
left(3) and left(2) and left(1) and left(0)); |
when alu_dec | alu_neg => |
cc_out(VBIT) <= (left(7) and (not left(6)) and (not left(5)) and (not left(4)) and |
(not left(3)) and (not left(2)) and (not left(1)) and (not left(0))); |
when alu_asr8 => |
cc_out(VBIT) <= left(0) xor left(7); |
when alu_lsr8 | alu_lsr16 => |
cc_out(VBIT) <= left(0); |
when alu_ror8 => |
cc_out(VBIT) <= left(0) xor cc(CBIT); |
when alu_lsl16 => |
cc_out(VBIT) <= left(15) xor left(14); |
when alu_rol8 | alu_asl8 => |
cc_out(VBIT) <= left(7) xor left(6); |
when alu_and | alu_ora | alu_eor | alu_com | |
alu_st8 | alu_st16 | alu_ld8 | alu_ld16 | alu_sex => |
cc_out(VBIT) <= '0'; |
when alu_andcc => |
cc_out(VBIT) <= left(VBIT) and cc(VBIT); |
when alu_orcc => |
cc_out(VBIT) <= left(VBIT) or cc(VBIT); |
when alu_tfr => |
cc_out(VBIT) <= left(VBIT); |
when others => |
cc_out(VBIT) <= cc(VBIT); |
end case; |
|
case alu_ctrl is |
when alu_andcc => |
cc_out(FBIT) <= left(FBIT) and cc(FBIT); |
when alu_orcc => |
cc_out(FBIT) <= left(FBIT) or cc(FBIT); |
when alu_tfr => |
cc_out(FBIT) <= left(FBIT); |
when alu_seif => |
cc_out(FBIT) <= '1'; |
when others => |
cc_out(FBIT) <= cc(FBIT); |
end case; |
|
case alu_ctrl is |
when alu_andcc => |
cc_out(EBIT) <= left(EBIT) and cc(EBIT); |
when alu_orcc => |
cc_out(EBIT) <= left(EBIT) or cc(EBIT); |
when alu_tfr => |
cc_out(EBIT) <= left(EBIT); |
when alu_see => |
cc_out(EBIT) <= '1'; |
when alu_cle => |
cc_out(EBIT) <= '0'; |
when others => |
cc_out(EBIT) <= cc(EBIT); |
end case; |
|
test_alu <= out_alu; |
test_cc <= cc_out; |
end process; |
|
------------------------------------ |
-- |
-- state sequencer |
-- |
------------------------------------ |
process( state, saved_state, |
op_code, pre_code, |
cc, ea, md, iv, |
irq, firq, nmi_req, nmi_ack, halt ) |
variable cond_true : boolean; -- variable used to evaluate coditional branches |
begin |
case state is |
when reset_state => -- released from reset |
-- reset the registers |
op_ctrl <= reset_op; |
pre_ctrl <= reset_pre; |
acca_ctrl <= reset_acca; |
accb_ctrl <= reset_accb; |
ix_ctrl <= reset_ix; |
iy_ctrl <= reset_iy; |
sp_ctrl <= reset_sp; |
up_ctrl <= reset_up; |
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 <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= reset_cc; |
dp_ctrl <= reset_dp; |
-- idle the bus |
dout_ctrl <= md_lo_dout; |
addr_ctrl <= idle_ad; |
st_ctrl <= idle_st; |
return_state <= vect_hi_state; |
next_state <= vect_hi_state; |
|
-- |
-- Jump via interrupt vector |
-- iv holds interrupt type |
-- fetch PC hi from vector location |
-- |
when vect_hi_state => |
-- default the registers |
op_ctrl <= latch_op; |
pre_ctrl <= latch_pre; |
nmi_ctrl <= latch_nmi; |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
sp_ctrl <= latch_sp; |
up_ctrl <= latch_up; |
md_ctrl <= latch_md; |
ea_ctrl <= latch_ea; |
iv_ctrl <= latch_iv; |
-- idle the ALU |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
dp_ctrl <= latch_dp; |
-- fetch pc low interrupt vector |
pc_ctrl <= pull_hi_pc; |
addr_ctrl <= int_hi_ad; |
dout_ctrl <= pc_hi_dout; |
st_ctrl <= idle_st; |
return_state <= vect_lo_state; |
next_state <= vect_lo_state; |
-- |
-- jump via interrupt vector |
-- iv holds vector type |
-- fetch PC lo from vector location |
-- |
when vect_lo_state => |
-- default the registers |
op_ctrl <= latch_op; |
pre_ctrl <= latch_pre; |
nmi_ctrl <= latch_nmi; |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
sp_ctrl <= latch_sp; |
up_ctrl <= latch_up; |
md_ctrl <= latch_md; |
ea_ctrl <= latch_ea; |
iv_ctrl <= latch_iv; |
-- idle the ALU |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
dp_ctrl <= latch_dp; |
-- fetch the vector low byte |
pc_ctrl <= pull_lo_pc; |
addr_ctrl <= int_lo_ad; |
dout_ctrl <= pc_lo_dout; |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= fetch_state; |
-- |
-- 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. |
-- |
when fetch_state => |
-- fetch the op code |
op_ctrl <= fetch_op; |
pre_ctrl <= fetch_pre; |
ea_ctrl <= reset_ea; |
md_ctrl <= latch_md; |
-- Fetch op code |
addr_ctrl <= fetch_ad; |
dout_ctrl <= md_lo_dout; |
dp_ctrl <= latch_dp; |
-- |
case op_code(7 downto 6) is |
when "10" => -- acca |
case op_code(3 downto 0) is |
when "0000" => -- suba |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "0001" => -- cmpa |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "0010" => -- sbca |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "0011" => |
case pre_code is |
when "00010000" => -- page 2 -- cmpd |
left_ctrl <= accd_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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "00010001" => -- page 3 -- cmpu |
left_ctrl <= up_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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when others => -- page 1 -- subd |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
end case; |
when "0100" => -- anda |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "0101" => -- bita |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "0110" => -- ldaa |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "0111" => -- staa |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "1000" => -- eora |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "1001" => -- adca |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "1010" => -- oraa |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "1011" => -- adda |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "1100" => |
case pre_code is |
when "00010000" => -- page 2 -- cmpy |
left_ctrl <= iy_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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "00010001" => -- page 3 -- cmps |
left_ctrl <= sp_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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when others => -- page 1 -- cmpx |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
end case; |
when "1101" => -- bsr / jsr |
left_ctrl <= pc_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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "1110" => -- ldx |
case pre_code is |
when "00010000" => -- page 2 -- ldy |
left_ctrl <= iy_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; |
iy_ctrl <= load_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when others => -- page 1 -- ldx |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
end case; |
when "1111" => -- stx |
case pre_code is |
when "00010000" => -- page 2 -- sty |
left_ctrl <= iy_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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when others => -- page 1 -- stx |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
end case; |
when others => |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
end case; |
when "11" => -- accb dual op |
case op_code(3 downto 0) is |
when "0000" => -- subb |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "0001" => -- cmpb |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "0010" => -- sbcb |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "0011" => -- addd |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "0100" => -- andb |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "0101" => -- bitb |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "0110" => -- ldab |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "0111" => -- stab |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "1000" => -- eorb |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "1001" => -- adcb |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "1010" => -- orab |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "1011" => -- addb |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "1100" => -- ldd |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "1101" => -- std |
left_ctrl <= accd_left; |
right_ctrl <= md_right; |
alu_ctrl <= alu_st16; |
cc_ctrl <= latch_cc; |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "1110" => -- ldu |
case pre_code is |
when "00010000" => -- page 2 -- lds |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= load_sp; |
when others => -- page 1 -- ldu |
left_ctrl <= up_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; |
iy_ctrl <= latch_iy; |
up_ctrl <= load_up; |
sp_ctrl <= latch_sp; |
end case; |
when "1111" => |
case pre_code is |
when "00010000" => -- page 2 -- sts |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when others => -- page 1 -- stu |
left_ctrl <= up_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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
end case; |
when others => |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
end case; |
when others => |
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; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
end case; |
if halt = '1' then |
iv_ctrl <= reset_iv; |
pc_ctrl <= latch_pc; |
nmi_ctrl <= latch_nmi; |
st_ctrl <= push_st; |
return_state <= fetch_state; |
next_state <= halt_state; |
-- service non maskable interrupts |
elsif (nmi_req = '1') and (nmi_ack = '0') then |
iv_ctrl <= nmi_iv; |
pc_ctrl <= latch_pc; |
nmi_ctrl <= set_nmi; |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= int_decr_state; |
-- service maskable interrupts |
else |
-- |
-- nmi request is not cleared until nmi input goes low |
-- |
if(nmi_req = '0') and (nmi_ack='1') then |
nmi_ctrl <= reset_nmi; |
else |
nmi_ctrl <= latch_nmi; |
end if; |
-- |
-- IRQ is level sensitive |
-- |
if (irq = '1') and (cc(IBIT) = '0') then |
iv_ctrl <= irq_iv; |
pc_ctrl <= latch_pc; |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= int_decr_state; |
elsif (firq = '1') and (cc(FBIT) = '0') then |
iv_ctrl <= firq_iv; |
pc_ctrl <= latch_pc; |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= int_decr_state; |
else |
-- Advance the PC to fetch next instruction byte |
iv_ctrl <= reset_iv; -- default to reset |
pc_ctrl <= incr_pc; |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= decode1_state; |
end if; |
end if; |
-- |
-- Here to decode instruction |
-- and fetch next byte of intruction |
-- whether it be necessary or not |
-- |
when decode1_state => |
pre_ctrl <= latch_pre; |
-- fetch first byte of address or immediate data |
ea_ctrl <= fetch_first_ea; |
md_ctrl <= fetch_first_md; |
addr_ctrl <= fetch_ad; |
dout_ctrl <= md_lo_dout; |
nmi_ctrl <= latch_nmi; |
dp_ctrl <= latch_dp; |
case op_code(7 downto 4) is |
-- |
-- direct single op (2 bytes) |
-- 6809 => 6 cycles |
-- cpu09 => 5 cycles |
-- 1 op=(pc) / pc=pc+1 |
-- 2 ea_hi=0 / ea_lo=(pc) / pc=pc+1 |
-- 3 md_lo=(ea) / pc=pc |
-- 4 alu_left=md / md=alu_out / pc=pc |
-- 5 (ea)=md_lo / pc=pc |
-- |
-- Exception is JMP |
-- 6809 => 3 cycles |
-- cpu09 => 3 cycles |
-- 1 op=(pc) / pc=pc+1 |
-- 2 ea_hi=0 / ea_lo=(pc) / pc=pc+1 |
-- 3 pc=ea |
-- |
when "0000" => |
op_ctrl <= latch_op; |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
sp_ctrl <= latch_sp; |
up_ctrl <= latch_up; |
iv_ctrl <= latch_iv; |
-- idle ALU |
left_ctrl <= pc_left; |
right_ctrl <= one_right; |
alu_ctrl <= alu_add16; |
cc_ctrl <= latch_cc; |
-- advance the PC |
pc_ctrl <= incr_pc; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= single_op_read_state; |
|
-- acca / accb inherent instructions |
when "0001" => |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
iv_ctrl <= latch_iv; |
case op_code(3 downto 0) is |
-- |
-- Page2 pre byte |
-- pre=(pc) / pc=pc+1 |
-- op=(pc) / pc=pc+1 |
-- |
when "0000" => -- page2 |
op_ctrl <= fetch_op; |
acca_ctrl <= latch_acca; |
-- |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
sp_ctrl <= latch_sp; |
-- advance pc |
pc_ctrl <= incr_pc; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= decode2_state; |
|
-- |
-- Page3 pre byte |
-- pre=(pc) / pc=pc+1 |
-- op=(pc) / pc=pc+1 |
-- |
when "0001" => -- page3 |
op_ctrl <= fetch_op; |
acca_ctrl <= latch_acca; |
-- idle ALU |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
sp_ctrl <= latch_sp; |
-- advance pc |
pc_ctrl <= incr_pc; |
-- Next state |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= decode3_state; |
|
-- |
-- nop - No operation ( 1 byte ) |
-- 6809 => 2 cycles |
-- cpu09 => 2 cycles |
-- 1 op=(pc) / pc=pc+1 |
-- 2 decode |
-- |
when "0010" => -- nop |
op_ctrl <= latch_op; |
acca_ctrl <= latch_acca; |
-- |
left_ctrl <= acca_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
sp_ctrl <= latch_sp; |
-- |
pc_ctrl <= latch_pc; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= fetch_state; |
|
-- |
-- sync - halt execution until an interrupt is received |
-- interrupt may be NMI, IRQ or FIRQ |
-- program execution continues if the |
-- interrupt is asserted for 3 clock cycles |
-- note that registers are not pushed onto the stack |
-- CPU09 => Interrupts need only be asserted for one clock cycle |
-- |
when "0011" => -- sync |
op_ctrl <= latch_op; |
acca_ctrl <= latch_acca; |
-- |
left_ctrl <= acca_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
sp_ctrl <= latch_sp; |
-- |
pc_ctrl <= latch_pc; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= sync_state; |
|
-- |
-- lbra -- long branch (3 bytes) |
-- 6809 => 5 cycles |
-- cpu09 => 4 cycles |
-- 1 op=(pc) / pc=pc+1 |
-- 2 md_hi=sign(pc) / md_lo=(pc) / pc=pc+1 |
-- 3 md_hi=md_lo / md_lo=(pc) / pc=pc+1 |
-- 4 pc=pc+md |
-- |
when "0110" => |
op_ctrl <= latch_op; |
acca_ctrl <= latch_acca; |
-- idle ALU |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
sp_ctrl <= latch_sp; |
-- increment the pc |
pc_ctrl <= incr_pc; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= lbranch_state; |
|
-- |
-- lbsr - long branch to subroutine (3 bytes) |
-- 6809 => 9 cycles |
-- cpu09 => 6 cycles |
-- 1 op=(pc) /pc=pc+1 |
-- 2 md_hi=sign(pc) / md_lo=(pc) / pc=pc+1 / sp=sp-1 |
-- 3 md_hi=md_lo / md_lo=(pc) / pc=pc+1 |
-- 4 (sp)= pc_lo / sp=sp-1 / pc=pc |
-- 5 (sp)=pc_hi / pc=pc |
-- 6 pc=pc+md |
-- |
when "0111" => |
op_ctrl <= latch_op; |
acca_ctrl <= latch_acca; |
-- pre decrement sp |
left_ctrl <= sp_left; |
right_ctrl <= one_right; |
alu_ctrl <= alu_sub16; |
cc_ctrl <= latch_cc; |
sp_ctrl <= load_sp; |
-- increment the pc |
pc_ctrl <= incr_pc; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= lbranch_state; |
|
when "1001" => -- daa |
op_ctrl <= latch_op; |
-- |
left_ctrl <= acca_left; |
right_ctrl <= accb_right; |
alu_ctrl <= alu_daa; |
cc_ctrl <= load_cc; |
acca_ctrl <= load_acca; |
sp_ctrl <= latch_sp; |
-- idle pc |
pc_ctrl <= latch_pc; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= fetch_state; |
|
when "1010" => -- orcc |
op_ctrl <= latch_op; |
acca_ctrl <= latch_acca; |
-- idle ALU |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
sp_ctrl <= latch_sp; |
-- increment the pc |
pc_ctrl <= incr_pc; |
-- next state |
st_ctrl <= push_st; |
return_state <= fetch_state; |
next_state <= orcc_state; |
|
when "1100" => -- andcc |
op_ctrl <= latch_op; |
acca_ctrl <= latch_acca; |
-- idle ALU |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
sp_ctrl <= latch_sp; |
-- increment the pc |
pc_ctrl <= incr_pc; |
-- |
st_ctrl <= push_st; |
return_state <= fetch_state; |
next_state <= andcc_state; |
|
when "1101" => -- sex |
op_ctrl <= latch_op; |
-- have sex |
left_ctrl <= accb_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_sex; |
cc_ctrl <= load_cc; |
acca_ctrl <= load_hi_acca; |
sp_ctrl <= latch_sp; |
-- idle PC |
pc_ctrl <= latch_pc; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= fetch_state; |
|
when "1110" => -- exg |
op_ctrl <= latch_op; |
acca_ctrl <= latch_acca; |
-- idle ALU |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
sp_ctrl <= latch_sp; |
-- increment the pc |
pc_ctrl <= incr_pc; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= exg_state; |
|
when "1111" => -- tfr |
op_ctrl <= latch_op; |
acca_ctrl <= latch_acca; |
-- idle ALU |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
sp_ctrl <= latch_sp; |
-- increment the pc |
pc_ctrl <= incr_pc; |
-- call transfer as a subroutine |
st_ctrl <= push_st; |
return_state <= fetch_state; |
next_state <= tfr_state; |
|
when others => |
op_ctrl <= latch_op; |
acca_ctrl <= latch_acca; |
-- idle ALU |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
sp_ctrl <= latch_sp; |
-- increment the pc |
pc_ctrl <= incr_pc; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= fetch_state; |
end case; |
-- |
-- Short branch conditional |
-- 6809 => always 3 cycles |
-- cpu09 => always = 3 cycles |
-- 1 op=(pc) / pc=pc+1 |
-- 2 md_hi=sign(pc) / md_lo=(pc) / pc=pc+1 / test cc |
-- 3 if cc tru pc=pc+md else pc=pc |
-- |
when "0010" => -- branch conditional |
op_ctrl <= latch_op; |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
sp_ctrl <= latch_sp; |
up_ctrl <= latch_up; |
iv_ctrl <= latch_iv; |
-- idle ALU |
left_ctrl <= pc_left; |
right_ctrl <= one_right; |
alu_ctrl <= alu_add16; |
cc_ctrl <= latch_cc; |
-- increment the pc |
pc_ctrl <= incr_pc; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= sbranch_state; |
-- |
-- Single byte stack operators |
-- Do not advance PC |
-- |
when "0011" => |
op_ctrl <= latch_op; |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
-- |
-- lea - load effective address (2+ bytes) |
-- 6809 => 4 cycles + addressing mode |
-- cpu09 => 4 cycles + addressing mode |
-- 1 op=(pc) / pc=pc+1 |
-- 2 md_lo=(pc) / pc=pc+1 |
-- 3 calculate ea |
-- 4 ix/iy/sp/up = ea |
-- |
case op_code(3 downto 0) is |
when "0000" | -- leax |
"0001" | -- leay |
"0010" | -- leas |
"0011" => -- leau |
left_ctrl <= pc_left; |
right_ctrl <= one_right; |
alu_ctrl <= alu_add16; |
cc_ctrl <= latch_cc; |
-- advance PC |
pc_ctrl <= incr_pc; |
-- |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
sp_ctrl <= latch_sp; |
up_ctrl <= latch_up; |
iv_ctrl <= latch_iv; |
-- |
st_ctrl <= push_st; |
return_state <= lea_state; |
next_state <= indexed_state; |
|
-- |
-- pshs - push registers onto sp stack |
-- 6809 => 5 cycles + registers |
-- cpu09 => 3 cycles + registers |
-- 1 op=(pc) / pc=pc+1 |
-- 2 ea_lo=(pc) / pc=pc+1 |
-- 3 if ea(7 downto 0) != "00000000" then sp=sp-1 |
-- 4 if ea(7) = 1 (sp)=pcl, sp=sp-1 |
-- 5 if ea(7) = 1 (sp)=pch |
-- if ea(6 downto 0) != "0000000" then sp=sp-1 |
-- 6 if ea(6) = 1 (sp)=upl, sp=sp-1 |
-- 7 if ea(6) = 1 (sp)=uph |
-- if ea(5 downto 0) != "000000" then sp=sp-1 |
-- 8 if ea(5) = 1 (sp)=iyl, sp=sp-1 |
-- 9 if ea(5) = 1 (sp)=iyh |
-- if ea(4 downto 0) != "00000" then sp=sp-1 |
-- 10 if ea(4) = 1 (sp)=ixl, sp=sp-1 |
-- 11 if ea(4) = 1 (sp)=ixh |
-- if ea(3 downto 0) != "0000" then sp=sp-1 |
-- 12 if ea(3) = 1 (sp)=dp |
-- if ea(2 downto 0) != "000" then sp=sp-1 |
-- 13 if ea(2) = 1 (sp)=accb |
-- if ea(1 downto 0) != "00" then sp=sp-1 |
-- 14 if ea(1) = 1 (sp)=acca |
-- if ea(0 downto 0) != "0" then sp=sp-1 |
-- 15 if ea(0) = 1 (sp)=cc |
-- |
when "0100" => -- pshs |
-- |
left_ctrl <= sp_left; |
right_ctrl <= one_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
-- advance PC |
pc_ctrl <= incr_pc; |
-- |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
sp_ctrl <= latch_sp; |
up_ctrl <= latch_up; |
iv_ctrl <= latch_iv; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= pshs_state; |
|
-- |
-- puls - pull registers of sp stack |
-- 6809 => 5 cycles + registers |
-- cpu09 => 3 cycles + registers |
-- |
when "0101" => -- puls |
left_ctrl <= pc_left; |
right_ctrl <= one_right; |
alu_ctrl <= alu_add16; |
cc_ctrl <= latch_cc; |
-- advance PC |
pc_ctrl <= incr_pc; |
-- |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
sp_ctrl <= latch_sp; |
up_ctrl <= latch_up; |
iv_ctrl <= latch_iv; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= puls_state; |
|
-- |
-- pshu - push registers onto up stack |
-- 6809 => 5 cycles + registers |
-- cpu09 => 3 cycles + registers |
-- |
when "0110" => -- pshu |
-- idle UP |
left_ctrl <= up_left; |
right_ctrl <= one_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
-- advance PC |
pc_ctrl <= incr_pc; |
-- |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
sp_ctrl <= latch_sp; |
up_ctrl <= latch_up; |
iv_ctrl <= latch_iv; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= pshu_state; |
|
-- |
-- pulu - pull registers of up stack |
-- 6809 => 5 cycles + registers |
-- cpu09 => 3 cycles + registers |
-- |
when "0111" => -- pulu |
left_ctrl <= pc_left; |
right_ctrl <= one_right; |
alu_ctrl <= alu_add16; |
cc_ctrl <= latch_cc; |
-- advance PC |
pc_ctrl <= incr_pc; |
-- |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
sp_ctrl <= latch_sp; |
up_ctrl <= latch_up; |
iv_ctrl <= latch_iv; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= pulu_state; |
|
-- |
-- rts - return from subroutine |
-- 6809 => 5 cycles |
-- cpu09 => 4 cycles |
-- 1 op=(pc) / pc=pc+1 |
-- 2 decode op |
-- 3 pc_hi = (sp) / sp=sp+1 |
-- 4 pc_lo = (sp) / sp=sp+1 |
-- |
when "1001" => |
left_ctrl <= sp_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
-- idle PC |
pc_ctrl <= latch_pc; |
-- |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
sp_ctrl <= latch_sp; |
up_ctrl <= latch_up; |
iv_ctrl <= latch_iv; |
-- |
st_ctrl <= push_st; |
return_state <= fetch_state; |
next_state <= pull_return_hi_state; |
|
-- |
-- abx - add accb to index register |
-- 6809 => 3 cycles |
-- cpu09 => 2 cycles |
-- 1 op=(pc) / pc=pc+1 |
-- 2 alu_left=ix / alu_right=accb / ix=alu_out / pc=pc |
-- |
when "1010" => -- abx |
left_ctrl <= ix_left; |
right_ctrl <= accb_right; |
alu_ctrl <= alu_add16; |
cc_ctrl <= latch_cc; |
ix_ctrl <= load_ix; |
-- |
pc_ctrl <= latch_pc; |
iy_ctrl <= latch_iy; |
sp_ctrl <= latch_sp; |
up_ctrl <= latch_up; |
iv_ctrl <= latch_iv; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= fetch_state; |
|
when "1011" => -- rti |
-- idle ALU |
left_ctrl <= sp_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
-- |
pc_ctrl <= latch_pc; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
sp_ctrl <= latch_sp; |
up_ctrl <= latch_up; |
iv_ctrl <= latch_iv; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= rti_cc_state; |
|
when "1100" => -- cwai |
-- pre decrement sp |
left_ctrl <= sp_left; |
right_ctrl <= one_right; |
alu_ctrl <= alu_sub16; |
cc_ctrl <= latch_cc; |
sp_ctrl <= load_sp; |
-- |
pc_ctrl <= latch_pc; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
iv_ctrl <= latch_iv; |
-- |
st_ctrl <= idle_st; |
return_state <= int_entire_state; -- set entire flag |
next_state <= andcc_state; |
|
when "1101" => -- mul |
left_ctrl <= acca_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
-- |
pc_ctrl <= latch_pc; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
sp_ctrl <= latch_sp; |
up_ctrl <= latch_up; |
iv_ctrl <= latch_iv; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= mul_state; |
|
when "1111" => -- swi |
-- predecrement SP |
left_ctrl <= sp_left; |
right_ctrl <= one_right; |
alu_ctrl <= alu_sub16; |
cc_ctrl <= latch_cc; |
sp_ctrl <= load_sp; |
-- |
pc_ctrl <= latch_pc; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
iv_ctrl <= swi_iv; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= int_entire_state; |
|
when others => |
-- idle ALU |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
-- idle PC |
pc_ctrl <= latch_pc; |
-- |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
sp_ctrl <= latch_sp; |
up_ctrl <= latch_up; |
iv_ctrl <= latch_iv; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= fetch_state; |
|
end case; |
-- |
-- Accumulator A Single operand |
-- source = acca, dest = acca |
-- Do not advance PC |
-- Typically 2 cycles 1 bytes |
-- 1 opcode fetch |
-- 2 post byte fetch / instruction decode |
-- Note that there is no post byte |
-- so do not advance PC in decode cycle |
-- Re-run opcode fetch cycle after decode |
-- |
when "0100" => -- acca single op |
op_ctrl <= latch_op; |
accb_ctrl <= latch_accb; |
pc_ctrl <= latch_pc; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
iv_ctrl <= latch_iv; |
left_ctrl <= acca_left; |
case op_code(3 downto 0) is |
when "0000" => -- neg |
right_ctrl <= zero_right; |
alu_ctrl <= alu_neg; |
acca_ctrl <= load_acca; |
cc_ctrl <= load_cc; |
when "0011" => -- com |
right_ctrl <= zero_right; |
alu_ctrl <= alu_com; |
acca_ctrl <= load_acca; |
cc_ctrl <= load_cc; |
when "0100" => -- lsr |
right_ctrl <= zero_right; |
alu_ctrl <= alu_lsr8; |
acca_ctrl <= load_acca; |
cc_ctrl <= load_cc; |
when "0110" => -- ror |
right_ctrl <= zero_right; |
alu_ctrl <= alu_ror8; |
acca_ctrl <= load_acca; |
cc_ctrl <= load_cc; |
when "0111" => -- asr |
right_ctrl <= zero_right; |
alu_ctrl <= alu_asr8; |
acca_ctrl <= load_acca; |
cc_ctrl <= load_cc; |
when "1000" => -- asl |
right_ctrl <= zero_right; |
alu_ctrl <= alu_asl8; |
acca_ctrl <= load_acca; |
cc_ctrl <= load_cc; |
when "1001" => -- rol |
right_ctrl <= zero_right; |
alu_ctrl <= alu_rol8; |
acca_ctrl <= load_acca; |
cc_ctrl <= load_cc; |
when "1010" => -- dec |
right_ctrl <= one_right; |
alu_ctrl <= alu_dec; |
acca_ctrl <= load_acca; |
cc_ctrl <= load_cc; |
when "1011" => -- undefined |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
acca_ctrl <= latch_acca; |
cc_ctrl <= latch_cc; |
when "1100" => -- inc |
right_ctrl <= one_right; |
alu_ctrl <= alu_inc; |
acca_ctrl <= load_acca; |
cc_ctrl <= load_cc; |
when "1101" => -- tst |
right_ctrl <= zero_right; |
alu_ctrl <= alu_st8; |
acca_ctrl <= latch_acca; |
cc_ctrl <= load_cc; |
when "1110" => -- jmp |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
acca_ctrl <= latch_acca; |
cc_ctrl <= latch_cc; |
when "1111" => -- clr |
right_ctrl <= zero_right; |
alu_ctrl <= alu_ld8; |
acca_ctrl <= load_acca; |
cc_ctrl <= load_cc; |
when others => |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
acca_ctrl <= latch_acca; |
cc_ctrl <= latch_cc; |
end case; |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= fetch_state; |
-- |
-- Single Operand accb |
-- source = accb, dest = accb |
-- Typically 2 cycles 1 bytes |
-- 1 opcode fetch |
-- 2 post byte fetch / instruction decode |
-- Note that there is no post byte |
-- so do not advance PC in decode cycle |
-- Re-run opcode fetch cycle after decode |
-- |
when "0101" => |
op_ctrl <= latch_op; |
acca_ctrl <= latch_acca; |
pc_ctrl <= latch_pc; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
iv_ctrl <= latch_iv; |
left_ctrl <= accb_left; |
case op_code(3 downto 0) is |
when "0000" => -- neg |
right_ctrl <= zero_right; |
alu_ctrl <= alu_neg; |
accb_ctrl <= load_accb; |
cc_ctrl <= load_cc; |
when "0011" => -- com |
right_ctrl <= zero_right; |
alu_ctrl <= alu_com; |
accb_ctrl <= load_accb; |
cc_ctrl <= load_cc; |
when "0100" => -- lsr |
right_ctrl <= zero_right; |
alu_ctrl <= alu_lsr8; |
accb_ctrl <= load_accb; |
cc_ctrl <= load_cc; |
when "0110" => -- ror |
right_ctrl <= zero_right; |
alu_ctrl <= alu_ror8; |
accb_ctrl <= load_accb; |
cc_ctrl <= load_cc; |
when "0111" => -- asr |
right_ctrl <= zero_right; |
alu_ctrl <= alu_asr8; |
accb_ctrl <= load_accb; |
cc_ctrl <= load_cc; |
when "1000" => -- asl |
right_ctrl <= zero_right; |
alu_ctrl <= alu_asl8; |
accb_ctrl <= load_accb; |
cc_ctrl <= load_cc; |
when "1001" => -- rol |
right_ctrl <= zero_right; |
alu_ctrl <= alu_rol8; |
accb_ctrl <= load_accb; |
cc_ctrl <= load_cc; |
when "1010" => -- dec |
right_ctrl <= one_right; |
alu_ctrl <= alu_dec; |
accb_ctrl <= load_accb; |
cc_ctrl <= load_cc; |
when "1011" => -- undefined |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
accb_ctrl <= latch_accb; |
cc_ctrl <= latch_cc; |
when "1100" => -- inc |
right_ctrl <= one_right; |
alu_ctrl <= alu_inc; |
accb_ctrl <= load_accb; |
cc_ctrl <= load_cc; |
when "1101" => -- tst |
right_ctrl <= zero_right; |
alu_ctrl <= alu_st8; |
accb_ctrl <= latch_accb; |
cc_ctrl <= load_cc; |
when "1110" => -- jmp |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
accb_ctrl <= latch_accb; |
cc_ctrl <= latch_cc; |
when "1111" => -- clr |
right_ctrl <= zero_right; |
alu_ctrl <= alu_ld8; |
accb_ctrl <= load_accb; |
cc_ctrl <= load_cc; |
when others => |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
accb_ctrl <= latch_accb; |
cc_ctrl <= latch_cc; |
end case; |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= fetch_state; |
-- |
-- Single operand indexed |
-- Two byte instruction so advance PC |
-- EA should hold index offset |
-- |
when "0110" => -- indexed single op |
op_ctrl <= latch_op; |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
iv_ctrl <= latch_iv; |
-- idle ALU |
left_ctrl <= pc_left; |
right_ctrl <= one_right; |
alu_ctrl <= alu_add16; |
cc_ctrl <= latch_cc; |
-- increment the pc |
pc_ctrl <= incr_pc; |
-- next state |
case op_code(3 downto 0) is |
when "1110" => -- jmp |
return_state <= jmp_state; |
when "1111" => -- clr |
return_state <= single_op_exec_state; |
when others => |
return_state <= single_op_read_state; |
end case; |
st_ctrl <= push_st; |
next_state <= indexed_state; |
-- |
-- Single operand extended addressing |
-- three byte instruction so advance the PC |
-- Low order EA holds high order address |
-- |
when "0111" => -- extended single op |
op_ctrl <= latch_op; |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
iv_ctrl <= latch_iv; |
-- idle ALU |
left_ctrl <= pc_left; |
right_ctrl <= one_right; |
alu_ctrl <= alu_add16; |
cc_ctrl <= latch_cc; |
-- increment PC |
pc_ctrl <= incr_pc; |
-- |
case op_code(3 downto 0) is |
when "1110" => -- jmp |
return_state <= jmp_state; |
when "1111" => -- clr |
return_state <= single_op_exec_state; |
when others => |
return_state <= single_op_read_state; |
end case; |
st_ctrl <= push_st; |
next_state <= extended_state; |
|
when "1000" => -- acca immediate |
op_ctrl <= latch_op; |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
iv_ctrl <= latch_iv; |
-- increment the pc |
pc_ctrl <= incr_pc; |
case op_code(3 downto 0) is |
when "0011" | -- subd # |
"1100" | -- cmpx # |
"1110" => -- ldx # |
-- idle ALU |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_add16; |
cc_ctrl <= latch_cc; |
sp_ctrl <= latch_sp; |
-- |
st_ctrl <= push_st; |
return_state <= fetch_state; |
next_state <= imm16_state; |
|
-- |
-- bsr offset - Branch to subroutine (2 bytes) |
-- 6809 => 7 cycles |
-- cpu09 => 5 cycles |
-- 1 op=(pc) / pc=pc+1 |
-- 2 md_hi=sign(pc) / md_lo=(pc) / sp=sp-1 / pc=pc+1 |
-- 3 (sp)=pc_lo / sp=sp-1 |
-- 4 (sp)=pc_hi |
-- 5 pc=pc+md |
-- |
when "1101" => -- bsr |
-- pre decrement SP |
left_ctrl <= sp_left; |
right_ctrl <= one_right; |
alu_ctrl <= alu_sub16; |
cc_ctrl <= latch_cc; |
sp_ctrl <= load_sp; |
-- |
st_ctrl <= push_st; |
return_state <= sbranch_state; |
next_state <= push_return_lo_state; |
|
when others => |
-- idle ALU |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_add16; |
cc_ctrl <= latch_cc; |
sp_ctrl <= latch_sp; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= fetch_state; |
end case; |
|
when "1001" => -- acca direct |
op_ctrl <= latch_op; |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
iv_ctrl <= latch_iv; |
-- increment the pc |
pc_ctrl <= incr_pc; |
case op_code(3 downto 0) is |
when "0011" | -- subd |
"1100" | -- cmpx |
"1110" => -- ldx |
-- idle ALU |
left_ctrl <= pc_left; |
right_ctrl <= one_right; |
alu_ctrl <= alu_add16; |
cc_ctrl <= latch_cc; |
sp_ctrl <= latch_sp; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= dual_op_read16_state; |
|
when "0111" => -- sta direct |
-- idle ALU |
left_ctrl <= acca_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
sp_ctrl <= latch_sp; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= dual_op_write8_state; |
|
when "1111" => -- stx direct |
-- idle ALU |
left_ctrl <= ix_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
sp_ctrl <= latch_sp; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= dual_op_write16_state; |
|
-- |
-- jsr direct - Jump to subroutine in direct page (2 bytes) |
-- 6809 => 7 cycles |
-- cpu09 => 5 cycles |
-- 1 op=(pc) / pc=pc+1 |
-- 2 ea_hi=0 / ea_lo=(pc) / sp=sp-1 / pc=pc+1 |
-- 3 (sp)=pc_lo / sp=sp-1 |
-- 4 (sp)=pc_hi |
-- 5 pc=ea |
-- |
when "1101" => -- jsr direct |
-- pre decrement sp |
left_ctrl <= sp_left; |
right_ctrl <= one_right; |
alu_ctrl <= alu_sub16; |
cc_ctrl <= latch_cc; |
sp_ctrl <= load_sp; |
-- |
st_ctrl <= push_st; |
return_state <= jmp_state; |
next_state <= push_return_lo_state; |
|
when others => |
-- idle ALU |
left_ctrl <= acca_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
sp_ctrl <= latch_sp; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= dual_op_read8_state; |
end case; |
|
when "1010" => -- acca indexed |
op_ctrl <= latch_op; |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
iv_ctrl <= latch_iv; |
-- increment the pc |
pc_ctrl <= incr_pc; |
case op_code(3 downto 0) is |
when "0011" | -- subd |
"1100" | -- cmpx |
"1110" => -- ldx |
-- idle ALU |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_add16; |
cc_ctrl <= latch_cc; |
sp_ctrl <= latch_sp; |
-- |
st_ctrl <= push_st; |
return_state <= dual_op_read16_state; |
next_state <= indexed_state; |
|
when "0111" => -- staa ,x |
-- idle ALU |
left_ctrl <= acca_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
sp_ctrl <= latch_sp; |
-- |
st_ctrl <= push_st; |
return_state <= dual_op_write8_state; |
next_state <= indexed_state; |
|
when "1111" => -- stx ,x |
-- idle ALU |
left_ctrl <= ix_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
sp_ctrl <= latch_sp; |
-- |
st_ctrl <= push_st; |
return_state <= dual_op_write16_state; |
next_state <= indexed_state; |
|
when "1101" => -- jsr ,x |
-- pre decrement SP |
left_ctrl <= sp_left; |
right_ctrl <= one_right; |
alu_ctrl <= alu_sub16; |
cc_ctrl <= latch_cc; |
sp_ctrl <= load_sp; |
-- |
st_ctrl <= push_st; |
return_state <= jsr_state; |
next_state <= indexed_state; |
|
when others => |
-- idle ALU |
left_ctrl <= pc_left; |
right_ctrl <= one_right; |
alu_ctrl <= alu_add16; |
cc_ctrl <= latch_cc; |
sp_ctrl <= latch_sp; |
-- |
st_ctrl <= push_st; |
return_state <= dual_op_read8_state; |
next_state <= indexed_state; |
end case; |
|
when "1011" => -- acca extended |
op_ctrl <= latch_op; |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
iv_ctrl <= latch_iv; |
-- increment the pc |
pc_ctrl <= incr_pc; |
case op_code(3 downto 0) is |
when "0011" | -- subd |
"1100" | -- cmpx |
"1110" => -- ldx |
-- idle ALU |
left_ctrl <= pc_left; |
right_ctrl <= one_right; |
alu_ctrl <= alu_add16; |
cc_ctrl <= latch_cc; |
sp_ctrl <= latch_sp; |
-- |
st_ctrl <= push_st; |
return_state <= dual_op_read16_state; |
next_state <= extended_state; |
|
when "0111" => -- staa > |
-- idle ALU |
left_ctrl <= acca_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
sp_ctrl <= latch_sp; |
-- |
st_ctrl <= push_st; |
return_state <= dual_op_write8_state; |
next_state <= extended_state; |
|
when "1111" => -- stx > |
-- idle ALU |
left_ctrl <= ix_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
sp_ctrl <= latch_sp; |
-- |
st_ctrl <= push_st; |
return_state <= dual_op_write16_state; |
next_state <= extended_state; |
|
when "1101" => -- jsr >extended |
-- pre decrement sp |
left_ctrl <= sp_left; |
right_ctrl <= one_right; |
alu_ctrl <= alu_sub16; |
cc_ctrl <= latch_cc; |
sp_ctrl <= load_sp; |
-- |
st_ctrl <= push_st; |
return_state <= jsr_state; |
next_state <= extended_state; |
|
when others => |
-- idle ALU |
left_ctrl <= acca_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_st8; |
cc_ctrl <= latch_cc; |
sp_ctrl <= latch_sp; |
-- |
st_ctrl <= push_st; |
return_state <= dual_op_read8_state; |
next_state <= extended_state; |
end case; |
|
when "1100" => -- accb immediate |
op_ctrl <= latch_op; |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
iv_ctrl <= latch_iv; |
-- |
left_ctrl <= pc_left; |
right_ctrl <= one_right; |
alu_ctrl <= alu_add16; |
cc_ctrl <= latch_cc; |
-- increment the pc |
pc_ctrl <= incr_pc; |
case op_code(3 downto 0) is |
when "0011" | -- addd # |
"1100" | -- ldd # |
"1110" => -- ldu # |
st_ctrl <= push_st; |
return_state <= fetch_state; |
next_state <= imm16_state; |
|
when others => |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= fetch_state; |
|
end case; |
|
|
when "1101" => -- accb direct |
op_ctrl <= latch_op; |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
iv_ctrl <= latch_iv; |
-- increment the pc |
pc_ctrl <= incr_pc; |
-- |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
-- |
case op_code(3 downto 0) is |
when "0011" | -- addd |
"1100" | -- ldd |
"1110" => -- ldu |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= dual_op_read16_state; |
|
when "0111" => -- stab direct |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= dual_op_write8_state; |
|
when "1101" => -- std direct |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= dual_op_write16_state; |
|
when "1111" => -- stu direct |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= dual_op_write16_state; |
|
when others => |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= dual_op_read8_state; |
end case; |
|
when "1110" => -- accb indexed |
op_ctrl <= latch_op; |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
iv_ctrl <= latch_iv; |
-- increment the pc |
pc_ctrl <= incr_pc; |
-- |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
-- |
case op_code(3 downto 0) is |
when "0011" | -- addd |
"1100" | -- ldd |
"1110" => -- ldu |
st_ctrl <= push_st; |
return_state <= dual_op_read16_state; |
next_state <= indexed_state; |
|
when "0111" => -- stab indexed |
st_ctrl <= push_st; |
return_state <= dual_op_write8_state; |
next_state <= indexed_state; |
|
when "1101" => -- std indexed |
st_ctrl <= push_st; |
return_state <= dual_op_write16_state; |
next_state <= indexed_state; |
|
when "1111" => -- stu indexed |
st_ctrl <= push_st; |
return_state <= dual_op_write16_state; |
next_state <= indexed_state; |
|
when others => |
st_ctrl <= push_st; |
return_state <= dual_op_read8_state; |
next_state <= indexed_state; |
end case; |
|
when "1111" => -- accb extended |
op_ctrl <= latch_op; |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
iv_ctrl <= latch_iv; |
-- increment the pc |
pc_ctrl <= incr_pc; |
-- |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
-- |
case op_code(3 downto 0) is |
when "0011" | -- addd |
"1100" | -- ldd |
"1110" => -- ldu |
st_ctrl <= push_st; |
return_state <= dual_op_read16_state; |
next_state <= extended_state; |
|
when "0111" => -- stab extended |
st_ctrl <= push_st; |
return_state <= dual_op_write8_state; |
next_state <= extended_state; |
|
when "1101" => -- std extended |
st_ctrl <= push_st; |
return_state <= dual_op_write16_state; |
next_state <= extended_state; |
|
when "1111" => -- stu extended |
st_ctrl <= push_st; |
return_state <= dual_op_write16_state; |
next_state <= extended_state; |
|
when others => |
st_ctrl <= push_st; |
return_state <= dual_op_read8_state; |
next_state <= extended_state; |
end case; |
|
when others => |
op_ctrl <= latch_op; |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
iv_ctrl <= latch_iv; |
-- idle the ALU |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
-- idle the pc |
pc_ctrl <= latch_pc; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= fetch_state; |
end case; |
|
-- |
-- Here to decode prefix 2 instruction |
-- and fetch next byte of intruction |
-- whether it be necessary or not |
-- |
when decode2_state => |
op_ctrl <= latch_op; |
pre_ctrl <= latch_pre; |
-- fetch first byte of address or immediate data |
ea_ctrl <= fetch_first_ea; |
md_ctrl <= fetch_first_md; |
addr_ctrl <= fetch_ad; |
dout_ctrl <= md_lo_dout; |
nmi_ctrl <= latch_nmi; |
dp_ctrl <= latch_dp; |
case op_code(7 downto 4) is |
-- |
-- lbcc -- long branch conditional |
-- 6809 => branch 6 cycles, no branch 5 cycles |
-- cpu09 => always 5 cycles |
-- 1 pre=(pc) / pc=pc+1 |
-- 2 op=(pc) / pc=pc+1 |
-- 3 md_hi=sign(pc) / md_lo=(pc) / pc=pc+1 |
-- 4 md_hi=md_lo / md_lo=(pc) / pc=pc+1 |
-- 5 if cond pc=pc+md else pc=pc |
-- |
when "0010" => |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
sp_ctrl <= latch_sp; |
up_ctrl <= latch_up; |
iv_ctrl <= latch_iv; |
-- increment the pc |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
pc_ctrl <= incr_pc; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= lbranch_state; |
|
-- |
-- Single byte stack operators |
-- Do not advance PC |
-- |
when "0011" => |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
pc_ctrl <= latch_pc; |
case op_code(3 downto 0) is |
when "1111" => -- swi 2 |
-- predecrement sp |
left_ctrl <= sp_left; |
right_ctrl <= one_right; |
alu_ctrl <= alu_sub16; |
cc_ctrl <= latch_cc; |
sp_ctrl <= load_sp; |
iv_ctrl <= swi2_iv; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= int_entire_state; |
|
when others => |
left_ctrl <= sp_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
sp_ctrl <= latch_sp; |
iv_ctrl <= latch_iv; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= fetch_state; |
end case; |
|
when "1000" => -- acca immediate |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
iv_ctrl <= latch_iv; |
-- Idle the ALU |
left_ctrl <= pc_left; |
right_ctrl <= one_right; |
alu_ctrl <= alu_add16; |
cc_ctrl <= latch_cc; |
-- increment the pc |
pc_ctrl <= incr_pc; |
case op_code(3 downto 0) is |
when "0011" | -- cmpd # |
"1100" | -- cmpy # |
"1110" => -- ldy # |
st_ctrl <= push_st; |
return_state <= fetch_state; |
next_state <= imm16_state; |
|
when others => |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= fetch_state; |
|
end case; |
|
when "1001" => -- acca direct |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
iv_ctrl <= latch_iv; |
-- idle the ALU |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
-- increment the pc |
pc_ctrl <= incr_pc; |
case op_code(3 downto 0) is |
when "0011" | -- cmpd < |
"1100" | -- cmpy < |
"1110" => -- ldy < |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= dual_op_read16_state; |
|
when "1111" => -- sty < |
st_ctrl <= push_st; |
return_state <= fetch_state; |
next_state <= dual_op_write16_state; |
|
when others => |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= fetch_state; |
|
end case; |
|
when "1010" => -- acca indexed |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
iv_ctrl <= latch_iv; |
-- idle the ALU |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
-- increment the pc |
pc_ctrl <= incr_pc; |
case op_code(3 downto 0) is |
when "0011" | -- cmpd ,ind |
"1100" | -- cmpy ,ind |
"1110" => -- ldy ,ind |
st_ctrl <= push_st; |
return_state <= dual_op_read16_state; |
next_state <= indexed_state; |
|
when "1111" => -- sty ,ind |
st_ctrl <= push_st; |
return_state <= dual_op_write16_state; |
next_state <= indexed_state; |
|
when others => |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= fetch_state; |
end case; |
|
when "1011" => -- acca extended |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
iv_ctrl <= latch_iv; |
-- idle the ALU |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
-- increment the pc |
pc_ctrl <= incr_pc; |
case op_code(3 downto 0) is |
when "0011" | -- cmpd < |
"1100" | -- cmpy < |
"1110" => -- ldy < |
st_ctrl <= push_st; |
return_state <= dual_op_read16_state; |
next_state <= extended_state; |
|
when "1111" => -- sty > |
st_ctrl <= push_st; |
return_state <= dual_op_write16_state; |
next_state <= extended_state; |
|
when others => |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= fetch_state; |
|
end case; |
|
when "1100" => -- accb immediate |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
iv_ctrl <= latch_iv; |
-- idle the alu |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
-- increment the pc |
pc_ctrl <= incr_pc; |
case op_code(3 downto 0) is |
when "0011" | -- undef # |
"1100" | -- undef # |
"1110" => -- lds # |
st_ctrl <= push_st; |
return_state <= fetch_state; |
next_state <= imm16_state; |
|
when others => |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= fetch_state; |
|
end case; |
|
when "1101" => -- accb direct |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
iv_ctrl <= latch_iv; |
-- idle the alu |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
-- increment the pc |
pc_ctrl <= incr_pc; |
case op_code(3 downto 0) is |
when "0011" | -- undef < |
"1100" | -- undef < |
"1110" => -- lds < |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= dual_op_read16_state; |
|
when "1111" => -- sts < |
st_ctrl <= push_st; |
return_state <= fetch_state; |
next_state <= dual_op_write16_state; |
|
when others => |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= fetch_state; |
|
end case; |
|
when "1110" => -- accb indexed |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
md_ctrl <= latch_md; |
iv_ctrl <= latch_iv; |
-- idle the alu |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
-- increment the pc |
pc_ctrl <= incr_pc; |
case op_code(3 downto 0) is |
when "0011" | -- undef ,ind |
"1100" | -- undef ,ind |
"1110" => -- lds ,ind |
st_ctrl <= push_st; |
return_state <= dual_op_read16_state; |
next_state <= indexed_state; |
|
when "1111" => -- sts ,ind |
st_ctrl <= push_st; |
return_state <= dual_op_write16_state; |
next_state <= indexed_state; |
|
when others => |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= fetch_state; |
|
end case; |
|
when "1111" => -- accb extended |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
iv_ctrl <= latch_iv; |
-- idle the alu |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
-- increment the pc |
pc_ctrl <= incr_pc; |
case op_code(3 downto 0) is |
when "0011" | -- undef > |
"1100" | -- undef > |
"1110" => -- lds > |
st_ctrl <= push_st; |
return_state <= dual_op_read16_state; |
next_state <= extended_state; |
|
when "1111" => -- sts > |
st_ctrl <= push_st; |
return_state <= dual_op_write16_state; |
next_state <= extended_state; |
|
when others => |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= fetch_state; |
|
end case; |
|
when others => |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
iv_ctrl <= latch_iv; |
-- idle the alu |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
-- idle the pc |
pc_ctrl <= latch_pc; |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= fetch_state; |
end case; |
-- |
-- Here to decode instruction |
-- and fetch next byte of intruction |
-- whether it be necessary or not |
-- |
when decode3_state => |
op_ctrl <= latch_op; |
pre_ctrl <= latch_pre; |
ea_ctrl <= fetch_first_ea; |
md_ctrl <= fetch_first_md; |
addr_ctrl <= fetch_ad; |
dout_ctrl <= md_lo_dout; |
nmi_ctrl <= latch_nmi; |
dp_ctrl <= latch_dp; |
case op_code(7 downto 4) is |
-- |
-- Single byte stack operators |
-- Do not advance PC |
-- |
when "0011" => |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
pc_ctrl <= latch_pc; |
-- |
case op_code(3 downto 0) is |
when "1111" => -- swi3 |
-- predecrement sp |
left_ctrl <= sp_left; |
right_ctrl <= one_right; |
alu_ctrl <= alu_sub16; |
cc_ctrl <= latch_cc; |
sp_ctrl <= load_sp; |
iv_ctrl <= swi3_iv; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= int_entire_state; |
when others => |
left_ctrl <= sp_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
sp_ctrl <= latch_sp; |
iv_ctrl <= latch_iv; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= fetch_state; |
end case; |
|
when "1000" => -- acca immediate |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
iv_ctrl <= latch_iv; |
-- idle the alu |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
-- increment the pc |
pc_ctrl <= incr_pc; |
case op_code(3 downto 0) is |
when "0011" | -- cmpu # |
"1100" | -- cmps # |
"1110" => -- undef # |
st_ctrl <= push_st; |
return_state <= fetch_state; |
next_state <= imm16_state; |
when others => |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= fetch_state; |
end case; |
|
when "1001" => -- acca direct |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
iv_ctrl <= latch_iv; |
-- idle the alu |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
-- increment the pc |
pc_ctrl <= incr_pc; |
case op_code(3 downto 0) is |
when "0011" | -- cmpu < |
"1100" | -- cmps < |
"1110" => -- undef < |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= dual_op_read16_state; |
|
when others => |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= fetch_state; |
|
end case; |
|
when "1010" => -- acca indexed |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
iv_ctrl <= latch_iv; |
-- idle the alu |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
-- increment the pc |
pc_ctrl <= incr_pc; |
case op_code(3 downto 0) is |
when "0011" | -- cmpu ,X |
"1100" | -- cmps ,X |
"1110" => -- undef ,X |
st_ctrl <= push_st; |
return_state <= dual_op_read16_state; |
next_state <= indexed_state; |
|
when others => |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= fetch_state; |
|
end case; |
|
when "1011" => -- acca extended |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
iv_ctrl <= latch_iv; |
-- idle the alu |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
-- increment the pc |
pc_ctrl <= incr_pc; |
case op_code(3 downto 0) is |
when "0011" | -- cmpu > |
"1100" | -- cmps > |
"1110" => -- undef > |
st_ctrl <= push_st; |
return_state <= dual_op_read16_state; |
next_state <= extended_state; |
when others => |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= fetch_state; |
end case; |
|
when others => |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
iv_ctrl <= latch_iv; |
-- idle the alu |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
-- idle the pc |
pc_ctrl <= latch_pc; |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= fetch_state; |
end case; |
|
-- |
-- here if ea holds low byte |
-- Direct |
-- Extended |
-- Indexed |
-- read memory location |
-- |
when single_op_read_state => |
op_ctrl <= latch_op; |
pre_ctrl <= latch_pre; |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
pc_ctrl <= latch_pc; |
iv_ctrl <= latch_iv; |
dp_ctrl <= latch_dp; |
nmi_ctrl <= latch_nmi; |
-- idle ALU |
left_ctrl <= ea_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
ea_ctrl <= latch_ea; |
-- read memory into md |
md_ctrl <= fetch_first_md; |
addr_ctrl <= read_ad; |
dout_ctrl <= md_lo_dout; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= single_op_exec_state; |
|
when single_op_exec_state => |
op_ctrl <= latch_op; |
pre_ctrl <= latch_pre; |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
dp_ctrl <= latch_dp; |
nmi_ctrl <= latch_nmi; |
iv_ctrl <= latch_iv; |
ea_ctrl <= latch_ea; |
-- idle the bus |
addr_ctrl <= idle_ad; |
dout_ctrl <= md_lo_dout; |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
case op_code(3 downto 0) is |
when "0000" => -- neg |
left_ctrl <= md_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_neg; |
cc_ctrl <= load_cc; |
md_ctrl <= load_md; |
pc_ctrl <= latch_pc; |
next_state <= single_op_write_state; |
when "0011" => -- com |
left_ctrl <= md_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_com; |
cc_ctrl <= load_cc; |
md_ctrl <= load_md; |
pc_ctrl <= latch_pc; |
next_state <= single_op_write_state; |
when "0100" => -- lsr |
left_ctrl <= md_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_lsr8; |
cc_ctrl <= load_cc; |
md_ctrl <= load_md; |
pc_ctrl <= latch_pc; |
next_state <= single_op_write_state; |
when "0110" => -- ror |
left_ctrl <= md_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_ror8; |
cc_ctrl <= load_cc; |
md_ctrl <= load_md; |
pc_ctrl <= latch_pc; |
next_state <= single_op_write_state; |
when "0111" => -- asr |
left_ctrl <= md_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_asr8; |
cc_ctrl <= load_cc; |
md_ctrl <= load_md; |
pc_ctrl <= latch_pc; |
next_state <= single_op_write_state; |
when "1000" => -- asl |
left_ctrl <= md_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_asl8; |
cc_ctrl <= load_cc; |
md_ctrl <= load_md; |
pc_ctrl <= latch_pc; |
next_state <= single_op_write_state; |
when "1001" => -- rol |
left_ctrl <= md_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_rol8; |
cc_ctrl <= load_cc; |
md_ctrl <= load_md; |
pc_ctrl <= latch_pc; |
next_state <= single_op_write_state; |
when "1010" => -- dec |
left_ctrl <= md_left; |
right_ctrl <= one_right; |
alu_ctrl <= alu_dec; |
cc_ctrl <= load_cc; |
md_ctrl <= load_md; |
pc_ctrl <= latch_pc; |
next_state <= single_op_write_state; |
when "1011" => -- undefined |
left_ctrl <= md_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
md_ctrl <= latch_md; |
pc_ctrl <= latch_pc; |
next_state <= fetch_state; |
when "1100" => -- inc |
left_ctrl <= md_left; |
right_ctrl <= one_right; |
alu_ctrl <= alu_inc; |
cc_ctrl <= load_cc; |
md_ctrl <= load_md; |
pc_ctrl <= latch_pc; |
next_state <= single_op_write_state; |
when "1101" => -- tst |
left_ctrl <= md_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_st8; |
cc_ctrl <= load_cc; |
md_ctrl <= latch_md; |
pc_ctrl <= latch_pc; |
next_state <= fetch_state; |
when "1110" => -- jmp |
left_ctrl <= md_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_ld16; |
cc_ctrl <= latch_cc; |
md_ctrl <= latch_md; |
pc_ctrl <= load_pc; |
next_state <= fetch_state; |
when "1111" => -- clr |
left_ctrl <= md_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_ld8; |
cc_ctrl <= load_cc; |
md_ctrl <= load_md; |
pc_ctrl <= latch_pc; |
next_state <= single_op_write_state; |
when others => |
left_ctrl <= md_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
md_ctrl <= latch_md; |
pc_ctrl <= latch_pc; |
next_state <= fetch_state; |
end case; |
-- |
-- single operand 8 bit write |
-- Write low 8 bits of ALU output |
-- EA holds address |
-- MD holds data |
-- |
when single_op_write_state => |
op_ctrl <= latch_op; |
pre_ctrl <= latch_pre; |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
pc_ctrl <= latch_pc; |
md_ctrl <= latch_md; |
iv_ctrl <= latch_iv; |
dp_ctrl <= latch_dp; |
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; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= fetch_state; |
|
-- |
-- here if ea holds address of low byte |
-- read memory location |
-- |
when dual_op_read8_state => |
op_ctrl <= latch_op; |
pre_ctrl <= latch_pre; |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
pc_ctrl <= latch_pc; |
iv_ctrl <= latch_iv; |
dp_ctrl <= latch_dp; |
nmi_ctrl <= latch_nmi; |
left_ctrl <= ea_left; |
-- Leave the ea alone |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
ea_ctrl <= latch_ea; |
-- read first data byte from ea |
md_ctrl <= fetch_first_md; |
addr_ctrl <= read_ad; |
dout_ctrl <= md_lo_dout; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= fetch_state; |
|
-- |
-- Here to read a 16 bit value into MD |
-- pointed to by the EA register |
-- The first byte is read |
-- and the EA is incremented |
-- |
when dual_op_read16_state => |
op_ctrl <= latch_op; |
pre_ctrl <= latch_pre; |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
cc_ctrl <= latch_cc; |
dp_ctrl <= latch_dp; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
pc_ctrl <= latch_pc; |
iv_ctrl <= latch_iv; |
nmi_ctrl <= latch_nmi; |
-- increment the effective address |
left_ctrl <= ea_left; |
right_ctrl <= one_right; |
alu_ctrl <= alu_add16; |
ea_ctrl <= load_ea; |
-- read the low byte of the 16 bit data |
md_ctrl <= fetch_first_md; |
addr_ctrl <= read_ad; |
dout_ctrl <= md_lo_dout; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= dual_op_read16_2_state; |
|
-- |
-- here to read the second byte |
-- pointed to by EA into MD |
-- |
when dual_op_read16_2_state => |
op_ctrl <= latch_op; |
pre_ctrl <= latch_pre; |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
cc_ctrl <= latch_cc; |
dp_ctrl <= latch_dp; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
pc_ctrl <= latch_pc; |
iv_ctrl <= latch_iv; |
nmi_ctrl <= latch_nmi; |
-- idle the effective address |
left_ctrl <= ea_left; |
right_ctrl <= one_right; |
alu_ctrl <= alu_nop; |
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; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= fetch_state; |
|
-- |
-- 16 bit Write state |
-- EA hold address of memory to write to |
-- Advance the effective address in ALU |
-- decode op_code to determine which |
-- register to write |
-- |
when dual_op_write16_state => |
op_ctrl <= latch_op; |
pre_ctrl <= latch_pre; |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
pc_ctrl <= latch_pc; |
md_ctrl <= latch_md; |
iv_ctrl <= latch_iv; |
dp_ctrl <= latch_dp; |
nmi_ctrl <= latch_nmi; |
-- increment the effective address |
left_ctrl <= ea_left; |
right_ctrl <= one_right; |
alu_ctrl <= alu_add16; |
cc_ctrl <= latch_cc; |
ea_ctrl <= load_ea; |
-- write the ALU hi byte at ea |
addr_ctrl <= write_ad; |
if op_code(6) = '0' then |
case op_code(3 downto 0) is |
when "1111" => -- stx / sty |
case pre_code is |
when "00010000" => -- page 2 -- sty |
dout_ctrl <= iy_hi_dout; |
when others => -- page 1 -- stx |
dout_ctrl <= ix_hi_dout; |
end case; |
when others => |
dout_ctrl <= md_hi_dout; |
end case; |
else |
case op_code(3 downto 0) is |
when "1101" => -- std |
dout_ctrl <= acca_dout; -- acca is high byte of ACCD |
when "1111" => -- stu / sts |
case pre_code is |
when "00010000" => -- page 2 -- sts |
dout_ctrl <= sp_hi_dout; |
when others => -- page 1 -- stu |
dout_ctrl <= up_hi_dout; |
end case; |
when others => |
dout_ctrl <= md_hi_dout; |
end case; |
end if; |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= dual_op_write8_state; |
|
-- |
-- Dual operand 8 bit write |
-- Write 8 bit accumulator |
-- or low byte of 16 bit register |
-- EA holds address |
-- decode opcode to determine |
-- which register to apply to the bus |
-- Also set the condition codes here |
-- |
when dual_op_write8_state => |
op_ctrl <= latch_op; |
pre_ctrl <= latch_pre; |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
pc_ctrl <= latch_pc; |
iv_ctrl <= latch_iv; |
dp_ctrl <= latch_dp; |
nmi_ctrl <= latch_nmi; |
md_ctrl <= latch_md; |
-- idle ALU |
left_ctrl <= ea_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
ea_ctrl <= latch_ea; |
-- |
if op_code(6) = '0' then -- '0' = acca line |
case op_code(3 downto 0) is |
when "0111" => -- sta |
dout_ctrl <= acca_dout; |
when "1111" => -- stx / sty |
case pre_code is |
when "00010000" => -- page 2 -- sty |
dout_ctrl <= iy_lo_dout; |
when others => -- page 1 -- stx |
dout_ctrl <= ix_lo_dout; |
end case; |
when others => |
dout_ctrl <= md_lo_dout; |
end case; |
else -- '1' = accb line |
case op_code(3 downto 0) is |
when "0111" => -- stb |
dout_ctrl <= accb_dout; |
when "1101" => -- std |
dout_ctrl <= accb_dout; -- accb is low byte of accd |
when "1111" => -- stu / sts |
case pre_code is |
when "00010000" => -- page 2 -- sts |
dout_ctrl <= sp_lo_dout; |
when others => -- page 1 -- stu |
dout_ctrl <= up_lo_dout; |
end case; |
when others => |
dout_ctrl <= md_lo_dout; |
end case; |
end if; |
-- write ALU low byte output |
addr_ctrl <= write_ad; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= fetch_state; |
|
-- |
-- 16 bit immediate addressing mode |
-- |
when imm16_state => |
op_ctrl <= latch_op; |
pre_ctrl <= latch_pre; |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
cc_ctrl <= latch_cc; |
dp_ctrl <= latch_dp; |
-- |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
-- |
iv_ctrl <= latch_iv; |
nmi_ctrl <= latch_nmi; |
ea_ctrl <= latch_ea; |
-- increment pc |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
pc_ctrl <= incr_pc; |
-- fetch next immediate byte |
md_ctrl <= fetch_next_md; |
addr_ctrl <= fetch_ad; |
dout_ctrl <= md_lo_dout; |
-- return to caller |
st_ctrl <= pull_st; |
return_state <= fetch_state; |
next_state <= saved_state; |
|
-- |
-- ea holds 8 bit index offet |
-- calculate the effective memory address |
-- using the alu |
-- |
when indexed_state => |
op_ctrl <= latch_op; |
pre_ctrl <= latch_pre; |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
iv_ctrl <= latch_iv; |
dp_ctrl <= latch_dp; |
nmi_ctrl <= latch_nmi; |
dout_ctrl <= md_lo_dout; |
-- |
-- decode indexing mode |
-- |
if md(7) = '0' then |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
case md(6 downto 5) is |
when "00" => |
left_ctrl <= ix_left; |
when "01" => |
left_ctrl <= iy_left; |
when "10" => |
left_ctrl <= up_left; |
when others => |
-- when "11" => |
left_ctrl <= sp_left; |
end case; |
right_ctrl <= md_sign5_right; |
alu_ctrl <= alu_add16; |
cc_ctrl <= latch_cc; |
ea_ctrl <= load_ea; |
-- |
md_ctrl <= latch_md; |
addr_ctrl <= idle_ad; |
pc_ctrl <= latch_pc; |
-- |
st_ctrl <= pull_st; |
return_state <= fetch_state; |
next_state <= saved_state; |
|
else |
case md(3 downto 0) is |
when "0000" => -- ,R+ |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
case md(6 downto 5) is |
when "00" => |
left_ctrl <= ix_left; |
when "01" => |
left_ctrl <= iy_left; |
when "10" => |
left_ctrl <= up_left; |
when others => |
left_ctrl <= sp_left; |
end case; |
-- |
right_ctrl <= zero_right; |
alu_ctrl <= alu_st16; |
cc_ctrl <= latch_cc; |
ea_ctrl <= load_ea; |
-- |
md_ctrl <= latch_md; |
addr_ctrl <= idle_ad; |
pc_ctrl <= latch_pc; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= postincr1_state; |
|
when "0001" => -- ,R++ |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
case md(6 downto 5) is |
when "00" => |
left_ctrl <= ix_left; |
when "01" => |
left_ctrl <= iy_left; |
when "10" => |
left_ctrl <= up_left; |
when others => |
-- when "11" => |
left_ctrl <= sp_left; |
end case; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_st16; |
cc_ctrl <= latch_cc; |
ea_ctrl <= load_ea; |
-- |
md_ctrl <= latch_md; |
addr_ctrl <= idle_ad; |
pc_ctrl <= latch_pc; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= postincr2_state; |
|
when "0010" => -- ,-R |
case md(6 downto 5) is |
when "00" => |
left_ctrl <= ix_left; |
ix_ctrl <= load_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "01" => |
left_ctrl <= iy_left; |
ix_ctrl <= latch_ix; |
iy_ctrl <= load_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "10" => |
left_ctrl <= up_left; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= load_up; |
sp_ctrl <= latch_sp; |
when others => |
-- when "11" => |
left_ctrl <= sp_left; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= load_sp; |
end case; |
right_ctrl <= one_right; |
alu_ctrl <= alu_sub16; |
cc_ctrl <= latch_cc; |
ea_ctrl <= load_ea; |
-- |
md_ctrl <= latch_md; |
addr_ctrl <= idle_ad; |
pc_ctrl <= latch_pc; |
-- |
st_ctrl <= pull_st; |
return_state <= fetch_state; |
next_state <= saved_state; |
|
when "0011" => -- ,--R |
case md(6 downto 5) is |
when "00" => |
left_ctrl <= ix_left; |
ix_ctrl <= load_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "01" => |
left_ctrl <= iy_left; |
ix_ctrl <= latch_ix; |
iy_ctrl <= load_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "10" => |
left_ctrl <= up_left; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= load_up; |
sp_ctrl <= latch_sp; |
when others => |
-- when "11" => |
left_ctrl <= sp_left; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= load_sp; |
end case; |
right_ctrl <= two_right; |
alu_ctrl <= alu_sub16; |
cc_ctrl <= latch_cc; |
ea_ctrl <= load_ea; |
-- |
md_ctrl <= latch_md; |
addr_ctrl <= idle_ad; |
pc_ctrl <= latch_pc; |
-- |
if md(4) = '0' then |
st_ctrl <= pull_st; |
return_state <= fetch_state; |
next_state <= saved_state; |
else |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= indirect_state; |
end if; |
|
when "0100" => -- ,R (zero offset) |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
case md(6 downto 5) is |
when "00" => |
left_ctrl <= ix_left; |
when "01" => |
left_ctrl <= iy_left; |
when "10" => |
left_ctrl <= up_left; |
when others => |
-- when "11" => |
left_ctrl <= sp_left; |
end case; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_st16; |
cc_ctrl <= latch_cc; |
ea_ctrl <= load_ea; |
-- |
md_ctrl <= latch_md; |
addr_ctrl <= idle_ad; |
pc_ctrl <= latch_pc; |
-- |
if md(4) = '0' then |
st_ctrl <= pull_st; |
return_state <= fetch_state; |
next_state <= saved_state; |
else |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= indirect_state; |
end if; |
|
when "0101" => -- ACCB,R |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
case md(6 downto 5) is |
when "00" => |
left_ctrl <= ix_left; |
when "01" => |
left_ctrl <= iy_left; |
when "10" => |
left_ctrl <= up_left; |
when others => |
-- when "11" => |
left_ctrl <= sp_left; |
end case; |
right_ctrl <= accb_right; |
alu_ctrl <= alu_add16; |
cc_ctrl <= latch_cc; |
ea_ctrl <= load_ea; |
-- |
md_ctrl <= latch_md; |
addr_ctrl <= idle_ad; |
pc_ctrl <= latch_pc; |
-- |
if md(4) = '0' then |
st_ctrl <= pull_st; |
return_state <= fetch_state; |
next_state <= saved_state; |
else |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= indirect_state; |
end if; |
|
when "0110" => -- ACCA,R |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
case md(6 downto 5) is |
when "00" => |
left_ctrl <= ix_left; |
when "01" => |
left_ctrl <= iy_left; |
when "10" => |
left_ctrl <= up_left; |
when others => |
-- when "11" => |
left_ctrl <= sp_left; |
end case; |
right_ctrl <= acca_right; |
alu_ctrl <= alu_add16; |
cc_ctrl <= latch_cc; |
ea_ctrl <= load_ea; |
-- |
md_ctrl <= latch_md; |
addr_ctrl <= idle_ad; |
pc_ctrl <= latch_pc; |
-- |
if md(4) = '0' then |
st_ctrl <= pull_st; |
return_state <= fetch_state; |
next_state <= saved_state; |
else |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= indirect_state; |
end if; |
|
when "0111" => -- undefined |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
case md(6 downto 5) is |
when "00" => |
left_ctrl <= ix_left; |
when "01" => |
left_ctrl <= iy_left; |
when "10" => |
left_ctrl <= up_left; |
when others => |
-- when "11" => |
left_ctrl <= sp_left; |
end case; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
ea_ctrl <= latch_ea; |
-- |
md_ctrl <= latch_md; |
addr_ctrl <= idle_ad; |
pc_ctrl <= latch_pc; |
-- |
if md(4) = '0' then |
st_ctrl <= pull_st; |
return_state <= fetch_state; |
next_state <= saved_state; |
else |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= indirect_state; |
end if; |
|
when "1000" => -- offset8,R |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
-- |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
ea_ctrl <= latch_ea; |
-- |
md_ctrl <= fetch_first_md; -- pick up 8 bit offset |
addr_ctrl <= fetch_ad; |
pc_ctrl <= incr_pc; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= index8_state; |
|
when "1001" => -- offset16,R |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
-- |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
ea_ctrl <= latch_ea; |
-- |
md_ctrl <= fetch_first_md; -- pick up first byte of 16 bit offset |
addr_ctrl <= fetch_ad; |
pc_ctrl <= incr_pc; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= index16_state; |
|
when "1010" => -- undefined |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
case md(6 downto 5) is |
when "00" => |
left_ctrl <= ix_left; |
when "01" => |
left_ctrl <= iy_left; |
when "10" => |
left_ctrl <= up_left; |
when others => |
-- when "11" => |
left_ctrl <= sp_left; |
end case; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
ea_ctrl <= latch_ea; |
-- |
md_ctrl <= latch_md; |
addr_ctrl <= idle_ad; |
pc_ctrl <= latch_pc; |
-- |
if md(4) = '0' then |
st_ctrl <= pull_st; |
return_state <= fetch_state; |
next_state <= saved_state; |
else |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= indirect_state; |
end if; |
|
when "1011" => -- ACCD,R |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
case md(6 downto 5) is |
when "00" => |
left_ctrl <= ix_left; |
when "01" => |
left_ctrl <= iy_left; |
when "10" => |
left_ctrl <= up_left; |
when others => |
-- when "11" => |
left_ctrl <= sp_left; |
end case; |
right_ctrl <= accd_right; |
alu_ctrl <= alu_add16; |
cc_ctrl <= latch_cc; |
ea_ctrl <= load_ea; |
-- |
md_ctrl <= latch_md; |
addr_ctrl <= idle_ad; |
pc_ctrl <= latch_pc; |
-- |
if md(4) = '0' then |
st_ctrl <= pull_st; |
return_state <= fetch_state; |
next_state <= saved_state; |
else |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= indirect_state; |
end if; |
|
when "1100" => -- offset8,PC |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
-- |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
ea_ctrl <= latch_ea; |
-- fetch 8 bit offset |
md_ctrl <= fetch_first_md; |
addr_ctrl <= fetch_ad; |
pc_ctrl <= incr_pc; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= pcrel8_state; |
|
when "1101" => -- offset16,PC |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
-- |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
ea_ctrl <= latch_ea; |
-- fetch offset |
md_ctrl <= fetch_first_md; |
addr_ctrl <= fetch_ad; |
pc_ctrl <= incr_pc; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= pcrel16_state; |
|
when "1110" => -- undefined |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
case md(6 downto 5) is |
when "00" => |
left_ctrl <= ix_left; |
when "01" => |
left_ctrl <= iy_left; |
when "10" => |
left_ctrl <= up_left; |
when others => |
-- when "11" => |
left_ctrl <= sp_left; |
end case; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
ea_ctrl <= load_ea; |
-- |
md_ctrl <= latch_md; |
addr_ctrl <= idle_ad; |
pc_ctrl <= latch_pc; |
-- |
if md(4) = '0' then |
st_ctrl <= pull_st; |
return_state <= fetch_state; |
next_state <= saved_state; |
else |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= indirect_state; |
end if; |
|
when others => |
-- when "1111" => -- [,address] |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
-- idle ALU |
left_ctrl <= pc_left; |
right_ctrl <= zero_right; |
alu_ctrl <= alu_nop; |
cc_ctrl <= latch_cc; |
ea_ctrl <= latch_ea; |
-- advance PC to pick up address |
md_ctrl <= fetch_first_md; |
addr_ctrl <= fetch_ad; |
pc_ctrl <= incr_pc; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= indexaddr_state; |
end case; |
end if; |
|
-- load index register with ea plus one |
when postincr1_state => |
op_ctrl <= latch_op; |
pre_ctrl <= latch_pre; |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
cc_ctrl <= latch_cc; |
dp_ctrl <= latch_dp; |
iv_ctrl <= latch_iv; |
nmi_ctrl <= latch_nmi; |
pc_ctrl <= latch_pc; |
md_ctrl <= latch_md; |
ea_ctrl <= latch_ea; |
-- |
left_ctrl <= ea_left; |
right_ctrl <= one_right; |
alu_ctrl <= alu_add16; |
case md(6 downto 5) is |
when "00" => |
ix_ctrl <= load_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "01" => |
ix_ctrl <= latch_ix; |
iy_ctrl <= load_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "10" => |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= load_up; |
sp_ctrl <= latch_sp; |
when others => |
-- when "11" => |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= load_sp; |
end case; |
addr_ctrl <= idle_ad; |
dout_ctrl <= md_lo_dout; |
-- return to previous state |
if md(4) = '0' then |
st_ctrl <= pull_st; |
return_state <= fetch_state; |
next_state <= saved_state; |
else |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= indirect_state; |
end if; |
|
-- load index register with ea plus two |
when postincr2_state => |
op_ctrl <= latch_op; |
pre_ctrl <= latch_pre; |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
cc_ctrl <= latch_cc; |
dp_ctrl <= latch_dp; |
iv_ctrl <= latch_iv; |
nmi_ctrl <= latch_nmi; |
pc_ctrl <= latch_pc; |
md_ctrl <= latch_md; |
ea_ctrl <= latch_ea; |
-- increment register by two (address) |
left_ctrl <= ea_left; |
right_ctrl <= two_right; |
alu_ctrl <= alu_add16; |
case md(6 downto 5) is |
when "00" => |
ix_ctrl <= load_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "01" => |
ix_ctrl <= latch_ix; |
iy_ctrl <= load_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
when "10" => |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= load_up; |
sp_ctrl <= latch_sp; |
when others => |
-- when "11" => |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= load_sp; |
end case; |
addr_ctrl <= idle_ad; |
dout_ctrl <= md_lo_dout; |
-- return to previous state |
if md(4) = '0' then |
st_ctrl <= pull_st; |
return_state <= fetch_state; |
next_state <= saved_state; |
else |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= indirect_state; |
end if; |
-- |
-- ea = index register + md (8 bit signed offset) |
-- ea holds post byte |
-- |
when index8_state => |
op_ctrl <= latch_op; |
pre_ctrl <= latch_pre; |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
cc_ctrl <= latch_cc; |
dp_ctrl <= latch_dp; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
iv_ctrl <= latch_iv; |
nmi_ctrl <= latch_nmi; |
pc_ctrl <= latch_pc; |
md_ctrl <= latch_md; |
case ea(6 downto 5) is |
when "00" => |
left_ctrl <= ix_left; |
when "01" => |
left_ctrl <= iy_left; |
when "10" => |
left_ctrl <= up_left; |
when others => |
-- when "11" => |
left_ctrl <= sp_left; |
end case; |
-- ea = index reg + md |
right_ctrl <= md_sign8_right; |
alu_ctrl <= alu_add16; |
ea_ctrl <= load_ea; |
-- idle bus |
addr_ctrl <= idle_ad; |
dout_ctrl <= md_lo_dout; |
-- return to previous state |
if ea(4) = '0' then |
st_ctrl <= pull_st; |
return_state <= fetch_state; |
next_state <= saved_state; |
else |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= indirect_state; |
end if; |
|
-- fetch low byte of 16 bit indexed offset |
when index16_state => |
op_ctrl <= latch_op; |
pre_ctrl <= latch_pre; |
acca_ctrl <= latch_acca; |
accb_ctrl <= latch_accb; |
cc_ctrl <= latch_cc; |
dp_ctrl <= latch_dp; |
ix_ctrl <= latch_ix; |
iy_ctrl <= latch_iy; |
up_ctrl <= latch_up; |
sp_ctrl <= latch_sp; |
iv_ctrl <= latch_iv; |
nmi_ctrl <= latch_nmi; |
-- advance pc |
left_ctrl <= pc_left; |
right_ctrl <= one_right; |
alu_ctrl <= alu_add16; |
pc_ctrl <= incr_pc; |
-- fetch low byte |
ea_ctrl <= latch_ea; |
md_ctrl <= fetch_next_md; |
addr_ctrl <= fetch_ad; |
dout_ctrl <= md_lo_dout; |
-- |
st_ctrl <= idle_st; |
return_state <= fetch_state; |
next_state <= index16_2_state; |
|
-- ea = index register + md (16 bit offset) |
-- ea holds post byte |
when index16_2_state => |
op_ctrl <= latch_op; |
/vhdl/sbug.vhd
0,0 → 1,2096
--===========================================================================---- |
-- |
-- S Y N T H E Z I A B L E SBUG - Monitor ROM for System09. |
-- |
-- www.OpenCores.Org - September 2003 |
-- This core adheres to the GNU public license |
-- |
-- FILE NAME: sbug.vhd |
-- ENTITY NAME: boot_rom |
-- ARCHITECTURE NAME: basic |
-- VERSION: 1.0 |
-- AUTHOR: John E. Kent |
-- DATE: 15 December 2002 |
-- DEPENDENCIES: ieee.Std_Logic_1164 |
-- ieee.std_logic_unsigned |
-- ieee.std_logic_arith |
-- DESCRIPTION: 2048 byte x 8 bit ROM Monitor program |
-- for the System09 using slices |
-- Sits at $F800 |
-- ACIA at $E004 |
-- DAT at $FFF0 |
-- |
-- |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_arith.all; |
use ieee.std_logic_unsigned.all; |
|
entity boot_rom is |
port ( |
addr : in std_logic_vector(10 downto 0); |
data : out std_logic_vector(7 downto 0) |
); |
end; |
|
architecture basic of boot_rom is |
constant width : integer := 8; |
constant memsize : integer := 2048; |
|
type rom_array is array(0 to memsize-1) of std_logic_vector(width-1 downto 0); |
|
constant rom_data : rom_array := |
( |
"11111000", |
"00010100", |
"11111000", |
"01100001", |
"11111101", |
"11001111", |
"11111101", |
"11001001", |
"11111101", |
"11011111", |
"11111101", |
"11101110", |
"11111101", |
"10111101", |
"11111101", |
"10110001", |
"11111101", |
"10101101", |
"11111011", |
"10000001", |
"10001110", |
"11111110", |
"01001111", |
"00010000", |
"10001110", |
"11011111", |
"11000000", |
"11000110", |
"00010000", |
"10100110", |
"10000000", |
"10100111", |
"10100000", |
"01011010", |
"00100110", |
"11111001", |
"10001110", |
"11100000", |
"00000100", |
"10111111", |
"11011111", |
"11100000", |
"00010111", |
"00000010", |
"01111010", |
"11000110", |
"00001100", |
"01101111", |
"11100010", |
"01011010", |
"00100110", |
"11111011", |
"00110000", |
"10001100", |
"11011101", |
"10101111", |
"01101010", |
"10000110", |
"11010000", |
"10100111", |
"11100100", |
"00011111", |
"01000011", |
"00010111", |
"00000101", |
"10111110", |
"10001110", |
"11111110", |
"01011111", |
"00010111", |
"00000101", |
"01110101", |
"10001110", |
"11011111", |
"11010000", |
"01001111", |
"11000110", |
"00001101", |
"01101101", |
"10000101", |
"00100111", |
"00000011", |
"10001011", |
"00000100", |
"00011001", |
"01011010", |
"00101010", |
"11110110", |
"00010111", |
"00000101", |
"00100110", |
"10001110", |
"11111110", |
"01110100", |
"00010111", |
"00000101", |
"01011100", |
"10001110", |
"11111110", |
"01111011", |
"00010111", |
"00000101", |
"01000110", |
"00010111", |
"00000101", |
"01100101", |
"10000100", |
"01111111", |
"10000001", |
"00001101", |
"00100111", |
"11110001", |
"00011111", |
"10001001", |
"10000001", |
"00100000", |
"00101100", |
"00001001", |
"10000110", |
"01011110", |
"00010111", |
"00000101", |
"01110011", |
"00011111", |
"10011000", |
"10001011", |
"01000000", |
"00010111", |
"00000101", |
"01101100", |
"00010111", |
"00000101", |
"01100111", |
"11000001", |
"01100000", |
"00101111", |
"00000010", |
"11000000", |
"00100000", |
"10001110", |
"11111110", |
"00010011", |
"11100001", |
"10000000", |
"00100111", |
"00001111", |
"00110000", |
"00000010", |
"10001100", |
"11111110", |
"01001111", |
"00100110", |
"11110101", |
"10001110", |
"11111110", |
"01111101", |
"00010111", |
"00000101", |
"00011110", |
"00100000", |
"11000000", |
"10101101", |
"10010100", |
"00100000", |
"10111100", |
"00011111", |
"00110100", |
"00111011", |
"10001110", |
"11111110", |
"10000011", |
"00010111", |
"00000100", |
"11111111", |
"00010111", |
"00000100", |
"00010001", |
"00010111", |
"00000100", |
"00011001", |
"00010111", |
"00000100", |
"00100001", |
"00010111", |
"00000100", |
"00101001", |
"00010111", |
"00000100", |
"00110001", |
"10001110", |
"11111110", |
"10000011", |
"00010111", |
"00000100", |
"11101010", |
"00010111", |
"00000100", |
"00110011", |
"00010111", |
"00000100", |
"00111010", |
"00010111", |
"00000100", |
"01000001", |
"00010110", |
"00000100", |
"01001000", |
"00010111", |
"00000100", |
"00100111", |
"00010111", |
"00000101", |
"00010111", |
"00010111", |
"00000100", |
"01010111", |
"00101001", |
"00000010", |
"10101111", |
"01001010", |
"00111001", |
"00010111", |
"00000011", |
"11101101", |
"00010111", |
"00000101", |
"00001001", |
"00010111", |
"00000100", |
"01001001", |
"00101001", |
"00000010", |
"10101111", |
"01001000", |
"00111001", |
"00010111", |
"00000100", |
"00000000", |
"00010111", |
"00000100", |
"11111011", |
"00010111", |
"00000100", |
"00111011", |
"00101001", |
"00000010", |
"10101111", |
"01000110", |
"00111001", |
"00010111", |
"00000011", |
"11100111", |
"00010111", |
"00000100", |
"11101101", |
"00010111", |
"00000100", |
"00101101", |
"00101001", |
"00000010", |
"10101111", |
"01000100", |
"00111001", |
"00010111", |
"00000011", |
"11001110", |
"00010111", |
"00000100", |
"11011111", |
"00010111", |
"00000100", |
"00110000", |
"00101001", |
"00000010", |
"10100111", |
"01000011", |
"00111001", |
"00010111", |
"00000011", |
"11110101", |
"00010111", |
"00000100", |
"11010001", |
"00010111", |
"00000100", |
"00100010", |
"00101001", |
"00000010", |
"10100111", |
"01000010", |
"00111001", |
"00010111", |
"00000011", |
"11011101", |
"00010111", |
"00000100", |
"11000011", |
"00010111", |
"00000100", |
"00010100", |
"00101001", |
"00000010", |
"10100111", |
"01000001", |
"00111001", |
"00010111", |
"00000011", |
"11100011", |
"00010111", |
"00000100", |
"10110101", |
"00010111", |
"00000100", |
"00000110", |
"00101001", |
"00000100", |
"10001010", |
"10000000", |
"10100111", |
"11000100", |
"00111001", |
"00010111", |
"00000011", |
"11101011", |
"00101001", |
"00101101", |
"00011111", |
"00010010", |
"10001110", |
"11111110", |
"10000011", |
"00010111", |
"00000100", |
"01011111", |
"00011111", |
"00100001", |
"00010111", |
"00000100", |
"00100110", |
"00010111", |
"00000100", |
"10010110", |
"10100110", |
"10100100", |
"00010111", |
"00000100", |
"00100110", |
"00010111", |
"00000100", |
"10001110", |
"00010111", |
"00000011", |
"11011111", |
"00101000", |
"00010001", |
"10000001", |
"00001000", |
"00100111", |
"11100001", |
"10000001", |
"00011000", |
"00100111", |
"11011101", |
"10000001", |
"01011110", |
"00100111", |
"00010111", |
"10000001", |
"00001101", |
"00100110", |
"00001111", |
"00111001", |
"10100111", |
"10100100", |
"10100001", |
"10100100", |
"00100111", |
"00001000", |
"00010111", |
"00000100", |
"01101111", |
"10000110", |
"00111111", |
"00010111", |
"00000100", |
"01101100", |
"00110001", |
"00100001", |
"00100000", |
"11000010", |
"00110001", |
"00111111", |
"00100000", |
"10111110", |
"00010111", |
"00000011", |
"00110101", |
"00011111", |
"00110010", |
"10001110", |
"11011111", |
"11000000", |
"00110000", |
"00011111", |
"00100000", |
"00000101", |
"00010111", |
"00000011", |
"10001011", |
"00101001", |
"00000110", |
"00110100", |
"00100000", |
"10101100", |
"11100001", |
"00100100", |
"00000001", |
"00111001", |
"00011111", |
"00010000", |
"11000011", |
"00000000", |
"00010000", |
"11000100", |
"11110000", |
"00110100", |
"00000110", |
"00011111", |
"00100000", |
"11000100", |
"11110000", |
"00011111", |
"00000001", |
"10101100", |
"11100100", |
"00100111", |
"00000101", |
"00010111", |
"00000100", |
"00100111", |
"00100111", |
"00000011", |
"00110010", |
"01100010", |
"00111001", |
"00110100", |
"00010000", |
"10001110", |
"11111110", |
"10000011", |
"00010111", |
"00000011", |
"11101000", |
"10101110", |
"11100100", |
"00010111", |
"00000011", |
"10101111", |
"11000110", |
"00010000", |
"10100110", |
"10000000", |
"00010111", |
"00000011", |
"10110000", |
"00010111", |
"00000100", |
"00011000", |
"01011010", |
"00100110", |
"11110101", |
"00010111", |
"00000100", |
"00010000", |
"10101110", |
"11100001", |
"11000110", |
"00010000", |
"10100110", |
"10000000", |
"10000001", |
"00100000", |
"00100101", |
"00000100", |
"10000001", |
"01111110", |
"00100011", |
"00000010", |
"10000110", |
"00101110", |
"00010111", |
"00000100", |
"00000001", |
"01011010", |
"00100110", |
"11101110", |
"00100000", |
"10111111", |
"01101111", |
"11100010", |
"01101111", |
"11100010", |
"00010111", |
"00000011", |
"00101011", |
"00110100", |
"00110000", |
"00101001", |
"01111011", |
"10101100", |
"01100010", |
"00100101", |
"01110111", |
"00010111", |
"00000011", |
"11101000", |
"00011111", |
"00100000", |
"11100011", |
"01100100", |
"00110100", |
"00000100", |
"10101011", |
"11100000", |
"10100111", |
"10100000", |
"00010000", |
"10101100", |
"11100100", |
"00100101", |
"11110001", |
"00010000", |
"10101110", |
"01100010", |
"00011111", |
"00100000", |
"11100011", |
"01100100", |
"00110100", |
"00000010", |
"11101011", |
"11100000", |
"11101000", |
"10100000", |
"00100111", |
"00111100", |
"10001110", |
"11111110", |
"10000011", |
"00010111", |
"00000011", |
"10000101", |
"00110000", |
"00111111", |
"00010111", |
"00000011", |
"01001100", |
"00110100", |
"00010000", |
"10001110", |
"11111110", |
"10100001", |
"00010111", |
"00000011", |
"10001000", |
"00110101", |
"00010000", |
"00010111", |
"00000001", |
"01000111", |
"00010111", |
"00000011", |
"01010000", |
"00010111", |
"00000011", |
"00111001", |
"10001110", |
"11111110", |
"10000111", |
"00010111", |
"00000011", |
"01110111", |
"10101110", |
"01100100", |
"00010111", |
"00000011", |
"00101110", |
"10001110", |
"11111110", |
"10001111", |
"00010111", |
"00000011", |
"01101100", |
"00011111", |
"10011000", |
"10001110", |
"11111110", |
"10100110", |
"00010111", |
"00000011", |
"00111110", |
"00010111", |
"00000011", |
"10000011", |
"00100110", |
"00011010", |
"00010000", |
"10101100", |
"11100100", |
"00100101", |
"10110011", |
"10000110", |
"00101011", |
"00010111", |
"00000011", |
"10000110", |
"00010111", |
"00000011", |
"01110100", |
"00100110", |
"00001011", |
"00010000", |
"10101110", |
"01100010", |
"01101100", |
"01100101", |
"00100110", |
"10010000", |
"01101100", |
"01100100", |
"00100110", |
"10001100", |
"00110010", |
"01100110", |
"00111001", |
"00010111", |
"00000010", |
"10110001", |
"00101001", |
"00011110", |
"10001100", |
"11011111", |
"11000000", |
"00100100", |
"00011010", |
"00110100", |
"00010000", |
"10001110", |
"11111111", |
"11111111", |
"10001101", |
"01010101", |
"00110101", |
"00010000", |
"00100111", |
"00001111", |
"10100110", |
"10000100", |
"10000001", |
"00111111", |
"00100111", |
"00001001", |
"10100111", |
"10100000", |
"10101111", |
"10100100", |
"10000110", |
"00111111", |
"10100111", |
"10000100", |
"00111001", |
"00010111", |
"00000011", |
"01001010", |
"10000110", |
"00111111", |
"00010110", |
"00000011", |
"01000111", |
"00010000", |
"10001110", |
"11011111", |
"11100011", |
"11000110", |
"00001000", |
"10001101", |
"00011000", |
"01011010", |
"00100110", |
"11111011", |
"00111001", |
"00011111", |
"01000011", |
"10101110", |
"01001010", |
"00110000", |
"00011111", |
"10001101", |
"00100110", |
"00100111", |
"00000100", |
"10101111", |
"01001010", |
"10001101", |
"00000110", |
"00010111", |
"11111101", |
"11100100", |
"00010110", |
"11111101", |
"10011010", |
"10101110", |
"00100001", |
"10001100", |
"11011111", |
"11000000", |
"00100100", |
"00001010", |
"10100110", |
"10000100", |
"10000001", |
"00111111", |
"00100110", |
"00000100", |
"10100110", |
"10100100", |
"10100111", |
"10000100", |
"10000110", |
"11111111", |
"10100111", |
"10100000", |
"10100111", |
"10100000", |
"10100111", |
"10100000", |
"00111001", |
"00010000", |
"10001110", |
"11011111", |
"11100011", |
"11000110", |
"00001000", |
"10100110", |
"10100000", |
"10101100", |
"10100001", |
"00100111", |
"00000100", |
"01011010", |
"00100110", |
"11110111", |
"00111001", |
"00110001", |
"00111101", |
"00111001", |
"10000110", |
"11011110", |
"10110111", |
"11110000", |
"00100100", |
"10000110", |
"11111111", |
"10110111", |
"11110000", |
"00010100", |
"10110111", |
"11110000", |
"00010000", |
"10110111", |
"11110000", |
"00010101", |
"10110111", |
"11110000", |
"00010110", |
"01111101", |
"11110000", |
"00010000", |
"10000110", |
"11011000", |
"10110111", |
"11110000", |
"00100000", |
"00010111", |
"00000000", |
"10010111", |
"10110110", |
"11110000", |
"00100000", |
"00101011", |
"11111011", |
"10000110", |
"00001001", |
"10110111", |
"11110000", |
"00100000", |
"00010111", |
"00000000", |
"10001010", |
"10110110", |
"11110000", |
"00100000", |
"10000101", |
"00000001", |
"00100110", |
"11111001", |
"10000101", |
"00010000", |
"00100110", |
"11001010", |
"10001110", |
"11000000", |
"00000000", |
"10001101", |
"01010010", |
"10001010", |
"00010000", |
"10110111", |
"11110000", |
"01000000", |
"00011111", |
"00010000", |
"01000011", |
"01010011", |
"11111101", |
"11110000", |
"00000000", |
"10001110", |
"11111110", |
"11111111", |
"10111111", |
"11110000", |
"00000010", |
"10000110", |
"11111111", |
"10110111", |
"11110000", |
"00010000", |
"10000110", |
"11111110", |
"10110111", |
"11110000", |
"00010100", |
"10000110", |
"00000001", |
"10110111", |
"11110000", |
"00100010", |
"10000110", |
"10001100", |
"10110111", |
"11110000", |
"00100000", |
"10001101", |
"01010010", |
"01011111", |
"00110100", |
"00000100", |
"01011111", |
"01111101", |
"11110000", |
"00010000", |
"00101010", |
"00001010", |
"01011010", |
"00100110", |
"11111000", |
"00110101", |
"00000100", |
"01011010", |
"00100110", |
"11110000", |
"00100000", |
"10001010", |
"00110101", |
"00000100", |
"10110110", |
"11110000", |
"00100000", |
"10000101", |
"00011100", |
"00100111", |
"00000001", |
"00111001", |
"11000110", |
"11011110", |
"11110111", |
"11110000", |
"00100100", |
"10001110", |
"11000000", |
"00000000", |
"10101111", |
"01001010", |
"00011111", |
"00110100", |
"00111011", |
"00110100", |
"00110110", |
"10100110", |
"01100010", |
"01000100", |
"01000100", |
"01000100", |
"01000100", |
"00010000", |
"10001110", |
"11011111", |
"11010000", |
"11100110", |
"10100110", |
"01010100", |
"01010100", |
"01010100", |
"01010100", |
"11100111", |
"11100100", |
"11100110", |
"10100110", |
"01010011", |
"01011000", |
"01011000", |
"01011000", |
"01011000", |
"10100110", |
"01100010", |
"10000100", |
"00001111", |
"10100111", |
"01100010", |
"11101010", |
"01100010", |
"11100111", |
"01100010", |
"00110101", |
"00110110", |
"00111001", |
"00110100", |
"00000100", |
"11000110", |
"00100000", |
"01011010", |
"00100110", |
"11111101", |
"00110101", |
"00000100", |
"00111001", |
"01111101", |
"11100000", |
"00011000", |
"01111111", |
"11100000", |
"00010100", |
"11000110", |
"00000011", |
"10001110", |
"00000000", |
"00000000", |
"00110000", |
"00000001", |
"10001100", |
"00000000", |
"00000000", |
"00100110", |
"11111001", |
"01011010", |
"00100110", |
"11110110", |
"10000110", |
"00001111", |
"10110111", |
"11100000", |
"00011000", |
"10001101", |
"00110111", |
"11110110", |
"11100000", |
"00011000", |
"11000101", |
"00000001", |
"00100110", |
"11111001", |
"10000110", |
"00000001", |
"10110111", |
"11100000", |
"00011010", |
"10001101", |
"00101001", |
"10000110", |
"10001100", |
"10110111", |
"11100000", |
"00011000", |
"10001101", |
"00100010", |
"10001110", |
"11000000", |
"00000000", |
"00100000", |
"00001001", |
"11000101", |
"00000010", |
"00100111", |
"00000101", |
"10110110", |
"11100000", |
"00011011", |
"10100111", |
"10000000", |
"11110110", |
"11100000", |
"00011000", |
"11000101", |
"00000001", |
"00100110", |
"11110000", |
"11000101", |
"00101100", |
"00100111", |
"00000001", |
"00111001", |
"10001110", |
"11000000", |
"00000000", |
"10101111", |
"01001010", |
"00011111", |
"00110100", |
"00111011", |
"11000110", |
"00100000", |
"01011010", |
"00100110", |
"11111101", |
"00111001", |
"10000110", |
"00010001", |
"00010111", |
"00000001", |
"11011101", |
"01111111", |
"11011111", |
"11100010", |
"00010111", |
"00000001", |
"10101101", |
"10000001", |
"01010011", |
"00100110", |
"11111001", |
"00010111", |
"00000001", |
"10100110", |
"10000001", |
"00111001", |
"00100111", |
"00111101", |
"10000001", |
"00110001", |
"00100110", |
"11110001", |
"00010111", |
"00000001", |
"00010111", |
"00110100", |
"00000010", |
"00101001", |
"00100110", |
"00010111", |
"00000000", |
"11111111", |
"00101001", |
"00100001", |
"00110100", |
"00010000", |
"11100110", |
"11100000", |
"11101011", |
"11100000", |
"11101011", |
"11100100", |
"01101010", |
"11100100", |
"01101010", |
"11100100", |
"00110100", |
"00000100", |
"00010111", |
"00000000", |
"11111101", |
"00110101", |
"00000100", |
"00101001", |
"00001100", |
"00110100", |
"00000010", |
"11101011", |
"11100000", |
"01101010", |
"11100100", |
"00100111", |
"00000101", |
"10100111", |
"10000000", |
"00100000", |
"11101011", |
"01011111", |
"00110101", |
"00000010", |
"11000001", |
"11111111", |
"00100111", |
"10110010", |
"10000110", |
"00111111", |
"00010111", |
"00000001", |
"10001111", |
"01110011", |
"11011111", |
"11100010", |
"10000110", |
"00010011", |
"00010110", |
"00000001", |
"10000111", |
"01101111", |
"11100010", |
"00010111", |
"00000000", |
"10111000", |
"00110100", |
"00110000", |
"00101001", |
"01001010", |
"10101100", |
"01100010", |
"00100101", |
"01000110", |
"00110000", |
"00000001", |
"10101111", |
"11100100", |
"10000110", |
"00010010", |
"00010111", |
"00000001", |
"01110001", |
"11101100", |
"11100100", |
"10100011", |
"01100010", |
"00100111", |
"00000110", |
"00010000", |
"10000011", |
"00000000", |
"00100000", |
"00100011", |
"00000010", |
"11000110", |
"00100000", |
"11100111", |
"01100100", |
"10001110", |
"11111110", |
"11101011", |
"00010111", |
"00000001", |
"00011010", |
"11001011", |
"00000011", |
"00011111", |
"10011000", |
"00010111", |
"00000000", |
"11100111", |
"10101110", |
"01100010", |
"00010111", |
"00000000", |
"11011010", |
"11101011", |
"01100010", |
"11101011", |
"01100011", |
"11101011", |
"10000100", |
"10100110", |
"10000000", |
"00010111", |
"00000000", |
"11010111", |
"01101010", |
"01100100", |
"00100110", |
"11110101", |
"01010011", |
"00011111", |
"10011000", |
"00010111", |
"00000000", |
"11001101", |
"10101111", |
"01100010", |
"10101100", |
"11100100", |
"00100110", |
"11000011", |
"10000110", |
"00010100", |
"00010111", |
"00000001", |
"00101111", |
"00110010", |
"01100101", |
"00111001", |
"10001110", |
"11111110", |
"10101110", |
"00010111", |
"00000000", |
"11110101", |
"00011111", |
"00110001", |
"00010110", |
"00000000", |
"10101100", |
"10001110", |
"11111110", |
"10111010", |
"00010111", |
"00000000", |
"11101010", |
"10101110", |
"01001000", |
"00010110", |
"00000000", |
"10100001", |
"10001110", |
"11111110", |
"11001100", |
"00010111", |
"00000000", |
"11011111", |
"10100110", |
"01000011", |
"00010110", |
"00000000", |
"10011110", |
"10001110", |
"11111110", |
"11000110", |
"00010111", |
"00000000", |
"11010100", |
"10101110", |
"01000100", |
"00010110", |
"00000000", |
"10001011", |
"10001110", |
"11111110", |
"11000000", |
"00010111", |
"00000000", |
"11001001", |
"10101110", |
"01000110", |
"00010110", |
"00000000", |
"10000000", |
"10001110", |
"11111110", |
"10110100", |
"00010111", |
"00000000", |
"10111110", |
"10101110", |
"01001010", |
"00100000", |
"01110110", |
"10001110", |
"11111110", |
"11010010", |
"00010111", |
"00000000", |
"10110100", |
"10100110", |
"01000001", |
"00100000", |
"01110100", |
"10001110", |
"11111110", |
"11010111", |
"00010111", |
"00000000", |
"10101010", |
"10100110", |
"01000010", |
"00100000", |
"01101010", |
"10001110", |
"11111110", |
"11011100", |
"00010111", |
"00000000", |
"10100000", |
"10100110", |
"11000100", |
"10001110", |
"11111110", |
"11100011", |
"00100000", |
"01110011", |
"10001101", |
"00001001", |
"00101001", |
"01001110", |
"00011111", |
"00010010", |
"10000110", |
"00101101", |
"00010111", |
"00000000", |
"10111111", |
"10001101", |
"00001111", |
"00101001", |
"01000011", |
"00011111", |
"00000001", |
"10001101", |
"00001001", |
"00101001", |
"00111101", |
"00110100", |
"00010000", |
"10100111", |
"01100001", |
"00110101", |
"00010000", |
"00111001", |
"10001101", |
"00010001", |
"00101001", |
"00110010", |
"01001000", |
"01001000", |
"01001000", |
"01001000", |
"00011111", |
"10001001", |
"10001101", |
"00000111", |
"00101001", |
"00101000", |
"00110100", |
"00000100", |
"10101011", |
"11100000", |
"00111001", |
"10001101", |
"01101111", |
"10000001", |
"00110000", |
"00100101", |
"00011101", |
"10000001", |
"00111001", |
"00100010", |
"00000011", |
"10000000", |
"00110000", |
"00111001", |
"10000001", |
"01000001", |
"00100101", |
"00010010", |
"10000001", |
"01000110", |
"00100010", |
"00000011", |
"10000000", |
"00110111", |
"00111001", |
"10000001", |
"01100001", |
"00100101", |
"00000111", |
"10000001", |
"01100110", |
"00100010", |
"00000011", |
"10000000", |
"01010111", |
"00111001", |
"00011010", |
"00000010", |
"00111001", |
"00110100", |
"00010000", |
"00110101", |
"00000010", |
"10001101", |
"00000010", |
"00110101", |
"00000010", |
"00110100", |
"00000010", |
"01000100", |
"01000100", |
"01000100", |
"01000100", |
"10001101", |
"00000100", |
"00110101", |
"00000010", |
"10000100", |
"00001111", |
"10001011", |
"00110000", |
"10000001", |
"00111001", |
"00101111", |
"00000010", |
"10001011", |
"00000111", |
"00100000", |
"01010111", |
"00110100", |
"00000010", |
"11000110", |
"00001000", |
"10100110", |
"10000000", |
"01101000", |
"11100100", |
"00100101", |
"00000010", |
"10000110", |
"00101101", |
"10001101", |
"01001001", |
"10001101", |
"01000101", |
"01011010", |
"00100110", |
"11110001", |
"00110101", |
"00000010", |
"00111001", |
"10001101", |
"00000010", |
"00100000", |
"00001100", |
"00110100", |
"00010000", |
"10001110", |
"11111110", |
"01110101", |
"10001101", |
"00000101", |
"00110101", |
"00010000", |
"00111001", |
"10001101", |
"00110001", |
"10100110", |
"10000000", |
"10000001", |
"00000100", |
"00100110", |
"11111000", |
"00111001", |
"01111101", |
"11011111", |
"11100010", |
"00100111", |
"00000110", |
"10001101", |
"00000100", |
"10000100", |
"01111111", |
"00100000", |
"00011111", |
"00110100", |
"00010000", |
"10111110", |
"11011111", |
"11100000", |
"10100110", |
"10000100", |
"10000101", |
"00000001", |
"00100111", |
"11111010", |
"10100110", |
"00000001", |
"00110101", |
"00010000", |
"00111001", |
"00110100", |
"00000010", |
"10100110", |
"10011111", |
"11011111", |
"11100000", |
"10000101", |
"00000001", |
"00110101", |
"00000010", |
"00111001", |
"10001101", |
"00000000", |
"10000110", |
"00100000", |
"00110100", |
"00010010", |
"10111110", |
"11011111", |
"11100000", |
"10100110", |
"10000100", |
"10000101", |
"00000010", |
"00100111", |
"11111010", |
"00110101", |
"00000010", |
"10100111", |
"00000001", |
"00110101", |
"00010000", |
"00111001", |
"10111110", |
"11011111", |
"11100000", |
"10000110", |
"00000011", |
"10100111", |
"10000100", |
"10000110", |
"00010001", |
"10100111", |
"10000100", |
"01101101", |
"00000001", |
"10000110", |
"11111111", |
"10110111", |
"11011111", |
"11100010", |
"00111001", |
"00000001", |
"11111001", |
"00100011", |
"00000010", |
"11111001", |
"00010101", |
"00000011", |
"11111001", |
"00110001", |
"00000100", |
"11111001", |
"00000111", |
"00010000", |
"11111000", |
"11001111", |
"00010101", |
"11111000", |
"11011101", |
"00011000", |
"11111000", |
"11111001", |
"00011001", |
"11111000", |
"11101011", |
"01000010", |
"11111010", |
"01111011", |
"01000100", |
"11111010", |
"11110100", |
"01000101", |
"11111001", |
"10010110", |
"01000111", |
"11111000", |
"10100101", |
"01001100", |
"11111100", |
"00001100", |
"01001101", |
"11111001", |
"01000001", |
"01010000", |
"11111100", |
"01100111", |
"01010001", |
"11111001", |
"11110010", |
"01010010", |
"11111000", |
"10101000", |
"01010011", |
"11111001", |
"10001010", |
"01010101", |
"11111011", |
"10110011", |
"01011000", |
"11111010", |
"10100111", |
"11111010", |
"10110011", |
"11111000", |
"10100111", |
"11111000", |
"10100111", |
"11111000", |
"10100111", |
"11111000", |
"10100111", |
"11111010", |
"10110011", |
"11111111", |
"11111111", |
"11111111", |
"11111111", |
"00000000", |
"00000000", |
"00000000", |
"00001101", |
"00001010", |
"00000000", |
"00000000", |
"00000000", |
"01010011", |
"00101101", |
"01000010", |
"01010101", |
"01000111", |
"00100000", |
"00110001", |
"00101110", |
"00111000", |
"00100000", |
"00101101", |
"00100000", |
"00000100", |
"01001011", |
"00001101", |
"00001010", |
"00000000", |
"00000000", |
"00000000", |
"00000100", |
"00111110", |
"00000100", |
"01010111", |
"01001000", |
"01000001", |
"01010100", |
"00111111", |
"00000100", |
"00100000", |
"00101101", |
"00100000", |
"00000100", |
"00101100", |
"00100000", |
"01010000", |
"01000001", |
"01010011", |
"01010011", |
"00100000", |
"00000100", |
"00101100", |
"00100000", |
"01000010", |
"01001001", |
"01010100", |
"01010011", |
"00100000", |
"01001001", |
"01001110", |
"00100000", |
"01000101", |
"01010010", |
"01010010", |
"01001111", |
"01010010", |
"00111010", |
"00100000", |
"00000100", |
"00100000", |
"00111101", |
"00111110", |
"00100000", |
"00000100", |
"00110111", |
"00110110", |
"00110101", |
"00110100", |
"00110011", |
"00110010", |
"00110001", |
"00110000", |
"00100000", |
"00100000", |
"01010011", |
"01010000", |
"00111101", |
"00000100", |
"00100000", |
"00100000", |
"01010000", |
"01000011", |
"00111101", |
"00000100", |
"00100000", |
"00100000", |
"01010101", |
"01010011", |
"00111101", |
"00000100", |
"00100000", |
"00100000", |
"01001001", |
"01011001", |
"00111101", |
"00000100", |
"00100000", |
"00100000", |
"01001001", |
"01011000", |
"00111101", |
"00000100", |
"00100000", |
"00100000", |
"01000100", |
"01010000", |
"00111101", |
"00000100", |
"00100000", |
"00100000", |
"01000001", |
"00111101", |
"00000100", |
"00100000", |
"00100000", |
"01000010", |
"00111101", |
"00000100", |
"00100000", |
"00100000", |
"01000011", |
"01000011", |
"00111010", |
"00100000", |
"00000100", |
"01000101", |
"01000110", |
"01001000", |
"01001001", |
"01001110", |
"01011010", |
"01010110", |
"01000011", |
"01010011", |
"00110001", |
"00000100", |
"11111111", |
"11111111", |
"11111111", |
"11111111", |
"11111111", |
"11111111", |
"11111111", |
"11111111", |
"11111111", |
"11111111", |
"11111111", |
"11111111", |
"11111111", |
"11111111", |
"11111111", |
"00000000", |
"00000000", |
"00000000", |
"10001110", |
"11111111", |
"11110000", |
"10000110", |
"00001111", |
"10100111", |
"10000000", |
"01001010", |
"00100110", |
"11111011", |
"10000110", |
"11110000", |
"10100111", |
"10000100", |
"10001110", |
"11010000", |
"10100000", |
"00010000", |
"10001110", |
"01010101", |
"10101010", |
"11101110", |
"10000100", |
"00010000", |
"10101111", |
"10000100", |
"00010000", |
"10101100", |
"10000100", |
"00100111", |
"00001011", |
"00110000", |
"10001001", |
"11110000", |
"00000000", |
"10001100", |
"11110000", |
"10100000", |
"00100110", |
"11101101", |
"00100000", |
"11010110", |
"11101111", |
"10000100", |
"00011111", |
"00010000", |
"01000011", |
"01000100", |
"01000100", |
"01000100", |
"01000100", |
"10110111", |
"11111111", |
"11111101", |
"00010000", |
"11001110", |
"11011111", |
"11000000", |
"00010000", |
"10001110", |
"11011111", |
"11010000", |
"10100111", |
"00101101", |
"01101111", |
"00101110", |
"10000110", |
"11110000", |
"10100111", |
"00101111", |
"10000110", |
"00001100", |
"01101111", |
"10100110", |
"01001010", |
"00101010", |
"11111011", |
"00110000", |
"10001001", |
"11110000", |
"00000000", |
"10001100", |
"11110000", |
"10100000", |
"00100111", |
"00100010", |
"11101110", |
"10000100", |
"00010000", |
"10001110", |
"01010101", |
"10101010", |
"00010000", |
"10101111", |
"10000100", |
"00010000", |
"10101100", |
"10000100", |
"00100110", |
"11101001", |
"11101111", |
"10000100", |
"00010000", |
"10001110", |
"11011111", |
"11010000", |
"00011111", |
"00010000", |
"01000100", |
"01000100", |
"01000100", |
"01000100", |
"00011111", |
"10001001", |
"10001000", |
"00001111", |
"10100111", |
"10100101", |
"00100000", |
"11010101", |
"10000110", |
"11110001", |
"00010000", |
"10001110", |
"11011111", |
"11010000", |
"10100111", |
"00101110", |
"10000110", |
"00001100", |
"11100110", |
"10100110", |
"00100110", |
"00000101", |
"01001010", |
"00101010", |
"11111001", |
"00100000", |
"00010100", |
"01101111", |
"10100110", |
"11100111", |
"00101100", |
"01001111", |
"00011111", |
"00100001", |
"11100110", |
"10100110", |
"00100111", |
"00000100", |
"01101111", |
"10100110", |
"11100111", |
"10000000", |
"01001100", |
"10000001", |
"00001100", |
"00101101", |
"11110011", |
"10001110", |
"11111111", |
"11110000", |
"11000110", |
"00010000", |
"10100110", |
"10100000", |
"10100111", |
"10000000", |
"01011010", |
"00100110", |
"11111001", |
"01010011", |
"11110111", |
"11011111", |
"11100010", |
"00010110", |
"11111000", |
"01100010", |
"01101110", |
"10011111", |
"11011111", |
"11000000", |
"01101110", |
"10011111", |
"11011111", |
"11000100", |
"01101110", |
"10011111", |
"11011111", |
"11000110", |
"01101110", |
"10011111", |
"11011111", |
"11001000", |
"01101110", |
"10011111", |
"11011111", |
"11001010", |
"00011111", |
"01000011", |
"10101110", |
"01001010", |
"11100110", |
"10000000", |
"10101111", |
"01001010", |
"01001111", |
"01011000", |
"01001001", |
"10111110", |
"11011111", |
"11001100", |
"10001100", |
"11111111", |
"11111111", |
"00100111", |
"00001111", |
"00110000", |
"10001011", |
"10111100", |
"11011111", |
"11001110", |
"00100010", |
"00001000", |
"00110100", |
"00010000", |
"11101100", |
"11000100", |
"10101110", |
"01000100", |
"01101110", |
"11110001", |
"00110111", |
"00011111", |
"11101110", |
"01000010", |
"01101110", |
"10011111", |
"11011111", |
"11000010", |
"11111111", |
"10110010", |
"11111111", |
"11000110", |
"11111111", |
"10110110", |
"11111111", |
"10111010", |
"11111111", |
"10111110", |
"11111111", |
"11000010", |
"11111111", |
"10110010", |
"11111111", |
"00000000" |
); |
begin |
data <= rom_data(conv_integer(addr)); |
end; |
|
/vhdl/testbench1.vhd
0,0 → 1,180
--===========================================================================---- |
-- |
-- T E S T B E N C H tesetbench1 - CPU09 Testbench. |
-- |
-- www.OpenCores.Org - September 2003 |
-- This core adheres to the GNU public license |
-- |
-- File name : Testbench1.vhd |
-- |
-- Purpose : cpu09 Microprocessor Test Bench 1 |
-- Contains ROM to print out "Hello World" |
-- on a none existant Uart |
-- |
-- Dependencies : ieee.Std_Logic_1164 |
-- ieee.std_logic_unsigned |
-- ieee.std_logic_arith |
-- ieee.numeric_std |
-- |
-- Uses : cpu09 (cpu09.vhd) CPU core |
-- |
-- Author : John E. Kent |
-- dilbert57@opencores.org |
-- |
--===========================================================================---- |
-- |
-- Revision History: |
--===========================================================================-- |
-- |
-- Version 0.1 - 12st April 2003 - John Kent |
-- First version |
-- |
-- Version 1.0- 6 Sep 2003 - John Kent |
-- Initial release to Open Cores |
-- |
--===========================================================================-- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use IEEE.STD_LOGIC_ARITH.ALL; |
use IEEE.STD_LOGIC_UNSIGNED.ALL; |
use ieee.numeric_std.all; |
-- library work; |
-- use work.UART_Def.all; |
-- use work.typedefines.all; |
-- use work.memory.all; |
|
entity my_testbench is |
end my_testbench; |
|
------------------------------------------------------------------------------- |
-- Architecture for memio Controller Unit |
------------------------------------------------------------------------------- |
architecture behavior of my_testbench is |
----------------------------------------------------------------------------- |
-- Signals |
----------------------------------------------------------------------------- |
-- CPU Interface signals |
signal SysClk : Std_Logic; |
signal cpu_reset : Std_Logic; |
signal cpu_rw : Std_Logic; |
signal cpu_vma : Std_Logic; |
signal cpu_addr : Std_Logic_Vector(15 downto 0); |
signal cpu_data_in : Std_Logic_Vector(7 downto 0); |
signal cpu_data_out: Std_Logic_Vector(7 downto 0); |
signal cpu_alu : Std_Logic_Vector(15 downto 0); |
signal cpu_cc : Std_Logic_Vector(7 downto 0); |
signal cpu_irq : Std_Logic; |
signal cpu_nmi : std_logic; |
signal cpu_firq : Std_Logic; |
|
|
constant width : integer := 8; |
constant memsize : integer := 64; |
|
type rom_array is array(0 to memsize-1) of std_logic_vector(width-1 downto 0); |
|
constant rom_data : rom_array := |
( |
"10001110", "11111000", "00101000", -- F800 - 8E F828 RESET LDX #MSG |
"10000110", "00010001", -- F803 - 86 11 LDA #$11 |
"10110111", "11100000", "00000100", -- F805 - B7 E004 STA UARTCR |
"10110110", "11100000", "00000100", -- F808 - B6 E004 POLL1 LDA UARTCR |
"10000101", "00000010", -- F80B - 85 02 BITA #TXBE |
"00100110", "11111001", -- F80D - 26 F9 BNE POLL1 |
"10100110", "10000000", -- F80F - A6 80 LDA ,X+ |
"00100111", "00000110", -- F811 - 27 06 BEQ POLL2 |
"00010010", -- F813 - 12 NOP |
"10110111", "11100000", "00000101", -- F814 - B7 E005 STA UARTDR |
"00100110", "11101111", -- F817 - 26 EF BNE POLL1 |
"10110110", "11100000", "00000100", -- F819 - B6 E004 POLL2 LDA UARTCR |
"10000101", "00000001", -- F81C - 85 01 BITA #RXBF |
"00100111", "11111001", -- F81E - 27 F9 BEQ POLL2 |
"10110110", "11100000", "00000101", -- F820 - B6 E005 LDA UARTDR |
"01111110", "11111000", "00000000", -- F823 - 7E F800 JMP RESET |
"00000000", "00000000", -- F826 - 00 00 fcb $00,$00 |
"01001000", "01100101", "01101100", -- F828 - 48 65 6c MSG FCC "Hel" |
"01101100", "01101111", "00100000", -- F82B - 6c 6f 20 FCC "lo " |
"01010111", "01101111", "01110010", -- F82E - 57 6f 72 FCC "Wor" |
"01101100", "01100100", -- F831 - 6c 64 FCC "ld" |
"00001010", "00001101", "00000000", -- F833 - 0a 0d 00 FCB LF,CR,NULL |
"00000000", "00000000", -- F836 - 00 00 fcb null,null |
"11111000", "00000000", -- F838 - F8 00 fdb $F800 ; Timer irq |
"11111000", "00000000", -- F83A - F8 00 fdb $F800 ; Ext IRQ |
"11111000", "00000000", -- F83C - F8 00 fcb $F800 ; SWI |
"11111000", "00000000" -- F83E - F8 00 fdb $F800 ; Reset |
); |
|
component cpu09 |
port ( |
clk: in std_logic; |
rst: in std_logic; |
rw: out std_logic; -- Asynchronous memory interface |
vma: out std_logic; |
address: out std_logic_vector(15 downto 0); |
data_in: in std_logic_vector(7 downto 0); |
data_out: out std_logic_vector(7 downto 0); |
halt: in std_logic; |
hold: in std_logic; |
irq: in std_logic; |
nmi: in std_logic; |
firq: in std_logic; |
test_alu: out std_logic_vector(15 downto 0); |
test_cc: out std_logic_vector(7 downto 0) |
); |
end component cpu09; |
|
|
begin |
cpu : cpu09 port map ( |
clk => SysClk, |
rst => cpu_reset, |
rw => cpu_rw, |
vma => cpu_vma, |
address => cpu_addr(15 downto 0), |
data_in => cpu_data_in, |
data_out => cpu_data_out, |
halt => '0', |
hold => '0', |
irq => cpu_irq, |
nmi => cpu_nmi, |
firq => cpu_firq, |
test_alu => cpu_alu, |
test_cc => cpu_cc |
); |
|
-- *** Test Bench - User Defined Section *** |
tb : PROCESS |
variable count : integer; |
BEGIN |
|
cpu_reset <= '0'; |
SysClk <= '0'; |
cpu_irq <= '0'; |
cpu_nmi <= '0'; |
cpu_firq <= '0'; |
|
for count in 0 to 512 loop |
SysClk <= '0'; |
if count = 0 then |
cpu_reset <= '1'; |
elsif count = 1 then |
cpu_reset <= '0'; |
end if; |
wait for 100 ns; |
SysClk <= '1'; |
wait for 100 ns; |
end loop; |
|
wait; -- will wait forever |
END PROCESS; |
-- *** End Test Bench - User Defined Section *** |
|
|
rom : PROCESS( cpu_addr ) |
begin |
cpu_data_in <= rom_data(conv_integer(cpu_addr(5 downto 0))); |
end process; |
|
end behavior; --===================== End of architecture =======================-- |
|
/vhdl/testbench2.vhd
0,0 → 1,304
--===========================================================================---- |
-- |
-- T E S T B E N C H tesetbench2 - CPU09 Testbench. |
-- |
-- www.OpenCores.Org - September 2003 |
-- This core adheres to the GNU public license |
-- |
-- File name : Testbench2.vhd |
-- |
-- Purpose : cpu09 Microprocessor Test Bench 2 |
-- Contains ROM to read sector from |
-- a none existant Compact Flash module |
-- |
-- Dependencies : ieee.Std_Logic_1164 |
-- ieee.std_logic_unsigned |
-- ieee.std_logic_arith |
-- ieee.numeric_std |
-- |
-- Uses : cpu09 (cpu09.vhd) CPU core |
-- |
-- Author : John E. Kent |
-- dilbert57@opencores.org |
-- |
--===========================================================================---- |
-- |
-- Revision History: |
--===========================================================================-- |
-- |
-- Version 0.1 - 12st April 2003 - John Kent |
-- First version |
-- |
-- Version 1.0- 6 Sep 2003 - John Kent |
-- Initial release to Open Cores |
-- |
--===========================================================================-- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use IEEE.STD_LOGIC_ARITH.ALL; |
use IEEE.STD_LOGIC_UNSIGNED.ALL; |
use ieee.numeric_std.all; |
|
entity my_testbench is |
end my_testbench; |
|
------------------------------------------------------------------------------- |
-- Architecture for memio Controller Unit |
------------------------------------------------------------------------------- |
architecture behavior of my_testbench is |
----------------------------------------------------------------------------- |
-- Signals |
----------------------------------------------------------------------------- |
|
-- CPU Interface signals |
signal SysClk : Std_Logic; |
signal cpu_reset : Std_Logic; |
signal cpu_rw : Std_Logic; |
signal cpu_vma : Std_Logic; |
signal cpu_addr : Std_Logic_Vector(15 downto 0); |
signal cpu_data_in : Std_Logic_Vector(7 downto 0); |
signal cpu_data_out: Std_Logic_Vector(7 downto 0); |
signal cpu_alu : Std_Logic_Vector(15 downto 0); |
signal cpu_cc : Std_Logic_Vector(7 downto 0); |
signal cpu_irq : Std_Logic; |
signal cpu_nmi : Std_Logic; |
signal cpu_firq : std_logic; |
|
constant width : integer := 8; |
constant memsize : integer := 128; |
|
type rom_array is array(0 to memsize-1) of std_logic_vector(width-1 downto 0); |
|
constant rom_data : rom_array := |
( |
"00010000", -- $F800 LDS #$F878 (Point to dummy return to test stack) |
"11001110", |
"11111000", |
"01111000", |
"10000110", -- $F804 LDA #$E0 *** START |
"11100000", |
"00011111", -- $F806 TFR A,DPR |
"10001011", |
--------------------------- |
-- "10001101", -- $F80E BSR WAITRDY $F86A |
-- "01100000", |
"10001101", -- $F808 BSR $F874 -- test sub call |
"01101010", |
--------------------------- |
"10000110", -- $F80A LDA #$E0 |
"11100000", |
"10010111", -- $F80C STA <$E016 |
"00010110", |
--------------------------- |
-- "10001101", -- $F80E BSR WAITRDY $F86A |
-- "01011010", |
"10001101", -- $F80E BSR $F810 |
"00000000", |
-------------------------- |
"10000110", -- $F810 LDA #$01 |
"00000001", |
"10010111", -- $F812 STA <$E011 |
"00010001", |
"10000110", -- $F814 LDA #$EF |
"11101111", |
"10010111", -- $F816 STA <$E017 |
"00010111", |
-------------------------- |
-- "10001101", -- $F818 BSR WAITRDY $F86A |
-- "01010000", |
"10001101", -- $F818 BSR $F816 |
"00000000", |
-------------------------- |
"00010000", -- $F81A LDY #$F800 |
"10001110", |
"11111000", |
"00000000", |
"11000110", -- $F81E LDB #$7C |
"01111100", |
"10000110", -- $F820 LDA #$01 *** RDLP1 |
"00000001", |
"10010111", -- $F822 STA <$E012 |
"00010010", |
"11010111", -- $F824 STB <$E013 |
"00010011", |
"10000110", -- $F826 LDA #$F4 |
"11110100", |
"10010111", -- $F828 STA <$E014 |
"00010100", |
"01001111", -- $F82A CLRA |
"10010111", -- $F82B STA <$E015 |
"00010101", |
"10001110", -- $F82D LDX #512 |
"00000010", |
"00000000", |
"10000110", -- $F830 LDA #$20 |
"00100000", |
"10010111", -- $F832 STA <$E017 |
"00010111", |
-------------------------- |
-- "10001101", -- $F834 BSR WAITRDY $F86A |
-- "00110100", |
"10001101", -- $F834 BSR * |
"00000000", |
-------------------------- |
"10010110", -- $F836 LDA <$E017 *** WAITDRQ |
"00010111", |
"10000101", -- $F838 BITA #$08 |
"00001000", |
"00100111", -- $F83A BEQ WAITDRQ |
"11111010", |
"10010110", -- $F83C LDA <$E010 |
"00010000", |
"10100111", -- $F83E STA ,Y+ |
"10100000", |
"00110000", -- $F840 LEAX -1,X |
"00011111", |
"10001100", -- $F842 CMPX #$0000 |
"00000000", |
"00000000", |
"00100110", -- $F845 BNE RDLP2 |
"11110011", |
-------------------------- |
-- "10001101", -- $F847 BSR WAITRDY $F86A |
-- "00100001", |
"10001101", -- $F847 BSR $F841 |
"00000000", |
-------------------------- |
"01011100", -- $F849 INCB |
"11000001", -- $F84A CMPB #$80 |
"10000000", |
"00100110", -- $F84C BNE RDLP1 |
"11010110", |
"10001110", -- $F84E LDX #$FF97 |
"11111111", |
"10010111", |
"00010000", -- $F851 LDY #$F000 |
"10001110", |
"11110000", |
"00000000", |
"11000110", -- $F855 LDB #$61 |
"01100001", |
"10100110", -- $F857 LDA 0,X+ *** MOVELP |
"10000000", |
"10100111", -- $F859 STA 0,Y+ |
"10100000", |
"01011010", -- $F85B DECB |
---------------------------- |
-- "00100110", -- $F85C BNE MOVELP |
-- "11111001", |
"00100110", --$F85C BNE $F861 |
"00000011", |
---------------------------- |
"01111110", -- $F85E JMP $F000 |
"11110000", |
"00000000", |
"00001111", -- $F861 CLR <$E030 |
"00110000", |
"01001111", -- $F863 CLRA |
"00011111", -- $F864 TFR A,DPR |
"10001011", |
"01101110", -- $F866 JMP [$FFFE] |
"10011111", |
"11111111", |
"11111110", |
-- |
-- Wait for Ready |
-- |
"10010110", -- $F86A LDA <$E017 *** WAITRDY |
"00010111", |
"00101011", -- $F86C BMI WAITRDY |
"11111100", |
"10010110", -- $F86E LDA <$E017 |
"00010111", |
"10000101", -- $F870 BITA #$40 |
"01000000", |
"00100111", -- $F872 BNE WAITRQY |
"11110110", |
"00111001", -- $F874 RTS |
"00010010", -- $F875 NOP |
"11111000", -- $F876 FDB $F80A -- dummy sub return |
"00001010", |
"11111000", -- $F878 FDB $F800 |
"00000000", |
"11111000", -- $F87A FDB $F800 |
"00000000", |
"11111000", -- $F87C FDB $F800 |
"00000000", |
"11111000", -- $F87E FDB $F800 |
"00000000" |
); |
|
component cpu09 |
port ( |
clk: in std_logic; |
rst: in std_logic; |
rw: out std_logic; -- Asynchronous memory interface |
vma: out std_logic; |
address: out std_logic_vector(15 downto 0); |
data_in: in std_logic_vector(7 downto 0); |
data_out: out std_logic_vector(7 downto 0); |
halt: in std_logic; |
hold: in std_logic; |
irq: in std_logic; |
nmi: in std_logic; |
firq: in std_logic; |
test_alu: out std_logic_vector(15 downto 0); |
test_cc: out std_logic_vector(7 downto 0) |
); |
end component cpu09; |
|
|
begin |
cpu : cpu09 port map ( |
clk => SysClk, |
rst => cpu_reset, |
rw => cpu_rw, |
vma => cpu_vma, |
address => cpu_addr(15 downto 0), |
data_in => cpu_data_in, |
data_out => cpu_data_out, |
halt => '0', |
hold => '0', |
irq => cpu_irq, |
nmi => cpu_nmi, |
firq => cpu_firq, |
test_alu => cpu_alu, |
test_cc => cpu_cc |
); |
|
-- *** Test Bench - User Defined Section *** |
tb : PROCESS |
variable count : integer; |
BEGIN |
|
cpu_reset <= '0'; |
SysClk <= '0'; |
cpu_irq <= '0'; |
cpu_nmi <= '0'; |
cpu_firq <= '0'; |
|
for count in 0 to 512 loop |
SysClk <= '0'; |
if count = 0 then |
cpu_reset <= '1'; |
elsif count = 1 then |
cpu_reset <= '0'; |
end if; |
wait for 100 ns; |
SysClk <= '1'; |
wait for 100 ns; |
end loop; |
|
wait; -- will wait forever |
END PROCESS; |
-- *** End Test Bench - User Defined Section *** |
|
|
rom : PROCESS( cpu_addr ) |
begin |
cpu_data_in <= rom_data(conv_integer(cpu_addr(6 downto 0))); |
end process; |
|
end behavior; --===================== End of architecture =======================-- |
|
/vhdl/testbench3.vhd
0,0 → 1,186
--===========================================================================---- |
-- |
-- T E S T B E N C H tesetbench3 - CPU09 Testbench. |
-- |
-- www.OpenCores.Org - September 2003 |
-- This core adheres to the GNU public license |
-- |
-- File name : Testbench3.vhd |
-- |
-- Purpose : cpu09 Microprocessor Test Bench 3 |
-- Contains ROM to test interrupts |
-- |
-- Dependencies : ieee.Std_Logic_1164 |
-- ieee.std_logic_unsigned |
-- ieee.std_logic_arith |
-- ieee.numeric_std |
-- |
-- Uses : cpu09 (cpu09.vhd) CPU core |
-- |
-- Author : John E. Kent |
-- dilbert57@opencores.org |
-- |
--===========================================================================---- |
-- |
-- Revision History: |
--===========================================================================-- |
-- |
-- Version 0.1 - 12st April 2003 - John Kent |
-- First version |
-- |
-- Version 1.0 - 6 Sep 2003 - John Kent |
-- Initial release to Open Cores |
-- |
--===========================================================================-- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use IEEE.STD_LOGIC_ARITH.ALL; |
use IEEE.STD_LOGIC_UNSIGNED.ALL; |
use ieee.numeric_std.all; |
|
entity my_testbench is |
end my_testbench; |
|
------------------------------------------------------------------------------- |
-- Architecture for memio Controller Unit |
------------------------------------------------------------------------------- |
architecture behavior of my_testbench is |
----------------------------------------------------------------------------- |
-- Signals |
----------------------------------------------------------------------------- |
signal cpu_irq : std_Logic; |
signal cpu_firq : std_logic; |
signal cpu_nmi : std_logic; |
|
-- CPU Interface signals |
signal SysClk : Std_Logic; |
signal cpu_reset : Std_Logic; |
signal cpu_rw : Std_Logic; |
signal cpu_vma : Std_Logic; |
signal cpu_addr : Std_Logic_Vector(15 downto 0); |
signal cpu_data_in : Std_Logic_Vector(7 downto 0); |
signal cpu_data_out: Std_Logic_Vector(7 downto 0); |
signal cpu_alu : Std_Logic_Vector(15 downto 0); |
signal cpu_cc : Std_Logic_Vector(7 downto 0); |
|
constant width : integer := 8; |
constant memsize : integer := 64; |
|
type rom_array is array(0 to memsize-1) of std_logic_vector(width-1 downto 0); |
|
constant rom_data : rom_array := |
( |
"00010000", "11001110", "11111000", "00110000", -- F800 - 10CE F830 RET1 LDS #STACK |
"00111111", -- F804 - 3F SWI |
"00010000", "00111111", -- F805 - 103F SWIVEC SWI2 |
"00010001", "00111111", -- F807 - 113F SWI2VEC SWI3 |
"00111011", -- F809 - 3B SWI3VEC RTI |
"00100000", "11111110", -- F80A - 20 FE BRA * |
"10110001", -- F80C - B1 STACK3 FCB $B1 ; CC |
"00110010", -- F80D - 32 FCB $32 ; ACCA |
"00110011", -- F8OE - 33 FCB $33 ; ACCB |
"00110100", -- F8OF - 34 FCB $34 ; DPR |
"00110101", "00110110", -- F810 - 3536 FDB $3536 ; IX |
"00110111", "00111000", -- F812 - 3738 FDB $3738 ; IY |
"00111001", "00111010", -- F814 - 393A FDB $393A ; UP |
"11111000", "00001001", -- F816 - F809 FDB SWI3VEC ; PC |
"10100001", -- F818 - A1 STACK2 FCB $A1 ; CC |
"00100010", -- F819 - 22 FCB $22 ; ACCA |
"00100011", -- F81A - 23 FCB $23 ; ACCB |
"00100100", -- F81B - 24 FCB $24 ; DPR |
"00100101", "00100110", -- F81C - 2526 FDB $2526 ; IX |
"00100111", "00101000", -- F81E - 2728 FDB $2728 ; IY |
"00101001", "00101010", -- F820 - 292A FDB $292A ; UP |
"11111000", "00001001", -- F822 - F809 FDB SWI3VEC ; PC |
"10010001", -- F824 - 91 STACK1 FCB $91 ; CC |
"00010010", -- F825 - 12 FCB $12 ; ACCA |
"00010011", -- F826 - 13 FCB $13 ; ACCB |
"00010100", -- F827 - 14 FCB $14 ; DPR |
"00010101", "00010110", -- F828 - 1516 FDB $1516 ; IX |
"00010111", "00011000", -- F82A - 1718 FDB $1718 ; IY |
"00011001", "00011010", -- F82C - 191A FDB $191A ; UP |
"11111000", "00000000", -- F82E - F800 FDB RESET ; PC |
"11111000", "00000000", -- F830 - F800 STACK FDB RESET ; RESV |
"11111000", "00001001", -- F832 - F809 FDB SWIVEC3 ; SWI3 |
"11111000", "00000111", -- F834 - F807 FDB SWIVEC2 ; SWI2 |
"11111000", "00000000", -- F836 - F800 fdb RESET ; FIRQ |
"11111000", "00000000", -- F838 - F800 fdb RESET ; IRQ |
"11111000", "00000101", -- F83A - F805 fdb SWIVEC ; SWI |
"11111000", "00000000", -- F83C - F800 fcb RESET ; NMI |
"11111000", "00000000" -- F83E - F800 fdb RESET ; Reset |
); |
|
component cpu09 |
port ( |
clk: in std_logic; |
rst: in std_logic; |
rw: out std_logic; -- Asynchronous memory interface |
vma: out std_logic; |
address: out std_logic_vector(15 downto 0); |
data_in: in std_logic_vector(7 downto 0); |
data_out: out std_logic_vector(7 downto 0); |
halt: in std_logic; |
hold: in std_logic; |
irq: in std_logic; |
nmi: in std_logic; |
firq: in std_logic; |
test_alu: out std_logic_vector(15 downto 0); |
test_cc: out std_logic_vector(7 downto 0) |
); |
end component cpu09; |
|
|
begin |
cpu : cpu09 port map ( |
clk => SysClk, |
rst => cpu_reset, |
rw => cpu_rw, |
vma => cpu_vma, |
address => cpu_addr(15 downto 0), |
data_in => cpu_data_in, |
data_out => cpu_data_out, |
halt => '0', |
hold => '0', |
irq => cpu_irq, |
nmi => cpu_nmi, |
firq => cpu_firq, |
test_alu => cpu_alu, |
test_cc => cpu_cc |
); |
|
-- *** Test Bench - User Defined Section *** |
tb : PROCESS |
variable count : integer; |
BEGIN |
|
cpu_reset <= '0'; |
SysClk <= '0'; |
cpu_irq <= '0'; |
cpu_nmi <= '0'; |
cpu_firq <= '0'; |
|
for count in 0 to 512 loop |
SysClk <= '0'; |
if count = 0 then |
cpu_reset <= '1'; |
elsif count = 1 then |
cpu_reset <= '0'; |
end if; |
wait for 100 ns; |
SysClk <= '1'; |
wait for 100 ns; |
end loop; |
|
wait; -- will wait forever |
END PROCESS; |
-- *** End Test Bench - User Defined Section *** |
|
|
rom : PROCESS( cpu_addr ) |
begin |
cpu_data_in <= rom_data(conv_integer(cpu_addr(5 downto 0))); |
end process; |
|
end behavior; --===================== End of architecture =======================-- |
|
/vhdl/testbench4.vhd
0,0 → 1,161
--===========================================================================-- |
-- |
-- MC6809 Microprocessor Test Bench 4 |
-- Test Software - SBUG ROM |
-- |
-- |
-- John Kent 12st April 2003 |
-- |
-- |
------------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
use IEEE.STD_LOGIC_ARITH.ALL; |
use ieee.numeric_std.all; |
|
entity my_testbench is |
end my_testbench; |
|
------------------------------------------------------------------------------- |
-- Architecture for memio Controller Unit |
------------------------------------------------------------------------------- |
architecture behavior of my_testbench is |
----------------------------------------------------------------------------- |
-- Signals |
----------------------------------------------------------------------------- |
signal cpu_irq : std_Logic; |
signal cpu_firq : std_logic; |
signal cpu_nmi : std_logic; |
|
-- CPU Interface signals |
signal SysClk : Std_Logic; |
signal cpu_reset : Std_Logic; |
signal cpu_rw : Std_Logic; |
signal cpu_vma : Std_Logic; |
signal cpu_addr : Std_Logic_Vector(15 downto 0); |
signal cpu_data_in : Std_Logic_Vector(7 downto 0); |
signal cpu_data_out: Std_Logic_Vector(7 downto 0); |
signal cpu_halt : Std_logic; |
signal cpu_hold : Std_logic; |
signal cpu_alu : Std_Logic_Vector(15 downto 0); |
signal cpu_cc : Std_Logic_Vector(7 downto 0); |
signal rom_data_out: Std_Logic_Vector(7 downto 0); |
signal ram_data_out: Std_Logic_Vector(7 downto 0); |
signal ram_cs : Std_Logic; |
|
component cpu09 |
port ( |
clk: in std_logic; |
rst: in std_logic; |
rw: out std_logic; -- Asynchronous memory interface |
vma: out std_logic; |
address: out std_logic_vector(15 downto 0); |
data_in: in std_logic_vector(7 downto 0); |
data_out: out std_logic_vector(7 downto 0); |
halt: in std_logic; |
hold: in std_logic; |
irq: in std_logic; |
nmi: in std_logic; |
firq: in std_logic; |
test_alu: out std_logic_vector(15 downto 0); |
test_cc: out std_logic_vector(7 downto 0) |
); |
end component; |
|
|
component sbug_rom |
Port ( |
MEMclk : in std_logic; |
MEMaddr : in std_logic_vector (10 downto 0); |
MEMrdata : out std_logic_vector (7 downto 0) |
); |
end component; |
|
component block_ram |
Port ( |
MEMclk : in std_logic; |
MEMcs : in std_logic; |
MEMrw : in std_logic; |
MEMaddr : in std_logic_vector (10 downto 0); |
MEMrdata : out std_logic_vector (7 downto 0); |
MEMwdata : in std_logic_vector (7 downto 0) |
); |
end component; |
|
begin |
my_cpu : cpu09 port map ( |
clk => SysClk, |
rst => cpu_reset, |
rw => cpu_rw, |
vma => cpu_vma, |
address => cpu_addr(15 downto 0), |
data_in => cpu_data_in, |
data_out => cpu_data_out, |
halt => cpu_halt, |
hold => cpu_hold, |
irq => cpu_irq, |
nmi => cpu_nmi, |
firq => cpu_firq, |
test_alu => cpu_alu, |
test_cc => cpu_cc |
); |
|
|
my_ram : block_ram port map ( |
MEMclk => SysClk, |
MEMcs => ram_cs, |
MEMrw => cpu_rw, |
MEMaddr => cpu_addr(10 downto 0), |
MEMrdata => ram_data_out, |
MEMwdata => cpu_data_out |
); |
|
my_rom : sbug_rom port map ( |
MEMclk => SysClk, |
MEMaddr => cpu_addr(10 downto 0), |
MEMrdata => rom_data_out |
); |
|
-- *** Test Bench - User Defined Section *** |
tb : PROCESS |
variable count : integer; |
BEGIN |
|
cpu_reset <= '0'; |
SysClk <= '0'; |
cpu_irq <= '0'; |
cpu_nmi <= '0'; |
cpu_firq <= '0'; |
cpu_halt <= '0'; |
cpu_hold <= '0'; |
|
for count in 0 to 512 loop |
SysClk <= '0'; |
if count = 0 then |
cpu_reset <= '1'; |
elsif count = 1 then |
cpu_reset <= '0'; |
end if; |
wait for 100 ns; |
SysClk <= '1'; |
wait for 100 ns; |
end loop; |
|
wait; -- will wait forever |
END PROCESS; |
-- *** End Test Bench - User Defined Section *** |
|
|
rom : PROCESS( cpu_addr, rom_data_out, ram_data_out ) |
begin |
if( cpu_addr(15 downto 11) = "11111" ) then |
cpu_data_in <= rom_data_out; |
ram_cs <= '0'; |
else |
cpu_data_in <= ram_data_out; |
ram_cs <= '1'; |
end if; |
end process; |
|
end behavior; --===================== End of architecture =======================-- |
|
/vhdl/System09.npl
0,0 → 1,37
JDF E |
// Created by ISE ver 1.0 |
PROJECT System09 |
DESIGN system09 Normal |
DEVKIT xc2s300e-6pq208 |
DEVFAM spartan2e |
FLOW XST VHDL |
STIMULUS testbench1.vhd Normal |
STIMULUS testbench2.vhd Normal |
STIMULUS testbench3.vhd Normal |
STIMULUS System09_tb.vhd Normal |
MODULE ioport.vhd |
MODSTYLE ioport Normal |
MODULE rxunit2.vhd |
MODSTYLE rxunit Normal |
MODULE txunit2.vhd |
MODSTYLE txunit Normal |
MODULE cpu09.vhd |
MODSTYLE cpu09 Normal |
MODULE clkunit2.vhd |
MODSTYLE clkunit Normal |
MODULE datram.vhd |
MODSTYLE dat_ram Normal |
MODULE timer.vhd |
MODSTYLE timer Normal |
MODULE System09.vhd |
MODSTYLE system09 Normal |
MODULE sbug.vhd |
MODSTYLE boot_rom Normal |
MODULE miniUART2.vhd |
MODSTYLE miniuart Normal |
|
[STRATEGY-LIST] |
Normal=True, 1062166682 |
|
[Normal] |
p_impactConfigMode=xstvhd, SPARTAN2E, Implementation.t_impactProgrammingTool, 1031246025, Slave Serial |
/vhdl/datram.vhd
0,0 → 1,184
--===========================================================================-- |
-- |
-- S Y N T H E Z I A B L E Dynamic Address Translation Registers |
-- |
-- www.OpenCores.Org - December 2002 |
-- This core adheres to the GNU public license |
-- |
-- File name : datram.vhd |
-- |
-- entity name : dat_ram |
-- |
-- Purpose : Implements a Dynamic Address Translation RAM module |
-- Maps the high order 4 address bits to 8 address lines |
-- extending the memory addressing range to 1 Mbytes |
-- Memory segments are mapped on 4 KByte boundaries |
-- The DAT registers map to the top of memory |
-- ($FFF0 - $FFFF) and are write only so can map over ROM. |
-- Since the DAT is not supported by SWTBUG for the 6800, |
-- the resgisters reset state map the bottom 64K of RAM. |
-- |
-- Dependencies : ieee.Std_Logic_1164 |
-- ieee.std_logic_unsigned |
-- |
-- Author : John E. Kent |
-- |
--===========================================================================---- |
-- |
-- Revision History: |
-- |
-- Date Revision Author |
-- 10 Nov 2002 0.1 John Kent |
-- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
|
entity dat_ram is |
port ( |
clk : in std_logic; |
rst : in std_logic; |
cs : in std_logic; |
rw : in std_logic; |
addr_hi : in std_logic_vector(3 downto 0); |
addr_lo : in std_logic_vector(3 downto 0); |
data_in : in std_logic_vector(7 downto 0); |
data_out : out std_logic_vector(7 downto 0)); |
end; |
|
architecture datram_arch of dat_ram is |
signal dat_reg0 : std_logic_vector(7 downto 0); |
signal dat_reg1 : std_logic_vector(7 downto 0); |
signal dat_reg2 : std_logic_vector(7 downto 0); |
signal dat_reg3 : std_logic_vector(7 downto 0); |
signal dat_reg4 : std_logic_vector(7 downto 0); |
signal dat_reg5 : std_logic_vector(7 downto 0); |
signal dat_reg6 : std_logic_vector(7 downto 0); |
signal dat_reg7 : std_logic_vector(7 downto 0); |
signal dat_reg8 : std_logic_vector(7 downto 0); |
signal dat_reg9 : std_logic_vector(7 downto 0); |
signal dat_reg10 : std_logic_vector(7 downto 0); |
signal dat_reg11 : std_logic_vector(7 downto 0); |
signal dat_reg12 : std_logic_vector(7 downto 0); |
signal dat_reg13 : std_logic_vector(7 downto 0); |
signal dat_reg14 : std_logic_vector(7 downto 0); |
signal dat_reg15 : std_logic_vector(7 downto 0); |
|
begin |
|
--------------------------------- |
-- |
-- Write DAT RAM |
-- |
--------------------------------- |
|
dat_write : process( clk, rst, addr_lo, cs, rw, data_in ) |
begin |
if clk'event and clk = '0' then |
if rst = '1' then |
dat_reg0 <= "00000000"; |
dat_reg1 <= "00000001"; |
dat_reg2 <= "00000010"; |
dat_reg3 <= "00000011"; |
dat_reg4 <= "00000100"; |
dat_reg5 <= "00000101"; |
dat_reg6 <= "00000110"; |
dat_reg7 <= "00000111"; |
dat_reg8 <= "00001000"; |
dat_reg9 <= "00001001"; |
dat_reg10 <= "00001010"; |
dat_reg11 <= "00001011"; |
dat_reg12 <= "00001100"; |
dat_reg13 <= "00001101"; |
dat_reg14 <= "00001110"; |
dat_reg15 <= "00001111"; |
else |
if cs = '1' and rw = '0' then |
case addr_lo is |
when "0000" => |
dat_reg0 <= data_in; |
when "0001" => |
dat_reg1 <= data_in; |
when "0010" => |
dat_reg2 <= data_in; |
when "0011" => |
dat_reg3 <= data_in; |
when "0100" => |
dat_reg4 <= data_in; |
when "0101" => |
dat_reg5 <= data_in; |
when "0110" => |
dat_reg6 <= data_in; |
when "0111" => |
dat_reg7 <= data_in; |
when "1000" => |
dat_reg8 <= data_in; |
when "1001" => |
dat_reg9 <= data_in; |
when "1010" => |
dat_reg10 <= data_in; |
when "1011" => |
dat_reg11 <= data_in; |
when "1100" => |
dat_reg12 <= data_in; |
when "1101" => |
dat_reg13 <= data_in; |
when "1110" => |
dat_reg14 <= data_in; |
when "1111" => |
dat_reg15 <= data_in; |
when others => |
null; |
end case; |
end if; |
end if; |
end if; |
end process; |
|
dat_read : process( addr_hi, |
dat_reg0, dat_reg1, dat_reg2, dat_reg3, |
dat_reg4, dat_reg5, dat_reg6, dat_reg7, |
dat_reg8, dat_reg9, dat_reg10, dat_reg11, |
dat_reg12, dat_reg13, dat_reg14, dat_reg15 ) |
begin |
case addr_hi is |
when "0000" => |
data_out <= dat_reg0; |
when "0001" => |
data_out <= dat_reg1; |
when "0010" => |
data_out <= dat_reg2; |
when "0011" => |
data_out <= dat_reg3; |
when "0100" => |
data_out <= dat_reg4; |
when "0101" => |
data_out <= dat_reg5; |
when "0110" => |
data_out <= dat_reg6; |
when "0111" => |
data_out <= dat_reg7; |
when "1000" => |
data_out <= dat_reg8; |
when "1001" => |
data_out <= dat_reg9; |
when "1010" => |
data_out <= dat_reg10; |
when "1011" => |
data_out <= dat_reg11; |
when "1100" => |
data_out <= dat_reg12; |
when "1101" => |
data_out <= dat_reg13; |
when "1110" => |
data_out <= dat_reg14; |
when "1111" => |
data_out <= dat_reg15; |
when others => |
null; |
end case; |
end process; |
|
end datram_arch; |
|
/vhdl/miniUART2.vhd
0,0 → 1,288
--===========================================================================-- |
-- |
-- S Y N T H E Z I A B L E miniUART C O R E |
-- |
-- www.OpenCores.Org - January 2000 |
-- This core adheres to the GNU public license |
-- |
-- Design units : miniUART core for the System68 |
-- |
-- File name : miniuart2.vhd |
-- |
-- Purpose : Implements an miniUART device for communication purposes |
-- between the CPU68 processor and the Host computer through |
-- an RS-232 communication protocol. |
-- |
-- Dependencies : ieee.std_logic_1164 |
-- ieee.numeric_std |
-- |
--===========================================================================-- |
------------------------------------------------------------------------------- |
-- Revision list |
-- Version Author Date Changes |
-- |
-- 0.1 Ovidiu Lupas 15 January 2000 New model |
-- 1.0 Ovidiu Lupas January 2000 Synthesis optimizations |
-- 2.0 Ovidiu Lupas April 2000 Bugs removed - RSBusCtrl |
-- the RSBusCtrl did not process all possible situations |
-- |
-- olupas@opencores.org |
-- |
-- 3.0 John Kent October 2002 Changed Status bits to match mc6805 |
-- Added CTS, RTS, Baud rate control |
-- & Software Reset |
-- 3.1 John Kent 5 January 2003 Added Word Format control a'la mc6850 |
-- 3.2 John Kent 19 July 2003 Latched Data input to UART |
-- 3.3 John Kent 6 September 2003 Changed Clock Edge. |
-- dilbert57@opencores.org |
-- |
------------------------------------------------------------------------------- |
-- Entity for miniUART Unit - 9600 baudrate -- |
------------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
entity miniUART is |
port ( |
SysClk : in Std_Logic; -- System Clock |
rst : in Std_Logic; -- Reset input (active high) |
cs : in Std_Logic; |
rw : in Std_Logic; |
RxD : in Std_Logic; |
TxD : out Std_Logic; |
CTS_n : in Std_Logic; |
RTS_n : out Std_Logic; |
Irq : out Std_Logic; -- interrupt |
Addr : in Std_Logic; -- Register Select |
DataIn : in Std_Logic_Vector(7 downto 0); -- |
DataOut : out Std_Logic_Vector(7 downto 0)); -- |
end; --================== End of entity ==============================-- |
------------------------------------------------------------------------------- |
-- Architecture for miniUART Controller Unit |
------------------------------------------------------------------------------- |
architecture uart of miniUART is |
----------------------------------------------------------------------------- |
-- Signals |
----------------------------------------------------------------------------- |
signal RxData : Std_Logic_Vector(7 downto 0); -- |
signal TxData : Std_Logic_Vector(7 downto 0); -- |
signal StatReg : Std_Logic_Vector(7 downto 0); -- status register |
-- StatReg detailed |
-----------+--------+--------+--------+--------+--------+--------+--------+ |
-- Irq | PErr | ORErr | FErr | CTS | DCD | TBufE | DRdy | |
-----------+--------+--------+--------+--------+--------+--------+--------+ |
signal CtrlReg : Std_Logic_Vector(7 downto 0); -- control register |
-- CtrlReg detailed |
-----------+--------+--------+--------+--------+--------+--------+--------+ |
-- IrqEnb |TxCtl(1)|TxCtl(0)|WdFmt(2)|WdFmt(1)|WdFmt(0)|BdCtl(1)|BdCtl(0)| |
-----------+--------+--------+--------+--------+--------+--------+--------+ |
-- IrqEnb |
-- 0 - Rx Interrupt disabled |
-- 1 - Rx Interrupt enabled |
-- TxCtl |
-- 0 1 - Tx Interrupt Enable |
-- 1 0 - RTS high |
-- WdFmt |
-- 0 0 0 - 7 data, even parity, 2 stop |
-- 0 0 1 - 7 data, odd parity, 2 stop |
-- 0 1 0 - 7 data, even parity, 1 stop |
-- 0 1 1 - 7 data, odd parity, 1 stop |
-- 1 0 0 - 8 data, no parity, 2 stop |
-- 1 0 1 - 8 data, no parity, 1 stop |
-- 1 1 0 - 8 data, even parity, 1 stop |
-- 1 1 1 - 8 data, odd parity, 1 stop |
-- BdCtl |
-- 0 0 - Baud Clk divide by 1 (not implemented) |
-- 0 1 - Baud Clk divide by 16 |
-- 1 0 - Baud Clk divide by 64 |
-- 1 1 - reset |
|
signal EnabRx : Std_Logic; -- Enable RX unit |
signal EnabTx : Std_Logic; -- Enable TX unit |
signal DRdy : Std_Logic; -- Receive Data ready |
signal TBufE : Std_Logic; -- Transmit buffer empty |
signal FErr : Std_Logic; -- Frame error |
signal OErr : Std_Logic; -- Output error |
signal PErr : Std_Logic; -- Parity Error |
signal Read : Std_Logic; -- Read receive buffer |
signal Load : Std_Logic; -- Load transmit buffer |
signal Int : Std_Logic; -- Interrupt bit |
signal Reset : Std_Logic; -- Reset (Software & Hardware) |
----------------------------------------------------------------------------- |
-- Baud rate Generator |
----------------------------------------------------------------------------- |
component ClkUnit |
port ( |
Clk : in Std_Logic; -- System Clock |
Reset : in Std_Logic; -- Reset input |
EnableRX : out Std_Logic; -- Control signal |
EnableTX : out Std_Logic; -- Control signal |
BaudRate : in Std_Logic_Vector(1 downto 0)); |
end component; |
----------------------------------------------------------------------------- |
-- Receive Unit |
----------------------------------------------------------------------------- |
component RxUnit |
port ( |
Clk : in Std_Logic; -- Clock signal |
Reset : in Std_Logic; -- Reset input |
Enable : in Std_Logic; -- Enable input |
RxD : in Std_Logic; -- RS-232 data input |
ReadD : in Std_Logic; -- Read data signal |
Format : in Std_Logic_Vector(2 downto 0); -- word format |
FRErr : out Std_Logic; -- Status signal |
ORErr : out Std_Logic; -- Status signal |
PAErr : out Std_logic; -- Status signal |
DARdy : out Std_Logic; -- Status signal |
DAOut : out Std_Logic_Vector(7 downto 0)); |
end component; |
----------------------------------------------------------------------------- |
-- Transmitter Unit |
----------------------------------------------------------------------------- |
component TxUnit |
port ( |
Clk : in Std_Logic; -- Clock signal |
Reset : in Std_Logic; -- Reset input |
Enable : in Std_Logic; -- Enable input |
LoadD : in Std_Logic; -- Load transmit data |
Format : in Std_Logic_Vector(2 downto 0); -- word format |
TxD : out Std_Logic; -- RS-232 data output |
TBE : out Std_Logic; -- Tx buffer empty |
DataO : in Std_Logic_Vector(7 downto 0)); |
end component; |
begin |
----------------------------------------------------------------------------- |
-- Instantiation of internal components |
----------------------------------------------------------------------------- |
|
ClkDiv : ClkUnit port map ( |
Clk => SysClk, |
EnableRx => EnabRX, |
EnableTx => EnabTX, |
BaudRate => CtrlReg(1 downto 0), |
Reset => Reset); |
|
TxDev : TxUnit port map ( |
Clk => SysClk, |
Reset => Reset, |
Enable => EnabTX, |
LoadD => Load, |
Format => CtrlReg(4 downto 2), |
TxD => TxD, |
TBE => TBufE, |
DataO => TxData); |
|
RxDev : RxUnit port map ( |
Clk => SysClk, |
Reset => Reset, |
Enable => EnabRX, |
RxD => RxD, |
ReadD => Read, |
Format => CtrlReg(4 downto 2), |
FRErr => FErr, |
ORErr => OErr, |
PAErr => PErr, |
DARdy => DRdy, |
DAOut => RxData); |
|
----------------------------------------------------------------------------- |
-- Implements the controller for Rx&Tx units |
----------------------------------------------------------------------------- |
RSBusCtrl : process(SysClk, Reset, DRdy, TBufE, FErr, OErr, CTS_n, PErr, Int, CtrlReg) |
variable StatM : Std_Logic_Vector(7 downto 0); |
begin |
if SysClk'event and SysClk='0' then |
if Reset = '1' then |
StatM := "00000000"; |
Int <= '0'; |
else |
StatM(0) := DRdy; |
StatM(1) := TBufE; |
StatM(2) := '0'; -- DCD |
StatM(3) := CTS_n; |
StatM(4) := FErr; -- Framing error |
StatM(5) := OErr; -- Overrun error |
StatM(6) := PErr; -- Parity error |
StatM(7) := Int; |
Int <= (CtrlReg(7) and DRdy) or |
((not CtrlReg(6)) and CtrlReg(5) and TBufE); |
end if; |
|
RTS_n <= CtrlReg(6) and not CtrlReg(5); |
Irq <= Int; |
StatReg <= StatM; |
end if; |
end process; |
|
----------------------------------------------------------------------------- |
-- Combinational section |
----------------------------------------------------------------------------- |
|
control_strobe: process(SysClk, Reset, cs, rw, Addr, DataIn, CtrlReg, TxData ) |
begin |
if SysClk'event and SysClk='0' then |
if (reset = '1') then |
CtrlReg <= "00000000"; |
Load <= '0'; |
Read <= '0'; |
else |
if cs = '1' then |
if Addr = '1' then |
CtrlReg <= CtrlReg; |
if rw = '0' then -- write data register |
TxData <= DataIn; |
Load <= '1'; |
Read <= '0'; |
else -- read Data Register |
TxData <= TxData; |
Load <= '0'; |
Read <= '1'; |
end if; -- rw |
else -- read Status Register |
TxData <= TxData; |
Load <= '0'; |
Read <= '0'; |
if rw = '0' then -- write control register |
CtrlReg <= DataIn; |
else -- read control Register |
CtrlReg <= CtrlReg; |
end if; -- rw |
end if; -- Addr |
else -- not selected |
Load <= '0'; |
Read <= '0'; |
CtrlReg <= CtrlReg; |
end if; -- cs |
end if; -- reset |
end if; -- SysClk |
end process; |
|
--------------------------------------------------------------- |
-- |
-- set data output mux |
-- |
-------------------------------------------------------------- |
|
data_port: process(Addr, StatReg, RxData ) |
begin |
if Addr = '1' then |
DataOut <= RxData; -- read data register |
else |
DataOut <= StatReg; -- read status register |
end if; -- Addr |
end process; |
|
--------------------------------------------------------------- |
-- |
-- reset may be hardware or software |
-- |
--------------------------------------------------------------- |
|
uart_reset: process(CtrlReg, rst ) |
begin |
Reset <= (CtrlReg(1) and CtrlReg(0)) or rst; |
end process; |
|
end uart; --===================== End of architecture =======================-- |
|
/vhdl/rxunit2.vhd
0,0 → 1,341
--===========================================================================-- |
-- |
-- S Y N T H E Z I A B L E miniUART C O R E |
-- |
-- www.OpenCores.Org - January 2000 |
-- This core adheres to the GNU public license |
-- |
-- Design units : miniUART core for the System68 |
-- |
-- File name : rxunit2.vhd |
-- |
-- Purpose : Implements an miniUART device for communication purposes |
-- between the cpu68 cpu and the Host computer through |
-- an RS-232 communication protocol. |
-- |
-- Dependencies : ieee.std_logic_1164.all; |
-- ieee.numeric_std.all; |
-- |
--===========================================================================-- |
------------------------------------------------------------------------------- |
-- Revision list |
-- Version Author Date Changes |
-- |
-- 0.1 Ovidiu Lupas 15 January 2000 New model |
-- 2.0 Ovidiu Lupas 17 April 2000 samples counter cleared for bit 0 |
-- olupas@opencores.org |
-- |
-- 3.0 John Kent 5 January 2003 Added 6850 word format control |
-- 3.1 John Kent 12 January 2003 Significantly revamped receive code. |
-- 3.3 John Kent 6 September 2003 Changed Clock Edge. |
-- dilbert57@opencores.org |
------------------------------------------------------------------------------- |
-- Description : Implements the receive unit of the miniUART core. Samples |
-- 16 times the RxD line and retain the value in the middle of |
-- the time interval. |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
|
------------------------------------------------------------------------------- |
-- Receive unit |
------------------------------------------------------------------------------- |
entity RxUnit is |
port ( |
Clk : in Std_Logic; -- system clock signal |
Reset : in Std_Logic; -- Reset input |
Enable : in Std_Logic; -- Enable input |
RxD : in Std_Logic; -- RS-232 data input |
ReadD : in Std_Logic; -- Read data signal |
Format : in Std_Logic_Vector(2 downto 0); |
FRErr : out Std_Logic; -- Status signal |
ORErr : out Std_Logic; -- Status signal |
PAErr : out Std_logic; -- Status Signal |
DARdy : out Std_Logic; -- Status signal |
DAOut : out Std_Logic_Vector(7 downto 0) |
); |
end; --================== End of entity ==============================-- |
------------------------------------------------------------------------------- |
-- Architecture for receive Unit |
------------------------------------------------------------------------------- |
architecture Behaviour of RxUnit is |
----------------------------------------------------------------------------- |
-- Signals |
----------------------------------------------------------------------------- |
signal RxStart : Std_Logic; -- Start Receive Request |
signal RxFinish : Std_Logic; -- Receive finished |
signal RxValid : Std_Logic; -- Receive data valid |
signal RxFalse : Std_Logic; -- False start flag |
signal tmpRxD : Std_Logic; -- RxD buffer |
signal tmpRxC : Std_Logic; -- Rx clock |
signal tmpDRdy : Std_Logic; -- Data Ready flag |
signal tmpRxVal : Std_Logic; -- Rx Data Valid |
signal tmpRxFin : Std_Logic; -- Rx Finish |
signal outErr : Std_Logic; -- Over run error bit |
signal frameErr : Std_Logic; -- Framing error bit |
signal ParityErr : Std_Logic; -- Parity Error Bit |
signal RxParity : Std_Logic; -- Calculated RX parity bit |
signal RxState : Std_Logic_Vector(3 downto 0); -- receive bit state |
signal SampleCnt : Std_Logic_Vector(3 downto 0); -- samples on one bit counter |
signal ShtReg : Std_Logic_Vector(7 downto 0); -- Shift Register |
signal DataOut : Std_Logic_Vector(7 downto 0); -- Data Output register |
|
constant CntOne : Std_Logic_Vector(3 downto 0):= "0001"; |
constant CntZero : Std_Logic_Vector(3 downto 0):= "0000"; |
|
begin |
--------------------------------------------------------------------- |
-- Receiver Read process |
--------------------------------------------------------------------- |
RcvRead : process(Clk, Reset, ReadD, RxValid, tmpRxVal, tmpDRdy ) |
begin |
if Clk'event and Clk='0' then |
if Reset = '1' then |
tmpDRdy <= '0'; |
tmpRxVal <= '0'; |
else |
if ReadD = '1' then |
tmpDRdy <= '0'; -- Data was read |
tmpRxVal <= tmpRxVal; |
else |
if RxValid = '1' and tmpRxVal = '0' then |
tmpDRdy <= '1'; -- Data was received |
tmpRxVal <= '1'; |
else |
tmpDRdy <= tmpDRdy; |
if RxValid = '0' and tmpRxVal = '1' then |
tmpRxVal <= '0'; |
else |
tmpRxVal <= tmpRxVal; |
end if; |
end if; -- RxValid |
end if; -- ReadD |
end if; -- reset |
end if; -- clk |
end process; |
|
--------------------------------------------------------------------- |
-- Receiver Synchronisation process |
--------------------------------------------------------------------- |
RcvSync : process(Clk, Reset, Enable, RxStart, RxFalse, RxFinish, RxD, SampleCnt ) |
variable CntIni : Std_Logic_Vector(3 downto 0); |
variable CntAdd : Std_Logic_Vector(3 downto 0); |
begin |
if Clk'event and Clk='0' then |
if Reset = '1' then |
RxStart <= '0'; |
SampleCnt <= "0000"; |
CntIni := SampleCnt; |
CntAdd := CntZero; |
else |
if Enable = '1' then |
if RxFinish = '1' and RxStart = '0' then -- Are we looking for a start bit ? |
if RxD = '0' then -- yes, look for Start Edge |
RxStart <= '1'; -- we have a start edge |
CntIni := CntZero; |
CntAdd := CntZero; |
else |
RxStart <= '0'; -- no start, spin sample count |
CntIni := SampleCnt; |
CntAdd := CntOne; |
end if; |
else |
if RxFinish = '0' and RxStart = '1' then -- have we received a start bit ? |
RxStart <= '0'; -- yes, reset start request |
else |
if RxFalse = '1' and RxStart = '1' then -- false start ? |
RxStart <= '0'; -- yep, reset start request |
else |
RxStart <= RxStart; |
end if; |
end if; |
CntIni := SampleCnt; |
CntAdd := CntOne; |
end if; -- RxStart |
else |
CntIni := SampleCnt; |
CntAdd := CntZero; |
RxStart <= RxStart; |
end if; -- enable |
end if; -- reset |
SampleCnt <= CntIni + CntAdd; |
end if; -- clk |
end process; |
|
|
--------------------------------------------------------------------- |
-- Receiver Clock process |
--------------------------------------------------------------------- |
RcvClock : process(Clk, Reset, SampleCnt, RxD, tmpRxD ) |
begin |
if Clk'event and Clk='0' then |
if Reset = '1' then |
tmpRxC <= '0'; |
tmpRxD <= '1'; |
else |
if SampleCnt = "1000" then |
tmpRxD <= RxD; |
else |
tmpRxD <= tmpRxD; |
end if; |
|
if SampleCnt = "1111" then |
tmpRxC <= '1'; |
else |
tmpRxC <= '0'; |
end if; |
end if; -- reset |
end if; -- clk |
end process; |
|
--------------------------------------------------------------------- |
-- Receiver process |
--------------------------------------------------------------------- |
RcvProc : process(Clk, Reset, RxState, tmpRxC, Enable, tmpRxD, RxStart, |
frameErr, outErr, DataOut, tmpDRdy, |
ShtReg, RxParity, parityErr, Format, |
RxValid, RxFalse, RxFinish |
) |
begin |
if Clk'event and Clk='0' then |
if Reset = '1' then |
frameErr <= '0'; |
outErr <= '0'; |
parityErr <= '0'; |
|
ShtReg <= "00000000"; -- Shift register |
RxParity <= '0'; -- Parity bit |
RxFinish <= '1'; -- Data RX finish flag |
RxValid <= '0'; -- Data RX data valid flag |
RxFalse <= '0'; |
RxState <= "1111"; |
DataOut <= "00000000"; |
else |
if tmpRxC = '1' and Enable = '1' then |
case RxState is |
when "0000" | "0001" | "0010" | "0011" | |
"0100" | "0101" | "0110" => -- data bits 0 to 6 |
ShtReg <= tmpRxD & ShtReg(7 downto 1); |
RxParity <= RxParity xor tmpRxD; |
parityErr <= parityErr; |
frameErr <= frameErr; |
outErr <= outErr; |
RxValid <= '0'; |
DataOut <= DataOut; |
RxFalse <= '0'; |
RxFinish <= '0'; |
if RxState = "0110" then |
if Format(2) = '0' then |
RxState <= "1000"; -- 7 data + parity |
else |
RxState <= "0111"; -- 8 data bits |
end if; -- Format(2) |
else |
RxState <= RxState + CntOne; |
end if; -- RxState |
when "0111" => -- data bit 7 |
ShtReg <= tmpRxD & ShtReg(7 downto 1); |
RxParity <= RxParity xor tmpRxD; |
parityErr <= parityErr; |
frameErr <= frameErr; |
outErr <= outErr; |
RxValid <= '0'; |
DataOut <= DataOut; |
RxFalse <= '0'; |
RxFinish <= '0'; |
if Format(1) = '1' then -- parity bit ? |
RxState <= "1000"; -- yes, go to parity |
else |
RxState <= "1001"; -- no, must be 2 stop bit bits |
end if; |
when "1000" => -- parity bit |
if Format(2) = '0' then |
ShtReg <= tmpRxD & ShtReg(7 downto 1); -- 7 data + parity |
else |
ShtReg <= ShtReg; -- 8 data + parity |
end if; |
RxParity <= RxParity; |
if Format(0) = '0' then -- parity polarity ? |
if RxParity = tmpRxD then -- check even parity |
parityErr <= '1'; |
else |
parityErr <= '0'; |
end if; |
else |
if RxParity = tmpRxD then -- check for odd parity |
parityErr <= '0'; |
else |
parityErr <= '1'; |
end if; |
end if; |
frameErr <= frameErr; |
outErr <= outErr; |
RxValid <= '0'; |
DataOut <= DataOut; |
RxFalse <= '0'; |
RxFinish <= '0'; |
RxState <= "1001"; |
when "1001" => -- stop bit (Only one required for RX) |
ShtReg <= ShtReg; |
RxParity <= RxParity; |
parityErr <= parityErr; |
if tmpRxD = '1' then -- stop bit expected |
frameErr <= '0'; -- yes, no framing error |
else |
frameErr <= '1'; -- no, framing error |
end if; |
if tmpDRdy = '1' then -- Has previous data been read ? |
outErr <= '1'; -- no, overrun error |
else |
outErr <= '0'; -- yes, no over run error |
end if; |
RxValid <= '1'; |
DataOut <= ShtReg; |
RxFalse <= '0'; |
RxFinish <= '1'; |
RxState <= "1111"; |
when others => -- this is the idle state |
ShtReg <= ShtReg; |
RxParity <= RxParity; |
parityErr <= parityErr; |
frameErr <= frameErr; |
outErr <= outErr; |
RxValid <= '0'; |
DataOut <= DataOut; |
if RxStart = '1' and tmpRxD = '0' then -- look for start request |
RxFalse <= '0'; |
RxFinish <= '0'; |
RxState <= "0000"; -- yes, read data |
else |
if RxStart = '1' and tmpRxD = '1' then -- start request, but no start bit |
RxFalse <= '1'; |
else |
RxFalse <= '0'; |
end if; |
RxFinish <= '1'; |
RxState <= "1111"; -- otherwise idle |
end if; |
end case; -- RxState |
else |
ShtReg <= ShtReg; |
RxParity <= RxParity; |
parityErr <= parityErr; |
frameErr <= frameErr; |
outErr <= outErr; |
RxValid <= RxValid; |
DataOut <= DataOut; |
RxFalse <= RxFalse; |
RxFinish <= RxFinish; |
RxState <= RxState; |
end if; -- tmpRxC |
end if; -- reset |
end if; -- clk |
end process; |
|
DARdy <= tmpDRdy; |
DAOut <= DataOut; |
FRErr <= frameErr; |
ORErr <= outErr; |
PAErr <= parityErr; |
|
end Behaviour; --==================== End of architecture ====================-- |
/vhdl/ioport.vhd
0,0 → 1,194
--===========================================================================---- |
-- |
-- S Y N T H E Z I A B L E ioport - 2 x 8 bit parallel I/O port |
-- |
-- www.OpenCores.Org - September 2003 |
-- This core adheres to the GNU public license |
-- |
-- File name : ioport.vhd |
-- |
-- Purpose : dual 8 bit I/O module for System09 |
-- |
-- Dependencies : ieee.Std_Logic_1164 |
-- ieee.std_logic_unsigned |
-- |
-- Uses : None |
-- |
-- Author : John E. Kent |
-- dilbert57@opencores.org |
-- |
--===========================================================================---- |
-- |
-- Revision History: |
--===========================================================================-- |
-- |
-- Version 0.1 - 11 Oct 2002 |
-- Used a loop counter for data direction & read port signals |
-- Version 0.2 - 5 Sept 2003 |
-- Reduced to 2 x 8 bit ports |
-- Version 1.0 - 6 Sept 2003 - John Kent |
-- Realeased to open Cores |
-- changed Clock Edge |
-- |
--=========================================================================== |
-- |
-- |
-- John Kent - 6 Sept 2002 |
-- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
|
entity ioport is |
port ( |
clk : in std_logic; |
rst : in std_logic; |
cs : in std_logic; |
rw : in std_logic; |
addr : in std_logic_vector(1 downto 0); |
data_in : in std_logic_vector(7 downto 0); |
data_out : out std_logic_vector(7 downto 0); |
porta_io : inout std_logic_vector(7 downto 0); |
portb_io : inout std_logic_vector(7 downto 0) |
); |
end; |
|
architecture ioport_arch of ioport is |
signal porta_ddr : std_logic_vector(7 downto 0); |
signal portb_ddr : std_logic_vector(7 downto 0); |
signal porta_data : std_logic_vector(7 downto 0); |
signal portb_data : std_logic_vector(7 downto 0); |
|
begin |
|
|
-------------------------------- |
-- |
-- read I/O port |
-- |
-------------------------------- |
|
ioport_read : process( addr, |
porta_ddr, portb_ddr, |
porta_data, portb_data, |
porta_io, portb_io ) |
variable count : integer; |
begin |
case addr is |
when "00" => |
for count in 0 to 7 loop |
if porta_ddr(count) = '1' then |
data_out(count) <= porta_data(count); |
else |
data_out(count) <= porta_io(count); |
end if; |
end loop; |
|
when "01" => |
for count in 0 to 7 loop |
if portb_ddr(count) = '1' then |
data_out(count) <= portb_data(count); |
else |
data_out(count) <= portb_io(count); |
end if; |
end loop; |
|
when "10" => |
data_out <= porta_ddr; |
when "11" => |
data_out <= portb_ddr; |
when others => |
data_out <= "00000000"; |
end case; |
end process; |
|
--------------------------------- |
-- |
-- Write I/O ports |
-- |
--------------------------------- |
|
ioport_write : process( clk, rst, addr, cs, rw, data_in, |
porta_data, portb_data, |
porta_ddr, portb_ddr ) |
begin |
if clk'event and clk = '0' then |
if rst = '1' then |
porta_data <= "00000000"; |
portb_data <= "00000000"; |
porta_ddr <= "00000000"; |
portb_ddr <= "00000000"; |
elsif cs = '1' and rw = '0' then |
case addr is |
when "00" => |
porta_data <= data_in; |
portb_data <= portb_data; |
porta_ddr <= porta_ddr; |
portb_ddr <= portb_ddr; |
when "01" => |
porta_data <= porta_data; |
portb_data <= data_in; |
porta_ddr <= porta_ddr; |
portb_ddr <= portb_ddr; |
when "10" => |
porta_data <= porta_data; |
portb_data <= portb_data; |
porta_ddr <= data_in; |
portb_ddr <= portb_ddr; |
when "11" => |
porta_data <= porta_data; |
portb_data <= portb_data; |
porta_ddr <= porta_ddr; |
portb_ddr <= data_in; |
when others => |
porta_data <= porta_data; |
portb_data <= portb_data; |
porta_ddr <= porta_ddr; |
portb_ddr <= portb_ddr; |
end case; |
else |
porta_data <= porta_data; |
portb_data <= portb_data; |
porta_ddr <= porta_ddr; |
portb_ddr <= portb_ddr; |
end if; |
end if; |
end process; |
|
--------------------------------- |
-- |
-- direction control port a |
-- |
--------------------------------- |
porta_direction : process ( porta_data, porta_ddr ) |
variable count : integer; |
begin |
for count in 0 to 7 loop |
if porta_ddr(count) = '1' then |
porta_io(count) <= porta_data(count); |
else |
porta_io(count) <= 'Z'; |
end if; |
end loop; |
end process; |
--------------------------------- |
-- |
-- direction control port b |
-- |
--------------------------------- |
portb_direction : process ( portb_data, portb_ddr ) |
variable count : integer; |
begin |
for count in 0 to 7 loop |
if portb_ddr(count) = '1' then |
portb_io(count) <= portb_data(count); |
else |
portb_io(count) <= 'Z'; |
end if; |
end loop; |
end process; |
--------------------------------- |
|
end ioport_arch; |
|
/vhdl/txunit2.vhd
0,0 → 1,232
--===========================================================================-- |
-- |
-- S Y N T H E Z I A B L E miniUART C O R E |
-- |
-- www.OpenCores.Org - January 2000 |
-- This core adheres to the GNU public license |
-- |
-- Design units : miniUART core for the System68 |
-- |
-- File name : txunit2.vhd |
-- |
-- Purpose : Implements an miniUART device for communication purposes |
-- between the CPU68 processor and the Host computer through |
-- an RS-232 communication protocol. |
-- |
-- Dependencies : IEEE.Std_Logic_1164 |
-- |
--===========================================================================-- |
------------------------------------------------------------------------------- |
-- Revision list |
-- Version Author Date Changes |
-- |
-- 0.1 Ovidiu Lupas 15 January 2000 New model |
-- 2.0 Ovidiu Lupas 17 April 2000 unnecessary variable removed |
-- olupas@opencores.org |
-- |
-- 3.0 John Kent 5 January 2003 added 6850 word format control |
-- 3.1 John Kent 12 January 2003 Rearranged state machine code |
-- 3.2 John Kent 30 March 2003 Revamped State machine |
-- 3.3 John Kent 6 September 2003 Changed Clock Edge. |
-- |
-- dilbert57@opencores.org |
-- |
------------------------------------------------------------------------------- |
-- Description : |
------------------------------------------------------------------------------- |
-- Entity for the Tx Unit -- |
------------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
use ieee.std_logic_unsigned.all; |
|
------------------------------------------------------------------------------- |
-- Transmitter unit |
------------------------------------------------------------------------------- |
entity TxUnit is |
port ( |
Clk : in Std_Logic; -- Clock signal |
Reset : in Std_Logic; -- Reset input |
Enable : in Std_Logic; -- Enable input |
LoadD : in Std_Logic; -- Load transmit data |
Format : in Std_Logic_Vector(2 downto 0); -- word format |
TxD : out Std_Logic; -- RS-232 data output |
TBE : out Std_Logic; -- Tx buffer empty |
DataO : in Std_Logic_Vector(7 downto 0)); |
end; --================== End of entity ==============================-- |
------------------------------------------------------------------------------- |
-- Architecture for TxUnit |
------------------------------------------------------------------------------- |
architecture Behaviour of TxUnit is |
type TxStateType is (TxReset_State, TxIdle_State, Start_State, Data_State, Parity_State, Stop_State ); |
----------------------------------------------------------------------------- |
-- Signals |
----------------------------------------------------------------------------- |
signal TBuff : Std_Logic_Vector(7 downto 0); -- transmit buffer |
signal tmpTBufE : Std_Logic; -- Transmit Buffer Empty |
|
signal TReg : Std_Logic_Vector(7 downto 0); -- transmit register |
signal TxParity : Std_logic; -- Parity Bit |
signal DataCnt : Std_Logic_Vector(3 downto 0); -- Data Bit Counter |
signal tmpTRegE : Std_Logic; -- Transmit Register empty |
signal TxState : TxStateType; |
|
signal NextTReg : Std_Logic_Vector(7 downto 0); -- transmit register |
signal NextTxParity : Std_logic; -- Parity Bit |
signal NextDataCnt : Std_Logic_Vector(3 downto 0); -- Data Bit Counter |
signal NextTRegE : Std_Logic; -- Transmit Register empty |
signal NextTxState : TxStateType; |
begin |
--------------------------------------------------------------------- |
-- Transmitter activation process |
--------------------------------------------------------------------- |
TxSync : process(Clk, Reset, Enable, LoadD, DataO, tmpTBufE, tmpTRegE, TBuff ) |
begin |
if Clk'event and Clk = '0' then |
if Reset = '1' then |
tmpTBufE <= '1'; |
TBuff <= "00000000"; |
else |
if LoadD = '1' then |
TBuff <= DataO; |
tmpTBufE <= '0'; |
else |
TBuff <= TBuff; |
if (Enable = '1') and (tmpTBufE = '0') and (tmpTRegE = '1') then |
tmpTBufE <= '1'; |
else |
tmpTBufE <= tmpTBufE; |
end if; |
end if; |
end if; -- reset |
end if; -- clk |
TBE <= tmpTBufE; |
|
end process; |
|
----------------------------------------------------------------------------- |
-- Implements the Tx unit |
----------------------------------------------------------------------------- |
TxProc : process(TxState, TBuff, TReg, TxParity, DataCnt, Format, tmpTRegE, tmpTBufE) |
begin |
case TxState is |
when TxReset_State => |
TxD <= '1'; |
NextTReg <= "00000000"; |
NextTxParity <= '0'; |
NextDataCnt <= "0000"; |
NextTRegE <= '1'; |
NextTxState <= TxIdle_State; |
|
when Start_State => |
TxD <= '0'; -- Start bit |
NextTReg <= TReg; |
NextTxParity <= '0'; |
if Format(2) = '0' then |
NextDataCnt <= "0110"; -- 7 data + parity |
else |
NextDataCnt <= "0111"; -- 8 data |
end if; |
NextTRegE <= '0'; |
NextTxState <= Data_State; |
|
when Data_State => |
TxD <= TReg(0); |
NextTReg <= '1' & TReg(7 downto 1); |
NextTxParity <= TxParity xor TReg(0); |
NextTRegE <= '0'; |
NextDataCnt <= DataCnt - "0001"; |
if DataCnt = "0000" then |
if (Format(2) = '1') and (Format(1) = '0') then |
if Format(0) = '0' then -- 8 data bits |
NextTxState <= Stop_State; -- 2 stops |
else |
NextTxState <= TxIdle_State; -- 1 stop |
end if; |
else |
NextTxState <= Parity_State; -- parity |
end if; |
else |
NextTxState <= Data_State; |
end if; |
|
when Parity_State => -- 7/8 data + parity bit |
if Format(0) = '0' then |
TxD <= not( TxParity ); -- even parity |
else |
TXD <= TxParity; -- odd parity |
end if; |
NextTreg <= Treg; |
NextTxParity <= '0'; |
NextTRegE <= '0'; |
NextDataCnt <= "0000"; |
if Format(1) = '0' then |
NextTxState <= Stop_State; -- 2 stops |
else |
NextTxState <= TxIdle_State; -- 1 stop |
end if; |
|
when Stop_State => -- first stop bit |
TxD <= '1'; -- 2 stop bits |
NextTreg <= Treg; |
NextTxParity <= '0'; |
NextDataCnt <= "0000"; |
NextTRegE <= '0'; |
NextTxState <= TxIdle_State; |
|
when others => -- TxIdle_State (2nd Stop bit) |
TxD <= '1'; |
NextTreg <= TBuff; |
NextTxParity <= '0'; |
NextDataCnt <= "0000"; |
if (tmpTBufE = '0') and (tmpTRegE = '1') then |
NextTRegE <= '0'; |
NextTxState <= Start_State; |
else |
NextTRegE <= '1'; |
NextTxState <= TxIdle_State; |
end if; |
|
end case; -- TxState |
|
end process; |
|
-- |
-- Tx State Machine |
-- Slowed down by "Enable" |
-- |
TX_State_Machine: process( Clk, Reset, Enable, |
Treg, NextTReg, |
TxParity, NextTxParity, |
DataCnt, NextDataCnt, |
tmpTRegE, NextTRegE, |
TxState, NextTxState ) |
begin |
if Clk'event and Clk = '0' then |
if Reset = '1' then |
Treg <= "00000000"; |
TxParity <= '0'; |
DataCnt <= "0000"; |
tmpTRegE <= '1'; |
TxState <= TxReset_State; |
else |
if Enable = '1' then |
Treg <= NextTreg; |
TxParity <= NextTxParity; |
DataCnt <= NextDataCnt; |
tmpTRegE <= NextTRegE; |
TxState <= NextTxState; |
else |
Treg <= Treg; |
TxParity <= TxParity; |
DataCnt <= DataCnt; |
tmpTRegE <= tmpTRegE; |
TxState <= TxState; |
end if; |
end if; |
end if; |
|
end process; |
|
end Behaviour; --=================== End of architecture ====================-- |
/vhdl/timer.vhd
0,0 → 1,256
--===========================================================================---- |
-- |
-- S Y N T H E Z I A B L E timer - 9 bit timer |
-- |
-- www.OpenCores.Org - September 2003 |
-- This core adheres to the GNU public license |
-- |
-- File name : timer.vhd |
-- |
-- Purpose : 9 bit timer module for System 09 |
-- |
-- Dependencies : ieee.Std_Logic_1164 |
-- ieee.std_logic_unsigned |
-- |
-- Uses : None |
-- |
-- Author : John E. Kent |
-- dilbert57@opencores.org |
-- |
--===========================================================================---- |
-- |
-- Revision History: |
--===========================================================================-- |
-- |
-- Version 0.1 - 6 Sept 2002 - John Kent |
-- converted to a single timer |
-- made syncronous with system clock |
-- |
-- Version 1.0 - 6 Sept 2003 - John Kent |
-- Realeased to open Cores |
-- changed Clock Edge |
-- |
--=========================================================================== |
-- |
-- Register Addressing: |
-- addr=0 rw=1 down count |
-- addr=0 rw=0 preset count |
-- addr=1 rw=1 status |
-- addr=0 rw=0 control |
-- |
-- Control register |
-- b0 = counter enable |
-- b1 = mode (0 = counter, 1 = timer) |
-- b7 = interrupt enable |
-- |
-- Status register |
-- b6 = timer output |
-- b7 = interrupt flag |
-- |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
|
entity timer is |
port ( |
clk : in std_logic; |
rst : in std_logic; |
cs : in std_logic; |
rw : in std_logic; |
addr : in std_logic; |
data_in : in std_logic_vector(7 downto 0); |
data_out : out std_logic_vector(7 downto 0); |
irq : out std_logic; |
timer_in : in std_logic; |
timer_out : out std_logic |
); |
end; |
|
architecture timer_arch of timer is |
signal timer_ctrl : std_logic_vector(7 downto 0); |
signal timer_stat : std_logic_vector(7 downto 0); |
signal timer_reg : std_logic_vector(7 downto 0); |
signal timer_count : std_logic_vector(7 downto 0); |
signal timer_int : std_logic; -- Timer interrupt |
signal timer_term : std_logic; -- Timer terminal count |
signal timer_tog : std_logic; -- Timer output |
-- |
-- control/status register bits |
-- |
constant T_enab : integer := 0; -- 0=disable, 1=enabled |
constant T_mode : integer := 1; -- 0=counter, 1=timer |
constant T_out : integer := 6; -- 0=disabled, 1=enabled |
constant T_irq : integer := 7; -- 0=disabled, 1-enabled |
|
begin |
|
-------------------------------- |
-- |
-- write control registers |
-- doesn't do anything yet |
-- |
-------------------------------- |
timer_write : process( clk, rst, cs, rw, addr, data_in, |
timer_reg, timer_ctrl, timer_term, timer_count ) |
begin |
if clk'event and clk = '0' then |
if rst = '1' then |
timer_reg <= "00000000"; |
timer_ctrl <= "00000000"; |
elsif cs = '1' and rw = '0' then |
if addr='0' then |
timer_reg <= data_in; |
timer_ctrl <= timer_ctrl; |
timer_term <= '0'; |
else |
timer_reg <= timer_reg; |
timer_ctrl <= data_in; |
timer_term <= timer_term; |
end if; |
else |
timer_ctrl <= timer_ctrl; |
timer_reg <= timer_reg; |
if (timer_ctrl(T_enab) = '1') then |
if (timer_count = "00000000" ) then |
timer_term <= '1'; |
elsif timer_ctrl(T_mode) = '0' then |
timer_term <= '0'; -- counter mode, reset on non zero |
else |
timer_term <= timer_term; -- timer mode, keep as is |
end if; |
else |
timer_term <= timer_term; |
end if; |
end if; |
end if; |
end process; |
|
-- |
-- timer data output mux |
-- |
timer_read : process( addr, timer_count, timer_stat ) |
begin |
if addr='0' then |
data_out <= timer_count; |
else |
data_out <= timer_stat; |
end if; |
end process; |
|
-------------------------------- |
-- |
-- counters |
-- |
-------------------------------- |
|
my_counter: process( clk, rst, timer_ctrl, timer_count, timer_reg, timer_in ) |
variable timer_tmp : std_logic; |
begin |
if clk'event and clk = '0' then |
if rst = '1' then |
timer_count <= "00000000"; |
timer_tmp := '0'; |
else |
if timer_ctrl( T_enab ) = '1' then |
if timer_in = '0' and timer_tmp = '1' then |
timer_tmp := '0'; |
if timer_count = "00000000" then |
timer_count <= timer_reg; |
else |
timer_count <= timer_count - 1; |
end if; |
elsif timer_in = '1' and timer_tmp = '0' then |
timer_tmp := '1'; |
timer_count <= timer_count; |
else |
timer_tmp := timer_tmp; |
timer_count <= timer_count; |
end if; |
else |
timer_tmp := timer_tmp; |
timer_count <= timer_count; |
end if; -- timer_ctrl |
end if; -- rst |
end if; -- clk |
end process; |
|
-- |
-- read timer strobe to reset interrupts |
-- |
timer_interrupt : process( Clk, rst, cs, rw, addr, |
timer_term, timer_int, timer_ctrl ) |
begin |
if clk'event and clk = '0' then |
if rst = '1' then |
timer_int <= '0'; |
elsif cs = '1' and rw = '1' then |
if addr = '0' then |
timer_int <= '0'; -- reset interrupt on read count |
else |
timer_int <= timer_int; |
end if; |
else |
if timer_term = '1' then |
timer_int <= '1'; |
else |
timer_int <= timer_int; |
end if; |
end if; |
end if; |
|
if timer_ctrl( T_irq ) = '1' then |
irq <= timer_int; |
else |
irq <= '0'; |
end if; |
end process; |
|
-- |
-- timer status register |
-- |
timer_status : process( timer_ctrl, timer_int, timer_tog ) |
begin |
timer_stat(5 downto 0) <= timer_ctrl(5 downto 0); |
timer_stat(T_out) <= timer_tog; |
timer_stat(T_irq) <= timer_int; |
end process; |
|
-- |
-- timer output |
-- |
timer_output : process( Clk, rst, timer_term, timer_ctrl, timer_tog ) |
variable timer_tmp : std_logic; -- tracks change in terminal count |
begin |
if clk'event and clk = '0' then |
if rst = '1' then |
timer_tog <= '0'; |
timer_tmp := '0'; |
elsif timer_ctrl(T_mode) = '0' then -- free running ? |
if (timer_term = '1') and (timer_tmp = '0') then |
timer_tmp := '1'; |
timer_tog <= not timer_tog; |
elsif (timer_term = '0') and (timer_tmp = '1') then |
timer_tmp := '0'; |
timer_tog <= timer_tog; |
else |
timer_tmp := timer_tmp; |
timer_tog <= timer_tog; |
end if; |
else -- one shot timer mode, follow terminal count |
if (timer_term = '1') and (timer_tmp = '0') then |
timer_tmp := '1'; |
timer_tog <= '1'; |
elsif (timer_term = '0') and (timer_tmp = '1') then |
timer_tmp := '0'; |
timer_tog <= '0'; |
else |
timer_tmp := timer_tmp; |
timer_tog <= timer_tog; |
end if; |
end if; |
end if; |
timer_out <= timer_tog and timer_ctrl(T_out); |
end process; |
|
end timer_arch; |
|
/vhdl/System09_tb.vhd
0,0 → 1,601
--===========================================================================---- |
-- |
-- T E S T B E N C H System09_tb - SOC Testbench. |
-- |
-- www.OpenCores.Org - September 2003 |
-- This core adheres to the GNU public license |
-- |
-- File name : System09_tb.vhd |
-- |
-- Purpose : Test Bench for system 09 |
-- Top level file for 6809 compatible system on a chip |
-- Designed with Xilinx XC2S300e Spartan 2+ FPGA. |
-- Implemented With BurchED B5-X300 FPGA board, |
-- B3-SRAM module, B5-CF module and B3-FPGA-CPU-IO module |
-- |
-- Dependencies : ieee.Std_Logic_1164 |
-- ieee.std_logic_unsigned |
-- ieee.std_logic_arith |
-- ieee.numeric_std |
-- |
-- Uses : boot_rom (sbug.vhd) Monitor ROM |
-- cpu09 (cpu09.vhd) CPU core |
-- dat_ram (datram.vhd) Dynamic Address Translation |
-- miniuart (minitUART2.vhd) ACIA / MiniUART |
-- (rxunit2.vhd) |
-- (tx_unit2.vhd) |
-- (clkunit2.vhd) |
-- timer (timer.vhd) Timer module |
-- |
-- Author : John E. Kent |
-- dilbert57@opencores.org |
-- |
--===========================================================================---- |
-- |
-- Revision History: |
--===========================================================================-- |
-- |
-- Version 1.0 |
-- John Kent - 6 Sep 2003 - Initial release to Open Cores |
-- |
--===========================================================================-- |
library ieee; |
use ieee.std_logic_1164.all; |
use IEEE.STD_LOGIC_ARITH.ALL; |
use IEEE.STD_LOGIC_UNSIGNED.ALL; |
use ieee.numeric_std.all; |
|
entity System09 is |
port( |
LED : out std_logic; -- Diagnostic LED Flasher |
|
-- Memory Interface signals |
ram_csn : out Std_Logic; |
ram_wrln : out Std_Logic; |
ram_wrun : out Std_Logic; |
ram_addr : out Std_Logic_Vector(16 downto 0); |
ram_data : inout Std_Logic_Vector(15 downto 0); |
|
-- Stuff on the peripheral board |
-- aux_clock : in Std_Logic; -- FPGA-CPU-IO clock |
|
-- PS/2 Mouse interface |
-- mouse_clock : in Std_Logic; |
-- mouse_data : in Std_Logic; |
|
-- Uart Interface |
rxbit : in Std_Logic; |
txbit : out Std_Logic; |
rts_n : out Std_Logic; |
cts_n : in Std_Logic; |
|
-- CRTC output signals |
-- v_drive : out Std_Logic; |
-- h_drive : out Std_Logic; |
-- blue_lo : out std_logic; |
-- blue_hi : out std_logic; |
-- green_lo : out std_logic; |
-- green_hi : out std_logic; |
-- red_lo : out std_logic; |
-- red_hi : out std_logic; |
-- buzzer : out std_logic; |
|
-- Compact Flash |
cf_rst_n : out std_logic; |
cf_cs0_n : out std_logic; |
cf_cs1_n : out std_logic; |
cf_rd_n : out std_logic; |
cf_wr_n : out std_logic; |
cf_cs16_n : out std_logic; |
cf_a : out std_logic_vector(2 downto 0); |
cf_d : inout std_logic_vector(15 downto 0); |
|
-- Test Pins |
|
test_alu : out std_logic_vector(15 downto 0); |
test_cc : out std_logic_vector(7 downto 0) |
); |
end; |
|
------------------------------------------------------------------------------- |
-- Architecture for memio Controller Unit |
------------------------------------------------------------------------------- |
architecture my_computer of System09 is |
----------------------------------------------------------------------------- |
-- Signals |
----------------------------------------------------------------------------- |
signal SysClk : std_logic; |
signal reset_n : std_logic; |
|
-- BOOT ROM |
signal rom_data_out : Std_Logic_Vector(7 downto 0); |
|
-- UART Interface signals |
signal uart_data_out : Std_Logic_Vector(7 downto 0); |
signal uart_cs : Std_Logic; |
signal uart_irq : Std_Logic; |
|
-- timer |
signal timer_data_out : std_logic_vector(7 downto 0); |
signal timer_cs : std_logic; |
signal timer_irq : std_logic; |
signal timer_out : std_logic; |
|
-- compact flash port |
signal cf_data_out : std_logic_vector(7 downto 0); |
signal cf_cs : std_logic; |
signal cf_rd : std_logic; |
signal cf_wr : std_logic; |
|
-- RAM |
signal ram_cs : std_logic; -- memory chip select |
signal ram_wrl : std_logic; -- memory write lower |
signal ram_wru : std_logic; -- memory write upper |
signal ram_data_out : std_logic_vector(7 downto 0); |
|
-- CPU Interface signals |
signal cpu_reset : Std_Logic; |
signal cpu_clk : Std_Logic; |
signal cpu_rw : std_logic; |
signal cpu_vma : std_logic; |
signal cpu_halt : std_logic; |
signal cpu_hold : std_logic; |
signal cpu_firq : std_logic; |
signal cpu_irq : std_logic; |
signal cpu_nmi : std_logic; |
signal cpu_addr : std_logic_vector(15 downto 0); |
signal cpu_data_in : std_logic_vector(7 downto 0); |
signal cpu_data_out: std_logic_vector(7 downto 0); |
|
-- Dynamic address translation |
signal dat_cs : std_logic; |
signal dat_addr : std_logic_vector(7 downto 0); |
|
-- Boot ROM Map switch |
-- signal map_cs : Std_Logic; |
-- signal map_sw : Std_Logic; |
|
-- synchronous RAM |
signal xram_data_out : std_logic_vector(7 downto 0); |
signal xram_cs : std_logic; |
|
-- Flashing Led test signals |
signal countL : std_logic_vector(23 downto 0); |
|
----------------------------------------------------------------- |
-- |
-- CPU09 CPU core |
-- |
----------------------------------------------------------------- |
|
component cpu09 |
port ( |
clk: in std_logic; |
rst: in std_logic; |
rw: out std_logic; -- Asynchronous memory interface |
vma: out std_logic; |
address: out std_logic_vector(15 downto 0); |
data_in: in std_logic_vector(7 downto 0); |
data_out: out std_logic_vector(7 downto 0); |
halt: in std_logic; |
hold: in std_logic; |
irq: in std_logic; |
nmi: in std_logic; |
firq: in std_logic; |
test_alu: out std_logic_vector(15 downto 0); |
test_cc: out std_logic_vector(7 downto 0) |
); |
end component; |
|
----------------------------------------------------------------- |
-- |
-- Open Cores Mini UART |
-- |
----------------------------------------------------------------- |
|
component miniUART |
port ( |
SysClk : in Std_Logic; -- System Clock |
rst : in Std_Logic; -- Reset input |
cs : in Std_Logic; |
rw : in Std_Logic; |
RxD : in Std_Logic; |
TxD : out Std_Logic; |
CTS_n : in Std_Logic; |
RTS_n : out Std_Logic; |
Irq : out Std_logic; |
Addr : in Std_Logic; |
DataIn : in Std_Logic_Vector(7 downto 0); -- |
DataOut : out Std_Logic_Vector(7 downto 0)); -- |
end component; |
|
---------------------------------------- |
-- |
-- Timer module |
-- |
---------------------------------------- |
|
component timer |
port ( |
clk : in std_logic; |
rst : in std_logic; |
cs : in std_logic; |
rw : in std_logic; |
addr : in std_logic; |
data_in : in std_logic_vector(7 downto 0); |
data_out : out std_logic_vector(7 downto 0); |
irq : out std_logic; |
timer_in : in std_logic; |
timer_out : out std_logic |
); |
end component; |
|
|
component boot_rom |
port ( |
addr : in Std_Logic_Vector(10 downto 0); -- 2K byte boot rom |
data : out Std_Logic_Vector(7 downto 0)); |
end component; |
|
--component sbug_rom |
-- Port ( |
-- MEMclk : in std_logic; |
-- MEMaddr : in std_logic_vector (10 downto 0); |
-- MEMrdata : out std_logic_vector (7 downto 0) |
-- ); |
--end component sbug_rom; |
|
component dat_ram |
port ( |
clk: in std_logic; |
rst: in std_logic; |
cs: in std_logic; |
rw: in std_logic; |
addr_lo: in std_logic_vector(3 downto 0); |
addr_hi: in std_logic_vector(3 downto 0); |
data_in: in std_logic_vector(7 downto 0); |
data_out: out std_logic_vector(7 downto 0) |
); |
end component; |
|
|
-- component block_ram |
-- Port ( |
-- MEMclk : in std_logic; |
-- MEMcs : in std_logic; |
-- MEMrw : in std_logic; |
-- MEMaddr : in std_logic_vector (10 downto 0); |
-- MEMrdata : out std_logic_vector (7 downto 0); |
-- MEMwdata : in std_logic_vector (7 downto 0) |
-- ); |
--end component; |
|
|
-- component BUFG |
-- port ( |
-- i: in std_logic; |
-- o: out std_logic |
-- ); |
-- end component; |
|
begin |
----------------------------------------------------------------------------- |
-- Instantiation of internal components |
----------------------------------------------------------------------------- |
|
my_cpu : cpu09 port map ( |
clk => SysClk, |
rst => cpu_reset, |
rw => cpu_rw, |
vma => cpu_vma, |
address => cpu_addr(15 downto 0), |
data_in => cpu_data_in, |
data_out => cpu_data_out, |
halt => cpu_halt, |
hold => cpu_hold, |
irq => cpu_irq, |
nmi => cpu_nmi, |
firq => cpu_firq, |
test_alu => test_alu, |
test_cc => test_cc |
); |
|
|
my_uart : miniUART port map ( |
SysClk => SysClk, |
rst => cpu_reset, |
cs => uart_cs, |
rw => cpu_rw, |
RxD => rxbit, |
TxD => txbit, |
CTS_n => cts_n, |
RTS_n => rts_n, |
Irq => uart_irq, |
Addr => cpu_addr(0), |
Datain => cpu_data_out, |
DataOut => uart_data_out |
); |
|
my_timer : timer port map ( |
clk => SysClk, |
rst => cpu_reset, |
cs => timer_cs, |
rw => cpu_rw, |
addr => cpu_addr(0), |
data_in => cpu_data_out, |
data_out => timer_data_out, |
irq => timer_irq, |
timer_in => CountL(5), |
timer_out => timer_out |
); |
|
my_rom : boot_rom port map ( |
addr => cpu_addr(10 downto 0), |
data => rom_data_out |
); |
|
--my_rom : sbug_rom port map ( |
-- MEMclk => SysClk, |
-- MEMaddr => cpu_addr(10 downto 0), |
-- MEMrdata => rom_data_out |
-- ); |
|
|
my_dat : dat_ram port map ( |
clk => SysClk, |
rst => cpu_reset, |
cs => dat_cs, |
rw => cpu_rw, |
addr_hi => cpu_addr(15 downto 12), |
addr_lo => cpu_addr(3 downto 0), |
data_in => cpu_data_out, |
data_out => dat_addr(7 downto 0) |
); |
|
|
--my_ram : block_ram port map ( |
-- MEMclk => SysClk, |
-- MEMcs => xram_cs, |
-- MEMrw => cpu_rw, |
-- MEMaddr => cpu_addr(10 downto 0), |
-- MEMwdata => cpu_data_out, |
-- MEMrdata => xram_data_out |
-- ); |
|
-- clk_buffer : BUFG port map( |
-- i => e_clk, |
-- o => cpu_clk |
-- ); |
|
---------------------------------------------------------------------- |
-- |
-- Process to decode memory map |
-- |
---------------------------------------------------------------------- |
|
mem_decode: process( |
cpu_addr, cpu_vma, |
-- map_cs, map_sw, |
rom_data_out, ram_data_out, |
-- xram_data_out, |
cf_data_out, |
timer_data_out, |
uart_data_out ) |
begin |
-- |
-- Memory map |
-- |
case cpu_addr(15 downto 11) is |
when "11111" => -- $F800 - $FFFF |
cpu_data_in <= rom_data_out; -- read ROM |
dat_cs <= cpu_vma; -- write DAT |
ram_cs <= '0'; |
uart_cs <= '0'; |
cf_cs <= '0'; |
timer_cs <= '0'; |
-- xram_cs <= '0'; |
-- map_cs <= '0'; |
-- when "11101" => -- $E800 - $EFFF |
-- when "11111" => -- $F800 - $FFFF |
-- if map_sw = '1' then |
-- cpu_data_in <= rom_data_out; -- read ROM |
-- dat_cs <= '0'; -- disable write to DAT |
-- ram_cs <= cpu_vma; -- enable write to RAM |
-- else |
-- cpu_data_in <= ram_data_out; -- read RAM |
-- dat_cs <= cpu_vma; -- enable write DAT |
-- ram_cs <= cpu_vma and cpu_rw; -- disable write to RAM |
-- end if; |
-- uart_cs <= '0'; |
-- cf_cs <= '0'; |
-- timer_cs <= '0'; |
-- map_cs <= '0'; |
-- when "11110" => -- $F000 - $F7FF |
-- cpu_data_in <= xram_data_out; |
-- dat_cs <= '0'; |
-- ram_cs <= '0'; |
-- uart_cs <= '0'; |
-- cf_cs <= '0'; |
-- xram_cs <= cpu_vma; |
when "11100" => -- $E000 - $E7FF |
dat_cs <= '0'; |
ram_cs <= '0'; |
-- xram_cs <= '0'; |
case cpu_addr(7 downto 4) is |
when "0000" => -- $E000 |
cpu_data_in <= uart_data_out; |
uart_cs <= cpu_vma; |
cf_cs <= '0'; |
timer_cs <= '0'; |
-- map_cs <= '0'; |
when "0001" => -- $E010 |
cpu_data_in <= cf_data_out; |
uart_cs <= '0'; |
cf_cs <= cpu_vma; |
timer_cs <= '0'; |
-- map_cs <= '0'; |
when "0010" => -- $E020 |
cpu_data_in <= timer_data_out; |
uart_cs <= '0'; |
cf_cs <= '0'; |
timer_cs <= cpu_vma; |
map_cs <= '0'; |
when "0011" => -- $E030 |
cpu_data_in <= "00000000"; |
uart_cs <= '0'; |
cf_cs <= '0'; |
timer_cs <= '0'; |
-- map_cs <= cpu_vma; |
when others => -- $E040 to $E7FF |
cpu_data_in <= "00000000"; |
uart_cs <= '0'; |
cf_cs <= '0'; |
timer_cs <= '0'; |
-- map_cs <= '0'; |
end case; |
when others => |
cpu_data_in <= ram_data_out; |
ram_cs <= cpu_vma; |
-- xram_cs <= '0'; |
dat_cs <= '0'; |
uart_cs <= '0'; |
cf_cs <= '0'; |
timer_cs <= '0'; |
-- map_cs <= '0'; |
end case; |
end process; |
|
-- |
-- B3-SRAM Control |
-- Processes to read and write memory based on bus signals |
-- |
ram_process: process( SysClk, Reset_n, |
cpu_addr, cpu_rw, cpu_data_out, |
dat_addr, |
ram_cs, ram_wrl, ram_wru, ram_data ) |
begin |
ram_csn <= not( ram_cs and Reset_n ); |
ram_wrl <= (not dat_addr(5)) and (not cpu_rw) and (not SysClk); |
ram_wrln <= not (ram_wrl); |
ram_wru <= dat_addr(5) and (not cpu_rw) and (not SysClk); |
ram_wrun <= not (ram_wru); |
ram_addr(16 downto 12) <= dat_addr(4 downto 0); |
ram_addr(11 downto 0) <= cpu_addr(11 downto 0); |
|
if ram_wrl = '1' then |
ram_data(7 downto 0) <= cpu_data_out; |
else |
ram_data(7 downto 0) <= "ZZZZZZZZ"; |
end if; |
|
if ram_wru = '1' then |
ram_data(15 downto 8) <= cpu_data_out; |
else |
ram_data(15 downto 8) <= "ZZZZZZZZ"; |
end if; |
|
if dat_addr(5) = '1' then |
ram_data_out <= ram_data(15 downto 8); |
else |
ram_data_out <= ram_data(7 downto 0); |
end if; |
end process; |
|
-- |
-- Compact Flash Control |
-- |
compact_flash: process( Reset_n, |
cpu_addr, cpu_rw, cpu_data_out, |
cf_cs, cf_rd, cf_wr, cf_d ) |
begin |
cf_rst_n <= Reset_n; |
cf_cs0_n <= not( cf_cs ) or cpu_addr(3); |
cf_cs1_n <= not( cf_cs and cpu_addr(3)); |
cf_cs16_n <= '1'; |
cf_wr <= cf_cs and (not cpu_rw); |
cf_rd <= cf_cs and cpu_rw; |
cf_wr_n <= not cf_wr; |
cf_rd_n <= not cf_rd; |
cf_a <= cpu_addr(2 downto 0); |
if cf_wr = '1' then |
cf_d(7 downto 0) <= cpu_data_out; |
else |
cf_d(7 downto 0) <= "ZZZZZZZZ"; |
end if; |
cf_data_out <= cf_d(7 downto 0); |
cf_d(15 downto 8) <= "ZZZZZZZZ"; |
end process; |
|
-- |
-- ROM Map switch |
-- The Map switch output is initially set |
-- On a Write to the Map Switch port, clear the Map Switch |
-- and map the RAM in place of the boot ROM. |
-- |
--map_proc : process( SysClk, Reset_n, map_cs, cpu_rw ) |
--begin |
-- if SysClk'event and SysClk = '1' then |
-- if Reset_n = '0' then |
-- map_sw <= '1'; |
-- else |
-- if (map_cs = '1') and (cpu_rw = '0') then |
-- map_sw <= '0'; |
-- else |
-- map_sw <= map_sw; |
-- end if; |
-- end if; |
-- end if; |
--end process; |
|
-- |
-- Interrupts and other bus control signals |
-- |
interrupts : process( Reset_n, uart_irq |
-- ,timer_irq |
) |
begin |
cpu_reset <= not Reset_n; -- CPU reset is active high |
cpu_irq <= uart_irq; |
cpu_nmi <= timer_irq; |
-- cpu_nmi <= '0'; |
cpu_firq <= '0'; |
cpu_halt <= '0'; |
cpu_hold <= '0'; |
end process; |
|
-- |
-- flash led to indicate code is working |
-- |
increment: process (SysClk, CountL ) |
begin |
if(SysClk'event and SysClk = '1') then |
countL <= countL + 1; |
end if; |
LED <= countL(21); |
end process; |
-- *** Test Bench - User Defined Section *** |
tb : PROCESS |
variable count : integer; |
BEGIN |
|
SysClk <= '0'; |
Reset_n <= '0'; |
|
for count in 0 to 512 loop |
SysClk <= '0'; |
if count = 0 then |
Reset_n <= '0'; |
elsif count = 1 then |
Reset_n <= '1'; |
end if; |
wait for 100 ns; |
SysClk <= '1'; |
wait for 100 ns; |
end loop; |
|
wait; -- will wait forever |
END PROCESS; |
|
|
end; --===================== End of architecture =======================-- |
|
/vhdl/system09.ucf
0,0 → 1,288
#### UCF file created by Project Navigator |
# |
NET "reset_n" LOC = "p57" ; |
NET "sysclk" LOC = "p77" ; |
# |
# For B5-Compact-Flash: |
# Connector A |
# |
#NET "pin2" LOC = "P3" ; #J1-2 |
#NET "pin3" LOC = "P4" ; #J1-3 |
#NET "cf_intrq" LOC = "P5" ; #J1-4 |
NET "cf_wr_n" LOC = "P6" ; #J1-5 |
NET "cf_rd_n" LOC = "P7" ; #J1-6 |
NET "cf_cs1_n" LOC = "P8" ; #J1-7 |
NET "cf_d<15>" LOC = "P9" ; #J1-8 |
NET "cf_d<14>" LOC = "P10" ; #J1-9 |
NET "cf_d<13>" LOC = "P11" ; #J1-10 |
NET "cf_d<12>" LOC = "P15" ; #J1-11 |
NET "cf_d<11>" LOC = "P16" ; #J1-12 |
#NET "cf_present" LOC = "P17" ; #J1-13 |
NET "cf_d<3>" LOC = "P18" ; #J1-14 |
NET "cf_d<4>" LOC = "P20" ; #J1-15 |
NET "cf_d<5>" LOC = "P21" ; #J1-16 |
NET "cf_d<6>" LOC = "P22" ; #J1-17 |
NET "cf_d<7>" LOC = "P23" ; #J1-18 |
NET "cf_cs0_n" LOC = "P24" ; #J1-19 |
# |
# For B5-Compact-Flash: |
# Connector B |
# |
NET "cf_a<2>" LOC = "P33" ; #J2-6 |
NET "cf_a<1>" LOC = "P34" ; #J2-7 |
NET "cf_a<0>" LOC = "P35" ; #J2-8 |
NET "cf_d<0>" LOC = "P36" ; #J2-9 |
NET "cf_d<1>" LOC = "P40" ; #J2-10 |
NET "cf_d<2>" LOC = "P41" ; #J2-11 |
NET "cf_cs16_n" LOC = "P42" ; #J2-12 |
NET "cf_d<10>" LOC = "P43" ; #J2-13 |
NET "cf_d<9>" LOC = "P44" ; #J2-14 |
NET "cf_d<8>" LOC = "P45" ; #J2-15 |
#NET "cf_pdiag" LOC = "P46" ; #J2-16 |
#NET "cf_dase" LOC = "P47" ; #J2-17 |
#NET "cf_iordy" LOC = "P48" ; #J2-18 |
NET "cf_rst_n" LOC = "P49" ; #J2-19 |
# |
# I/O Port |
# Connector C |
# |
#NET "porta<0>" LOC = "p55" ; #pin 3 |
#NET "porta<1>" LOC = "p56" ; #pin 4 |
#NET "porta<2>" LOC = "p58" ; #pin 5 |
#NET "porta<3>" LOC = "p59" ; #pin 6 |
#NET "porta<4>" LOC = "p60" ; #pin 7 |
#NET "porta<5>" LOC = "p61" ; #pin 8 |
#NET "porta<6>" LOC = "p62" ; #pin 8 |
#NET "porta<7>" LOC = "p63" ; #pin 10 |
#NET "portb<0>" LOC = "p64" ; #pin 11 |
#NET "portb<1>" LOC = "p68" ; #pin 12 |
#NET "portb<2>" LOC = "p69" ; #pin 13 |
#NET "portb<3>" LOC = "p70" ; #pin 14 |
#NET "portb<4>" LOC = "p71" ; #pin 15 |
#NET "portb<5>" LOC = "p73" ; #pin 16 |
#NET "portb<6>" LOC = "p74" ; #pin 17 |
#NET "portb<7>" LOC = "p75" ; #pin 18 |
#NET "timer_out" LOC = "p81" ; #pin 19 |
# |
# For B3-FPGA-CPU-IO |
# Connector D |
# |
#NET "aux_clock" LOC = "p80" ; #pin 2 |
#NET "buzzer" LOC = "p82" ; #pin 3 |
NET "led" LOC = "p82" ; #pin 3 |
#NET "mouse_clock" LOC = "p83" ; #pin 4 |
#NET "mouse_data" LOC = "p84" ; #pin 5 |
NET "cts_n" LOC = "p86" ; #pin 6 |
NET "rts_n" LOC = "p87" ; #pin 7 |
NET "txbit" LOC = "p88" ; #pin 8 |
NET "rxbit" LOC = "p89" ; #pin 9 |
#NET "kb_clock" LOC = "p93" ; #pin 10 |
#NET "kb_data" LOC = "p94" ; #pin 11 |
#NET "v_drive" LOC = "p95" ; #pin 12 |
#NET "h_drive" LOC = "p96" ; #pin 13 |
#NET "blue_lo" LOC = "p97" ; #pin 14 |
#NET "blue_hi" LOC = "p98" ; #pin 15 |
#NET "green_lo" LOC = "p99" ; #pin 16 |
#NET "green_hi" LOC = "p100"; #pin 17 |
#NET "red_lo" LOC = "p101"; #pin 18 |
#NET "red_hi" LOC = "p102"; #pin 19 |
# |
# For modified B3-SRAM |
# Connector E |
# |
NET "ram_addr<0>" LOC = "p108"; #J1.2 |
NET "ram_addr<1>" LOC = "p109"; #J1.3 |
NET "ram_addr<2>" LOC = "p110"; #J1.4 |
NET "ram_addr<3>" LOC = "p111"; #J1.5 |
NET "ram_addr<4>" LOC = "p112"; #J1.6 |
NET "ram_addr<5>" LOC = "p113"; #J1.7 |
NET "ram_addr<6>" LOC = "p114"; #J1.8 |
NET "ram_addr<7>" LOC = "p115"; #J1.9 |
NET "ram_csn" LOC = "p116"; #J1.10 |
NET "ram_addr<8>" LOC = "p120"; #J1.11 |
NET "ram_addr<9>" LOC = "p121"; #J1.12 |
NET "ram_addr<10>" LOC = "p122"; #J1.13 |
NET "ram_addr<11>" LOC = "p123"; #J1.14 |
NET "ram_addr<12>" LOC = "p125"; #J1.15 |
NET "ram_addr<13>" LOC = "p126"; #J1.16 |
NET "ram_addr<14>" LOC = "p127"; #J1.17 |
NET "ram_addr<15>" LOC = "p129"; #J1.18 |
NET "ram_addr<16>" LOC = "p132"; #J1.19 |
# |
# For modified B3-SRAM |
# Connector F |
# |
NET "ram_data<0>" LOC = "p133"; #J2.2 |
NET "ram_data<1>" LOC = "p134"; #J2.3 |
NET "ram_data<2>" LOC = "p135"; #J2.4 |
NET "ram_data<3>" LOC = "p136"; #J2.5 |
NET "ram_data<4>" LOC = "p138"; #J2.6 |
NET "ram_data<5>" LOC = "p139"; #J2.7 |
NET "ram_data<6>" LOC = "p140"; #J2.8 |
NET "ram_data<7>" LOC = "p141"; #J2.9 |
NET "ram_data<8>" LOC = "p145"; #J2.10 |
NET "ram_data<9>" LOC = "p146"; #J2.11 |
NET "ram_data<10>" LOC = "p147"; #J2.12 |
NET "ram_data<11>" LOC = "p148"; #J2.13 |
NET "ram_data<12>" LOC = "p149"; #J2.14 |
NET "ram_data<13>" LOC = "p150"; #J2.15 |
NET "ram_data<14>" LOC = "p151"; #J2.16 |
NET "ram_data<15>" LOC = "p152"; #J2.17 |
NET "ram_wrun" LOC = "p153"; #J2.18 |
NET "ram_wrln" LOC = "p154"; #J2.19 |
# |
# Connector G |
# |
#NET "pin2" LOC = "p182"; #pin 2 (clk input) |
NET "test_alu<0>" LOC = "p160"; #pin 3 |
NET "test_alu<1>" LOC = "p161"; #pin 4 |
NET "test_alu<2>" LOC = "p162"; #pin 5 |
NET "test_alu<3>" LOC = "p163"; #pin 6 |
NET "test_alu<4>" LOC = "p164"; #pin 7 |
NET "test_alu<5>" LOC = "p165"; #pin 8 |
NET "test_alu<6>" LOC = "p166"; #pin 9 |
NET "test_alu<7>" LOC = "p167"; #pin 10 |
NET "test_alu<8>" LOC = "p168"; #pin 11 |
NET "test_alu<9>" LOC = "p169"; #pin 12 |
NET "test_alu<10>" LOC = "p173"; #pin 13 |
NET "test_alu<11>" LOC = "p174"; #pin 14 |
NET "test_alu<12>" LOC = "p175"; #pin 15 |
NET "test_alu<13>" LOC = "p176"; #pin 16 |
NET "test_alu<14>" LOC = "p178"; #pin 17 |
NET "test_alu<15>" LOC = "p179"; #pin 18 |
#NET "pin19" LOC = "p180"; #pin 19 |
# |
# Connector H |
# |
#NET "pin2" LOC = "p185"; #pin 2 (clk input) |
#NET "pin3" LOC = "p181"; #pin 3 |
#NET "uart_csn" LOC = "p187"; #pin 4 |
#NET "test_rw" LOC = "p188"; #pin 5 |
#NET "test_d0" LOC = "p189"; #pin 6 |
#NET "test_d1" LOC = "p191"; #pin 7 |
#NET "pin8" LOC = "p192"; #pin 8 |
#NET "pin9" LOC = "p193"; #pin 9 |
#NET "pin10" LOC = "p194"; #pin 10 |
NET "test_cc<0>" LOC = "p198"; #pin 11 |
NET "test_cc<1>" LOC = "p199"; #pin 12 |
NET "test_cc<2>" LOC = "p200"; #pin 13 |
NET "test_cc<3>" LOC = "p201"; #pin 14 |
NET "test_cc<4>" LOC = "p202"; #pin 15 |
NET "test_cc<5>" LOC = "p203"; #pin 16 |
NET "test_cc<6>" LOC = "p204"; #pin 17 |
NET "test_cc<7>" LOC = "p205"; #pin 18 |
#NET "pin19" LOC = "p206"; #pin 19 |
# |
# Timing Groups |
# |
INST "ram_addr<0>" TNM = "ram_addr"; |
INST "ram_addr<1>" TNM = "ram_addr"; |
INST "ram_addr<2>" TNM = "ram_addr"; |
INST "ram_addr<3>" TNM = "ram_addr"; |
INST "ram_addr<4>" TNM = "ram_addr"; |
INST "ram_addr<5>" TNM = "ram_addr"; |
INST "ram_addr<6>" TNM = "ram_addr"; |
INST "ram_addr<7>" TNM = "ram_addr"; |
INST "ram_addr<8>" TNM = "ram_addr"; |
INST "ram_addr<9>" TNM = "ram_addr"; |
INST "ram_addr<10>" TNM = "ram_addr"; |
INST "ram_addr<11>" TNM = "ram_addr"; |
INST "ram_addr<12>" TNM = "ram_addr"; |
INST "ram_addr<13>" TNM = "ram_addr"; |
INST "ram_addr<14>" TNM = "ram_addr"; |
INST "ram_addr<15>" TNM = "ram_addr"; |
INST "ram_addr<16>" TNM = "ram_addr"; |
INST "ram_data<0>" TNM = "ram_data"; |
INST "ram_data<1>" TNM = "ram_data"; |
INST "ram_data<2>" TNM = "ram_data"; |
INST "ram_data<3>" TNM = "ram_data"; |
INST "ram_data<4>" TNM = "ram_data"; |
INST "ram_data<5>" TNM = "ram_data"; |
INST "ram_data<6>" TNM = "ram_data"; |
INST "ram_data<7>" TNM = "ram_data"; |
INST "ram_data<8>" TNM = "ram_data"; |
INST "ram_data<9>" TNM = "ram_data"; |
INST "ram_data<10>" TNM = "ram_data"; |
INST "ram_data<11>" TNM = "ram_data"; |
INST "ram_data<12>" TNM = "ram_data"; |
INST "ram_data<13>" TNM = "ram_data"; |
INST "ram_data<14>" TNM = "ram_data"; |
INST "ram_data<15>" TNM = "ram_data"; |
INST "ram_wrln" TNM = "ram_wr"; |
INST "ram_wrun" TNM = "ram_wr"; |
INST "ram_csn" TNM = "ram_cs"; |
INST "test_alu<0>" TNM = "test_alu"; |
INST "test_alu<1>" TNM = "test_alu"; |
INST "test_alu<2>" TNM = "test_alu"; |
INST "test_alu<3>" TNM = "test_alu"; |
INST "test_alu<4>" TNM = "test_alu"; |
INST "test_alu<5>" TNM = "test_alu"; |
INST "test_alu<6>" TNM = "test_alu"; |
INST "test_alu<7>" TNM = "test_alu"; |
INST "test_alu<8>" TNM = "test_alu"; |
INST "test_alu<9>" TNM = "test_alu"; |
INST "test_alu<10>" TNM = "test_alu"; |
INST "test_alu<11>" TNM = "test_alu"; |
INST "test_alu<12>" TNM = "test_alu"; |
INST "test_alu<13>" TNM = "test_alu"; |
INST "test_alu<14>" TNM = "test_alu"; |
INST "test_alu<15>" TNM = "test_alu"; |
INST "test_cc<0>" TNM = "test_cc"; |
INST "test_cc<1>" TNM = "test_cc"; |
INST "test_cc<2>" TNM = "test_cc"; |
INST "test_cc<3>" TNM = "test_cc"; |
INST "test_cc<4>" TNM = "test_cc"; |
INST "test_cc<5>" TNM = "test_cc"; |
INST "test_cc<6>" TNM = "test_cc"; |
INST "test_cc<7>" TNM = "test_cc"; |
# |
# Timing Constraints |
# |
TIMEGRP "ram_cs" OFFSET = OUT 40 ns AFTER "sysclk"; |
TIMEGRP "ram_wr" OFFSET = OUT 40 ns AFTER "sysclk"; |
TIMEGRP "ram_addr" OFFSET = OUT 40 ns AFTER "sysclk"; |
TIMEGRP "ram_data" OFFSET = OUT 40 ns AFTER "sysclk"; |
TIMEGRP "ram_data" OFFSET = IN 15 ns BEFORE "sysclk"; |
TIMEGRP "test_alu" OFFSET = OUT 90 ns AFTER "sysclk"; |
TIMEGRP "test_cc" OFFSET = OUT 95 ns AFTER "sysclk"; |
NET "sysclk" TNM_NET = "sysclk"; |
TIMESPEC "TS_sysclk" = PERIOD "sysclk" 100 ns LOW 50 %; |
# |
# Fast I/O Pins |
# |
NET "ram_addr<0>" FAST; |
NET "ram_addr<1>" FAST; |
NET "ram_addr<2>" FAST; |
NET "ram_addr<3>" FAST; |
NET "ram_addr<4>" FAST; |
NET "ram_addr<5>" FAST; |
NET "ram_addr<6>" FAST; |
NET "ram_addr<7>" FAST; |
NET "ram_addr<8>" FAST; |
NET "ram_addr<9>" FAST; |
NET "ram_addr<10>" FAST; |
NET "ram_addr<11>" FAST; |
NET "ram_addr<12>" FAST; |
NET "ram_addr<13>" FAST; |
NET "ram_addr<14>" FAST; |
NET "ram_addr<15>" FAST; |
NET "ram_addr<16>" FAST; |
NET "ram_csn" FAST; |
NET "ram_data<0>" FAST; |
NET "ram_data<1>" FAST; |
NET "ram_data<2>" FAST; |
NET "ram_data<3>" FAST; |
NET "ram_data<4>" FAST; |
NET "ram_data<5>" FAST; |
NET "ram_data<6>" FAST; |
NET "ram_data<7>" FAST; |
NET "ram_data<8>" FAST; |
NET "ram_data<9>" FAST; |
NET "ram_data<10>" FAST; |
NET "ram_data<11>" FAST; |
NET "ram_data<12>" FAST; |
NET "ram_data<13>" FAST; |
NET "ram_data<14>" FAST; |
NET "ram_data<15>" FAST; |
NET "ram_wrln" FAST; |
NET "ram_wrun" FAST; |
/vhdl/clkunit2.vhd
0,0 → 1,138
--===========================================================================-- |
-- |
-- S Y N T H E Z I A B L E miniUART C O R E |
-- |
-- www.OpenCores.Org - January 2000 |
-- This core adheres to the GNU public license |
|
-- Design units : miniUART core for the System68 |
-- |
-- File name : clkunit2.vhd |
-- |
-- Purpose : Implements an miniUART device for communication purposes |
-- between the CPU68 processor and the Host computer through |
-- an RS-232 communication protocol. |
-- |
-- Dependencies : ieee.std_logic_1164 |
-- ieee.numeric_std |
-- |
--===========================================================================-- |
------------------------------------------------------------------------------- |
-- Revision list |
-- Version Author Date Changes |
-- |
-- 0.1 Ovidiu Lupas 15 January 2000 New model |
-- olupas@opencores.org |
-- |
-- 2.0 John Kent 10 November 2002 Added programmable baud rate |
-- 3.0 John Kent 15 December 2002 Fix TX clock divider |
-- 3.1 John kent 12 January 2003 Changed divide by 1 for 38.4Kbps |
-- 3.3 John Kent 6 September 2003 Changed Clock Edge. |
-- dilbert57@opencores.org |
------------------------------------------------------------------------------- |
-- Description : Generates the Baud clock and enable signals for RX & TX |
-- units. |
------------------------------------------------------------------------------- |
-- Entity for Baud rate generator Unit - 9600 baudrate -- |
------------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
------------------------------------------------------------------------------- |
-- Baud rate generator |
------------------------------------------------------------------------------- |
entity ClkUnit is |
port ( |
Clk : in Std_Logic; -- System Clock |
Reset : in Std_Logic; -- Reset input |
EnableRx : out Std_Logic; -- Control signal |
EnableTx : out Std_Logic; -- Control signal |
BaudRate : in Std_Logic_Vector(1 downto 0)); |
end; --================== End of entity ==============================-- |
------------------------------------------------------------------------------- |
-- Architecture for Baud rate generator Unit |
------------------------------------------------------------------------------- |
architecture Behaviour of ClkUnit is |
signal tmpEnRx : std_logic; |
|
begin |
----------------------------------------------------------------------------- |
-- Divides the system clock of 40 MHz div 260 gives 153KHz for 9600bps |
-- 48 MHz div 156 gives 306KHz for 19.2Kbps |
-- 24 MHz div 156 gives 153KHz for 9600bps |
-- 9.8304MHz div 32 gives 306KHz for 19.2Kbps |
-- 4.9152MHz div 32 gives 153KHz for 9600bps |
----------------------------------------------------------------------------- |
DivClk : process(Clk,Reset,tmpEnRx, BaudRate) |
variable Count : unsigned(7 downto 0); |
constant CntOne : Unsigned(7 downto 0):="00000001"; |
begin |
if Clk'event and Clk = '0' then |
if Reset = '1' then |
Count := "00000000"; |
tmpEnRx <= '0'; |
else |
if Count = "00000000" then |
tmpEnRx <= '1'; |
case BaudRate is |
when "00" => |
-- 6850 divide by 1 ((1*2)-1) (synchronous) |
-- miniUart 9.83MHz div 16 = 38.4Kbps |
Count := "00001111"; |
when "01" => |
-- 6850 divide by 16 ((16*2)-1) (9600 Baud) |
-- miniUart 9.83MHz div 32 = 19.2Kbps |
Count := "00011111"; |
when "10" => |
-- 6850 divide by 64 ((64*2)-1) (2400 Baud) |
-- miniUart 9.83MHz div 128 = 4800bps |
Count := "01111111"; |
when others => |
-- when "11" => -- reset |
Count := "00000000"; |
null; |
end case; |
else |
tmpEnRx <= '0'; |
Count := Count - CntOne; |
end if; |
end if; |
end if; |
EnableRx <= tmpEnRx; |
end process; |
|
----------------------------------------------------------------------------- |
-- Provides the EnableTX signal, at 9.6 KHz |
-- Divide by 16 |
-- Except it wasn't ... it counted up to "10010" (18) |
----------------------------------------------------------------------------- |
DivClk16 : process(Clk,Reset,tmpEnRX) |
variable Cnt16 : unsigned(4 downto 0); |
constant CntOne : Unsigned(4 downto 0):="00001"; |
begin |
if Clk'event and Clk = '0' then |
if Reset = '1' then |
Cnt16 := "00000"; |
EnableTX <= '0'; |
else |
case Cnt16 is |
when "00000" => |
if tmpEnRx = '1' then |
Cnt16 := "01111"; |
EnableTx <='1'; |
else |
Cnt16 := Cnt16; |
EnableTx <= '0'; |
end if; |
when others => |
if tmpEnRx = '1' then |
Cnt16 := Cnt16 - CntOne; |
else |
Cnt16 := Cnt16; |
end if; |
EnableTX <= '0'; |
end case; |
end if; |
end if; |
end process; |
end Behaviour; --==================== End of architecture ===================-- |
/vhdl/System09.vhd
0,0 → 1,691
--===========================================================================---- |
-- |
-- S Y N T H E Z I A B L E System09 - SOC. |
-- |
-- www.OpenCores.Org - September 2003 |
-- This core adheres to the GNU public license |
-- |
-- File name : System09.vhd |
-- |
-- Purpose : Top level file for 6809 compatible system on a chip |
-- Designed with Xilinx XC2S300e Spartan 2+ FPGA. |
-- Implemented With BurchED B5-X300 FPGA board, |
-- B3-SRAM module, B5-CF module and B3-FPGA-CPU-IO module |
-- |
-- Dependencies : ieee.Std_Logic_1164 |
-- ieee.std_logic_unsigned |
-- ieee.std_logic_arith |
-- ieee.numeric_std |
-- |
-- Uses : boot_rom (sbug.vhd) Monitor ROM |
-- cpu09 (cpu09.vhd) CPU core |
-- dat_ram (datram.vhd) Dynamic Address Translation |
-- miniuart (minitUART2.vhd) ACIA / MiniUART |
-- (rxunit2.vhd) |
-- (tx_unit2.vhd) |
-- (clkunit2.vhd) |
-- timer (timer.vhd) Timer module |
-- |
-- Author : John E. Kent |
-- dilbert57@opencores.org |
-- |
--===========================================================================---- |
-- |
-- Revision History: |
--===========================================================================-- |
-- Version 0.1 - 20 March 2003 |
-- Version 0.2 - 30 March 2003 |
-- Version 0.3 - 29 April 2003 |
-- Version 0.4 - 29 June 2003 |
-- Version 0.5 - 19 July 2003 |
-- prints out "Hello World" |
-- Version 0.6 - 5 September 2003 |
-- Runs SBUG |
-- Version 1.0- 6 Sep 2003 - John Kent |
-- Inverted SysClk |
-- Initial release to Open Cores |
-- |
--===========================================================================-- |
library ieee; |
use ieee.std_logic_1164.all; |
use IEEE.STD_LOGIC_ARITH.ALL; |
use IEEE.STD_LOGIC_UNSIGNED.ALL; |
use ieee.numeric_std.all; |
|
entity System09 is |
port( |
SysClk : in Std_Logic; -- System Clock input |
Reset_n : in Std_logic; -- Master Reset input (active low) |
LED : out std_logic; -- Diagnostic LED Flasher |
|
-- Memory Interface signals |
ram_csn : out Std_Logic; |
ram_wrln : out Std_Logic; |
ram_wrun : out Std_Logic; |
ram_addr : out Std_Logic_Vector(16 downto 0); |
ram_data : inout Std_Logic_Vector(15 downto 0); |
|
-- Stuff on the peripheral board |
-- aux_clock : in Std_Logic; -- FPGA-CPU-IO clock |
|
-- PS/2 Mouse interface |
-- mouse_clock : in Std_Logic; |
-- mouse_data : in Std_Logic; |
|
-- Uart Interface |
rxbit : in Std_Logic; |
txbit : out Std_Logic; |
rts_n : out Std_Logic; |
cts_n : in Std_Logic; |
|
-- CRTC output signals |
-- v_drive : out Std_Logic; |
-- h_drive : out Std_Logic; |
-- blue_lo : out std_logic; |
-- blue_hi : out std_logic; |
-- green_lo : out std_logic; |
-- green_hi : out std_logic; |
-- red_lo : out std_logic; |
-- red_hi : out std_logic; |
-- buzzer : out std_logic; |
|
-- Compact Flash |
cf_rst_n : out std_logic; |
cf_cs0_n : out std_logic; |
cf_cs1_n : out std_logic; |
cf_rd_n : out std_logic; |
cf_wr_n : out std_logic; |
cf_cs16_n : out std_logic; |
cf_a : out std_logic_vector(2 downto 0); |
cf_d : inout std_logic_vector(15 downto 0); |
|
-- Parallel I/O port |
-- porta : inout std_logic_vector(7 downto 0); |
-- portb : inout std_logic_vector(7 downto 0); |
-- timer_out : out std_logic; |
|
-- Test Pins |
test_alu : out std_logic_vector(15 downto 0); |
test_cc : out std_logic_vector(7 downto 0) |
); |
end System09; |
|
------------------------------------------------------------------------------- |
-- Architecture for memio Controller Unit |
------------------------------------------------------------------------------- |
architecture my_computer of System09 is |
----------------------------------------------------------------------------- |
-- Signals |
----------------------------------------------------------------------------- |
-- BOOT ROM |
signal rom_data_out : Std_Logic_Vector(7 downto 0); |
|
-- UART Interface signals |
signal uart_data_out : Std_Logic_Vector(7 downto 0); |
signal uart_cs : Std_Logic; |
signal uart_irq : Std_Logic; |
|
-- timer |
-- signal timer_data_out : std_logic_vector(7 downto 0); |
-- signal timer_cs : std_logic; |
-- signal timer_irq : std_logic; |
|
-- Parallel I/O port |
-- signal ioport_data_out : std_logic_vector(7 downto 0); |
-- signal ioport_cs : std_logic; |
|
-- compact flash port |
signal cf_data_out : std_logic_vector(7 downto 0); |
signal cf_cs : std_logic; |
signal cf_rd : std_logic; |
signal cf_wr : std_logic; |
|
-- RAM |
signal ram_cs : std_logic; -- memory chip select |
signal ram_wrl : std_logic; -- memory write lower |
signal ram_wru : std_logic; -- memory write upper |
signal ram_data_out : std_logic_vector(7 downto 0); |
|
-- CPU Interface signals |
signal cpu_reset : Std_Logic; |
signal cpu_clk : Std_Logic; |
signal cpu_rw : std_logic; |
signal cpu_vma : std_logic; |
signal cpu_halt : std_logic; |
signal cpu_hold : std_logic; |
signal cpu_firq : std_logic; |
signal cpu_irq : std_logic; |
signal cpu_nmi : std_logic; |
signal cpu_addr : std_logic_vector(15 downto 0); |
signal cpu_data_in : std_logic_vector(7 downto 0); |
signal cpu_data_out: std_logic_vector(7 downto 0); |
|
-- Dynamic address translation |
signal dat_cs : std_logic; |
signal dat_addr : std_logic_vector(7 downto 0); |
|
-- Boot ROM Map switch |
-- signal map_cs : Std_Logic; |
-- signal map_sw : Std_Logic; |
|
-- synchronous RAM |
-- signal xram_data_out : std_logic_vector(7 downto 0); |
-- signal xram_cs : std_logic; |
|
-- Flashing Led test signals |
signal countL : std_logic_vector(23 downto 0); |
|
----------------------------------------------------------------- |
-- |
-- CPU09 CPU core |
-- |
----------------------------------------------------------------- |
|
component cpu09 |
port ( |
clk: in std_logic; |
rst: in std_logic; |
rw: out std_logic; -- Asynchronous memory interface |
vma: out std_logic; |
address: out std_logic_vector(15 downto 0); |
data_in: in std_logic_vector(7 downto 0); |
data_out: out std_logic_vector(7 downto 0); |
halt: in std_logic; |
hold: in std_logic; |
irq: in std_logic; |
nmi: in std_logic; |
firq: in std_logic; |
test_alu: out std_logic_vector(15 downto 0); |
test_cc: out std_logic_vector(7 downto 0) |
); |
end component; |
|
----------------------------------------------------------------- |
-- |
-- Open Cores Mini UART |
-- |
----------------------------------------------------------------- |
|
component miniUART |
port ( |
SysClk : in Std_Logic; -- System Clock |
rst : in Std_Logic; -- Reset input |
cs : in Std_Logic; |
rw : in Std_Logic; |
RxD : in Std_Logic; |
TxD : out Std_Logic; |
CTS_n : in Std_Logic; |
RTS_n : out Std_Logic; |
Irq : out Std_logic; |
Addr : in Std_Logic; |
DataIn : in Std_Logic_Vector(7 downto 0); -- |
DataOut : out Std_Logic_Vector(7 downto 0)); -- |
end component; |
|
---------------------------------------- |
-- |
-- Timer module |
-- |
---------------------------------------- |
|
--component timer |
-- port ( |
-- clk : in std_logic; |
-- rst : in std_logic; |
-- cs : in std_logic; |
-- rw : in std_logic; |
-- addr : in std_logic; |
-- data_in : in std_logic_vector(7 downto 0); |
-- data_out : out std_logic_vector(7 downto 0); |
-- irq : out std_logic; |
-- timer_in : in std_logic; |
-- timer_out : out std_logic |
-- ); |
--end component; |
|
---------------------------------------- |
-- |
-- Dual 8 bit Parallel I/O module |
-- |
---------------------------------------- |
--component ioport |
-- port ( |
-- clk : in std_logic; |
-- rst : in std_logic; |
-- cs : in std_logic; |
-- rw : in std_logic; |
-- addr : in std_logic_vector(1 downto 0); |
-- data_in : in std_logic_vector(7 downto 0); |
-- data_out : out std_logic_vector(7 downto 0); |
-- porta_io : inout std_logic_vector(7 downto 0); |
-- portb_io : inout std_logic_vector(7 downto 0) |
-- ); |
--end component; |
|
---------------------------------------- |
-- |
-- SBUG Slice Monitor ROM |
-- |
---------------------------------------- |
component boot_rom |
port ( |
addr : in Std_Logic_Vector(10 downto 0); -- 2K byte boot rom |
data : out Std_Logic_Vector(7 downto 0)); |
end component; |
|
---------------------------------------- |
-- |
-- SBUG Block RAM Monitor ROM |
-- |
---------------------------------------- |
--component sbug_rom |
-- Port ( |
-- MEMclk : in std_logic; |
-- MEMaddr : in std_logic_vector (10 downto 0); |
-- MEMrdata : out std_logic_vector (7 downto 0) |
-- ); |
--end component; |
|
---------------------------------------- |
-- |
-- Dynamic Address Translation Registers |
-- |
---------------------------------------- |
component dat_ram |
port ( |
clk: in std_logic; |
rst: in std_logic; |
cs: in std_logic; |
rw: in std_logic; |
addr_lo: in std_logic_vector(3 downto 0); |
addr_hi: in std_logic_vector(3 downto 0); |
data_in: in std_logic_vector(7 downto 0); |
data_out: out std_logic_vector(7 downto 0) |
); |
end component; |
|
---------------------------------------- |
-- |
-- Block RAM module |
-- |
---------------------------------------- |
-- component block_ram |
-- Port ( |
-- MEMclk : in std_logic; |
-- MEMcs : in std_logic; |
-- MEMrw : in std_logic; |
-- MEMaddr : in std_logic_vector (10 downto 0); |
-- MEMrdata : out std_logic_vector (7 downto 0); |
-- MEMwdata : in std_logic_vector (7 downto 0) |
-- ); |
--end component; |
|
|
-- component BUFG |
-- port ( |
-- i: in std_logic; |
-- o: out std_logic |
-- ); |
-- end component; |
|
begin |
----------------------------------------------------------------------------- |
-- Instantiation of internal components |
----------------------------------------------------------------------------- |
|
my_cpu : cpu09 port map ( |
clk => SysClk, |
rst => cpu_reset, |
rw => cpu_rw, |
vma => cpu_vma, |
address => cpu_addr(15 downto 0), |
data_in => cpu_data_in, |
data_out => cpu_data_out, |
halt => cpu_halt, |
hold => cpu_hold, |
irq => cpu_irq, |
nmi => cpu_nmi, |
firq => cpu_firq, |
test_alu => test_alu, |
test_cc => test_cc |
); |
|
|
my_uart : miniUART port map ( |
SysClk => SysClk, |
rst => cpu_reset, |
cs => uart_cs, |
rw => cpu_rw, |
RxD => rxbit, |
TxD => txbit, |
CTS_n => cts_n, |
RTS_n => rts_n, |
Irq => uart_irq, |
Addr => cpu_addr(0), |
Datain => cpu_data_out, |
DataOut => uart_data_out |
); |
|
--my_timer : timer port map ( |
-- clk => SysClk, |
-- rst => cpu_reset, |
-- cs => timer_cs, |
-- rw => cpu_rw, |
-- addr => cpu_addr(0), |
-- data_in => cpu_data_out, |
-- data_out => timer_data_out, |
-- irq => timer_irq, |
-- timer_in => CountL(5), |
-- timer_out => timer_out |
-- ); |
|
--my_ioport : ioport port map ( |
-- clk => SysClk, |
-- rst => cpu_reset, |
-- cs => ioport_cs, |
-- rw => cpu_rw, |
-- addr => cpu_addr(1 downto 0), |
-- data_in => cpu_data_out, |
-- data_out => ioport_data_out, |
-- porta_io => porta, |
-- portb_io => portb |
-- ); |
|
my_rom : boot_rom port map ( |
addr => cpu_addr(10 downto 0), |
data => rom_data_out |
); |
|
--my_rom : sbug_rom port map ( |
-- MEMclk => SysClk, |
-- MEMaddr => cpu_addr(10 downto 0), |
-- MEMrdata => rom_data_out |
-- ); |
|
my_dat : dat_ram port map ( |
clk => SysClk, |
rst => cpu_reset, |
cs => dat_cs, |
rw => cpu_rw, |
addr_hi => cpu_addr(15 downto 12), |
addr_lo => cpu_addr(3 downto 0), |
data_in => cpu_data_out, |
data_out => dat_addr(7 downto 0) |
); |
|
--my_ram : block_ram port map ( |
-- MEMclk => SysClk, |
-- MEMcs => xram_cs, |
-- MEMrw => cpu_rw, |
-- MEMaddr => cpu_addr(10 downto 0), |
-- MEMwdata => cpu_data_out, |
-- MEMrdata => xram_data_out |
-- ); |
|
-- clk_buffer : BUFG port map( |
-- i => e_clk, |
-- o => cpu_clk |
-- ); |
|
---------------------------------------------------------------------- |
-- |
-- Process to decode memory map |
-- |
---------------------------------------------------------------------- |
|
mem_decode: process( SysClk, Reset_n, |
cpu_addr, cpu_rw, cpu_vma, |
dat_cs, dat_addr, |
-- map_cs, map_sw, |
rom_data_out, ram_data_out, |
-- xram_data_out, |
cf_data_out, |
-- timer_data_out, ioport_data_out, |
uart_data_out ) |
begin |
case cpu_addr(15 downto 11) is |
-- |
-- SBUG Monitor ROM $F800 - $FFFF |
-- |
when "11111" => -- $F800 - $FFFF |
cpu_data_in <= rom_data_out; -- read ROM |
dat_cs <= cpu_vma; -- write DAT |
ram_cs <= '0'; |
uart_cs <= '0'; |
cf_cs <= '0'; |
-- timer_cs <= '0'; |
-- ioport_cs <= '0'; |
-- xram_cs <= '0'; |
-- map_cs <= '0'; |
|
-- |
-- Shadow RAM Monitor switch |
-- |
-- when "11101" => -- $E800 - $EFFF |
-- when "11111" => -- $F800 - $FFFF |
-- if map_sw = '1' then |
-- cpu_data_in <= rom_data_out; -- read ROM |
-- dat_cs <= '0'; -- disable write to DAT |
-- ram_cs <= cpu_vma; -- enable write to RAM |
-- else |
-- cpu_data_in <= ram_data_out; -- read RAM |
-- dat_cs <= cpu_vma; -- enable write DAT |
-- ram_cs <= cpu_vma and cpu_rw; -- disable write to RAM |
-- end if; |
-- uart_cs <= '0'; |
-- cf_cs <= '0'; |
-- timer_cs <= '0'; |
-- ioport_cs <= '0'; |
-- xram_cs <= cpu_vma; |
-- map_cs <= '0'; |
|
-- |
-- Synchronous Block RAM $F000 - $F7FF |
-- |
-- when "11110" => -- $F000 - $F7FF |
-- cpu_data_in <= xram_data_out; |
-- dat_cs <= '0'; |
-- ram_cs <= '0'; |
-- uart_cs <= '0'; |
-- cf_cs <= '0'; |
-- timer_cs <= '0'; |
-- ioport_cs <= '0'; |
-- xram_cs <= cpu_vma; |
-- map_cs <= '0'; |
|
-- |
-- IO Devices $E000 - $E7FF |
-- |
when "11100" => -- $E000 - $E7FF |
dat_cs <= '0'; |
ram_cs <= '0'; |
-- xram_cs <= '0'; |
case cpu_addr(7 downto 4) is |
-- |
-- UART / ACIA $E000 |
-- |
when "0000" => -- $E000 |
cpu_data_in <= uart_data_out; |
uart_cs <= cpu_vma; |
cf_cs <= '0'; |
-- timer_cs <= '0'; |
-- ioport_cs <= '0'; |
-- map_cs <= '0'; |
-- |
-- Compact Flash $E010 - $E01F |
-- |
when "0001" => -- $E010 |
cpu_data_in <= cf_data_out; |
uart_cs <= '0'; |
cf_cs <= cpu_vma; |
-- timer_cs <= '0'; |
-- ioport_cs <= '0'; |
-- map_cs <= '0'; |
-- |
-- Timer $E020 - $E02F |
-- |
-- when "0010" => -- $E020 |
-- cpu_data_in <= timer_data_out; |
-- uart_cs <= '0'; |
-- cf_cs <= '0'; |
-- timer_cs <= cpu_vma; |
-- ioport_cs <= '0'; |
-- map_cs <= '0'; |
|
-- |
-- ROM Map switch $E030 |
-- |
-- when "0011" => -- $E030 |
-- cpu_data_in <= "00000000"; |
-- uart_cs <= '0'; |
-- cf_cs <= '0'; |
-- timer_cs <= '0'; |
-- ioport_cs <= '0'; |
-- map_cs <= cpu_vma; |
|
-- |
-- I/O port $E040 - $E04F |
-- |
-- when "0100" => -- $E040 |
-- cpu_data_in <= ioport_data_out; |
-- uart_cs <= '0'; |
-- cf_cs <= '0'; |
-- timer_cs <= '0'; |
-- ioport_cs <= cpu_vma; |
-- map_cs <= '0'; |
|
when others => -- $E040 to $E7FF |
cpu_data_in <= "00000000"; |
uart_cs <= '0'; |
cf_cs <= '0'; |
-- timer_cs <= '0'; |
-- ioport_cs <= '0'; |
-- map_cs <= '0'; |
end case; |
-- |
-- Everything else is RAM |
-- |
when others => |
cpu_data_in <= ram_data_out; |
ram_cs <= cpu_vma; |
dat_cs <= '0'; |
uart_cs <= '0'; |
cf_cs <= '0'; |
-- timer_cs <= '0'; |
-- ioport_cs <= '0'; |
-- xram_cs <= '0'; |
-- map_cs <= '0'; |
end case; |
end process; |
|
-- |
-- B3-SRAM Control |
-- Processes to read and write memory based on bus signals |
-- |
ram_process: process( SysClk, Reset_n, |
cpu_addr, cpu_rw, cpu_vma, cpu_data_out, |
dat_addr, |
ram_cs, ram_wrl, ram_wru, ram_data_out ) |
begin |
ram_csn <= not( ram_cs and Reset_n ); |
ram_wrl <= (not dat_addr(5)) and (not cpu_rw) and SysClk; |
ram_wrln <= not (ram_wrl); |
ram_wru <= dat_addr(5) and (not cpu_rw) and SysClk; |
ram_wrun <= not (ram_wru); |
ram_addr(16 downto 12) <= dat_addr(4 downto 0); |
ram_addr(11 downto 0) <= cpu_addr(11 downto 0); |
|
if ram_wrl = '1' then |
ram_data(7 downto 0) <= cpu_data_out; |
else |
ram_data(7 downto 0) <= "ZZZZZZZZ"; |
end if; |
|
if ram_wru = '1' then |
ram_data(15 downto 8) <= cpu_data_out; |
else |
ram_data(15 downto 8) <= "ZZZZZZZZ"; |
end if; |
|
if dat_addr(5) = '1' then |
ram_data_out <= ram_data(15 downto 8); |
else |
ram_data_out <= ram_data(7 downto 0); |
end if; |
end process; |
|
-- |
-- Compact Flash Control |
-- |
compact_flash: process( SysClk, Reset_n, |
cpu_addr, cpu_rw, cpu_vma, cpu_data_out, |
cf_cs, cf_rd, cf_wr, cf_data_out ) |
begin |
cf_rst_n <= Reset_n; |
cf_cs0_n <= not( cf_cs ) or cpu_addr(3); |
cf_cs1_n <= not( cf_cs and cpu_addr(3)); |
cf_cs16_n <= '1'; |
cf_wr <= cf_cs and (not cpu_rw); |
cf_rd <= cf_cs and cpu_rw; |
cf_wr_n <= not cf_wr; |
cf_rd_n <= not cf_rd; |
cf_a <= cpu_addr(2 downto 0); |
if cf_wr = '1' then |
cf_d(7 downto 0) <= cpu_data_out; |
else |
cf_d(7 downto 0) <= "ZZZZZZZZ"; |
end if; |
cf_data_out <= cf_d(7 downto 0); |
cf_d(15 downto 8) <= "ZZZZZZZZ"; |
end process; |
|
-- |
-- ROM Map switch |
-- The Map switch output is initially set |
-- On a Write to the Map Switch port, clear the Map Switch |
-- and map the RAM in place of the boot ROM. |
-- |
--map_proc : process( SysClk, Reset_n, map_cs, cpu_rw ) |
--begin |
-- if SysClk'event and SysClk = '0' then |
-- if Reset_n = '0' then |
-- map_sw <= '1'; |
-- else |
-- if (map_cs = '1') and (cpu_rw = '0') then |
-- map_sw <= '0'; |
-- else |
-- map_sw <= map_sw; |
-- end if; |
-- end if; |
-- end if; |
--end process; |
|
-- |
-- Interrupts and other bus control signals |
-- |
interrupts : process( Reset_n, uart_irq |
-- ,timer_irq |
) |
begin |
cpu_reset <= not Reset_n; -- CPU reset is active high |
cpu_irq <= uart_irq; |
-- cpu_nmi <= timer_irq; |
cpu_nmi <= '0'; |
cpu_firq <= '0'; |
cpu_halt <= '0'; |
cpu_hold <= '0'; |
end process; |
|
-- |
-- flash led to indicate code is working |
-- |
increment: process (SysClk, CountL ) |
begin |
if(SysClk'event and SysClk = '0') then |
countL <= countL + 1; |
end if; |
LED <= countL(21); |
end process; |
|
end my_computer; --===================== End of architecture =======================-- |
|