URL
https://opencores.org/ocsvn/System09/System09/trunk
Subversion Repositories System09
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 2 to Rev 3
- ↔ Reverse comparison
Rev 2 → Rev 3
/tags/V10/rtl/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; |
/tags/V10/rtl/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; |
|
/tags/V10/rtl/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 =======================-- |
|
/tags/V10/rtl/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 =======================-- |
|
/tags/V10/rtl/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 =======================-- |
|
/tags/V10/rtl/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 =======================-- |
|
/tags/V10/rtl/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 |
/tags/V10/rtl/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; |
|
/tags/V10/rtl/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 =======================-- |
|
/tags/V10/rtl/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 ====================-- |
/tags/V10/rtl/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; |
|
/tags/V10/rtl/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 ====================-- |
/tags/V10/rtl/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; |
|
/tags/V10/rtl/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 =======================-- |
|
/tags/V10/rtl/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; |
/tags/V10/rtl/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 ===================-- |
/tags/V10/rtl/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 =======================-- |
|
/tags/V10/doc/SBUG_Listing.pdf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
tags/V10/doc/SBUG_Listing.pdf
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: tags/V10/doc/SBUG_UsersGuide.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: tags/V10/doc/SBUG_UsersGuide.pdf
===================================================================
--- tags/V10/doc/SBUG_UsersGuide.pdf (nonexistent)
+++ tags/V10/doc/SBUG_UsersGuide.pdf (revision 3)
tags/V10/doc/SBUG_UsersGuide.pdf
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: tags/V10/sw/sbug_src.s19
===================================================================
--- tags/V10/sw/sbug_src.s19 (nonexistent)
+++ tags/V10/sw/sbug_src.s19 (revision 3)
@@ -0,0 +1,65 @@
+S123F800F814F861FDCFFDC9FDDFFDEEFDBDFDB1FDADFB818EFE4F108EDFC0C610A680A7DD
+S123F820A05A26F98EE004BFDFE017027AC60C6FE25A26FB308CDDAF6A86D0A7E41F43177E
+S123F84005BE8EFE5F1705758EDFD04FC60D6D8527038B04195A2AF61705268EFE7417056A
+S123F8605C8EFE7B170546170565847F810D27F11F8981202C09865E1705731F988B40170B
+S123F880056C170567C1602F02C0208EFE13E180270F30028CFE4F26F58EFE7D17051E207F
+S123F8A0C0AD9420BC1F343B8EFE831704FF1704111704191704211704291704318EFE8375
+S123F8C01704EA17043317043A1704411604481704271705171704572902AF4A391703ED73
+S123F8E01705091704492902AF48391704001704FB17043B2902AF46391703E71704ED1720
+S123F900042D2902AF44391703CE1704DF1704302902A743391703F51704D117042229027D
+S123F920A742391703DD1704C31704142902A741391703E31704B517040629048A80A7C4C1
+S123F940391703EB292D1F128EFE8317045F1F21170426170496A6A417042617048E1703D5
+S123F960DF2811810827E1811827DD815E2717810D260F39A7A4A1A4270817046F863F17FF
+S123F980046C312120C2313F20BE1703351F328EDFC0301F200517038B29063420ACE12457
+S123F9A001391F10C30010C4F034061F20C4F01F01ACE42705170427270332623934108E3F
+S123F9C0FE831703E8AEE41703AFC610A6801703B01704185A26F5170410AEE1C610A68021
+S123F9E081202504817E2302862E1704015A26EE20BF6FE26FE217032B3430297BAC6225D6
+S123FA00771703E81F20E3643404ABE0A7A010ACE425F110AE621F20E3643402EBE0E8A0F4
+S123FA20273C8EFE83170385303F17034C34108EFEA1170388351017014717035017033968
+S123FA408EFE87170377AE6417032E8EFE8F17036C1F988EFEA617033E170383261A10AC29
+S123FA60E425B3862B170386170374260B10AE626C6526906C64268C3266391702B1291EAB
+S123FA808CDFC0241A34108EFFFF8D553510270FA684813F2709A7A0AFA4863FA7843917D8
+S123FAA0034A863F160347108EDFE3C6088D185A26FB391F43AE4A301F8D262704AF4A8D3C
+S123FAC00617FDE416FD9AAE218CDFC0240AA684813F2604A6A4A78486FFA7A0A7A0A7A06C
+S123FAE039108EDFE3C608A6A0ACA127045A26F739313D3986DEB7F02486FFB7F014B7F070
+S123FB0010B7F015B7F0167DF01086D8B7F020170097B6F0202BFB8609B7F02017008AB66F
+S123FB20F020850126F9851026CA8EC0008D528A10B7F0401F104353FDF0008EFEFFBFF0ED
+S123FB400286FFB7F01086FEB7F0148601B7F022868CB7F0208D525F34045F7DF0102A0A75
+S123FB605A26F835045A26F0208A3504B6F020851C270139C6DEF7F0248EC000AF4A1F346C
+S123FB803B3436A66244444444108EDFD0E6A654545454E7E4E6A65358585858A662840FD6
+S123FBA0A762EA62E7623536393404C6205A26FD3504397DE0187FE014C6038E0000300182
+S123FBC08C000026F95A26F6860FB7E0188D37F6E018C50126F98601B7E01A8D29868CB76E
+S123FBE0E0188D228EC0002009C5022705B6E01BA780F6E018C50126F0C52C2701398EC0AE
+S123FC0000AF4A1F343BC6205A26FD3986111701DD7FDFE21701AD815326F91701A68139C1
+S123FC20273D813126F1170117340229261700FF29213410E6E0EBE0EBE46AE46AE4340407
+S123FC401700FD3504290C3402EBE06AE42705A78020EB5F3502C1FF27B2863F17018F7363
+S123FC60DFE286131601876FE21700B83430294AAC6225463001AFE48612170171ECE4A3C0
+S123FC80622706108300202302C620E7648EFEEB17011ACB031F981700E7AE621700DAEBB0
+S123FCA062EB63EB84A6801700D76A6426F5531F981700CDAF62ACE426C3861417012F3299
+S123FCC065398EFEAE1700F51F311600AC8EFEBA1700EAAE481600A18EFECC1700DFA643FF
+S123FCE016009E8EFEC61700D4AE4416008B8EFEC01700C9AE461600808EFEB41700BEAE03
+S123FD004A20768EFED21700B4A64120748EFED71700AAA642206A8EFEDC1700A0A6C48EAE
+S123FD20FEE320738D09294E1F12862D1700BF8D0F29431F018D09293D3410A76135103996
+S123FD408D112932484848481F898D0729283404ABE0398D6F8130251D8139220380303946
+S123FD60814125128146220380373981612507816622038057391A0239341035028D0235EC
+S123FD80023402444444448D043502840F8B3081392F028B0720573402C608A68068E42572
+S123FDA002862D8D498D455A26F13502398D02200C34108EFE758D053510398D31A680818C
+S123FDC00426F8397DDFE227068D04847F201F3410BEDFE0A684850127FAA601351039349B
+S123FDE002A69FDFE085013502398D0086203412BEDFE0A684850227FA3502A701351039DE
+S123FE00BEDFE08603A7848611A7846D0186FFB7DFE23901F92302F91503F93104F90710D9
+S123FE20F8CF15F8DD18F8F919F8EB42FA7B44FAF445F99647F8A54CFC0C4DF94150FC67D9
+S123FE4051F9F252F8A853F98A55FBB358FAA7FAB3F8A7F8A7F8A7F8A7FAB3FFFFFFFF00CC
+S123FE6000000D0A000000532D42554720312E38202D20044B0D0A000000043E0457484159
+S123FE80543F04202D20042C205041535320042C204249545320494E204552524F523A2076
+S123FEA004203D3E20043736353433323130202053503D04202050433D04202055533D047E
+S123FEC0202049593D04202049583D04202044503D042020413D042020423D042020434379
+S120FEE03A2004454648494E5A5643533104FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+S123FF008EFFF0860FA7804A26FB86F0A7848ED0A0108E55AAEE8410AF8410AC84270B30A6
+S123FF2089F0008CF0A026ED20D6EF841F104344444444B7FFFD10CEDFC0108EDFD0A72DD9
+S123FF406F2E86F0A72F860C6FA64A2AFB3089F0008CF0A02722EE84108E55AA10AF84102E
+S123FF60AC8426E9EF84108EDFD01F10444444441F89880FA7A520D586F1108EDFD0A72E26
+S123FF80860CE6A626054A2AF920146FA6E72C4F1F21E6A627046FA6E7804C810C2DF38E02
+S123FFA0FFF0C610A6A0A7805A26F953F7DFE216F8626E9FDFC06E9FDFC46E9FDFC66E9FFC
+S123FFC0DFC86E9FDFCA1F43AE4AE680AF4A4F5849BEDFCC8CFFFF270F308BBCDFCE2208A0
+S123FFE03410ECC4AE446EF1371FEE426E9FDFC2FFB2FFC6FFB6FFBAFFBEFFC2FFB2FF0072
+S9030000FC
Index: tags/V10/sw/sbug_src.txt
===================================================================
--- tags/V10/sw/sbug_src.txt (nonexistent)
+++ tags/V10/sw/sbug_src.txt (revision 3)
@@ -0,0 +1,1402 @@
+* NAM SBUG18 MP-09 MONITOR
+ OPT l
+ PAGE
+*
+* MONITOR PROGRAM FOR THE SOUTHWEST TECHNICAL
+* PRODUCTS MP-09 CPU BOARD AS COMMENTED BY....
+*
+* ALLEN CLARK WALLACE WATSON
+* 2502 REGAL OAKS LANE 4815 EAST 97th AVE.
+* LUTZ, FLA. 33549 TEMPLE TERRACE, FLA. 33617
+* PH. 813-977-0347 PH. 813-985-1359
+*
+* MODIFIED TO SBUG09 VER 1.8 BY: RANDY JARRETT
+* 2561 NANTUCKET DR APT. E
+* ATLANTA, GA 30345
+* PH. 404-320-1043
+*
+*
+* *** COMMANDS ***
+*
+* CONTROL A = ALTER THE "A" ACCUMULATOR
+* CONTROL B = ALTER THE "B" ACCUMULATOR
+* CONTROL C = ALTER THE CONDITION CODE REGISTER
+* CONTROL D = ALTER THE DIRECT PAGE REGISTER
+* CONTROL P = ALTER THE PROGRAM COUNTER
+* CONTROL U = ALTER USER STACK POINTER
+* CONTROL X = ALTER "X" INDEX REGISTER
+* CONTROL Y = ALTER "Y" INDEX REGISTER
+* B hhhh = SET BREAKPOINT AT LOCATION $hhhh
+* D = BOOT A SWTPC 8 INCH FLOPPY SYSTEM
+* U = BOOT A SWTPC 5 INCH FLOPPY SYSTEM
+* E ssss-eeee = EXAMINE MEMORY FROM STARTING ADDRESS ssss
+* -TO ENDING ADDRESS eeee.
+* G = CONTINUE EXECUTION FROM BREAKPOINT OR SWI
+* L = LOAD TAPE
+* M hhhh = EXAMINE AND CHANGE MEMORY LOCATION hhhh
+* P ssss-eeee = PUNCH TAPE, START ssss TO END eeee ADDR.
+* Q ssss-eeee = TEST MEMORY FROM ssss TO eeee
+* R = DISPLAY REGISTER CONTENTS
+* S = DISPLAY STACK FROM ssss TO $DFC0
+* X = REMOVE ALL BREAKPOINTS
+*
+*
+TSTPAT EQU $55AA TEST PATTERN
+*
+*
+*
+ ORG $DFC0
+STACK RMB 2 TOP OF INTERNAL STACK / USER VECTOR
+SWI3 RMB 2 SOFTWARE INTERRUPT VECTOR #3
+SWI2 RMB 2 SOFTWARE INTERRUPT VECTOR #2
+FIRQ RMB 2 FAST INTERRUPT VECTOR
+IRQ RMB 2 INTERRUPT VECTOR
+SWI RMB 2 SOFTWARE INTERRUPT VECTOR
+SVCVO RMB 2 SUPERVISOR CALL VECTOR ORGIN
+SVCVL RMB 2 SUPERVISOR CALL VECTOR LIMIT
+LRARAM RMB 16 LRA ADDRESSES
+CPORT RMB 2 RE-VECTORABLE CONTROL PORT
+ECHO RMB 1 ECHO FLAG
+BPTBL RMB 24 BREAKPOINT TABLE BASE ADDR
+ACIAS EQU $E004 CONTROL PORT
+Comreg EQU $E018 COMMAND REGISTER
+Drvreg EQU $E014 DRIVE REGISTER
+Secreg EQU $E01A SECTOR REGISTER
+Datreg EQU $E01B DATA REGISTER
+*
+ADDREG EQU $F000 ADDRESS REGISTER
+CNTREG EQU $F002 COUNT REGISTER
+CCREG EQU $F010 CHANNEL CONTROL REGISTER
+PRIREG EQU $F014 DMA PRIORITY REGISTER
+AAAREG EQU $F015 ???
+BBBREG EQU $F016 ???
+COMREG EQU $F020 1791 COMMAND REGISTER
+SECREG EQU $F022 SECTOR REGISTER
+DRVREG EQU $F024 DRIVE SELECT LATCH
+CCCREG EQU $F040 ???
+*
+IC11 EQU $FFF0 DAT RAM CHIP
+*
+ ORG $F800
+ FDB MONITOR
+ FDB NEXTCMD
+ FDB INCH
+ FDB INCHE
+ FDB INCHEK
+ FDB OUTCH
+ FDB PDATA
+ FDB PCRLF
+ FDB PSTRNG
+ FDB LRA
+*
+* MONITOR
+*
+* VECTOR ADDRESS STRING IS.....
+* $F8A1-$F8A1-$F8A1-$F8A1-$F8A1-$FAB0-$FFFF-$FFFF
+*
+MONITOR LDX #RAMVEC POINT TO VECTOR ADDR. STRING
+ LDY #STACK POINT TO RAM VECTOR LOCATION
+ LDB #$10 BYTES TO MOVE = 16
+LOOPA LDA ,X+ GET VECTOR BYTE
+ STA ,Y+ PUT VECTORS IN RAM / $DFC0-$DFCF
+ DECB SUBTRACT 1 FROM NUMBER OF BYTES TO MOVE
+ BNE LOOPA CONTINUE UNTIL ALL VECTORS MOVED
+*
+* CONTENTS FROM TO FUNCTION
+* $F8A1 $FE40 $DFC0 USER-V
+* $F8A1 $FE42 $DFC2 SWI3-V
+* $F8A1 $FE44 $DFC4 SWI2-V
+* $F8A1 $FE46 $DFC6 FIRQ-V
+* $F8A1 $FE48 $DFC8 IRQ-V
+* $FAB0 $FE4A $DFCA SWI-V
+* $FFFF $FE4C $DFCC SVC-VO
+* $FFFF $FE4E $DFCE SVC-VL
+*
+ LDX #ACIAS GET CONTROL PORT ADDR.
+ STX CPORT STORE ADDR. IN RAM
+ LBSR XBKPNT CLEAR OUTSTANDING BREAKPOINTS
+ LDB #12 CLEAR 12 BYTES ON STACK
+CLRSTK CLR ,-S
+ DECB
+ BNE CLRSTK
+ LEAX MONITOR,PCR SET PC TO SBUG-E ENTRY
+ STX 10,S ON STACK
+ LDA #$D0 PRESET CONDITION CODES ON STACK
+ STA ,S
+ TFR S,U
+ LBSR ACINIZ INITIALIZE CONTROL PORT
+ LDX #MSG1 POINT TO 'SBUG 1.8' MESSAGE
+ LBSR PDATA PRINT MSG
+ LDX #LRARAM POINT TO LRA RAM STORAGE AREA
+ CLRA START TOTAL AT ZERO
+ LDB #13 TOTAL UP ALL ACTIVE RAM MEMORY
+FNDREL TST B,X TEST FOR RAM AT NEXT LOC.
+ BEQ RELPAS IF NO RAM GO TO NEXT LOC.
+ ADDA #4 ELSE ADD 4K TO TOTAL
+ DAA ADJ. TOTAL FOR DECIMAL
+RELPAS DECB SUB. 1 FROM LOCS. TO TEST
+ BPL FNDREL PRINT TOTAL OF RAM
+ LBSR OUT2H OUTPUT HEX BYTE AS ASCII
+ LDX #MSG2 POINT TO MSG 'K' CR/LF + 3 NULS
+ LBSR PDATA PRINT MSG
+*
+***** NEXTCMD *****
+*
+NEXTCMD LDX #MSG3 POINT TO MSG ">"
+ LBSR PSTRNG PRINT MSG
+ LBSR INCH GET ONE CHAR. FROM TERMINAL
+ ANDA #$7F STRIP PARITY FROM CHAR.
+ CMPA #$0D IS IT CARRIAGE RETURN ?
+ BEQ NEXTCMD IF CR THEN GET ANOTHER CHAR.
+ TFR A,B PUT CHAR. IN "B" ACCUM.
+ CMPA #$20 IS IT CONTROL OR DATA CHAR ?
+ BGE PRTCMD IF CMD CHAR IS DATA, PRNT IT
+ LDA #'^ ELSE CNTRL CHAR CMD SO...
+ LBSR OUTCH PRINT "^"
+ TFR B,A RECALL CNTRL CMD CHAR
+ ADDA #$40 CONVERT IT TO ASCII LETTER
+PRTCMD LBSR OUTCH PRNT CMD CHAR
+ LBSR OUT1S PRNT SPACE
+ CMPB #$60
+ BLE NXTCH0
+ SUBB #$20
+*
+*
+***** DO TABLE LOOKUP *****
+* FOR COMMAND FUNCTIONS
+*
+*
+NXTCH0 LDX #JMPTAB POINT TO JUMP TABLE
+NXTCHR CMPB ,X+ DOES COMMAND MATCH TABLE ENTRY ?
+ BEQ JMPCMD BRANCH IF MATCH FOUND
+ LEAX 2,X POINT TO NEXT ENTRY IN TABLE
+ CMPX #TABEND REACHED END OF TABLE YET ?
+ BNE NXTCHR IF NOT END, CHECK NEXT ENTRY
+ LDX #MSG4 POINT TO MSG "WHAT?"
+ LBSR PDATA PRINT MSG
+ BRA NEXTCMD IF NO MATCH, PRMPT FOR NEW CMD
+JMPCMD JSR [,X] JUMP TO COMMAND ROUTINE
+ BRA NEXTCMD PROMPT FOR NEW COMMAND
+*
+* "G" GO OR CONTINUE
+*
+GO TFR U,S
+RTI RTI
+*
+* "R" DISPLAY REGISTERS
+*
+REGSTR LDX #MSG5 POINT TO MSG " - "
+ LBSR PSTRNG PRINT MSG
+ LBSR PRTSP $FCBF
+ LBSR PRTUS $FCCA
+ LBSR PRTDP $FCD5
+ LBSR PRTIX $FCE0
+ LBSR PRTIY $FCEB
+ LDX #MSG5 POINT TO MSG " - "
+ LBSR PSTRNG PRINT MSG
+ LBSR PRTPC $FCF5
+ LBSR PRTA $FCFF
+ LBSR PRTB $FD09
+ LBRA PRTCC $FD13
+*
+*
+* ALTER "PC" PROGRAM COUNTER
+*
+*
+ALTRPC LBSR PRTPC $FCF5 PRINT MSG " PC = "
+ LBSR OUT1S OUTPUT SPACE
+ LBSR IN1ADR GET NEW CONTENTS FOR "PC"
+ BVS ALTPCD EXIT IF INVALID HEX
+ STX 10,U POKE IN NEW CONTENTS
+ALTPCD RTS ;
+*
+*
+* ALTER "U" USER STACK POINTER
+*
+*
+ALTRU LBSR PRTUS $FCCA PRINT MSG " US = "
+ LBSR OUT1S OUTPUT SPACE
+ LBSR IN1ADR
+ BVS ALTUD
+ STX 8,U
+ALTUD RTS ;
+*
+*
+* ALTER "Y" INDEX REGISTER
+*
+*
+ALTRY LBSR PRTIY PRINT MSG " IY = "
+ LBSR OUT1S OUTPUT SPACE
+ LBSR IN1ADR
+ BVS ALTYD
+ STX 6,U $F8F0
+ALTYD RTS ;
+*
+*
+* ALTER "X" INDEX REGISTER
+*
+*
+ALTRX LBSR PRTIX $FCE0 PRINT MSG " IX = "
+ LBSR OUT1S OUTPUT SPACE
+ LBSR IN1ADR
+ BVS ALTXD
+ STX 4,U
+ALTXD RTS ;
+*
+*
+* ALTER "DP" DIRECT PAGE REGISTER
+*
+*
+ALTRDP LBSR PRTDP $FCD5 PRINT MSG " DP = "
+ LBSR OUT1S OUTPUT SPACE
+ LBSR BYTE INPUT BYTE (2 HEX CHAR)
+ BVS ALTDPD
+ STA 3,U
+ALTDPD RTS ;
+*
+*
+* ALTER "B" ACCUMULATOR
+*
+*
+ALTRB LBSR PRTB $FD09 PRINT MSG " B = "
+ LBSR OUT1S OUTPUT SPACE
+ LBSR BYTE INPUT BYTE (2 HEX CHAR)
+ BVS ALTBD
+ STA 2,U
+ALTBD RTS $F91C
+*
+*
+* ALTER "A" ACCUMULATOR
+*
+*
+ALTRA LBSR PRTA $FCFF RINT MSG " A = "
+ LBSR OUT1S OUTPUT SPACE
+ LBSR BYTE INPUT BYTE (2 HEX CHAR)
+ BVS ALTAD
+ STA 1,U
+ALTAD RTS ;
+*
+*
+* ALTER "CC" REGISTER
+*
+*
+ALTRCC LBSR PRTCC $FD13 PRINT MSG " CC: "
+ LBSR OUT1S OUTPUT SPACE
+ LBSR BYTE INPUT BYTE (2 HEX CHAR)
+ BVS ALTCCD
+ ORA #$80 SETS "E" FLAG IN PRINT LIST
+ STA ,U
+ALTCCD RTS ;
+*
+***** "M" MEMORY EXAMINE AND CHANGE *****
+*
+MEMCHG LBSR IN1ADR INPUT ADDRESS
+ BVS CHRTN IF NOT HEX, RETURN
+ TFR X,Y SAVE ADDR IN "Y"
+MEMC2 LDX #MSG5 POINT TO MSG " - "
+ LBSR PSTRNG PRINT MSG
+ TFR Y,X FETCH ADDRESS
+ LBSR OUT4H PRINT ADDR IN HEX
+ LBSR OUT1S OUTPUT SPACE
+ LDA ,Y GET CONTENTS OF CURRENT ADDR.
+ LBSR OUT2H OUTPUT CONTENTS IN ASCII
+ LBSR OUT1S OUTPUT SPACE
+ LBSR BYTE LOOP WAITING FOR OPERATOR INPUT
+ BVC CHANGE IF VALID HEX GO CHANGE MEM. LOC.
+ CMPA #8 IS IT A BACKSPACE (CNTRL H)?
+ BEQ MEMC2 PROMPT OPERATOR AGAIN
+ CMPA #$18 IS IT A CANCEL (CNTRL X)?
+ BEQ MEMC2 PROMPT OPERATOR AGAIN
+ CMPA #'^ IS IT AN UP ARROW?
+ BEQ BACK DISPLAY PREVIOUS BYTE
+ CMPA #$D IS IT A CR?
+ BNE FORWRD DISPLAY NEXT BYTE
+CHRTN RTS EXIT ROUTINE
+*
+*
+CHANGE STA ,Y CHANGE BYTE IN MEMORY
+ CMPA ,Y DID MEMORY BYTE CHANGE?
+ BEQ FORWRD $F972
+ LBSR OUT1S OUTPUT SPACE
+ LDA #'? LOAD QUESTION MARK
+ LBSR OUTCH PRINT IT
+FORWRD LEAY 1,Y POINT TO NEXT HIGHER MEM LOCATION
+ BRA MEMC2 PRINT LOCATION & CONTENTS
+BACK LEAY -1,Y POINT TO LAST MEM LOCATION
+ BRA MEMC2 PRINT LOCATION & CONTENTS
+*
+* "S" DISPLAY STACK
+* HEX-ASCII DISPLAY OF CURRENT STACK CONTENTS FROM
+** CURRENT STACK POINTER TO INTERNAL STACK LIMIT.
+*
+DISSTK LBSR PRTSP PRINT CURRENT STACK POINTER
+ TFR U,Y
+ LDX #STACK LOAD INTERNAL STACK AS UPPER LIMIT
+ LEAX -1,X POINT TO CURRENT STACK
+ BRA MDUMP1 ENTER MEMORY DUMP OF STACK CONTENTS
+*
+* "E" DUMP MEMORY FOR EXAMINE IN HEX AND ASCII
+* AFTER CALLING 'IN2ADR' LOWER ADDRESS IN Y-REG.
+* UPPER ADDRESS IN X-REG.
+* IF HEX ADDRESSES ARE INVALID (V)=1.
+*
+MEMDUMP LBSR IN2ADR INPUT ADDRESS BOUNDRIES
+ BVS EDPRTN NEW COMMAND IF ILLEGAL HEX
+MDUMP1 PSHS Y COMPARE LOWER TO UPPER BOUNDS
+ CMPX ,S++ LOWER BOUNDS > UPPER BOUNDS?
+ BCC AJDUMP IF NOT, DUMP HEX AND ASCII
+EDPRTN RTS ;
+*
+* ADJUST LOWER AND UPPER ADDRESS LIMITS
+* TO EVEN 16 BYTE BOUNDRIES.
+*
+* IF LOWER ADDR = $4532
+* LOWER BOUNDS WILL BE ADJUSTED TO = $4530.
+*
+* IF UPPER ADDR = $4567
+* UPPER BOUNDS WILL BE ADJUSTED TO = $4570.
+*
+* ENTER WITH LOWER ADDRESS IN X-REG.
+* -UPPER ADDRESS ON TOP OF STACK.
+*
+AJDUMP TFR X,D GET UPPER ADDR IN D-REG
+ ADDD #$10 ADD 16 TO UPPER ADDRESS
+ ANDB #$F0 MASK TO EVEN 16 BYTE BOUNDRY
+ PSHS A,B SAVE ON STACK AS UPPER DUMP LIMIT
+ TFR Y,D $F9A5 GET LOWER ADDRESS IN D-REG
+ ANDB #$F0 MASK TO EVEN 16 BYTE BOUNDRY
+ TFR D,X PUT IN X-REG AS LOWER DUMP LIMIT
+NXTLIN CMPX ,S COMPARE LOWER TO UPPER LIMIT
+ BEQ SKPDMP IF EQUAL SKIP HEX-ASCII DUMP
+ LBSR INCHEK CHECK FOR INPUT FROM KEYBOARD
+ BEQ EDUMP IF NONE, CONTINUE WITH DUMP
+SKPDMP LEAS 2,S READJUST STACK IF NOT DUMPING
+ RTS ;
+*
+* PRINT 16 HEX BYTES FOLLOWED BY 16 ASCII CHARACTERS
+* FOR EACH LINE THROUGHOUT ADDRESS LIMITS.
+*
+EDUMP PSHS X PUSH LOWER ADDR LIMIT ON STACK
+ LDX #MSG5 POINT TO MSG " - "
+ LBSR PSTRNG PRINT MSG
+ LDX ,S LOAD LOWER ADDR FROM TOP OF STACK
+ LBSR OUT4H PRINT THE ADDRESS LBSR OUT2S PRINT 2 SPACES
+ LDB #$10 LOAD COUNT OF 16 BYTES TO DUMP
+ELOOP LDA ,X+ GET FROM MEMORY HEX BYTE TO PRINT
+ LBSR OUT2H OUTPUT HEX BYTE AS ASCII
+ LBSR OUT1S OUTPUT SPACE
+ DECB $F9D1 DECREMENT BYTE COUNT
+ BNE ELOOP CONTINUE TIL 16 HEX BYTES PRINTED
+*
+* PRINT 16 ASCII CHARACTERS
+* IF NOT PRINTABLE OR NOT VALID
+* ASCII PRINT A PERIOD (.)
+ LBSR OUT2S 2 SPACES
+ LDX ,S++ GET LOW LIMIT FRM STACK - ADJ STACK
+ LDB #$10 SET ASCII CHAR TO PRINT = 16
+EDPASC LDA ,X+ GET CHARACTER FROM MEMORY
+ CMPA #$20 IF LESS THAN $20, NON-PRINTABLE?
+ BCS PERIOD IF SO, PRINT PERIOD INSTEAD
+ CMPA #$7E IS IT VALID ASCII?
+ BLS PRASC IF SO PRINT IT
+PERIOD LDA #'. LOAD A PERIOD (.)
+PRASC LBSR OUTCH PRINT ASCII CHARACTER
+ DECB DECREMENT COUNT
+ BNE EDPASC
+ BRA NXTLIN
+*
+***** "Q" MEMORY TEST *****
+*
+MEMTST CLR ,-S CLEAR BYTE ON STACK
+ CLR ,-S CLEAR ANOTHER BYTE
+ LBSR IN2ADR GET BEGIN(Y) & END(X) ADDR. LIMITS
+ PSHS X,Y SAVE ADDRESSES ON STACK
+ BVS ADJSK6 EXIT IF NOT VALID HEX
+ CMPX 2,S COMPARE BEGIN TO END ADDR.
+ BCS ADJSK6 EXIT IF BEGIN > END ADDR.
+ LBSR OUT1S OUTPUT SPACE
+MEMSET TFR Y,D PUT BEGIN ADDR. IN 'D'-ACCUM.
+ ADDD 4,S ADD PASS COUNT TO BEGIN ADDR
+ PSHS B ADD LS BYTE TO MS BYTE OF BEGIN ADDR
+ ADDA ,S+
+ STA ,Y+ SAVE THIS DATA BYTE AT BEGIN ADDR
+ CMPY ,S COMPARE END TO BEGIN ADDR
+ BCS MEMSET IF BEGIN LOWER, CONTINUE TO SET MEMORY
+ LDY 2,S RELOAD BEGIN ADDRESS
+TEST1 TFR Y,D PUT BEGIN ADDR IN 'D'-ACC.
+ ADDD 4,S ADD PASS COUNT TO ADDRESS
+ PSHS A ADD MS BYTE TO LS BYTE OF ADDRESS
+ ADDB ,S+
+ EORB ,Y+ EX-OR THIS DATA WITH DATA IN MEMORY LOC.
+ BEQ GUDPAS IF (Z) SET, MEMORY BYTE OK
+ LDX #MSG5 POINT TO MSG " - "
+ LBSR PSTRNG PRINT MSG
+ LEAX -1,Y GET ERROR ADDRESS IN X-REG
+ LBSR OUT4H OUTPUT IT
+ PSHS X PUSH ERROR ADDR ON STACK
+ LDX #MSG8 POINT TO MSG " =>"
+ LBSR PDATA PRINT MSG
+ PULS X POP ERROR ADDR FROM STACK
+ LBSR LRA GET PHYSICAL ADDR FROM LRA
+ LBSR XASCII OUTPUT EXTENDED 4 BITS OF PHYSICAL ADDR
+ LBSR OUT4H OUTPUT LS 16 BITS OF PHYSICAL ADDR
+ LDX #MSG6 POINT TO MSG ", PASS "
+ LBSR PDATA PRINT MSG
+ LDX 4,S LOAD PASS COUNT
+ LBSR OUT4H OUTPUT IT
+ LDX #MSG7 POINT TO MSG ", BITS IN ERROR
+ LBSR PDATA PRINT MSG
+ TFR B,A GET ERROR BYTE INTO A-ACC
+ LDX #MSG9 POINT TO MSG "76543210"
+ LBSR BIASCI OUTPUT IN BINARY/ASCII FORMAT
+ LBSR INCHEK CHECK FOR INPUT FROM KEYBOARD $FA56
+ BNE ADJSK6 IF SO, EXIT MEMORY TEST
+GUDPAS CMPY ,S COMPARE END ADDR TO BEGIN ADDR
+ BCS TEST1
+ LDA #'+ GET "PASS" SYMBOL IF MEMORY PASS OK
+ LBSR OUTCH OUTPUT SYMBOL TO TERMINAL
+ LBSR INCHEK INPUT FROM KEYBOARD?
+ BNE ADJSK6 IF SO, EXIT MEMORY TEST
+ LDY 2,S LOAD BEGIN ADDRESS
+ INC 5,S INCREMENT LS BYTE OF PASS COUNT
+ BNE MEMSET IF NOT ZERO, SET NEXT MEMORY BYTE
+ INC 4,S INCREMENT MS BYTE OF PASS COUNT
+ BNE MEMSET DONE WITH 65,535 PASSES OF MEMORY?
+ADJSK6 LEAS 6,S ADJ STACK POINTER BY 6
+ RTS
+*
+***** "B" SET BREAKPOINT *****
+*
+BRKPNT LBSR IN1ADR GET BREAKPOINT ADDRESS
+ BVS EXITBP EXIT IF INVALID HEX ADDR.
+ CMPX #STACK ADDRESS ILLEGAL IF >=$DFC0
+ BCC BPERR IF ERROR PRINT (?), EXIT
+ PSHS X $FA82 PUSH BP ADDRESS ON STACK
+ LDX #$FFFF LOAD DUMMY ADDR TO TEST BP TABLE
+ BSR BPTEST TEST BP TABLE FOR FREE SPACE
+ PULS X POP BP ADDRESS FROM STACK
+ BEQ BPERR (Z) SET, OUT OF BP TABLE SPACE
+ LDA ,X GET DATA AT BREAKPOINT ADDRESS
+ CMPA #$3F IS IT A SWI?
+ BEQ BPERR IF SWI ALREADY, INDICATE ERROR
+ STA ,Y+ SAVE DATA BYTE IN BP TABLE
+ STX ,Y SAVE BP ADDRESS IN BP TABLE
+ LDA #$3F LOAD A SWI ($3F)
+ STA ,X SAVE SWI AT BREAKPOINT ADDRESS
+EXITBP RTS ;
+*
+* INDICATE ERROR SETTING BREAKPOINT
+*
+BPERR LBSR OUT1S OUTPUT SPACE
+ LDA #'? LOAD (?), INDICATE BREAKPOINT ERROR
+ LBRA OUTCH PRINT "?"
+*
+*** "X" CLEAR OUTSTANDING BREAKPOINTS ***
+*
+XBKPNT LDY #BPTBL POINT TO BREAKPOINT TABLE
+ LDB #8 LOAD BREAKPOINT COUNTER
+XBPLP BSR RPLSWI REMOVE USED ENTRY IN BP TABLE
+ DECB $FAAC DECREMENT BP COUNTER
+ BNE XBPLP END OF BREAKPOINT TABLE?
+ RTS
+*
+***** SWI ENTRY POINT *****
+*
+SWIE TFR S,U TRANSFER STACK TO USER POINTER
+ LDX 10,U LOAD PC FROM STACK INTO X-REG
+ LEAX -1,X ADJUST ADDR DOWN 1 BYTE.
+ BSR BPTEST FIND BREAKPOINT IN BP TABLE
+ BEQ REGPR IF FOUND, REPLACE DATA AT BP ADDR
+ STX 10,U SAVE BREAKPOINT ADDR IN STACK
+ BSR RPLSWI GO REPLACE SWI WITH ORIGINAL DATA
+REGPR LBSR REGSTR GO PRINT REGISTERS
+ LBRA NEXTCMD GET NEXT COMMAND
+RPLSWI LDX 1,Y LOAD BP ADDRESS FROM BP TABLE
+ CMPX #STACK COMPARE TO TOP AVAILABLE USER MEMORY
+ BCC FFSTBL GO RESET TABLE ENTRY TO $FF'S
+ LDA ,X GET DATA FROM BP ADDRESS
+ CMPA #$3F IS IT SWI?
+ BNE FFSTBL IF NOT, RESET TABLE ENTRY TO $FF'S
+ LDA ,Y GET ORIGINAL DATA FROM BP TABLE
+ STA ,X $FAD3 RESTORE DATA AT BP ADDRESS
+FFSTBL LDA #$FF LOAD $FF IN A-ACC
+ STA ,Y+ RESET BREAKPOINT TABLE DATA TO $FF'S
+ STA ,Y+ RESET BREAKPOINT TABLE ADDR TO $FF'S
+ STA ,Y+
+ RTS
+*
+** SEARCH BREAKPOINT TABLE FOR MATCH **
+*
+BPTEST LDY #BPTBL POINT TO BREAKPOINT TABLE
+ LDB #8 LOAD BREAKPOINT COUNTER
+FNDBP LDA ,Y+ LOAD DATA BYTE
+ CMPX ,Y++ COMPARE ADDRESS, IS IT SAME?
+ BEQ BPADJ IF SO, ADJUST POINTER FOR TABLE ENTRY
+ DECB IF NOT, DECREMENT BREAKPOINT COUNTER
+ BNE FNDBP AND LOOK FOR NEXT POSSIBLE MATCH
+ RTS ;
+*
+*
+BPADJ LEAY -3,Y MOVE POINTER TO BEGIN OF BP ENTRY
+ RTS
+*
+*** "D" DISK BOOT FOR DMAF2 ***
+*
+DBOOT LDA #$DE
+ STA DRVREG
+ LDA #$FF
+ STA PRIREG $FAF8
+ STA CCREG
+ STA AAAREG
+ STA BBBREG
+ TST CCREG
+ LDA #$D8
+ STA COMREG
+ LBSR DLY
+DBOOT0 LDA COMREG
+ BMI DBOOT0
+ LDA #$09
+ STA COMREG
+ LBSR DLY
+*
+DISKWT LDA COMREG FETCH DRIVE STATUS
+ BITA #1 TEST BUSY BIT
+ BNE DISKWT LOOP UNTIL NOT BUSY
+*
+ BITA #$10
+ BNE DBOOT
+*
+ LDX #$C000 LOGICAL ADDR. = $C000
+ BSR LRA GET 20 BIT PHYSICAL ADDR. OF LOG. ADDR.
+ ORA #$10
+ STA CCCREG
+ TFR X,D
+ COMA ;
+ COMB ;
+ STD ADDREG
+ LDX #$FEFF LOAD DMA BYTE COUNT = $100
+ STX CNTREG STORE IN COUNT REGISTER
+ LDA #$FF LOAD THE CHANNEL REGISTER
+ STA CCREG
+ LDA #$FE SET CHANNEL 0
+ STA PRIREG
+ LDA #1 SET SECTOR TO "1"
+ STA SECREG ISSUE COMMAND
+ LDA #$8C SET SINGLE SECTOR READ
+ STA COMREG ISSUE COMMAND
+ BSR DLY
+*
+* THE FOLLOWING CODE TESTS THE STATUS OF THE
+* CHANNEL CONTROL REGISTER. IF "D7" IS NOT
+* ZERO THEN IT WILL LOOP WAITING FOR "D7"
+* TO GO TO ZERO. IF AFTER 65,536 TRIES IT
+* IS STILL A ONE THE BOOT OPERATION WILL
+* BE STARTED OVER FROM THE BEGINING.
+*
+ CLRB ;
+DBOOT1 PSHS B $FB55
+ CLRB ;
+DBOOT2 TST CCREG
+ BPL DBOOT3
+ DECB ;
+ BNE DBOOT2
+ PULS B
+ DECB
+ BNE DBOOT1
+ BRA DBOOT
+DBOOT3 PULS B
+ LDA COMREG
+ BITA #$1C
+ BEQ DBOOT4
+ RTS ;
+*
+*
+DBOOT4 LDB #$DE
+ STB DRVREG
+ LDX #$C000
+ STX 10,U
+ TFR U,S $FB7B
+ RTI ;
+*
+***** LRA LOAD REAL ADDRESS *****
+*
+* THE FOLLOWING CODE LOADS THE 20-BIT
+* PHYSICAL ADDRESS OF A MEMORY BYTE
+* INTO THE "A" AND "X" REGISTERS. THIS
+* ROUTINE IS ENTERED WITH THE LOGICAL
+* ADDRESS OF A MEMORY BYTE IN THE "IX"
+* REGISTER. EXIT IS MADE WITH THE HIGH-
+* ORDER FOUR BITS OF THE 20-BIT PHYSICAL
+* ADDRESS IN THE "A" REGISTER, AND THE
+* LOW-ORDER 16-BITS OF THE 20-BIT
+* PHYSICAL ADDRESS IN THE "IX" REGISTER.
+* ALL OTHER REGISTERS ARE PRESERVED.
+* THIS ROUTINE IS REQUIRED SINCE THE
+* DMAF1 AND DMAF2 DISK CONTROLLERS MUST
+* PRESENT PHYSICAL ADDRESSES ON THE
+* SYSTEM BUS.
+*
+LRA PSHS A,B,X,Y PUSH REGISTERS ON STACK
+ LDA 2,S GET MSB LOGICAL ADDR FRM X REG ON STACK
+ LSRA ;
+ LSRA ADJ FOR INDEXED INTO
+ LSRA CORRESPONDING LOCATION
+ LSRA IN LRA TABLE
+ LDY #LRARAM LOAD LRA TABLE BASE ADDRESS
+ LDB A,Y GET PHYSICAL ADDR. DATA FROM LRA TABLE
+ LSRB ADJ. REAL ADDR. TO REFLECT EXTENDED
+ LSRB PHYSICAL ADDRESS.
+ LSRB EXTENDED MS 4-BITS ARE RETURNED
+ LSRB IN THE "A" ACCUMULATOR
+ STB ,S MS 4 BITS IN A ACCUM. STORED ON STACK
+ LDB A,Y LOAD REAL ADDRESS DATA FROM LRA TABLE
+ COMB COMP TO ADJ FOR PHYSICAL ADDR. IN X REG
+ ASLB ADJ DATA FOR RELOCATION IN X REG
+ ASLB ;
+ ASLB $FB97
+ ASLB ;
+ LDA 2,S GET MS BYTE OF LOGICAL ADDR.
+ ANDA #$0F MASK MS NIBBLE OF LOGICAL ADDRESS
+ STA 2,S SAVE IT IN X REG ON STACK
+ ORB 2,S SET MS BYTE IN X REG TO ADJ PHY ADDR.
+*
+* PLUS LS NIBBLE OF LOGICAL ADDRESS
+ STB 2,S SAVE AS LS 16 BITS OF PHY ADDR IN X REG
+* ON STACK
+ PULS A,B,X,Y POP REGS. FROM STACK
+ RTS ;
+*
+* DELAY LOOP
+*
+DLY PSHS B SAVE CONTENTS OF "B"
+ LDB #$20 GET LOOP DELAY VALUE
+SUB1 DECB SUBTRACT ONE FROM VALUE
+ BNE SUB1 LOOP UNTIL ZERO
+ PULS B RESTORE CONTENTS OF "B"
+ RTS ;
+*
+***** "U" MINIDISK BOOT *****
+*
+MINBOOT TST Comreg
+ CLR Drvreg SELECT DRIVE 0
+*
+* DELAY BEFORE ISSUING RESTORE COMMAND
+ LDB #3
+ LDX #0
+LOOP LEAX 1,X $FBBB
+ CMPX #0
+ BNE LOOP
+ DECB $FBC2
+ BNE LOOP
+*
+ LDA #$0F *LOAD HEAD, VERIFY, 20msec/step
+ STA Comreg ISSUE RESTORE COMMAND
+ BSR DELAY
+LOOP1 LDB Comreg $FBCC
+ BITB #1
+ BNE LOOP1 LOOP UNTIL THRU
+ LDA #1
+ STA Secreg SET SECTOR REGISTER TO ONE
+ BSR DELAY
+ LDA #$8C LOAD HEAD, DELAY 10msec,
+ STA Comreg AND READ SINGLE RECORD
+ BSR DELAY
+ LDX #$C000
+ BRA LOOP3
+*
+LOOP2 BITB #2 $FBE6 DRQ?
+ BEQ LOOP3
+ LDA Datreg
+ STA ,X+
+*
+LOOP3 LDB Comreg FETCH STATUS
+ BITB #1 BUSY?
+ BNE LOOP2
+ BITB #$2C CRC ERROR OR LOST DATA?
+ BEQ LOOP4
+ RTS ;
+LOOP4 LDX #$C000 $FBFB
+ STX 10,U
+ TFR U,S
+ RTI ;
+*
+* DELAY
+*
+DELAY LDB #$20
+LOOP5 DECB ;
+ BNE LOOP5
+ RTS ;
+*
+***** "L" LOAD MIKBUG TAPE *****
+*
+LOAD LDA #$11 LOAD 'DC1' CASS. READ ON CODE
+ LBSR OUTCH OUTPUT IT TO TERMINAL PORT
+ CLR ECHO TURN OFF ECHO FLAG
+LOAD1 LBSR ECHON INPUT 8 BIT BYTE WITH NO ECHO
+LOAD2 CMPA #'S IS IT AN "S", START CHARACTER ?
+ BNE LOAD1 IF NOT, DISCARD AND GET NEXT CHAR.
+ LBSR ECHON
+ CMPA #'9 IS IT A "9" , END OF FILE CHAR ?
+ BEQ LOAD21 IF SO, EXIT LOAD
+ CMPA #'1 IS IT A "1" , FILE LOAD CHAR ?
+ BNE LOAD2 IF NOT, LOOK FOR START CHAR.
+ LBSR BYTE INPUT BYTE COUNT
+ PSHS A PUSH COUNT ON STACK
+ BVS LODERR (V) C-CODE SET, ILLEGAL HEX
+ LBSR IN1ADR INPUT LOAD ADDRESS
+ BVS LODERR (V) C-CODE SET, ADDR NOT HEX
+ PSHS X PUSH ADDR ON STACK
+ LDB ,S+ LOAD MSB OF ADDR AS CHECKSUM BYTE
+ ADDB ,S+ ADD LSB OF ADDR TO CHECKSUM
+ ADDB ,S ADD BYTE COUNT BYTE TO CHECKSUM
+ DEC ,S $FC37 DECREMENT BYTE COUNT 2 TO BYPASS
+ DEC ,S ADDRESS BYTES.
+LOAD10 PSHS B PUSH CHECKSUM ON STACK
+ LBSR BYTE INPUT DATA BYTE (2 HEX CHAR)
+ PULS B POP CHECKSUM FROM STACK
+ BVS LODERR (V) SET, DATA BYTE NOT HEX
+ PSHS A PUSH DATA BYTE ON STACK
+ ADDB ,S+ ADD DATA TO CHECKSUM, AUTO INC STACK
+ DEC ,S DECREMENT BYTE COUNT 1
+ BEQ LOAD16 IF BYTE COUNT ZERO, TEST CHECKSUM
+ STA ,X+ SAVE DATA BYTE IN MEMORY
+ BRA LOAD10 GET NEXT DATA BYTE
+LODERR CLRB ;ERROR CONDITION, ZERO CHECKSUM ;
+LOAD16 PULS A ADJUST STACK (REMOVE BYTE COUNT)
+ CMPB #$FF CHECKSUM OK?
+ BEQ LOAD IF SO, LOAD NEXT LINE
+ LDA #'? LOAD (?) ERROR INDICATOR
+ LBSR OUTCH OUTPUT IT TO TERMINAL
+LOAD21 COM ECHO TURN ECHO ON
+ LDA #$13 $FC5F LOAD 'DC3' CASS. READ OFF CODE
+ LBRA OUTCH OUTPUT IT
+*
+***** "P" PUNCH MIKBUG TAPE *****
+*
+PUNCH CLR ,-S CLEAR RESERVED BYTE ON STACK
+ LBSR IN2ADR GET BEGIN AND END ADDRESS
+ PSHS X,Y SAVE ADDRESSES ON STACK
+ BVS PUNEXT (V) C-CODE SET, EXIT PUNCH
+ CMPX 2,S COMPARE BEGIN TO END ADDR
+ BCS PUNEXT IF BEGIN GREATER THAN END, EXIT PUNCH
+ LEAX 1,X INCREMENT END ADDRESS
+ STX ,S STORE END ADDR ON STACK
+ LDA #$12 LOAD 'DC2' PUNCH ON CODE
+ LBSR OUTCH OUTPUT IT TO TERMINAL
+PUNCH2 LDD ,S LOAD END ADDR IN D-ACC
+ SUBD 2,S SUBTRACT BEGIN FROM END
+ BEQ PUNCH3 SAME, PUNCH 32 BYTES DEFAULT
+ CMPD #$20 LESS THAN 32 BYTES?
+ BLS PUNCH4 PUNCH THAT MANY BYTES
+PUNCH3 LDB #$20 LOAD BYTE COUNT OF 32.
+PUNCH4 STB 4,S STORE ON STACK AS BYTE COUNT
+ LDX #MSG20 POINT TO MSG "S1"
+ LBSR PSTRNG PRINT MSG
+ ADDB #3 ADD 3 BYTES TO BYTE COUNT
+ TFR B,A GET BYTE COUNT IN A-ACC TO PUNCH
+ LBSR OUT2H OUTPUT BYTE COUNT
+ LDX 2,S LOAD BEGIN ADDRESS
+ LBSR OUT4H PUNCH ADDRESS
+ ADDB 2,S ADD ADDR MSB TO CHECKSUM
+ ADDB 3,S ADD ADDR LSB TO CHECKSUM
+PUNCHL ADDB ,X ADD DATA BYTE TO CHECKSUM
+ LDA ,X+ LOAD DATA BYTE TO PUNCH
+ LBSR OUT2H OUTPUT DATA BYTE
+ DEC 4,S DECREMENT BYTE COUNT
+ BNE PUNCHL NOT DONE, PUNCH NEXT BYTE
+ COMB 1's COMPLIMENT CHECKSUM BYTE
+ TFR B,A GET IT IN A-ACC TO PUNCH
+ LBSR OUT2H OUTPUT CHECKSUM BYTE
+ STX 2,S SAVE X-REG IN STACK AS NEW PUNCH ADDR
+ CMPX ,S COMPARE IT TO END ADDR
+ BNE PUNCH2 $FCB5 PUNCH NOT DONE, CONT.
+PUNEXT LDA #$14 LOAD 'DC4' PUNCH OFF CODE
+ LBSR OUTCH OUTPUT IT
+ LEAS 5,S READJUST STACK POINTER
+ RTS ;
+*
+*
+PRTSP LDX #MSG10 POINT TO MSG "SP="
+ LBSR PDATA PRINT MSG
+ TFR U,X
+ LBRA OUT4H
+PRTUS LDX #MSG12 POINT TO MSG "US="
+ LBSR PDATA PRINT MSG
+ LDX 8,U
+ LBRA OUT4H
+PRTDP LDX #MSG15 POINT TO MSG "DP="
+ LBSR PDATA PRINT MSG
+ LDA 3,U
+ LBRA OUT2H OUTPUT HEX BYTE AS ASCII
+PRTIX LDX #MSG14 POINT TO MSG "IX="
+ LBSR PDATA PRINT MSG
+ LDX 4,U $FCE6
+ LBRA OUT4H
+PRTIY LDX #MSG13 POINT TO MSG "IY="
+ LBSR PDATA PRINT MSG
+ LDX 6,U
+ LBRA OUT4H
+PRTPC LDX #MSG11 POINT TO MSG "PC="
+ LBSR PDATA PRINT MSG
+ LDX 10,U
+ BRA OUT4H
+PRTA LDX #MSG16 POINT TO MSG "A="
+ LBSR PDATA PRINT MSG
+ LDA 1,U
+ BRA OUT2H OUTPUT HEX BYTE AS ASCII
+PRTB LDX #MSG17 POINT TO MSG "B="
+ LBSR PDATA PRINT MSG
+ LDA 2,U
+ BRA OUT2H OUTPUT HEX BYTE AS ASCII
+PRTCC LDX #MSG18 POINT TO MSG "CC:"
+ LBSR PDATA PRINT MSG
+ LDA ,U
+ LDX #MSG19 POINT TO MSG "EFHINZVC"
+ BRA BIASCI OUTPUT IN BINARY/ASCII FORMAT
+*
+* THE FOLLOWING ROUTINE LOOPS WAITING FOR THE
+* OPERATOR TO INPUT TWO VALID HEX ADDRESSES.
+* THE FIRST ADDRESS INPUT IS RETURNED IN "IY".
+* THE SECOND IS RETURNED IN "IX". THE "V" BIT
+* IN THE C-CODE REG. IS SET IF AN INVALID HEX
+* ADDRESS IS INPUT.
+*
+IN2ADR BSR IN1ADR GET FIRST ADDRESS
+ BVS NOTHEX EXIT IF NOT VALID HEX
+ TFR X,Y SAVE FIRST ADDR. IN "IY"
+ LDA #'-
+ LBSR OUTCH PRINT " - "
+*
+* THE FOLLOWING ROUTINE LOOPS WAITING FOR THE
+* OPERATOR TO INPUT ONE VALID HEX ADDRESS. THE
+* ADDRESS IS RETURNED IN THE "X" REGISTER.
+*
+IN1ADR BSR BYTE INPUT BYTE (2 HEX CHAR)
+ BVS NOTHEX EXIT IF NOT VALID HEX
+ TFR D,X
+ BSR BYTE INPUT BYTE (2 HEX CHAR)
+ BVS NOTHEX
+ PSHS X
+ STA 1,S
+ PULS X
+ RTS ;
+*
+***** INPUT BYTE (2 HEX CHAR.) *****
+*
+BYTE BSR INHEX GET HEX LEFT
+ BVS NOTHEX EXIT IF NOT VALID HEX
+ ASLA ;
+ ASLA ;
+ ASLA ; SHIFT INTO LEFT NIBBLE
+ ASLA ;
+ TFR A,B PUT HEXL IN "B"
+ BSR INHEX GET HEX RIGHT
+ BVS NOTHEX EXIT IF NOT VALID HEX
+ PSHS B PUSH HEXL ON STACK
+ ADDA ,S+ ADD HEXL TO HEXR AND ADJ. STK
+ RTS RETURN WITH HEX L&R IN "A"
+*
+*
+INHEX BSR ECHON INPUT ASCII CHAR.
+ CMPA #'0 IS IT > OR = "0" ?
+ BCS NOTHEX IF LESS IT AIN'T HEX
+ CMPA #'9 IS IT < OR = "9" ?
+ BHI INHEXA IF > MAYBE IT'S ALPHA
+ SUBA #$30 ASCII ADJ. NUMERIC
+ RTS ;
+*
+*
+INHEXA CMPA #'A IS IT > OR = "A"
+ BCS NOTHEX IF LESS IT AIN'T HEX
+ CMPA #'F IS IT < OR = "F" ?
+ BHI INHEXL IF > IT AIN'T HEX
+ SUBA #$37 ASCII ADJ. ALPHA
+ RTS ;
+*
+INHEXL CMPA #'a IS IT > OR = "a"
+ BCS NOTHEX IF LESS IT AIN'T HEX
+ CMPA #'f IS IT < "f"
+ BHI NOTHEX IF > IT AIN'T HEX
+ SUBA #$57 ADJUST TO LOWER CASE
+ RTS ;
+*
+*
+NOTHEX ORCC #2 SET (V) FLAG IN C-CODES REGISTER
+ RTS ;
+*
+*
+OUT4H PSHS X PUSH X-REG. ON THE STACK
+ PULS A POP MS BYTE OF X-REG INTO A-ACC.
+ BSR OUTHL OUTPUT HEX LEFT
+ PULS A POP LS BYTE OF X-REG INTO A-ACC.
+OUTHL EQU *
+OUT2H PSHS A SAVE IT BACK ON STACK
+ LSRA CONVERT UPPER HEX NIBBLE TO ASCII
+ LSRA ;
+ LSRA ;
+ LSRA ;
+ BSR XASCII PRINT HEX NIBBLE AS ASCII
+OUTHR PULS A CONVERT LOWER HEX NIBBLE TO ASCII
+ ANDA #$0F STRIP LEFT NIBBLE
+XASCII ADDA #$30 ASCII ADJ
+ CMPA #$39 IS IT < OR = "9" ?
+ BLE OUTC IF LESS, OUTPUT IT
+ ADDA #7 IF > MAKE ASCII LETTER
+OUTC BRA OUTCH OUTPUT CHAR
+*
+* BINARY / ASCII --- THIS ROUTINE
+* OUTPUTS A BYTE IN ENHANCED
+* BINARY FORMAT. THE ENHANCEMENT
+* IS DONE BY SUBSTITUTING ASCII
+* LETTERS FOR THE ONES IN THE BYTE.
+* THE ASCII ENHANCEMENT LETTERS
+* ARE OBTAINED FROM THE STRING
+* POINTED TO BY THE INDEX REG. "X".
+*
+BIASCI PSHS A SAVE "A" ON STACK
+ LDB #8 PRESET LOOP# TO BITS PER BYTE
+OUTBA LDA ,X+ GET LETTER FROM STRING
+ ASL ,S TEST BYTE FOR "1" IN B7
+ BCS PRTBA IF ONE PRINT LETTER
+ LDA #'- IF ZERO PRINT "-"
+PRTBA BSR OUTCH PRINT IT
+ BSR OUT1S PRINT SPACE
+ DECB SUB 1 FROM #BITS YET TO PRINT
+ BNE OUTBA
+ PULS A
+ RTS
+*
+* PRINT STRING PRECEEDED BY A CR & LF.
+*
+PSTRNG BSR PCRLF PRINT CR/LF
+ BRA PDATA PRINT STRING POINTED TO BY IX
+*
+* PCRLF
+*
+PCRLF PSHS X SAVE IX
+ LDX #MSG2+1 POINT TO MSG CR/LF + 3 NULS
+ BSR PDATA PRINT MSG
+ PULS X RESTORE IX
+ RTS ;
+PRINT BSR OUTCH
+*
+* PDATA
+*
+PDATA LDA ,X+ GET 1st CHAR. TO PRINT
+ CMPA #4 IS IT EOT?
+ BNE PRINT IF NOT EOT PRINT IT
+ RTS ;
+*
+*
+ECHON TST ECHO IS ECHO REQUIRED ?
+ BEQ INCH ECHO NOT REQ. IF CLEAR
+*
+* INCHE
+*
+* ---GETS CHARACTER FROM TERMINAL AND
+* ECHOS SAME. THE CHARACTER IS RETURNED
+* IN THE "A" ACCUMULATOR WITH THE PARITY
+* BIT MASKED OFF. ALL OTHER REGISTERS
+* ARE PRESERVED.
+*
+INCHE BSR INCH GET CHAR FROM TERMINAL
+ ANDA #$7F STRIP PARITY FROM CHAR.
+ BRA OUTCH ECHO CHAR TO TERMINAL
+*
+* INCH
+*
+* GET CHARACTER FROM TERMINAL. RETURN
+* CHARACTER IN "A" ACCUMULATOR AND PRESERVE
+* ALL OTHER REGISTERS. THE INPUT CHARACTER
+* IS 8 BITS AND IS NOT ECHOED.
+*
+*
+INCH PSHS X SAVE IX
+ LDX CPORT POINT TO TERMINAL PORT
+GETSTA LDA ,X FETCH PORT STATUS
+ BITA #1 TEST READY BIT, RDRF ?
+ BEQ GETSTA IF NOT RDY, THEN TRY AGAIN
+ LDA 1,X FETCH CHAR
+ PULS X RESTORE IX
+ RTS ;
+*
+* INCHEK
+*
+* CHECK FOR A CHARACTER AVAILABLE FROM
+* THE TERMINAL. THE SERIAL PORT IS CHECKED
+* FOR READ READY. ALL REGISTERS ARE
+* PRESERVED, AND THE "Z" BIT WILL BE
+* CLEAR IF A CHARACTER CAN BE READ.
+*
+*
+INCHEK PSHS A SAVE A ACCUM.
+ LDA [CPORT] FETCH PORT STATUS
+ BITA #1 TEST READY BIT, RDRF ?
+ PULS A RESTORE A ACCUM.
+ RTS ;
+*
+OUT2S BSR OUT1S OUTPUT 2 SPACES
+OUT1S LDA #$20 OUTPUT 1 SPACE
+*
+*
+* OUTCH
+*
+* OUTPUT CHARACTER TO TERMINAL.
+* THE CHAR. TO BE OUTPUT IS
+* PASSED IN THE A REGISTER.
+* ALL REGISTERS ARE PRESERVED.
+*
+OUTCH PSHS A,X SAVE A ACCUM AND IX
+ LDX CPORT GET ADDR. OF TERMINAL
+FETSTA LDA ,X FETCH PORT STATUS
+ BITA #2 TEST TDRE, OK TO XMIT ?
+ BEQ FETSTA IF NOT LOOP UNTIL RDY
+ PULS A GET CHAR. FOR XMIT
+ STA 1,X XMIT CHAR.
+ PULS X RESTORE IX
+ RTS ;
+*
+*
+ACINIZ LDX CPORT POINT TO CONTROL PORT ADDRESS
+ LDA #3 RESET ACIA PORT CODE
+ STA ,X STORE IN CONTROL REGISTER
+ LDA #$11 SET 8 DATA, 2 STOP AN 0 PARITY
+ STA ,X STORE IN CONTROL REGISTER
+ TST 1,X ANYTHING IN DATA REGISTER?
+ LDA #$FF TURN ON ECHO FLAG
+ STA ECHO
+ RTS
+*
+*
+* MONITOR KEYBOARD COMMAND JUMP TABLE
+*
+*
+JMPTAB EQU *
+ FCB 1 " ^A " $F91D
+ FDB ALTRA
+ FCB 2 " ^B " $F90F
+ FDB ALTRB
+ FCB 3 " ^C " $F92B
+ FDB ALTRCC
+ FCB 4 " ^D " $F901
+ FDB ALTRDP
+ FCB $10 " ^P " $F8C9
+ FDB ALTRPC
+ FCB $15 " ^U " $F8D7
+ FDB ALTRU
+ FCB $18 " ^X " $F8F3
+ FDB ALTRX
+ FCB $19 " ^Y " $F8E5
+ FDB ALTRY
+*
+ FCC 'B'
+ FDB BRKPNT *$FA78
+ FCC 'D'
+ FDB DBOOT *$FAF1
+ FCC 'E'
+ FDB MEMDUMP *$F990
+ FCC 'G'
+ FDB GO *$F89F
+ FCC 'L'
+ FDB LOAD *$FC09
+ FCC 'M'
+ FDB MEMCHG *$F93B
+ FCC 'P'
+ FDB PUNCH *$FC64
+ FCC 'Q'
+ FDB MEMTST *$F9EF
+ FCC 'R'
+ FDB REGSTR *$F8A2
+ FCC 'S'
+ FDB DISSTK *$F984
+ FCC 'U'
+ FDB MINBOOT *$FBB0
+ FCC 'X'
+ FDB XBKPNT *$FAA4
+*
+TABEND EQU *
+*
+* ** 6809 VECTOR ADDRESSES **
+*
+* FOLLOWING ARE THE ADDRESSES OF THE VECTOR ROUTINES
+* FOR THE 6809 PROCESSOR. DURING INITIALIZATION THEY
+* ARE RELOCATED TO RAM FROM $DFC0 TO $DFCF. THEY ARE
+* RELOCATED TO RAM SO THAT THE USER MAY REVECTOR TO
+* HIS OWN ROUTINES IF HE SO DESIRES.
+*
+*
+RAMVEC FDB SWIE USER-V
+ FDB RTI SWI3-V
+ FDB RTI SWI2-V
+ FDB RTI FIRQ-V
+ FDB RTI IRQ-V
+ FDB SWIE SWI-V
+ FDB $FFFF SVC-VO
+ FDB $FFFF SVC-VL
+*
+* PRINTABLE MESSAGE STRINGS
+*
+MSG1 FCB $0,$0,$0,$D,$A,$0,$0,$0 * 0, CR/LF, 0
+ FCC 'S-BUG 1.8 - '
+ FCB 4
+MSG2 FCB 'K,$D,$A,$0,$0,$0,4 K, * CR/LF + 3 NULS
+MSG3 FCC '>'
+ FCB 4
+MSG4 FCC 'WHAT?'
+ FCB 4
+MSG5 FCC ' - '
+ FCB 4'
+MSG6 FCC ', PASS '
+ FCB 4
+MSG7 FCC ', BITS IN ERROR: '
+ FCB 4
+MSG8 FCC ' => '
+ FCB 4
+MSG9 FCC '76543210'
+MSG10 FCC ' SP='
+ FCB 4
+MSG11 FCC ' PC='
+ FCB 4
+MSG12 FCC ' US='
+ FCB 4
+MSG13 FCC ' IY='
+ FCB 4
+MSG14 FCC ' IX='
+ FCB 4
+MSG15 FCC ' DP='
+ FCB 4
+MSG16 FCC ' A='
+ FCB 4
+MSG17 FCC ' B='
+ FCB 4
+MSG18 FCC ' CC: '
+ FCB 4
+MSG19 FCC 'EFHINZVC'
+MSG20 FCC 'S1'
+ FCB 4
+*
+* MESSAGE EXPANSION AREA
+*
+ FCB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
+ FCB $FF,$FF,$FF,$FF,$FF,$FF,$FF
+*
+* POWER UP/ RESET/ NMI ENTRY POINT
+*
+ ORG $FF00
+*
+*
+START LDX #IC11 POINT TO DAT RAM IC11
+ LDA #$F GET COMPLIMENT OF ZERO
+*
+*
+* INITIALIZE DAT RAM --- LOADS $F-$0 IN LOCATIONS $0-$F
+* OF DAT RAM, THUS STORING COMPLEMENT OF MSB OF ADDRESS
+* IN THE DAT RAM. THE COMPLEMENT IS REQUIRED BECAUSE THE
+* OUTPUT OF IC11, A 74S189, IS THE INVERSE OF THE DATA
+* STORED IN IT.
+*
+*
+DATLP STA ,X+ STORE & POINT TO NEXT RAM LOCATION
+ DECA GET COMP. VALUE FOR NEXT LOCATION
+ BNE DATLP ALL 16 LOCATIONS INITIALIZED ?
+*
+* NOTE: IX NOW CONTAINS $0000, DAT RAM IS NO LONGER
+* ADDRESSED, AND LOGICAL ADDRESSES NOW EQUAL
+* PHYSICAL ADDRESSES.
+*
+ LDA #$F0
+ STA ,X STORE $F0 AT $FFFF
+ LDX #$D0A0 ASSUME RAM TO BE AT $D000-$DFFF
+ LDY #TSTPAT LOAD TEST DATA PATTERN INTO "Y"
+TSTRAM LDU ,X SAVE DATA FROM TEST LOCATION
+ STY ,X STORE TEST PATTERN AT $D0A0
+ CMPY ,X IS THERE RAM AT THIS LOCATION ?
+ BEQ CNVADR IF MATCH THERE'S RAM, SO SKIP
+ LEAX -$1000,X ELSE POINT 4K LOWER
+ CMPX #$F0A0 DECREMENTED PAST ZER0 YET ?
+ BNE TSTRAM IF NOT CONTINUE TESTING FOR RAM
+ BRA START ELSE START ALL OVER AGAIN
+*
+*
+* THE FOLLOWING CODE STORES THE COMPLEMENT OF
+* THE MS CHARACTER OF THE FOUR CHARACTER HEX
+* ADDRESS OF THE FIRST 4K BLOCK OF RAM LOCATED
+* BY THE ROUTINE "TSTRAM" INTO THE DAT RAM. IT
+* IS STORED IN RAM IN THE LOCATION THAT IS
+* ADDRESSED WHEN THE PROCESSOR ADDRESS IS $D---,
+* THUS IF THE FIRST 4K BLOCK OF RAM IS FOUND
+* WHEN TESTING LOCATION $70A0, MEANING THERE
+* IS NO RAM PHYSICALLY ADDRESSED IN THE RANGE
+* $8000-$DFFF, THEN THE COMPLEMENT OF THE
+* "7" IN THE $70A0 WILL BE STORED IN
+* THE DAT RAM. THUS WHEN THE PROCESSOR OUTPUTS
+* AN ADDRESS OF $D---, THE DAT RAM WILL RESPOND
+* BY RECOMPLEMENTING THE "7" AND OUTPUTTING THE
+* 7 ONTO THE A12-A15 ADDRESS LINES. THUS THE
+* RAM THAT IS PHYSICALLY ADDRESSED AT $7---
+* WILL RESPOND AND APPEAR TO THE 6809 THAT IT
+* IS AT $D--- SINCE THAT IS THE ADDRESS THE
+* 6809 WILL BE OUTPUTING WHEN THAT 4K BLOCK
+* OF RAM RESPONDS.
+*
+*
+CNVADR STU ,X RESTORE DATA AT TEST LOCATION
+ TFR X,D PUT ADDR. OF PRESENT 4K BLOCK IN D
+ COMA COMPLEMENT MSB OF THAT ADDRESS
+ LSRA PUT MS 4 BITS OF ADDRESS IN
+ LSRA LOCATION D0-D3 TO ALLOW STORING
+ LSRA IT IN THE DYNAMIC ADDRESS
+ LSRA TRANSLATION RAM.
+ STA $FFFD STORE XLATION FACTOR IN DAT "D"
+*
+ LDS #STACK INITIALIZE STACK POINTER
+*
+*
+* THE FOLLOWING CHECKS TO FIND THE REAL PHYSICAL ADDRESSES
+* OF ALL 4K BLKS OF RAM IN THE SYSTEM. WHEN EACH 4K BLK
+* OF RAM IS LOCATED, THE COMPLEMENT OF IT'S REAL ADDRESS
+* IS THEN STORED IN A "LOGICAL" TO "REAL" ADDRESS XLATION
+* TABLE THAT IS BUILT FROM $DFD0 TO $DFDF. FOR EXAMPLE IF
+* THE SYSTEM HAS RAM THAT IS PHYSICALLY LOCATED (WIRED TO
+* RESPOND) AT THE HEX LOCATIONS $0--- THRU $F---....
+*
+* 0 1 2 3 4 5 6 7 8 9 A B C D E F
+* 4K 4K 4K 4K 4K 4K 4K 4K -- 4K 4K 4K 4K -- -- --
+*
+* ....FOR A TOTAL OF 48K OF RAM, THEN THE TRANSLATION TABLE
+* CREATED FROM $DFD0 TO $DFDF WILL CONSIST OF THE FOLLOWING....
+*
+* 0 1 2 3 4 5 6 7 8 9 A B C D E F
+* 0F 0E 0D 0C 0B 0A 09 08 06 05 00 00 04 03 F1 F0
+*
+*
+* HERE WE SEE THE LOGICAL ADDRESSES OF MEMORY FROM $0000-$7FFF
+* HAVE NOT BEEN SELECTED FOR RELOCATION SO THAT THEIR PHYSICAL
+* ADDRESS WILL = THEIR LOGICAL ADDRESS; HOWEVER, THE 4K BLOCK
+* PHYSICALLY AT $9000 WILL HAVE ITS ADDRESS TRANSLATED SO THAT
+* IT WILL LOGICALLY RESPOND AT $8000. LIKEWISE $A,$B, AND $C000
+* WILL BE TRANSLATED TO RESPOND TO $9000,$C000, AND $D000
+* RESPECTIVELY. THE USER SYSTEM WILL LOGICALLY APPEAR TO HAVE
+* MEMORY ADDRESSED AS FOLLOWS....
+*
+* 0 1 2 3 4 5 6 7 8 9 A B C D E F
+* 4K 4K 4K 4K 4K 4K 4K 4K 4K 4K -- -- 4K 4K -- --
+*
+*
+ LDY #LRARAM POINT TO LOGICAL/REAL ADDR. TABLE
+ STA 13,Y STORE $D--- XLATION FACTOR AT $DFDD
+ CLR 14,Y CLEAR $DFDE
+ LDA #$F0 DESTINED FOR IC8 AN MEM EXPANSION ?
+ STA 15,Y STORE AT $DFDF
+ LDA #$0C PRESET NUMBER OF BYTES TO CLEAR
+CLRLRT CLR A,Y CLEAR $DFDC THRU $DFD0
+ DECA SUB. 1 FROM BYTES LEFT TO CLEAR
+ BPL CLRLRT CONTINUE IF NOT DONE CLEARING
+FNDRAM LEAX -$1000,X POINT TO NEXT LOWER 4K OF RAM
+ CMPX #$F0A0 TEST FOR DECREMENT PAST ZERO
+ BEQ FINTAB SKIP IF FINISHED
+ LDU ,X SAVE DATA AT CURRENT TEST LOCATION
+ LDY #TSTPAT LOAD TEST DATA PATTERN INTO Y REG.
+ STY ,X STORE TEST PATT. INTO RAM TEST LOC.
+ CMPY ,X VERIFY RAM AT TEST LOCATION
+ BNE FNDRAM IF NO RAM GO LOOK 4K LOWER
+ STU ,X ELSE RESTORE DATA TO TEST LOCATION
+ LDY #LRARAM POINT TO LOGICAL/REAL ADDR. TABLE
+ TFR X,D PUT ADDR. OF PRESENT 4K BLOCK IN D
+ LSRA PUT MS 4 BITS OF ADDR. IN LOC. D0-D3
+ LSRA TO ALLOW STORING IT IN THE DAT RAM.
+ LSRA
+ LSRA
+ TFR A,B SAVE OFFSET INTO LRARAM TABLE
+ EORA #$0F INVERT MSB OF ADDR. OF CURRENT 4K BLK
+ STA B,Y SAVE TRANSLATION FACTOR IN LRARAM TABLE
+ BRA FNDRAM GO TRANSLATE ADDR. OF NEXT 4K BLK
+FINTAB LDA #$F1 DESTINED FOR IC8 AND MEM EXPANSION ?
+ LDY #LRARAM POINT TO LRARAM TABLE
+ STA 14,Y STORE $F1 AT $DFCE
+*
+* THE FOLLOWING CHECKS TO SEE IF THERE IS A 4K BLK OF
+* RAM LOCATED AT $C000-$CFFF. IF NONE THERE IT LOCATES
+* THE NEXT LOWER 4K BLK AN XLATES ITS ADDR SO IT
+* LOGICALLY RESPONDS TO THE ADDRESS $C---.
+*
+*
+ LDA #$0C PRESET NUMBER HEX "C"
+FINDC LDB A,Y GET ENTRY FROM LRARAM TABLE
+ BNE FOUNDC BRANCH IF RAM THIS PHYSICAL ADDR.
+ DECA ELSE POINT 4K LOWER
+ BPL FINDC GO TRY AGAIN
+ BRA XFERTF
+FOUNDC CLR A,Y CLR XLATION FACTOR OF 4K BLOCK FOUND
+ STB $C,Y GIVE IT XLATION FACTOR MOVING IT TO $C---
+*
+* THE FOLLOWING CODE ADJUSTS THE TRANSLATION
+* FACTORS SUCH THAT ALL REMAINING RAM WILL
+* RESPOND TO A CONTIGUOUS BLOCK OF LOGICAL
+* ADDRESSES FROM $0000 AND UP....
+*
+ CLRA START AT ZERO
+ TFR Y,X START POINTER "X" START OF "LRARAM" TABLE.
+COMPRS LDB A,Y GET ENTRY FROM "LRARAM" TABLE
+ BEQ PNTNXT IF IT'S ZER0 SKIP
+ CLR A,Y ELSE ERASE FROM TABLE
+ STB ,X+ AND ENTER ABOVE LAST ENTRY- BUMP
+PNTNXT INCA GET OFFSET TO NEXT ENTRY
+ CMPA #$0C LAST ENTRY YET ?
+ BLT COMPRS
+*
+* THE FOLLOWING CODE TRANSFER THE TRANSLATION
+* FACTORS FROM THE LRARAM TABLE TO IC11 ON
+* THE MP-09 CPU CARD.
+*
+XFERTF LDX #IC11 POINT TO DAT RAM IC11
+ LDB #$10 GET NO. OF BYTES TO MOVE
+FETCH LDA ,Y+ GET BYTE AND POINT TO NEXT
+ STA ,X+ POKE XLATION FACTOR IN IC11
+ DECB SUB 1 FROM BYTES TO MOVE
+ BNE FETCH CONTINUE UNTIL 16 MOVED
+ COMB SET "B" NON-ZERO
+ STB ECHO TURN ON ECHO FLAG
+ LBRA MONITOR INITIALIZATION IS COMPLETE
+*
+*
+V1 JMP [STACK]
+V2 JMP [SWI2]
+V3 JMP [FIRQ]
+V4 JMP [IRQ]
+V5 JMP [SWI]
+*
+* SWI3 ENTRY POINT
+*
+SWI3E TFR S,U
+ LDX 10,U *$FFC8
+ LDB ,X+
+ STX 10,U
+ CLRA
+ ASLB
+ ROLA
+ LDX SVCVO
+ CMPX #$FFFF
+ BEQ SWI3Z
+ LEAX D,X
+ CMPX SVCVL
+ BHI SWI3Z
+ PSHS X
+ LDD ,U
+ LDX 4,U
+ JMP [,S++]
+SWI3Z PULU A,B,X,CC,DP
+ LDU 2,U
+ JMP [SWI3]
+*
+* 6809 VECTORS
+*
+ FDB V1 USER-V
+ FDB SWI3E SWI3-V
+ FDB V2 SWI2-V
+ FDB V3 FIRQ-V
+ FDB V4 IRQ-V
+ FDB V5 SWI-V
+ FDB V1 NMI-V
+ FDB START RESTART-V
+ END START
Index: tags/V10/sw/sbug_src.lst
===================================================================
--- tags/V10/sw/sbug_src.lst (nonexistent)
+++ tags/V10/sw/sbug_src.lst (revision 3)
@@ -0,0 +1,1412 @@
+0001 * NAM SBUG18 MP-09 MONITOR
+0002 OPT l
+sbug_src.txt page 2
+0004 *
+0005 * MONITOR PROGRAM FOR THE SOUTHWEST TECHNICAL
+0006 * PRODUCTS MP-09 CPU BOARD AS COMMENTED BY....
+0007 *
+0008 * ALLEN CLARK WALLACE WATSON
+0009 * 2502 REGAL OAKS LANE 4815 EAST 97th AVE.
+0010 * LUTZ, FLA. 33549 TEMPLE TERRACE, FLA. 33617
+0011 * PH. 813-977-0347 PH. 813-985-1359
+0012 *
+0013 * MODIFIED TO SBUG09 VER 1.8 BY: RANDY JARRETT
+0014 * 2561 NANTUCKET DR APT. E
+0015 * ATLANTA, GA 30345
+0016 * PH. 404-320-1043
+0017 *
+0018 *
+0019 * *** COMMANDS ***
+0020 *
+0021 * CONTROL A = ALTER THE "A" ACCUMULATOR
+0022 * CONTROL B = ALTER THE "B" ACCUMULATOR
+0023 * CONTROL C = ALTER THE CONDITION CODE REGISTER
+0024 * CONTROL D = ALTER THE DIRECT PAGE REGISTER
+0025 * CONTROL P = ALTER THE PROGRAM COUNTER
+0026 * CONTROL U = ALTER USER STACK POINTER
+0027 * CONTROL X = ALTER "X" INDEX REGISTER
+0028 * CONTROL Y = ALTER "Y" INDEX REGISTER
+0029 * B hhhh = SET BREAKPOINT AT LOCATION $hhhh
+0030 * D = BOOT A SWTPC 8 INCH FLOPPY SYSTEM
+0031 * U = BOOT A SWTPC 5 INCH FLOPPY SYSTEM
+0032 * E ssss-eeee = EXAMINE MEMORY FROM STARTING ADDRESS ssss
+0033 * -TO ENDING ADDRESS eeee.
+0034 * G = CONTINUE EXECUTION FROM BREAKPOINT OR SWI
+0035 * L = LOAD TAPE
+0036 * M hhhh = EXAMINE AND CHANGE MEMORY LOCATION hhhh
+0037 * P ssss-eeee = PUNCH TAPE, START ssss TO END eeee ADDR.
+0038 * Q ssss-eeee = TEST MEMORY FROM ssss TO eeee
+0039 * R = DISPLAY REGISTER CONTENTS
+0040 * S = DISPLAY STACK FROM ssss TO $DFC0
+0041 * X = REMOVE ALL BREAKPOINTS
+0042 *
+0043 *
+0044 55aa TSTPAT EQU $55AA TEST PATTERN
+0045 *
+0046 *
+0047 *
+0048 dfc0 ORG $DFC0
+0049 dfc0 STACK RMB 2 TOP OF INTERNAL STACK / USER VECTOR
+0050 dfc2 SWI3 RMB 2 SOFTWARE INTERRUPT VECTOR #3
+0051 dfc4 SWI2 RMB 2 SOFTWARE INTERRUPT VECTOR #2
+0052 dfc6 FIRQ RMB 2 FAST INTERRUPT VECTOR
+0053 dfc8 IRQ RMB 2 INTERRUPT VECTOR
+0054 dfca SWI RMB 2 SOFTWARE INTERRUPT VECTOR
+0055 dfcc SVCVO RMB 2 SUPERVISOR CALL VECTOR ORGIN
+0056 dfce SVCVL RMB 2 SUPERVISOR CALL VECTOR LIMIT
+0057 dfd0 LRARAM RMB 16 LRA ADDRESSES
+0058 dfe0 CPORT RMB 2 RE-VECTORABLE CONTROL PORT
+0059 dfe2 ECHO RMB 1 ECHO FLAG
+0060 dfe3 BPTBL RMB 24 BREAKPOINT TABLE BASE ADDR
+0061 e004 ACIAS EQU $E004 CONTROL PORT
+0062 e018 Comreg EQU $E018 COMMAND REGISTER
+0063 e014 Drvreg EQU $E014 DRIVE REGISTER
+0064 e01a Secreg EQU $E01A SECTOR REGISTER
+0065 e01b Datreg EQU $E01B DATA REGISTER
+0066 *
+0067 f000 ADDREG EQU $F000 ADDRESS REGISTER
+0068 f002 CNTREG EQU $F002 COUNT REGISTER
+0069 f010 CCREG EQU $F010 CHANNEL CONTROL REGISTER
+0070 f014 PRIREG EQU $F014 DMA PRIORITY REGISTER
+0071 f015 AAAREG EQU $F015 ???
+0072 f016 BBBREG EQU $F016 ???
+0073 f020 COMREG EQU $F020 1791 COMMAND REGISTER
+0074 f022 SECREG EQU $F022 SECTOR REGISTER
+0075 f024 DRVREG EQU $F024 DRIVE SELECT LATCH
+0076 f040 CCCREG EQU $F040 ???
+0077 *
+0078 fff0 IC11 EQU $FFF0 DAT RAM CHIP
+0079 *
+0080 f800 ORG $F800
+0081 f800 f8 14 FDB MONITOR
+0082 f802 f8 61 FDB NEXTCMD
+0083 f804 fd cf FDB INCH
+0084 f806 fd c9 FDB INCHE
+0085 f808 fd df FDB INCHEK
+0086 f80a fd ee FDB OUTCH
+0087 f80c fd bd FDB PDATA
+0088 f80e fd b1 FDB PCRLF
+0089 f810 fd ad FDB PSTRNG
+0090 f812 fb 81 FDB LRA
+0091 *
+0092 * MONITOR
+0093 *
+0094 * VECTOR ADDRESS STRING IS.....
+0095 * $F8A1-$F8A1-$F8A1-$F8A1-$F8A1-$FAB0-$FFFF-$FFFF
+0096 *
+0097 f814 8e fe 4f MONITOR LDX #RAMVEC POINT TO VECTOR ADDR. STRING
+0098 f817 10 8e df c0 LDY #STACK POINT TO RAM VECTOR LOCATION
+0099 f81b c6 10 LDB #$10 BYTES TO MOVE = 16
+0100 f81d a6 80 LOOPA LDA ,X+ GET VECTOR BYTE
+0101 f81f a7 a0 STA ,Y+ PUT VECTORS IN RAM / $DFC0-$DFCF
+0102 f821 5a DECB SUBTRACT 1 FROM NUMBER OF BYTES TO MOVE
+0103 f822 26 f9 BNE LOOPA CONTINUE UNTIL ALL VECTORS MOVED
+0104 *
+0105 * CONTENTS FROM TO FUNCTION
+0106 * $F8A1 $FE40 $DFC0 USER-V
+0107 * $F8A1 $FE42 $DFC2 SWI3-V
+0108 * $F8A1 $FE44 $DFC4 SWI2-V
+0109 * $F8A1 $FE46 $DFC6 FIRQ-V
+0110 * $F8A1 $FE48 $DFC8 IRQ-V
+0111 * $FAB0 $FE4A $DFCA SWI-V
+0112 * $FFFF $FE4C $DFCC SVC-VO
+0113 * $FFFF $FE4E $DFCE SVC-VL
+0114 *
+0115 f824 8e e0 04 LDX #ACIAS GET CONTROL PORT ADDR.
+0116 f827 bf df e0 STX CPORT STORE ADDR. IN RAM
+0117 f82a 17 02 7a LBSR XBKPNT CLEAR OUTSTANDING BREAKPOINTS
+0118 f82d c6 0c LDB #12 CLEAR 12 BYTES ON STACK
+0119 f82f 6f e2 CLRSTK CLR ,-S
+0120 f831 5a DECB
+0121 f832 26 fb BNE CLRSTK
+0122 f834 30 8c dd LEAX MONITOR,PCR SET PC TO SBUG-E ENTRY
+0123 f837 af 6a STX 10,S ON STACK
+0124 f839 86 d0 LDA #$D0 PRESET CONDITION CODES ON STACK
+0125 f83b a7 e4 STA ,S
+0126 f83d 1f 43 TFR S,U
+0127 f83f 17 05 be LBSR ACINIZ INITIALIZE CONTROL PORT
+0128 f842 8e fe 5f LDX #MSG1 POINT TO 'SBUG 1.8' MESSAGE
+0129 f845 17 05 75 LBSR PDATA PRINT MSG
+0130 f848 8e df d0 LDX #LRARAM POINT TO LRA RAM STORAGE AREA
+0131 f84b 4f CLRA START TOTAL AT ZERO
+0132 f84c c6 0d LDB #13 TOTAL UP ALL ACTIVE RAM MEMORY
+0133 f84e 6d 85 FNDREL TST B,X TEST FOR RAM AT NEXT LOC.
+0134 f850 27 03 BEQ RELPAS IF NO RAM GO TO NEXT LOC.
+0135 f852 8b 04 ADDA #4 ELSE ADD 4K TO TOTAL
+0136 f854 19 DAA ADJ. TOTAL FOR DECIMAL
+0137 f855 5a RELPAS DECB SUB. 1 FROM LOCS. TO TEST
+0138 f856 2a f6 BPL FNDREL PRINT TOTAL OF RAM
+0139 f858 17 05 26 LBSR OUT2H OUTPUT HEX BYTE AS ASCII
+0140 f85b 8e fe 74 LDX #MSG2 POINT TO MSG 'K' CR/LF + 3 NULS
+0141 f85e 17 05 5c LBSR PDATA PRINT MSG
+0142 *
+0143 ***** NEXTCMD *****
+0144 *
+0145 f861 8e fe 7b NEXTCMD LDX #MSG3 POINT TO MSG ">"
+0146 f864 17 05 46 LBSR PSTRNG PRINT MSG
+0147 f867 17 05 65 LBSR INCH GET ONE CHAR. FROM TERMINAL
+0148 f86a 84 7f ANDA #$7F STRIP PARITY FROM CHAR.
+0149 f86c 81 0d CMPA #$0D IS IT CARRIAGE RETURN ?
+0150 f86e 27 f1 BEQ NEXTCMD IF CR THEN GET ANOTHER CHAR.
+0151 f870 1f 89 TFR A,B PUT CHAR. IN "B" ACCUM.
+0152 f872 81 20 CMPA #$20 IS IT CONTROL OR DATA CHAR ?
+0153 f874 2c 09 BGE PRTCMD IF CMD CHAR IS DATA, PRNT IT
+0154 f876 86 5e LDA #'^ ELSE CNTRL CHAR CMD SO...
+0155 f878 17 05 73 LBSR OUTCH PRINT "^"
+0156 f87b 1f 98 TFR B,A RECALL CNTRL CMD CHAR
+0157 f87d 8b 40 ADDA #$40 CONVERT IT TO ASCII LETTER
+0158 f87f 17 05 6c PRTCMD LBSR OUTCH PRNT CMD CHAR
+0159 f882 17 05 67 LBSR OUT1S PRNT SPACE
+0160 f885 c1 60 CMPB #$60
+0161 f887 2f 02 BLE NXTCH0
+0162 f889 c0 20 SUBB #$20
+0163 *
+0164 *
+0165 ***** DO TABLE LOOKUP *****
+0166 * FOR COMMAND FUNCTIONS
+0167 *
+0168 *
+0169 f88b 8e fe 13 NXTCH0 LDX #JMPTAB POINT TO JUMP TABLE
+0170 f88e e1 80 NXTCHR CMPB ,X+ DOES COMMAND MATCH TABLE ENTRY ?
+0171 f890 27 0f BEQ JMPCMD BRANCH IF MATCH FOUND
+0172 f892 30 02 LEAX 2,X POINT TO NEXT ENTRY IN TABLE
+0173 f894 8c fe 4f CMPX #TABEND REACHED END OF TABLE YET ?
+0174 f897 26 f5 BNE NXTCHR IF NOT END, CHECK NEXT ENTRY
+0175 f899 8e fe 7d LDX #MSG4 POINT TO MSG "WHAT?"
+0176 f89c 17 05 1e LBSR PDATA PRINT MSG
+0177 f89f 20 c0 BRA NEXTCMD IF NO MATCH, PRMPT FOR NEW CMD
+0178 f8a1 ad 94 JMPCMD JSR [,X] JUMP TO COMMAND ROUTINE
+0179 f8a3 20 bc BRA NEXTCMD PROMPT FOR NEW COMMAND
+0180 *
+0181 * "G" GO OR CONTINUE
+0182 *
+0183 f8a5 1f 34 GO TFR U,S
+0184 f8a7 3b RTI RTI
+0185 *
+0186 * "R" DISPLAY REGISTERS
+0187 *
+0188 f8a8 8e fe 83 REGSTR LDX #MSG5 POINT TO MSG " - "
+0189 f8ab 17 04 ff LBSR PSTRNG PRINT MSG
+0190 f8ae 17 04 11 LBSR PRTSP $FCBF
+0191 f8b1 17 04 19 LBSR PRTUS $FCCA
+0192 f8b4 17 04 21 LBSR PRTDP $FCD5
+0193 f8b7 17 04 29 LBSR PRTIX $FCE0
+0194 f8ba 17 04 31 LBSR PRTIY $FCEB
+0195 f8bd 8e fe 83 LDX #MSG5 POINT TO MSG " - "
+0196 f8c0 17 04 ea LBSR PSTRNG PRINT MSG
+0197 f8c3 17 04 33 LBSR PRTPC $FCF5
+0198 f8c6 17 04 3a LBSR PRTA $FCFF
+0199 f8c9 17 04 41 LBSR PRTB $FD09
+0200 f8cc 16 04 48 LBRA PRTCC $FD13
+0201 *
+0202 *
+0203 * ALTER "PC" PROGRAM COUNTER
+0204 *
+0205 *
+0206 f8cf 17 04 27 ALTRPC LBSR PRTPC $FCF5 PRINT MSG " PC = "
+0207 f8d2 17 05 17 LBSR OUT1S OUTPUT SPACE
+0208 f8d5 17 04 57 LBSR IN1ADR GET NEW CONTENTS FOR "PC"
+0209 f8d8 29 02 BVS ALTPCD EXIT IF INVALID HEX
+0210 f8da af 4a STX 10,U POKE IN NEW CONTENTS
+0211 f8dc 39 ALTPCD RTS ;
+0212 *
+0213 *
+0214 * ALTER "U" USER STACK POINTER
+0215 *
+0216 *
+0217 f8dd 17 03 ed ALTRU LBSR PRTUS $FCCA PRINT MSG " US = "
+0218 f8e0 17 05 09 LBSR OUT1S OUTPUT SPACE
+0219 f8e3 17 04 49 LBSR IN1ADR
+0220 f8e6 29 02 BVS ALTUD
+0221 f8e8 af 48 STX 8,U
+0222 f8ea 39 ALTUD RTS ;
+0223 *
+0224 *
+0225 * ALTER "Y" INDEX REGISTER
+0226 *
+0227 *
+0228 f8eb 17 04 00 ALTRY LBSR PRTIY PRINT MSG " IY = "
+0229 f8ee 17 04 fb LBSR OUT1S OUTPUT SPACE
+0230 f8f1 17 04 3b LBSR IN1ADR
+0231 f8f4 29 02 BVS ALTYD
+0232 f8f6 af 46 STX 6,U $F8F0
+0233 f8f8 39 ALTYD RTS ;
+0234 *
+0235 *
+0236 * ALTER "X" INDEX REGISTER
+0237 *
+0238 *
+0239 f8f9 17 03 e7 ALTRX LBSR PRTIX $FCE0 PRINT MSG " IX = "
+0240 f8fc 17 04 ed LBSR OUT1S OUTPUT SPACE
+0241 f8ff 17 04 2d LBSR IN1ADR
+0242 f902 29 02 BVS ALTXD
+0243 f904 af 44 STX 4,U
+0244 f906 39 ALTXD RTS ;
+0245 *
+0246 *
+0247 * ALTER "DP" DIRECT PAGE REGISTER
+0248 *
+0249 *
+0250 f907 17 03 ce ALTRDP LBSR PRTDP $FCD5 PRINT MSG " DP = "
+0251 f90a 17 04 df LBSR OUT1S OUTPUT SPACE
+0252 f90d 17 04 30 LBSR BYTE INPUT BYTE (2 HEX CHAR)
+0253 f910 29 02 BVS ALTDPD
+0254 f912 a7 43 STA 3,U
+0255 f914 39 ALTDPD RTS ;
+0256 *
+0257 *
+0258 * ALTER "B" ACCUMULATOR
+0259 *
+0260 *
+0261 f915 17 03 f5 ALTRB LBSR PRTB $FD09 PRINT MSG " B = "
+0262 f918 17 04 d1 LBSR OUT1S OUTPUT SPACE
+0263 f91b 17 04 22 LBSR BYTE INPUT BYTE (2 HEX CHAR)
+0264 f91e 29 02 BVS ALTBD
+0265 f920 a7 42 STA 2,U
+0266 f922 39 ALTBD RTS $F91C
+0267 *
+0268 *
+0269 * ALTER "A" ACCUMULATOR
+0270 *
+0271 *
+0272 f923 17 03 dd ALTRA LBSR PRTA $FCFF RINT MSG " A = "
+0273 f926 17 04 c3 LBSR OUT1S OUTPUT SPACE
+0274 f929 17 04 14 LBSR BYTE INPUT BYTE (2 HEX CHAR)
+0275 f92c 29 02 BVS ALTAD
+0276 f92e a7 41 STA 1,U
+0277 f930 39 ALTAD RTS ;
+0278 *
+0279 *
+0280 * ALTER "CC" REGISTER
+0281 *
+0282 *
+0283 f931 17 03 e3 ALTRCC LBSR PRTCC $FD13 PRINT MSG " CC: "
+0284 f934 17 04 b5 LBSR OUT1S OUTPUT SPACE
+0285 f937 17 04 06 LBSR BYTE INPUT BYTE (2 HEX CHAR)
+0286 f93a 29 04 BVS ALTCCD
+0287 f93c 8a 80 ORA #$80 SETS "E" FLAG IN PRINT LIST
+0288 f93e a7 c4 STA ,U
+0289 f940 39 ALTCCD RTS ;
+0290 *
+0291 ***** "M" MEMORY EXAMINE AND CHANGE *****
+0292 *
+0293 f941 17 03 eb MEMCHG LBSR IN1ADR INPUT ADDRESS
+0294 f944 29 2d BVS CHRTN IF NOT HEX, RETURN
+0295 f946 1f 12 TFR X,Y SAVE ADDR IN "Y"
+0296 f948 8e fe 83 MEMC2 LDX #MSG5 POINT TO MSG " - "
+0297 f94b 17 04 5f LBSR PSTRNG PRINT MSG
+0298 f94e 1f 21 TFR Y,X FETCH ADDRESS
+0299 f950 17 04 26 LBSR OUT4H PRINT ADDR IN HEX
+0300 f953 17 04 96 LBSR OUT1S OUTPUT SPACE
+0301 f956 a6 a4 LDA ,Y GET CONTENTS OF CURRENT ADDR.
+0302 f958 17 04 26 LBSR OUT2H OUTPUT CONTENTS IN ASCII
+0303 f95b 17 04 8e LBSR OUT1S OUTPUT SPACE
+0304 f95e 17 03 df LBSR BYTE LOOP WAITING FOR OPERATOR INPUT
+0305 f961 28 11 BVC CHANGE IF VALID HEX GO CHANGE MEM. LOC.
+0306 f963 81 08 CMPA #8 IS IT A BACKSPACE (CNTRL H)?
+0307 f965 27 e1 BEQ MEMC2 PROMPT OPERATOR AGAIN
+0308 f967 81 18 CMPA #$18 IS IT A CANCEL (CNTRL X)?
+0309 f969 27 dd BEQ MEMC2 PROMPT OPERATOR AGAIN
+0310 f96b 81 5e CMPA #'^ IS IT AN UP ARROW?
+0311 f96d 27 17 BEQ BACK DISPLAY PREVIOUS BYTE
+0312 f96f 81 0d CMPA #$D IS IT A CR?
+0313 f971 26 0f BNE FORWRD DISPLAY NEXT BYTE
+0314 f973 39 CHRTN RTS EXIT ROUTINE
+0315 *
+0316 *
+0317 f974 a7 a4 CHANGE STA ,Y CHANGE BYTE IN MEMORY
+0318 f976 a1 a4 CMPA ,Y DID MEMORY BYTE CHANGE?
+0319 f978 27 08 BEQ FORWRD $F972
+0320 f97a 17 04 6f LBSR OUT1S OUTPUT SPACE
+0321 f97d 86 3f LDA #'? LOAD QUESTION MARK
+0322 f97f 17 04 6c LBSR OUTCH PRINT IT
+0323 f982 31 21 FORWRD LEAY 1,Y POINT TO NEXT HIGHER MEM LOCATION
+0324 f984 20 c2 BRA MEMC2 PRINT LOCATION & CONTENTS
+0325 f986 31 3f BACK LEAY -1,Y POINT TO LAST MEM LOCATION
+0326 f988 20 be BRA MEMC2 PRINT LOCATION & CONTENTS
+0327 *
+0328 * "S" DISPLAY STACK
+0329 * HEX-ASCII DISPLAY OF CURRENT STACK CONTENTS FROM
+0330 ** CURRENT STACK POINTER TO INTERNAL STACK LIMIT.
+0331 *
+0332 f98a 17 03 35 DISSTK LBSR PRTSP PRINT CURRENT STACK POINTER
+0333 f98d 1f 32 TFR U,Y
+0334 f98f 8e df c0 LDX #STACK LOAD INTERNAL STACK AS UPPER LIMIT
+0335 f992 30 1f LEAX -1,X POINT TO CURRENT STACK
+0336 f994 20 05 BRA MDUMP1 ENTER MEMORY DUMP OF STACK CONTENTS
+0337 *
+0338 * "E" DUMP MEMORY FOR EXAMINE IN HEX AND ASCII
+0339 * AFTER CALLING 'IN2ADR' LOWER ADDRESS IN Y-REG.
+0340 * UPPER ADDRESS IN X-REG.
+0341 * IF HEX ADDRESSES ARE INVALID (V)=1.
+0342 *
+0343 f996 17 03 8b MEMDUMP LBSR IN2ADR INPUT ADDRESS BOUNDRIES
+0344 f999 29 06 BVS EDPRTN NEW COMMAND IF ILLEGAL HEX
+0345 f99b 34 20 MDUMP1 PSHS Y COMPARE LOWER TO UPPER BOUNDS
+0346 f99d ac e1 CMPX ,S++ LOWER BOUNDS > UPPER BOUNDS?
+0347 f99f 24 01 BCC AJDUMP IF NOT, DUMP HEX AND ASCII
+0348 f9a1 39 EDPRTN RTS ;
+0349 *
+0350 * ADJUST LOWER AND UPPER ADDRESS LIMITS
+0351 * TO EVEN 16 BYTE BOUNDRIES.
+0352 *
+0353 * IF LOWER ADDR = $4532
+0354 * LOWER BOUNDS WILL BE ADJUSTED TO = $4530.
+0355 *
+0356 * IF UPPER ADDR = $4567
+0357 * UPPER BOUNDS WILL BE ADJUSTED TO = $4570.
+0358 *
+0359 * ENTER WITH LOWER ADDRESS IN X-REG.
+0360 * -UPPER ADDRESS ON TOP OF STACK.
+0361 *
+0362 f9a2 1f 10 AJDUMP TFR X,D GET UPPER ADDR IN D-REG
+0363 f9a4 c3 00 10 ADDD #$10 ADD 16 TO UPPER ADDRESS
+0364 f9a7 c4 f0 ANDB #$F0 MASK TO EVEN 16 BYTE BOUNDRY
+0365 f9a9 34 06 PSHS A,B SAVE ON STACK AS UPPER DUMP LIMIT
+0366 f9ab 1f 20 TFR Y,D $F9A5 GET LOWER ADDRESS IN D-REG
+0367 f9ad c4 f0 ANDB #$F0 MASK TO EVEN 16 BYTE BOUNDRY
+0368 f9af 1f 01 TFR D,X PUT IN X-REG AS LOWER DUMP LIMIT
+0369 f9b1 ac e4 NXTLIN CMPX ,S COMPARE LOWER TO UPPER LIMIT
+0370 f9b3 27 05 BEQ SKPDMP IF EQUAL SKIP HEX-ASCII DUMP
+0371 f9b5 17 04 27 LBSR INCHEK CHECK FOR INPUT FROM KEYBOARD
+0372 f9b8 27 03 BEQ EDUMP IF NONE, CONTINUE WITH DUMP
+0373 f9ba 32 62 SKPDMP LEAS 2,S READJUST STACK IF NOT DUMPING
+0374 f9bc 39 RTS ;
+0375 *
+0376 * PRINT 16 HEX BYTES FOLLOWED BY 16 ASCII CHARACTERS
+0377 * FOR EACH LINE THROUGHOUT ADDRESS LIMITS.
+0378 *
+0379 f9bd 34 10 EDUMP PSHS X PUSH LOWER ADDR LIMIT ON STACK
+0380 f9bf 8e fe 83 LDX #MSG5 POINT TO MSG " - "
+0381 f9c2 17 03 e8 LBSR PSTRNG PRINT MSG
+0382 f9c5 ae e4 LDX ,S LOAD LOWER ADDR FROM TOP OF STACK
+0383 f9c7 17 03 af LBSR OUT4H PRINT THE ADDRESS LBSR OUT2S PRINT 2 SPACES
+0384 f9ca c6 10 LDB #$10 LOAD COUNT OF 16 BYTES TO DUMP
+0385 f9cc a6 80 ELOOP LDA ,X+ GET FROM MEMORY HEX BYTE TO PRINT
+0386 f9ce 17 03 b0 LBSR OUT2H OUTPUT HEX BYTE AS ASCII
+0387 f9d1 17 04 18 LBSR OUT1S OUTPUT SPACE
+0388 f9d4 5a DECB $F9D1 DECREMENT BYTE COUNT
+0389 f9d5 26 f5 BNE ELOOP CONTINUE TIL 16 HEX BYTES PRINTED
+0390 *
+0391 * PRINT 16 ASCII CHARACTERS
+0392 * IF NOT PRINTABLE OR NOT VALID
+0393 * ASCII PRINT A PERIOD (.)
+0394 f9d7 17 04 10 LBSR OUT2S 2 SPACES
+0395 f9da ae e1 LDX ,S++ GET LOW LIMIT FRM STACK - ADJ STACK
+0396 f9dc c6 10 LDB #$10 SET ASCII CHAR TO PRINT = 16
+0397 f9de a6 80 EDPASC LDA ,X+ GET CHARACTER FROM MEMORY
+0398 f9e0 81 20 CMPA #$20 IF LESS THAN $20, NON-PRINTABLE?
+0399 f9e2 25 04 BCS PERIOD IF SO, PRINT PERIOD INSTEAD
+0400 f9e4 81 7e CMPA #$7E IS IT VALID ASCII?
+0401 f9e6 23 02 BLS PRASC IF SO PRINT IT
+0402 f9e8 86 2e PERIOD LDA #'. LOAD A PERIOD (.)
+0403 f9ea 17 04 01 PRASC LBSR OUTCH PRINT ASCII CHARACTER
+0404 f9ed 5a DECB DECREMENT COUNT
+0405 f9ee 26 ee BNE EDPASC
+0406 f9f0 20 bf BRA NXTLIN
+0407 *
+0408 ***** "Q" MEMORY TEST *****
+0409 *
+0410 f9f2 6f e2 MEMTST CLR ,-S CLEAR BYTE ON STACK
+0411 f9f4 6f e2 CLR ,-S CLEAR ANOTHER BYTE
+0412 f9f6 17 03 2b LBSR IN2ADR GET BEGIN(Y) & END(X) ADDR. LIMITS
+0413 f9f9 34 30 PSHS X,Y SAVE ADDRESSES ON STACK
+0414 f9fb 29 7b BVS ADJSK6 EXIT IF NOT VALID HEX
+0415 f9fd ac 62 CMPX 2,S COMPARE BEGIN TO END ADDR.
+0416 f9ff 25 77 BCS ADJSK6 EXIT IF BEGIN > END ADDR.
+0417 fa01 17 03 e8 LBSR OUT1S OUTPUT SPACE
+0418 fa04 1f 20 MEMSET TFR Y,D PUT BEGIN ADDR. IN 'D'-ACCUM.
+0419 fa06 e3 64 ADDD 4,S ADD PASS COUNT TO BEGIN ADDR
+0420 fa08 34 04 PSHS B ADD LS BYTE TO MS BYTE OF BEGIN ADDR
+0421 fa0a ab e0 ADDA ,S+
+0422 fa0c a7 a0 STA ,Y+ SAVE THIS DATA BYTE AT BEGIN ADDR
+0423 fa0e 10 ac e4 CMPY ,S COMPARE END TO BEGIN ADDR
+0424 fa11 25 f1 BCS MEMSET IF BEGIN LOWER, CONTINUE TO SET MEMORY
+0425 fa13 10 ae 62 LDY 2,S RELOAD BEGIN ADDRESS
+0426 fa16 1f 20 TEST1 TFR Y,D PUT BEGIN ADDR IN 'D'-ACC.
+0427 fa18 e3 64 ADDD 4,S ADD PASS COUNT TO ADDRESS
+0428 fa1a 34 02 PSHS A ADD MS BYTE TO LS BYTE OF ADDRESS
+0429 fa1c eb e0 ADDB ,S+
+0430 fa1e e8 a0 EORB ,Y+ EX-OR THIS DATA WITH DATA IN MEMORY LOC.
+0431 fa20 27 3c BEQ GUDPAS IF (Z) SET, MEMORY BYTE OK
+0432 fa22 8e fe 83 LDX #MSG5 POINT TO MSG " - "
+0433 fa25 17 03 85 LBSR PSTRNG PRINT MSG
+0434 fa28 30 3f LEAX -1,Y GET ERROR ADDRESS IN X-REG
+0435 fa2a 17 03 4c LBSR OUT4H OUTPUT IT
+0436 fa2d 34 10 PSHS X PUSH ERROR ADDR ON STACK
+0437 fa2f 8e fe a1 LDX #MSG8 POINT TO MSG " =>"
+0438 fa32 17 03 88 LBSR PDATA PRINT MSG
+0439 fa35 35 10 PULS X POP ERROR ADDR FROM STACK
+0440 fa37 17 01 47 LBSR LRA GET PHYSICAL ADDR FROM LRA
+0441 fa3a 17 03 50 LBSR XASCII OUTPUT EXTENDED 4 BITS OF PHYSICAL ADDR
+0442 fa3d 17 03 39 LBSR OUT4H OUTPUT LS 16 BITS OF PHYSICAL ADDR
+0443 fa40 8e fe 87 LDX #MSG6 POINT TO MSG ", PASS "
+0444 fa43 17 03 77 LBSR PDATA PRINT MSG
+0445 fa46 ae 64 LDX 4,S LOAD PASS COUNT
+0446 fa48 17 03 2e LBSR OUT4H OUTPUT IT
+0447 fa4b 8e fe 8f LDX #MSG7 POINT TO MSG ", BITS IN ERROR
+0448 fa4e 17 03 6c LBSR PDATA PRINT MSG
+0449 fa51 1f 98 TFR B,A GET ERROR BYTE INTO A-ACC
+0450 fa53 8e fe a6 LDX #MSG9 POINT TO MSG "76543210"
+0451 fa56 17 03 3e LBSR BIASCI OUTPUT IN BINARY/ASCII FORMAT
+0452 fa59 17 03 83 LBSR INCHEK CHECK FOR INPUT FROM KEYBOARD $FA56
+0453 fa5c 26 1a BNE ADJSK6 IF SO, EXIT MEMORY TEST
+0454 fa5e 10 ac e4 GUDPAS CMPY ,S COMPARE END ADDR TO BEGIN ADDR
+0455 fa61 25 b3 BCS TEST1
+0456 fa63 86 2b LDA #'+ GET "PASS" SYMBOL IF MEMORY PASS OK
+0457 fa65 17 03 86 LBSR OUTCH OUTPUT SYMBOL TO TERMINAL
+0458 fa68 17 03 74 LBSR INCHEK INPUT FROM KEYBOARD?
+0459 fa6b 26 0b BNE ADJSK6 IF SO, EXIT MEMORY TEST
+0460 fa6d 10 ae 62 LDY 2,S LOAD BEGIN ADDRESS
+0461 fa70 6c 65 INC 5,S INCREMENT LS BYTE OF PASS COUNT
+0462 fa72 26 90 BNE MEMSET IF NOT ZERO, SET NEXT MEMORY BYTE
+0463 fa74 6c 64 INC 4,S INCREMENT MS BYTE OF PASS COUNT
+0464 fa76 26 8c BNE MEMSET DONE WITH 65,535 PASSES OF MEMORY?
+0465 fa78 32 66 ADJSK6 LEAS 6,S ADJ STACK POINTER BY 6
+0466 fa7a 39 RTS
+0467 *
+0468 ***** "B" SET BREAKPOINT *****
+0469 *
+0470 fa7b 17 02 b1 BRKPNT LBSR IN1ADR GET BREAKPOINT ADDRESS
+0471 fa7e 29 1e BVS EXITBP EXIT IF INVALID HEX ADDR.
+0472 fa80 8c df c0 CMPX #STACK ADDRESS ILLEGAL IF >=$DFC0
+0473 fa83 24 1a BCC BPERR IF ERROR PRINT (?), EXIT
+0474 fa85 34 10 PSHS X $FA82 PUSH BP ADDRESS ON STACK
+0475 fa87 8e ff ff LDX #$FFFF LOAD DUMMY ADDR TO TEST BP TABLE
+0476 fa8a 8d 55 BSR BPTEST TEST BP TABLE FOR FREE SPACE
+0477 fa8c 35 10 PULS X POP BP ADDRESS FROM STACK
+0478 fa8e 27 0f BEQ BPERR (Z) SET, OUT OF BP TABLE SPACE
+0479 fa90 a6 84 LDA ,X GET DATA AT BREAKPOINT ADDRESS
+0480 fa92 81 3f CMPA #$3F IS IT A SWI?
+0481 fa94 27 09 BEQ BPERR IF SWI ALREADY, INDICATE ERROR
+0482 fa96 a7 a0 STA ,Y+ SAVE DATA BYTE IN BP TABLE
+0483 fa98 af a4 STX ,Y SAVE BP ADDRESS IN BP TABLE
+0484 fa9a 86 3f LDA #$3F LOAD A SWI ($3F)
+0485 fa9c a7 84 STA ,X SAVE SWI AT BREAKPOINT ADDRESS
+0486 fa9e 39 EXITBP RTS ;
+0487 *
+0488 * INDICATE ERROR SETTING BREAKPOINT
+0489 *
+0490 fa9f 17 03 4a BPERR LBSR OUT1S OUTPUT SPACE
+0491 faa2 86 3f LDA #'? LOAD (?), INDICATE BREAKPOINT ERROR
+0492 faa4 16 03 47 LBRA OUTCH PRINT "?"
+0493 *
+0494 *** "X" CLEAR OUTSTANDING BREAKPOINTS ***
+0495 *
+0496 faa7 10 8e df e3 XBKPNT LDY #BPTBL POINT TO BREAKPOINT TABLE
+0497 faab c6 08 LDB #8 LOAD BREAKPOINT COUNTER
+0498 faad 8d 18 XBPLP BSR RPLSWI REMOVE USED ENTRY IN BP TABLE
+0499 faaf 5a DECB $FAAC DECREMENT BP COUNTER
+0500 fab0 26 fb BNE XBPLP END OF BREAKPOINT TABLE?
+0501 fab2 39 RTS
+0502 *
+0503 ***** SWI ENTRY POINT *****
+0504 *
+0505 fab3 1f 43 SWIE TFR S,U TRANSFER STACK TO USER POINTER
+0506 fab5 ae 4a LDX 10,U LOAD PC FROM STACK INTO X-REG
+0507 fab7 30 1f LEAX -1,X ADJUST ADDR DOWN 1 BYTE.
+0508 fab9 8d 26 BSR BPTEST FIND BREAKPOINT IN BP TABLE
+0509 fabb 27 04 BEQ REGPR IF FOUND, REPLACE DATA AT BP ADDR
+0510 fabd af 4a STX 10,U SAVE BREAKPOINT ADDR IN STACK
+0511 fabf 8d 06 BSR RPLSWI GO REPLACE SWI WITH ORIGINAL DATA
+0512 fac1 17 fd e4 REGPR LBSR REGSTR GO PRINT REGISTERS
+0513 fac4 16 fd 9a LBRA NEXTCMD GET NEXT COMMAND
+0514 fac7 ae 21 RPLSWI LDX 1,Y LOAD BP ADDRESS FROM BP TABLE
+0515 fac9 8c df c0 CMPX #STACK COMPARE TO TOP AVAILABLE USER MEMORY
+0516 facc 24 0a BCC FFSTBL GO RESET TABLE ENTRY TO $FF'S
+0517 face a6 84 LDA ,X GET DATA FROM BP ADDRESS
+0518 fad0 81 3f CMPA #$3F IS IT SWI?
+0519 fad2 26 04 BNE FFSTBL IF NOT, RESET TABLE ENTRY TO $FF'S
+0520 fad4 a6 a4 LDA ,Y GET ORIGINAL DATA FROM BP TABLE
+0521 fad6 a7 84 STA ,X $FAD3 RESTORE DATA AT BP ADDRESS
+0522 fad8 86 ff FFSTBL LDA #$FF LOAD $FF IN A-ACC
+0523 fada a7 a0 STA ,Y+ RESET BREAKPOINT TABLE DATA TO $FF'S
+0524 fadc a7 a0 STA ,Y+ RESET BREAKPOINT TABLE ADDR TO $FF'S
+0525 fade a7 a0 STA ,Y+
+0526 fae0 39 RTS
+0527 *
+0528 ** SEARCH BREAKPOINT TABLE FOR MATCH **
+0529 *
+0530 fae1 10 8e df e3 BPTEST LDY #BPTBL POINT TO BREAKPOINT TABLE
+0531 fae5 c6 08 LDB #8 LOAD BREAKPOINT COUNTER
+0532 fae7 a6 a0 FNDBP LDA ,Y+ LOAD DATA BYTE
+0533 fae9 ac a1 CMPX ,Y++ COMPARE ADDRESS, IS IT SAME?
+0534 faeb 27 04 BEQ BPADJ IF SO, ADJUST POINTER FOR TABLE ENTRY
+0535 faed 5a DECB IF NOT, DECREMENT BREAKPOINT COUNTER
+0536 faee 26 f7 BNE FNDBP AND LOOK FOR NEXT POSSIBLE MATCH
+0537 faf0 39 RTS ;
+0538 *
+0539 *
+0540 faf1 31 3d BPADJ LEAY -3,Y MOVE POINTER TO BEGIN OF BP ENTRY
+0541 faf3 39 RTS
+0542 *
+0543 *** "D" DISK BOOT FOR DMAF2 ***
+0544 *
+0545 faf4 86 de DBOOT LDA #$DE
+0546 faf6 b7 f0 24 STA DRVREG
+0547 faf9 86 ff LDA #$FF
+0548 fafb b7 f0 14 STA PRIREG $FAF8
+0549 fafe b7 f0 10 STA CCREG
+0550 fb01 b7 f0 15 STA AAAREG
+0551 fb04 b7 f0 16 STA BBBREG
+0552 fb07 7d f0 10 TST CCREG
+0553 fb0a 86 d8 LDA #$D8
+0554 fb0c b7 f0 20 STA COMREG
+0555 fb0f 17 00 97 LBSR DLY
+0556 fb12 b6 f0 20 DBOOT0 LDA COMREG
+0557 fb15 2b fb BMI DBOOT0
+0558 fb17 86 09 LDA #$09
+0559 fb19 b7 f0 20 STA COMREG
+0560 fb1c 17 00 8a LBSR DLY
+0561 *
+0562 fb1f b6 f0 20 DISKWT LDA COMREG FETCH DRIVE STATUS
+0563 fb22 85 01 BITA #1 TEST BUSY BIT
+0564 fb24 26 f9 BNE DISKWT LOOP UNTIL NOT BUSY
+0565 *
+0566 fb26 85 10 BITA #$10
+0567 fb28 26 ca BNE DBOOT
+0568 *
+0569 fb2a 8e c0 00 LDX #$C000 LOGICAL ADDR. = $C000
+0570 fb2d 8d 52 BSR LRA GET 20 BIT PHYSICAL ADDR. OF LOG. ADDR.
+0571 fb2f 8a 10 ORA #$10
+0572 fb31 b7 f0 40 STA CCCREG
+0573 fb34 1f 10 TFR X,D
+0574 fb36 43 COMA ;
+0575 fb37 53 COMB ;
+0576 fb38 fd f0 00 STD ADDREG
+0577 fb3b 8e fe ff LDX #$FEFF LOAD DMA BYTE COUNT = $100
+0578 fb3e bf f0 02 STX CNTREG STORE IN COUNT REGISTER
+0579 fb41 86 ff LDA #$FF LOAD THE CHANNEL REGISTER
+0580 fb43 b7 f0 10 STA CCREG
+0581 fb46 86 fe LDA #$FE SET CHANNEL 0
+0582 fb48 b7 f0 14 STA PRIREG
+0583 fb4b 86 01 LDA #1 SET SECTOR TO "1"
+0584 fb4d b7 f0 22 STA SECREG ISSUE COMMAND
+0585 fb50 86 8c LDA #$8C SET SINGLE SECTOR READ
+0586 fb52 b7 f0 20 STA COMREG ISSUE COMMAND
+0587 fb55 8d 52 BSR DLY
+0588 *
+0589 * THE FOLLOWING CODE TESTS THE STATUS OF THE
+0590 * CHANNEL CONTROL REGISTER. IF "D7" IS NOT
+0591 * ZERO THEN IT WILL LOOP WAITING FOR "D7"
+0592 * TO GO TO ZERO. IF AFTER 65,536 TRIES IT
+0593 * IS STILL A ONE THE BOOT OPERATION WILL
+0594 * BE STARTED OVER FROM THE BEGINING.
+0595 *
+0596 fb57 5f CLRB ;
+0597 fb58 34 04 DBOOT1 PSHS B $FB55
+0598 fb5a 5f CLRB ;
+0599 fb5b 7d f0 10 DBOOT2 TST CCREG
+0600 fb5e 2a 0a BPL DBOOT3
+0601 fb60 5a DECB ;
+0602 fb61 26 f8 BNE DBOOT2
+0603 fb63 35 04 PULS B
+0604 fb65 5a DECB
+0605 fb66 26 f0 BNE DBOOT1
+0606 fb68 20 8a BRA DBOOT
+0607 fb6a 35 04 DBOOT3 PULS B
+0608 fb6c b6 f0 20 LDA COMREG
+0609 fb6f 85 1c BITA #$1C
+0610 fb71 27 01 BEQ DBOOT4
+0611 fb73 39 RTS ;
+0612 *
+0613 *
+0614 fb74 c6 de DBOOT4 LDB #$DE
+0615 fb76 f7 f0 24 STB DRVREG
+0616 fb79 8e c0 00 LDX #$C000
+0617 fb7c af 4a STX 10,U
+0618 fb7e 1f 34 TFR U,S $FB7B
+0619 fb80 3b RTI ;
+0620 *
+0621 ***** LRA LOAD REAL ADDRESS *****
+0622 *
+0623 * THE FOLLOWING CODE LOADS THE 20-BIT
+0624 * PHYSICAL ADDRESS OF A MEMORY BYTE
+0625 * INTO THE "A" AND "X" REGISTERS. THIS
+0626 * ROUTINE IS ENTERED WITH THE LOGICAL
+0627 * ADDRESS OF A MEMORY BYTE IN THE "IX"
+0628 * REGISTER. EXIT IS MADE WITH THE HIGH-
+0629 * ORDER FOUR BITS OF THE 20-BIT PHYSICAL
+0630 * ADDRESS IN THE "A" REGISTER, AND THE
+0631 * LOW-ORDER 16-BITS OF THE 20-BIT
+0632 * PHYSICAL ADDRESS IN THE "IX" REGISTER.
+0633 * ALL OTHER REGISTERS ARE PRESERVED.
+0634 * THIS ROUTINE IS REQUIRED SINCE THE
+0635 * DMAF1 AND DMAF2 DISK CONTROLLERS MUST
+0636 * PRESENT PHYSICAL ADDRESSES ON THE
+0637 * SYSTEM BUS.
+0638 *
+0639 fb81 34 36 LRA PSHS A,B,X,Y PUSH REGISTERS ON STACK
+0640 fb83 a6 62 LDA 2,S GET MSB LOGICAL ADDR FRM X REG ON STACK
+0641 fb85 44 LSRA ;
+0642 fb86 44 LSRA ADJ FOR INDEXED INTO
+0643 fb87 44 LSRA CORRESPONDING LOCATION
+0644 fb88 44 LSRA IN LRA TABLE
+0645 fb89 10 8e df d0 LDY #LRARAM LOAD LRA TABLE BASE ADDRESS
+0646 fb8d e6 a6 LDB A,Y GET PHYSICAL ADDR. DATA FROM LRA TABLE
+0647 fb8f 54 LSRB ADJ. REAL ADDR. TO REFLECT EXTENDED
+0648 fb90 54 LSRB PHYSICAL ADDRESS.
+0649 fb91 54 LSRB EXTENDED MS 4-BITS ARE RETURNED
+0650 fb92 54 LSRB IN THE "A" ACCUMULATOR
+0651 fb93 e7 e4 STB ,S MS 4 BITS IN A ACCUM. STORED ON STACK
+0652 fb95 e6 a6 LDB A,Y LOAD REAL ADDRESS DATA FROM LRA TABLE
+0653 fb97 53 COMB COMP TO ADJ FOR PHYSICAL ADDR. IN X REG
+0654 fb98 58 ASLB ADJ DATA FOR RELOCATION IN X REG
+0655 fb99 58 ASLB ;
+0656 fb9a 58 ASLB $FB97
+0657 fb9b 58 ASLB ;
+0658 fb9c a6 62 LDA 2,S GET MS BYTE OF LOGICAL ADDR.
+0659 fb9e 84 0f ANDA #$0F MASK MS NIBBLE OF LOGICAL ADDRESS
+0660 fba0 a7 62 STA 2,S SAVE IT IN X REG ON STACK
+0661 fba2 ea 62 ORB 2,S SET MS BYTE IN X REG TO ADJ PHY ADDR.
+0662 *
+0663 * PLUS LS NIBBLE OF LOGICAL ADDRESS
+0664 fba4 e7 62 STB 2,S SAVE AS LS 16 BITS OF PHY ADDR IN X REG
+0665 * ON STACK
+0666 fba6 35 36 PULS A,B,X,Y POP REGS. FROM STACK
+0667 fba8 39 RTS ;
+0668 *
+0669 * DELAY LOOP
+0670 *
+0671 fba9 34 04 DLY PSHS B SAVE CONTENTS OF "B"
+0672 fbab c6 20 LDB #$20 GET LOOP DELAY VALUE
+0673 fbad 5a SUB1 DECB SUBTRACT ONE FROM VALUE
+0674 fbae 26 fd BNE SUB1 LOOP UNTIL ZERO
+0675 fbb0 35 04 PULS B RESTORE CONTENTS OF "B"
+0676 fbb2 39 RTS ;
+0677 *
+0678 ***** "U" MINIDISK BOOT *****
+0679 *
+0680 fbb3 7d e0 18 MINBOOT TST Comreg
+0681 fbb6 7f e0 14 CLR Drvreg SELECT DRIVE 0
+0682 *
+0683 * DELAY BEFORE ISSUING RESTORE COMMAND
+0684 fbb9 c6 03 LDB #3
+0685 fbbb 8e 00 00 LDX #0
+0686 fbbe 30 01 LOOP LEAX 1,X $FBBB
+0687 fbc0 8c 00 00 CMPX #0
+0688 fbc3 26 f9 BNE LOOP
+0689 fbc5 5a DECB $FBC2
+0690 fbc6 26 f6 BNE LOOP
+0691 *
+0692 fbc8 86 0f LDA #$0F *LOAD HEAD, VERIFY, 20msec/step
+0693 fbca b7 e0 18 STA Comreg ISSUE RESTORE COMMAND
+0694 fbcd 8d 37 BSR DELAY
+0695 fbcf f6 e0 18 LOOP1 LDB Comreg $FBCC
+0696 fbd2 c5 01 BITB #1
+0697 fbd4 26 f9 BNE LOOP1 LOOP UNTIL THRU
+0698 fbd6 86 01 LDA #1
+0699 fbd8 b7 e0 1a STA Secreg SET SECTOR REGISTER TO ONE
+0700 fbdb 8d 29 BSR DELAY
+0701 fbdd 86 8c LDA #$8C LOAD HEAD, DELAY 10msec,
+0702 fbdf b7 e0 18 STA Comreg AND READ SINGLE RECORD
+0703 fbe2 8d 22 BSR DELAY
+0704 fbe4 8e c0 00 LDX #$C000
+0705 fbe7 20 09 BRA LOOP3
+0706 *
+0707 fbe9 c5 02 LOOP2 BITB #2 $FBE6 DRQ?
+0708 fbeb 27 05 BEQ LOOP3
+0709 fbed b6 e0 1b LDA Datreg
+0710 fbf0 a7 80 STA ,X+
+0711 *
+0712 fbf2 f6 e0 18 LOOP3 LDB Comreg FETCH STATUS
+0713 fbf5 c5 01 BITB #1 BUSY?
+0714 fbf7 26 f0 BNE LOOP2
+0715 fbf9 c5 2c BITB #$2C CRC ERROR OR LOST DATA?
+0716 fbfb 27 01 BEQ LOOP4
+0717 fbfd 39 RTS ;
+0718 fbfe 8e c0 00 LOOP4 LDX #$C000 $FBFB
+0719 fc01 af 4a STX 10,U
+0720 fc03 1f 34 TFR U,S
+0721 fc05 3b RTI ;
+0722 *
+0723 * DELAY
+0724 *
+0725 fc06 c6 20 DELAY LDB #$20
+0726 fc08 5a LOOP5 DECB ;
+0727 fc09 26 fd BNE LOOP5
+0728 fc0b 39 RTS ;
+0729 *
+0730 ***** "L" LOAD MIKBUG TAPE *****
+0731 *
+0732 fc0c 86 11 LOAD LDA #$11 LOAD 'DC1' CASS. READ ON CODE
+0733 fc0e 17 01 dd LBSR OUTCH OUTPUT IT TO TERMINAL PORT
+0734 fc11 7f df e2 CLR ECHO TURN OFF ECHO FLAG
+0735 fc14 17 01 ad LOAD1 LBSR ECHON INPUT 8 BIT BYTE WITH NO ECHO
+0736 fc17 81 53 LOAD2 CMPA #'S IS IT AN "S", START CHARACTER ?
+0737 fc19 26 f9 BNE LOAD1 IF NOT, DISCARD AND GET NEXT CHAR.
+0738 fc1b 17 01 a6 LBSR ECHON
+0739 fc1e 81 39 CMPA #'9 IS IT A "9" , END OF FILE CHAR ?
+0740 fc20 27 3d BEQ LOAD21 IF SO, EXIT LOAD
+0741 fc22 81 31 CMPA #'1 IS IT A "1" , FILE LOAD CHAR ?
+0742 fc24 26 f1 BNE LOAD2 IF NOT, LOOK FOR START CHAR.
+0743 fc26 17 01 17 LBSR BYTE INPUT BYTE COUNT
+0744 fc29 34 02 PSHS A PUSH COUNT ON STACK
+0745 fc2b 29 26 BVS LODERR (V) C-CODE SET, ILLEGAL HEX
+0746 fc2d 17 00 ff LBSR IN1ADR INPUT LOAD ADDRESS
+0747 fc30 29 21 BVS LODERR (V) C-CODE SET, ADDR NOT HEX
+0748 fc32 34 10 PSHS X PUSH ADDR ON STACK
+0749 fc34 e6 e0 LDB ,S+ LOAD MSB OF ADDR AS CHECKSUM BYTE
+0750 fc36 eb e0 ADDB ,S+ ADD LSB OF ADDR TO CHECKSUM
+0751 fc38 eb e4 ADDB ,S ADD BYTE COUNT BYTE TO CHECKSUM
+0752 fc3a 6a e4 DEC ,S $FC37 DECREMENT BYTE COUNT 2 TO BYPASS
+0753 fc3c 6a e4 DEC ,S ADDRESS BYTES.
+0754 fc3e 34 04 LOAD10 PSHS B PUSH CHECKSUM ON STACK
+0755 fc40 17 00 fd LBSR BYTE INPUT DATA BYTE (2 HEX CHAR)
+0756 fc43 35 04 PULS B POP CHECKSUM FROM STACK
+0757 fc45 29 0c BVS LODERR (V) SET, DATA BYTE NOT HEX
+0758 fc47 34 02 PSHS A PUSH DATA BYTE ON STACK
+0759 fc49 eb e0 ADDB ,S+ ADD DATA TO CHECKSUM, AUTO INC STACK
+0760 fc4b 6a e4 DEC ,S DECREMENT BYTE COUNT 1
+0761 fc4d 27 05 BEQ LOAD16 IF BYTE COUNT ZERO, TEST CHECKSUM
+0762 fc4f a7 80 STA ,X+ SAVE DATA BYTE IN MEMORY
+0763 fc51 20 eb BRA LOAD10 GET NEXT DATA BYTE
+0764 fc53 5f LODERR CLRB ;ERROR CONDITION, ZERO CHECKSUM ;
+0765 fc54 35 02 LOAD16 PULS A ADJUST STACK (REMOVE BYTE COUNT)
+0766 fc56 c1 ff CMPB #$FF CHECKSUM OK?
+0767 fc58 27 b2 BEQ LOAD IF SO, LOAD NEXT LINE
+0768 fc5a 86 3f LDA #'? LOAD (?) ERROR INDICATOR
+0769 fc5c 17 01 8f LBSR OUTCH OUTPUT IT TO TERMINAL
+0770 fc5f 73 df e2 LOAD21 COM ECHO TURN ECHO ON
+0771 fc62 86 13 LDA #$13 $FC5F LOAD 'DC3' CASS. READ OFF CODE
+0772 fc64 16 01 87 LBRA OUTCH OUTPUT IT
+0773 *
+0774 ***** "P" PUNCH MIKBUG TAPE *****
+0775 *
+0776 fc67 6f e2 PUNCH CLR ,-S CLEAR RESERVED BYTE ON STACK
+0777 fc69 17 00 b8 LBSR IN2ADR GET BEGIN AND END ADDRESS
+0778 fc6c 34 30 PSHS X,Y SAVE ADDRESSES ON STACK
+0779 fc6e 29 4a BVS PUNEXT (V) C-CODE SET, EXIT PUNCH
+0780 fc70 ac 62 CMPX 2,S COMPARE BEGIN TO END ADDR
+0781 fc72 25 46 BCS PUNEXT IF BEGIN GREATER THAN END, EXIT PUNCH
+0782 fc74 30 01 LEAX 1,X INCREMENT END ADDRESS
+0783 fc76 af e4 STX ,S STORE END ADDR ON STACK
+0784 fc78 86 12 LDA #$12 LOAD 'DC2' PUNCH ON CODE
+0785 fc7a 17 01 71 LBSR OUTCH OUTPUT IT TO TERMINAL
+0786 fc7d ec e4 PUNCH2 LDD ,S LOAD END ADDR IN D-ACC
+0787 fc7f a3 62 SUBD 2,S SUBTRACT BEGIN FROM END
+0788 fc81 27 06 BEQ PUNCH3 SAME, PUNCH 32 BYTES DEFAULT
+0789 fc83 10 83 00 20 CMPD #$20 LESS THAN 32 BYTES?
+0790 fc87 23 02 BLS PUNCH4 PUNCH THAT MANY BYTES
+0791 fc89 c6 20 PUNCH3 LDB #$20 LOAD BYTE COUNT OF 32.
+0792 fc8b e7 64 PUNCH4 STB 4,S STORE ON STACK AS BYTE COUNT
+0793 fc8d 8e fe eb LDX #MSG20 POINT TO MSG "S1"
+0794 fc90 17 01 1a LBSR PSTRNG PRINT MSG
+0795 fc93 cb 03 ADDB #3 ADD 3 BYTES TO BYTE COUNT
+0796 fc95 1f 98 TFR B,A GET BYTE COUNT IN A-ACC TO PUNCH
+0797 fc97 17 00 e7 LBSR OUT2H OUTPUT BYTE COUNT
+0798 fc9a ae 62 LDX 2,S LOAD BEGIN ADDRESS
+0799 fc9c 17 00 da LBSR OUT4H PUNCH ADDRESS
+0800 fc9f eb 62 ADDB 2,S ADD ADDR MSB TO CHECKSUM
+0801 fca1 eb 63 ADDB 3,S ADD ADDR LSB TO CHECKSUM
+0802 fca3 eb 84 PUNCHL ADDB ,X ADD DATA BYTE TO CHECKSUM
+0803 fca5 a6 80 LDA ,X+ LOAD DATA BYTE TO PUNCH
+0804 fca7 17 00 d7 LBSR OUT2H OUTPUT DATA BYTE
+0805 fcaa 6a 64 DEC 4,S DECREMENT BYTE COUNT
+0806 fcac 26 f5 BNE PUNCHL NOT DONE, PUNCH NEXT BYTE
+0807 fcae 53 COMB 1's COMPLIMENT CHECKSUM BYTE
+0808 fcaf 1f 98 TFR B,A GET IT IN A-ACC TO PUNCH
+0809 fcb1 17 00 cd LBSR OUT2H OUTPUT CHECKSUM BYTE
+0810 fcb4 af 62 STX 2,S SAVE X-REG IN STACK AS NEW PUNCH ADDR
+0811 fcb6 ac e4 CMPX ,S COMPARE IT TO END ADDR
+0812 fcb8 26 c3 BNE PUNCH2 $FCB5 PUNCH NOT DONE, CONT.
+0813 fcba 86 14 PUNEXT LDA #$14 LOAD 'DC4' PUNCH OFF CODE
+0814 fcbc 17 01 2f LBSR OUTCH OUTPUT IT
+0815 fcbf 32 65 LEAS 5,S READJUST STACK POINTER
+0816 fcc1 39 RTS ;
+0817 *
+0818 *
+0819 fcc2 8e fe ae PRTSP LDX #MSG10 POINT TO MSG "SP="
+0820 fcc5 17 00 f5 LBSR PDATA PRINT MSG
+0821 fcc8 1f 31 TFR U,X
+0822 fcca 16 00 ac LBRA OUT4H
+0823 fccd 8e fe ba PRTUS LDX #MSG12 POINT TO MSG "US="
+0824 fcd0 17 00 ea LBSR PDATA PRINT MSG
+0825 fcd3 ae 48 LDX 8,U
+0826 fcd5 16 00 a1 LBRA OUT4H
+0827 fcd8 8e fe cc PRTDP LDX #MSG15 POINT TO MSG "DP="
+0828 fcdb 17 00 df LBSR PDATA PRINT MSG
+0829 fcde a6 43 LDA 3,U
+0830 fce0 16 00 9e LBRA OUT2H OUTPUT HEX BYTE AS ASCII
+0831 fce3 8e fe c6 PRTIX LDX #MSG14 POINT TO MSG "IX="
+0832 fce6 17 00 d4 LBSR PDATA PRINT MSG
+0833 fce9 ae 44 LDX 4,U $FCE6
+0834 fceb 16 00 8b LBRA OUT4H
+0835 fcee 8e fe c0 PRTIY LDX #MSG13 POINT TO MSG "IY="
+0836 fcf1 17 00 c9 LBSR PDATA PRINT MSG
+0837 fcf4 ae 46 LDX 6,U
+0838 fcf6 16 00 80 LBRA OUT4H
+0839 fcf9 8e fe b4 PRTPC LDX #MSG11 POINT TO MSG "PC="
+0840 fcfc 17 00 be LBSR PDATA PRINT MSG
+0841 fcff ae 4a LDX 10,U
+0842 fd01 20 76 BRA OUT4H
+0843 fd03 8e fe d2 PRTA LDX #MSG16 POINT TO MSG "A="
+0844 fd06 17 00 b4 LBSR PDATA PRINT MSG
+0845 fd09 a6 41 LDA 1,U
+0846 fd0b 20 74 BRA OUT2H OUTPUT HEX BYTE AS ASCII
+0847 fd0d 8e fe d7 PRTB LDX #MSG17 POINT TO MSG "B="
+0848 fd10 17 00 aa LBSR PDATA PRINT MSG
+0849 fd13 a6 42 LDA 2,U
+0850 fd15 20 6a BRA OUT2H OUTPUT HEX BYTE AS ASCII
+0851 fd17 8e fe dc PRTCC LDX #MSG18 POINT TO MSG "CC:"
+0852 fd1a 17 00 a0 LBSR PDATA PRINT MSG
+0853 fd1d a6 c4 LDA ,U
+0854 fd1f 8e fe e3 LDX #MSG19 POINT TO MSG "EFHINZVC"
+0855 fd22 20 73 BRA BIASCI OUTPUT IN BINARY/ASCII FORMAT
+0856 *
+0857 * THE FOLLOWING ROUTINE LOOPS WAITING FOR THE
+0858 * OPERATOR TO INPUT TWO VALID HEX ADDRESSES.
+0859 * THE FIRST ADDRESS INPUT IS RETURNED IN "IY".
+0860 * THE SECOND IS RETURNED IN "IX". THE "V" BIT
+0861 * IN THE C-CODE REG. IS SET IF AN INVALID HEX
+0862 * ADDRESS IS INPUT.
+0863 *
+0864 fd24 8d 09 IN2ADR BSR IN1ADR GET FIRST ADDRESS
+0865 fd26 29 4e BVS NOTHEX EXIT IF NOT VALID HEX
+0866 fd28 1f 12 TFR X,Y SAVE FIRST ADDR. IN "IY"
+0867 fd2a 86 2d LDA #'-
+0868 fd2c 17 00 bf LBSR OUTCH PRINT " - "
+0869 *
+0870 * THE FOLLOWING ROUTINE LOOPS WAITING FOR THE
+0871 * OPERATOR TO INPUT ONE VALID HEX ADDRESS. THE
+0872 * ADDRESS IS RETURNED IN THE "X" REGISTER.
+0873 *
+0874 fd2f 8d 0f IN1ADR BSR BYTE INPUT BYTE (2 HEX CHAR)
+0875 fd31 29 43 BVS NOTHEX EXIT IF NOT VALID HEX
+0876 fd33 1f 01 TFR D,X
+0877 fd35 8d 09 BSR BYTE INPUT BYTE (2 HEX CHAR)
+0878 fd37 29 3d BVS NOTHEX
+0879 fd39 34 10 PSHS X
+0880 fd3b a7 61 STA 1,S
+0881 fd3d 35 10 PULS X
+0882 fd3f 39 RTS ;
+0883 *
+0884 ***** INPUT BYTE (2 HEX CHAR.) *****
+0885 *
+0886 fd40 8d 11 BYTE BSR INHEX GET HEX LEFT
+0887 fd42 29 32 BVS NOTHEX EXIT IF NOT VALID HEX
+0888 fd44 48 ASLA ;
+0889 fd45 48 ASLA ;
+0890 fd46 48 ASLA ; SHIFT INTO LEFT NIBBLE
+0891 fd47 48 ASLA ;
+0892 fd48 1f 89 TFR A,B PUT HEXL IN "B"
+0893 fd4a 8d 07 BSR INHEX GET HEX RIGHT
+0894 fd4c 29 28 BVS NOTHEX EXIT IF NOT VALID HEX
+0895 fd4e 34 04 PSHS B PUSH HEXL ON STACK
+0896 fd50 ab e0 ADDA ,S+ ADD HEXL TO HEXR AND ADJ. STK
+0897 fd52 39 RTS RETURN WITH HEX L&R IN "A"
+0898 *
+0899 *
+0900 fd53 8d 6f INHEX BSR ECHON INPUT ASCII CHAR.
+0901 fd55 81 30 CMPA #'0 IS IT > OR = "0" ?
+0902 fd57 25 1d BCS NOTHEX IF LESS IT AIN'T HEX
+0903 fd59 81 39 CMPA #'9 IS IT < OR = "9" ?
+0904 fd5b 22 03 BHI INHEXA IF > MAYBE IT'S ALPHA
+0905 fd5d 80 30 SUBA #$30 ASCII ADJ. NUMERIC
+0906 fd5f 39 RTS ;
+0907 *
+0908 *
+0909 fd60 81 41 INHEXA CMPA #'A IS IT > OR = "A"
+0910 fd62 25 12 BCS NOTHEX IF LESS IT AIN'T HEX
+0911 fd64 81 46 CMPA #'F IS IT < OR = "F" ?
+0912 fd66 22 03 BHI INHEXL IF > IT AIN'T HEX
+0913 fd68 80 37 SUBA #$37 ASCII ADJ. ALPHA
+0914 fd6a 39 RTS ;
+0915 *
+0916 fd6b 81 61 INHEXL CMPA #'a IS IT > OR = "a"
+0917 fd6d 25 07 BCS NOTHEX IF LESS IT AIN'T HEX
+0918 fd6f 81 66 CMPA #'f IS IT < "f"
+0919 fd71 22 03 BHI NOTHEX IF > IT AIN'T HEX
+0920 fd73 80 57 SUBA #$57 ADJUST TO LOWER CASE
+0921 fd75 39 RTS ;
+0922 *
+0923 *
+0924 fd76 1a 02 NOTHEX ORCC #2 SET (V) FLAG IN C-CODES REGISTER
+0925 fd78 39 RTS ;
+0926 *
+0927 *
+0928 fd79 34 10 OUT4H PSHS X PUSH X-REG. ON THE STACK
+0929 fd7b 35 02 PULS A POP MS BYTE OF X-REG INTO A-ACC.
+0930 fd7d 8d 02 BSR OUTHL OUTPUT HEX LEFT
+0931 fd7f 35 02 PULS A POP LS BYTE OF X-REG INTO A-ACC.
+0932 fd81 OUTHL EQU *
+0933 fd81 34 02 OUT2H PSHS A SAVE IT BACK ON STACK
+0934 fd83 44 LSRA CONVERT UPPER HEX NIBBLE TO ASCII
+0935 fd84 44 LSRA ;
+0936 fd85 44 LSRA ;
+0937 fd86 44 LSRA ;
+0938 fd87 8d 04 BSR XASCII PRINT HEX NIBBLE AS ASCII
+0939 fd89 35 02 OUTHR PULS A CONVERT LOWER HEX NIBBLE TO ASCII
+0940 fd8b 84 0f ANDA #$0F STRIP LEFT NIBBLE
+0941 fd8d 8b 30 XASCII ADDA #$30 ASCII ADJ
+0942 fd8f 81 39 CMPA #$39 IS IT < OR = "9" ?
+0943 fd91 2f 02 BLE OUTC IF LESS, OUTPUT IT
+0944 fd93 8b 07 ADDA #7 IF > MAKE ASCII LETTER
+0945 fd95 20 57 OUTC BRA OUTCH OUTPUT CHAR
+0946 *
+0947 * BINARY / ASCII --- THIS ROUTINE
+0948 * OUTPUTS A BYTE IN ENHANCED
+0949 * BINARY FORMAT. THE ENHANCEMENT
+0950 * IS DONE BY SUBSTITUTING ASCII
+0951 * LETTERS FOR THE ONES IN THE BYTE.
+0952 * THE ASCII ENHANCEMENT LETTERS
+0953 * ARE OBTAINED FROM THE STRING
+0954 * POINTED TO BY THE INDEX REG. "X".
+0955 *
+0956 fd97 34 02 BIASCI PSHS A SAVE "A" ON STACK
+0957 fd99 c6 08 LDB #8 PRESET LOOP# TO BITS PER BYTE
+0958 fd9b a6 80 OUTBA LDA ,X+ GET LETTER FROM STRING
+0959 fd9d 68 e4 ASL ,S TEST BYTE FOR "1" IN B7
+0960 fd9f 25 02 BCS PRTBA IF ONE PRINT LETTER
+0961 fda1 86 2d LDA #'- IF ZERO PRINT "-"
+0962 fda3 8d 49 PRTBA BSR OUTCH PRINT IT
+0963 fda5 8d 45 BSR OUT1S PRINT SPACE
+0964 fda7 5a DECB SUB 1 FROM #BITS YET TO PRINT
+0965 fda8 26 f1 BNE OUTBA
+0966 fdaa 35 02 PULS A
+0967 fdac 39 RTS
+0968 *
+0969 * PRINT STRING PRECEEDED BY A CR & LF.
+0970 *
+0971 fdad 8d 02 PSTRNG BSR PCRLF PRINT CR/LF
+0972 fdaf 20 0c BRA PDATA PRINT STRING POINTED TO BY IX
+0973 *
+0974 * PCRLF
+0975 *
+0976 fdb1 34 10 PCRLF PSHS X SAVE IX
+0977 fdb3 8e fe 75 LDX #MSG2+1 POINT TO MSG CR/LF + 3 NULS
+0978 fdb6 8d 05 BSR PDATA PRINT MSG
+0979 fdb8 35 10 PULS X RESTORE IX
+0980 fdba 39 RTS ;
+0981 fdbb 8d 31 PRINT BSR OUTCH
+0982 *
+0983 * PDATA
+0984 *
+0985 fdbd a6 80 PDATA LDA ,X+ GET 1st CHAR. TO PRINT
+0986 fdbf 81 04 CMPA #4 IS IT EOT?
+0987 fdc1 26 f8 BNE PRINT IF NOT EOT PRINT IT
+0988 fdc3 39 RTS ;
+0989 *
+0990 *
+0991 fdc4 7d df e2 ECHON TST ECHO IS ECHO REQUIRED ?
+0992 fdc7 27 06 BEQ INCH ECHO NOT REQ. IF CLEAR
+0993 *
+0994 * INCHE
+0995 *
+0996 * ---GETS CHARACTER FROM TERMINAL AND
+0997 * ECHOS SAME. THE CHARACTER IS RETURNED
+0998 * IN THE "A" ACCUMULATOR WITH THE PARITY
+0999 * BIT MASKED OFF. ALL OTHER REGISTERS
+1000 * ARE PRESERVED.
+1001 *
+1002 fdc9 8d 04 INCHE BSR INCH GET CHAR FROM TERMINAL
+1003 fdcb 84 7f ANDA #$7F STRIP PARITY FROM CHAR.
+1004 fdcd 20 1f BRA OUTCH ECHO CHAR TO TERMINAL
+1005 *
+1006 * INCH
+1007 *
+1008 * GET CHARACTER FROM TERMINAL. RETURN
+1009 * CHARACTER IN "A" ACCUMULATOR AND PRESERVE
+1010 * ALL OTHER REGISTERS. THE INPUT CHARACTER
+1011 * IS 8 BITS AND IS NOT ECHOED.
+1012 *
+1013 *
+1014 fdcf 34 10 INCH PSHS X SAVE IX
+1015 fdd1 be df e0 LDX CPORT POINT TO TERMINAL PORT
+1016 fdd4 a6 84 GETSTA LDA ,X FETCH PORT STATUS
+1017 fdd6 85 01 BITA #1 TEST READY BIT, RDRF ?
+1018 fdd8 27 fa BEQ GETSTA IF NOT RDY, THEN TRY AGAIN
+1019 fdda a6 01 LDA 1,X FETCH CHAR
+1020 fddc 35 10 PULS X RESTORE IX
+1021 fdde 39 RTS ;
+1022 *
+1023 * INCHEK
+1024 *
+1025 * CHECK FOR A CHARACTER AVAILABLE FROM
+1026 * THE TERMINAL. THE SERIAL PORT IS CHECKED
+1027 * FOR READ READY. ALL REGISTERS ARE
+1028 * PRESERVED, AND THE "Z" BIT WILL BE
+1029 * CLEAR IF A CHARACTER CAN BE READ.
+1030 *
+1031 *
+1032 fddf 34 02 INCHEK PSHS A SAVE A ACCUM.
+1033 fde1 a6 9f df e0 LDA [CPORT] FETCH PORT STATUS
+1034 fde5 85 01 BITA #1 TEST READY BIT, RDRF ?
+1035 fde7 35 02 PULS A RESTORE A ACCUM.
+1036 fde9 39 RTS ;
+1037 *
+1038 fdea 8d 00 OUT2S BSR OUT1S OUTPUT 2 SPACES
+1039 fdec 86 20 OUT1S LDA #$20 OUTPUT 1 SPACE
+1040 *
+1041 *
+1042 * OUTCH
+1043 *
+1044 * OUTPUT CHARACTER TO TERMINAL.
+1045 * THE CHAR. TO BE OUTPUT IS
+1046 * PASSED IN THE A REGISTER.
+1047 * ALL REGISTERS ARE PRESERVED.
+1048 *
+1049 fdee 34 12 OUTCH PSHS A,X SAVE A ACCUM AND IX
+1050 fdf0 be df e0 LDX CPORT GET ADDR. OF TERMINAL
+1051 fdf3 a6 84 FETSTA LDA ,X FETCH PORT STATUS
+1052 fdf5 85 02 BITA #2 TEST TDRE, OK TO XMIT ?
+1053 fdf7 27 fa BEQ FETSTA IF NOT LOOP UNTIL RDY
+1054 fdf9 35 02 PULS A GET CHAR. FOR XMIT
+1055 fdfb a7 01 STA 1,X XMIT CHAR.
+1056 fdfd 35 10 PULS X RESTORE IX
+1057 fdff 39 RTS ;
+1058 *
+1059 *
+1060 fe00 be df e0 ACINIZ LDX CPORT POINT TO CONTROL PORT ADDRESS
+1061 fe03 86 03 LDA #3 RESET ACIA PORT CODE
+1062 fe05 a7 84 STA ,X STORE IN CONTROL REGISTER
+1063 fe07 86 11 LDA #$11 SET 8 DATA, 2 STOP AN 0 PARITY
+1064 fe09 a7 84 STA ,X STORE IN CONTROL REGISTER
+1065 fe0b 6d 01 TST 1,X ANYTHING IN DATA REGISTER?
+1066 fe0d 86 ff LDA #$FF TURN ON ECHO FLAG
+1067 fe0f b7 df e2 STA ECHO
+1068 fe12 39 RTS
+1069 *
+1070 *
+1071 * MONITOR KEYBOARD COMMAND JUMP TABLE
+1072 *
+1073 *
+1074 fe13 JMPTAB EQU *
+1075 fe13 01 FCB 1 " ^A " $F91D
+1076 fe14 f9 23 FDB ALTRA
+1077 fe16 02 FCB 2 " ^B " $F90F
+1078 fe17 f9 15 FDB ALTRB
+1079 fe19 03 FCB 3 " ^C " $F92B
+1080 fe1a f9 31 FDB ALTRCC
+1081 fe1c 04 FCB 4 " ^D " $F901
+1082 fe1d f9 07 FDB ALTRDP
+1083 fe1f 10 FCB $10 " ^P " $F8C9
+1084 fe20 f8 cf FDB ALTRPC
+1085 fe22 15 FCB $15 " ^U " $F8D7
+1086 fe23 f8 dd FDB ALTRU
+1087 fe25 18 FCB $18 " ^X " $F8F3
+1088 fe26 f8 f9 FDB ALTRX
+1089 fe28 19 FCB $19 " ^Y " $F8E5
+1090 fe29 f8 eb FDB ALTRY
+1091 *
+1092 fe2b 42 FCC 'B'
+1093 fe2c fa 7b FDB BRKPNT *$FA78
+1094 fe2e 44 FCC 'D'
+1095 fe2f fa f4 FDB DBOOT *$FAF1
+1096 fe31 45 FCC 'E'
+1097 fe32 f9 96 FDB MEMDUMP *$F990
+1098 fe34 47 FCC 'G'
+1099 fe35 f8 a5 FDB GO *$F89F
+1100 fe37 4c FCC 'L'
+1101 fe38 fc 0c FDB LOAD *$FC09
+1102 fe3a 4d FCC 'M'
+1103 fe3b f9 41 FDB MEMCHG *$F93B
+1104 fe3d 50 FCC 'P'
+1105 fe3e fc 67 FDB PUNCH *$FC64
+1106 fe40 51 FCC 'Q'
+1107 fe41 f9 f2 FDB MEMTST *$F9EF
+1108 fe43 52 FCC 'R'
+1109 fe44 f8 a8 FDB REGSTR *$F8A2
+1110 fe46 53 FCC 'S'
+1111 fe47 f9 8a FDB DISSTK *$F984
+1112 fe49 55 FCC 'U'
+1113 fe4a fb b3 FDB MINBOOT *$FBB0
+1114 fe4c 58 FCC 'X'
+1115 fe4d fa a7 FDB XBKPNT *$FAA4
+1116 *
+1117 fe4f TABEND EQU *
+1118 *
+1119 * ** 6809 VECTOR ADDRESSES **
+1120 *
+1121 * FOLLOWING ARE THE ADDRESSES OF THE VECTOR ROUTINES
+1122 * FOR THE 6809 PROCESSOR. DURING INITIALIZATION THEY
+1123 * ARE RELOCATED TO RAM FROM $DFC0 TO $DFCF. THEY ARE
+1124 * RELOCATED TO RAM SO THAT THE USER MAY REVECTOR TO
+1125 * HIS OWN ROUTINES IF HE SO DESIRES.
+1126 *
+1127 *
+1128 fe4f fa b3 RAMVEC FDB SWIE USER-V
+1129 fe51 f8 a7 FDB RTI SWI3-V
+1130 fe53 f8 a7 FDB RTI SWI2-V
+1131 fe55 f8 a7 FDB RTI FIRQ-V
+1132 fe57 f8 a7 FDB RTI IRQ-V
+1133 fe59 fa b3 FDB SWIE SWI-V
+1134 fe5b ff ff FDB $FFFF SVC-VO
+1135 fe5d ff ff FDB $FFFF SVC-VL
+1136 *
+1137 * PRINTABLE MESSAGE STRINGS
+1138 *
+1139 fe5f 00 00 00 0d 0a 00 MSG1 FCB $0,$0,$0,$D,$A,$0,$0,$0 * 0, CR/LF, 0
+ 00 00
+1140 fe67 53 2d 42 55 47 20 FCC 'S-BUG 1.8 - '
+ 31 2e 38 20 2d 20
+1141 fe73 04 FCB 4
+1142 fe74 4b 0d 0a 00 00 00 MSG2 FCB 'K,$D,$A,$0,$0,$0,4 K, * CR/LF + 3 NULS
+ 04
+1143 fe7b 3e MSG3 FCC '>'
+1144 fe7c 04 FCB 4
+1145 fe7d 57 48 41 54 3f MSG4 FCC 'WHAT?'
+1146 fe82 04 FCB 4
+1147 fe83 20 2d 20 MSG5 FCC ' - '
+1148 fe86 04 FCB 4'
+1149 fe87 2c 20 50 41 53 53 MSG6 FCC ', PASS '
+ 20
+1150 fe8e 04 FCB 4
+1151 fe8f 2c 20 42 49 54 53 MSG7 FCC ', BITS IN ERROR: '
+ 20 49 4e 20 45 52
+ 52 4f 52 3a 20
+1152 fea0 04 FCB 4
+1153 fea1 20 3d 3e 20 MSG8 FCC ' => '
+1154 fea5 04 FCB 4
+1155 fea6 37 36 35 34 33 32 MSG9 FCC '76543210'
+ 31 30
+1156 feae 20 20 53 50 3d MSG10 FCC ' SP='
+1157 feb3 04 FCB 4
+1158 feb4 20 20 50 43 3d MSG11 FCC ' PC='
+1159 feb9 04 FCB 4
+1160 feba 20 20 55 53 3d MSG12 FCC ' US='
+1161 febf 04 FCB 4
+1162 fec0 20 20 49 59 3d MSG13 FCC ' IY='
+1163 fec5 04 FCB 4
+1164 fec6 20 20 49 58 3d MSG14 FCC ' IX='
+1165 fecb 04 FCB 4
+1166 fecc 20 20 44 50 3d MSG15 FCC ' DP='
+1167 fed1 04 FCB 4
+1168 fed2 20 20 41 3d MSG16 FCC ' A='
+1169 fed6 04 FCB 4
+1170 fed7 20 20 42 3d MSG17 FCC ' B='
+1171 fedb 04 FCB 4
+1172 fedc 20 20 43 43 3a 20 MSG18 FCC ' CC: '
+1173 fee2 04 FCB 4
+1174 fee3 45 46 48 49 4e 5a MSG19 FCC 'EFHINZVC'
+ 56 43
+1175 feeb 53 31 MSG20 FCC 'S1'
+1176 feed 04 FCB 4
+1177 *
+1178 * MESSAGE EXPANSION AREA
+1179 *
+1180 feee ff ff ff ff ff ff FCB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
+ ff ff
+1181 fef6 ff ff ff ff ff ff FCB $FF,$FF,$FF,$FF,$FF,$FF,$FF
+ ff
+1182 *
+1183 * POWER UP/ RESET/ NMI ENTRY POINT
+1184 *
+1185 ff00 ORG $FF00
+1186 *
+1187 *
+1188 ff00 8e ff f0 START LDX #IC11 POINT TO DAT RAM IC11
+1189 ff03 86 0f LDA #$F GET COMPLIMENT OF ZERO
+1190 *
+1191 *
+1192 * INITIALIZE DAT RAM --- LOADS $F-$0 IN LOCATIONS $0-$F
+1193 * OF DAT RAM, THUS STORING COMPLEMENT OF MSB OF ADDRESS
+1194 * IN THE DAT RAM. THE COMPLEMENT IS REQUIRED BECAUSE THE
+1195 * OUTPUT OF IC11, A 74S189, IS THE INVERSE OF THE DATA
+1196 * STORED IN IT.
+1197 *
+1198 *
+1199 ff05 a7 80 DATLP STA ,X+ STORE & POINT TO NEXT RAM LOCATION
+1200 ff07 4a DECA GET COMP. VALUE FOR NEXT LOCATION
+1201 ff08 26 fb BNE DATLP ALL 16 LOCATIONS INITIALIZED ?
+1202 *
+1203 * NOTE: IX NOW CONTAINS $0000, DAT RAM IS NO LONGER
+1204 * ADDRESSED, AND LOGICAL ADDRESSES NOW EQUAL
+1205 * PHYSICAL ADDRESSES.
+1206 *
+1207 ff0a 86 f0 LDA #$F0
+1208 ff0c a7 84 STA ,X STORE $F0 AT $FFFF
+1209 ff0e 8e d0 a0 LDX #$D0A0 ASSUME RAM TO BE AT $D000-$DFFF
+1210 ff11 10 8e 55 aa LDY #TSTPAT LOAD TEST DATA PATTERN INTO "Y"
+1211 ff15 ee 84 TSTRAM LDU ,X SAVE DATA FROM TEST LOCATION
+1212 ff17 10 af 84 STY ,X STORE TEST PATTERN AT $D0A0
+1213 ff1a 10 ac 84 CMPY ,X IS THERE RAM AT THIS LOCATION ?
+1214 ff1d 27 0b BEQ CNVADR IF MATCH THERE'S RAM, SO SKIP
+1215 ff1f 30 89 f0 00 LEAX -$1000,X ELSE POINT 4K LOWER
+1216 ff23 8c f0 a0 CMPX #$F0A0 DECREMENTED PAST ZER0 YET ?
+1217 ff26 26 ed BNE TSTRAM IF NOT CONTINUE TESTING FOR RAM
+1218 ff28 20 d6 BRA START ELSE START ALL OVER AGAIN
+1219 *
+1220 *
+1221 * THE FOLLOWING CODE STORES THE COMPLEMENT OF
+1222 * THE MS CHARACTER OF THE FOUR CHARACTER HEX
+1223 * ADDRESS OF THE FIRST 4K BLOCK OF RAM LOCATED
+1224 * BY THE ROUTINE "TSTRAM" INTO THE DAT RAM. IT
+1225 * IS STORED IN RAM IN THE LOCATION THAT IS
+1226 * ADDRESSED WHEN THE PROCESSOR ADDRESS IS $D---,
+1227 * THUS IF THE FIRST 4K BLOCK OF RAM IS FOUND
+1228 * WHEN TESTING LOCATION $70A0, MEANING THERE
+1229 * IS NO RAM PHYSICALLY ADDRESSED IN THE RANGE
+1230 * $8000-$DFFF, THEN THE COMPLEMENT OF THE
+1231 * "7" IN THE $70A0 WILL BE STORED IN
+1232 * THE DAT RAM. THUS WHEN THE PROCESSOR OUTPUTS
+1233 * AN ADDRESS OF $D---, THE DAT RAM WILL RESPOND
+1234 * BY RECOMPLEMENTING THE "7" AND OUTPUTTING THE
+1235 * 7 ONTO THE A12-A15 ADDRESS LINES. THUS THE
+1236 * RAM THAT IS PHYSICALLY ADDRESSED AT $7---
+1237 * WILL RESPOND AND APPEAR TO THE 6809 THAT IT
+1238 * IS AT $D--- SINCE THAT IS THE ADDRESS THE
+1239 * 6809 WILL BE OUTPUTING WHEN THAT 4K BLOCK
+1240 * OF RAM RESPONDS.
+1241 *
+1242 *
+1243 ff2a ef 84 CNVADR STU ,X RESTORE DATA AT TEST LOCATION
+1244 ff2c 1f 10 TFR X,D PUT ADDR. OF PRESENT 4K BLOCK IN D
+1245 ff2e 43 COMA COMPLEMENT MSB OF THAT ADDRESS
+1246 ff2f 44 LSRA PUT MS 4 BITS OF ADDRESS IN
+1247 ff30 44 LSRA LOCATION D0-D3 TO ALLOW STORING
+1248 ff31 44 LSRA IT IN THE DYNAMIC ADDRESS
+1249 ff32 44 LSRA TRANSLATION RAM.
+1250 ff33 b7 ff fd STA $FFFD STORE XLATION FACTOR IN DAT "D"
+1251 *
+1252 ff36 10 ce df c0 LDS #STACK INITIALIZE STACK POINTER
+1253 *
+1254 *
+1255 * THE FOLLOWING CHECKS TO FIND THE REAL PHYSICAL ADDRESSES
+1256 * OF ALL 4K BLKS OF RAM IN THE SYSTEM. WHEN EACH 4K BLK
+1257 * OF RAM IS LOCATED, THE COMPLEMENT OF IT'S REAL ADDRESS
+1258 * IS THEN STORED IN A "LOGICAL" TO "REAL" ADDRESS XLATION
+1259 * TABLE THAT IS BUILT FROM $DFD0 TO $DFDF. FOR EXAMPLE IF
+1260 * THE SYSTEM HAS RAM THAT IS PHYSICALLY LOCATED (WIRED TO
+1261 * RESPOND) AT THE HEX LOCATIONS $0--- THRU $F---....
+1262 *
+1263 * 0 1 2 3 4 5 6 7 8 9 A B C D E F
+1264 * 4K 4K 4K 4K 4K 4K 4K 4K -- 4K 4K 4K 4K -- -- --
+1265 *
+1266 * ....FOR A TOTAL OF 48K OF RAM, THEN THE TRANSLATION TABLE
+1267 * CREATED FROM $DFD0 TO $DFDF WILL CONSIST OF THE FOLLOWING....
+1268 *
+1269 * 0 1 2 3 4 5 6 7 8 9 A B C D E F
+1270 * 0F 0E 0D 0C 0B 0A 09 08 06 05 00 00 04 03 F1 F0
+1271 *
+1272 *
+1273 * HERE WE SEE THE LOGICAL ADDRESSES OF MEMORY FROM $0000-$7FFF
+1274 * HAVE NOT BEEN SELECTED FOR RELOCATION SO THAT THEIR PHYSICAL
+1275 * ADDRESS WILL = THEIR LOGICAL ADDRESS; HOWEVER, THE 4K BLOCK
+1276 * PHYSICALLY AT $9000 WILL HAVE ITS ADDRESS TRANSLATED SO THAT
+1277 * IT WILL LOGICALLY RESPOND AT $8000. LIKEWISE $A,$B, AND $C000
+1278 * WILL BE TRANSLATED TO RESPOND TO $9000,$C000, AND $D000
+1279 * RESPECTIVELY. THE USER SYSTEM WILL LOGICALLY APPEAR TO HAVE
+1280 * MEMORY ADDRESSED AS FOLLOWS....
+1281 *
+1282 * 0 1 2 3 4 5 6 7 8 9 A B C D E F
+1283 * 4K 4K 4K 4K 4K 4K 4K 4K 4K 4K -- -- 4K 4K -- --
+1284 *
+1285 *
+1286 ff3a 10 8e df d0 LDY #LRARAM POINT TO LOGICAL/REAL ADDR. TABLE
+1287 ff3e a7 2d STA 13,Y STORE $D--- XLATION FACTOR AT $DFDD
+1288 ff40 6f 2e CLR 14,Y CLEAR $DFDE
+1289 ff42 86 f0 LDA #$F0 DESTINED FOR IC8 AN MEM EXPANSION ?
+1290 ff44 a7 2f STA 15,Y STORE AT $DFDF
+1291 ff46 86 0c LDA #$0C PRESET NUMBER OF BYTES TO CLEAR
+1292 ff48 6f a6 CLRLRT CLR A,Y CLEAR $DFDC THRU $DFD0
+1293 ff4a 4a DECA SUB. 1 FROM BYTES LEFT TO CLEAR
+1294 ff4b 2a fb BPL CLRLRT CONTINUE IF NOT DONE CLEARING
+1295 ff4d 30 89 f0 00 FNDRAM LEAX -$1000,X POINT TO NEXT LOWER 4K OF RAM
+1296 ff51 8c f0 a0 CMPX #$F0A0 TEST FOR DECREMENT PAST ZERO
+1297 ff54 27 22 BEQ FINTAB SKIP IF FINISHED
+1298 ff56 ee 84 LDU ,X SAVE DATA AT CURRENT TEST LOCATION
+1299 ff58 10 8e 55 aa LDY #TSTPAT LOAD TEST DATA PATTERN INTO Y REG.
+1300 ff5c 10 af 84 STY ,X STORE TEST PATT. INTO RAM TEST LOC.
+1301 ff5f 10 ac 84 CMPY ,X VERIFY RAM AT TEST LOCATION
+1302 ff62 26 e9 BNE FNDRAM IF NO RAM GO LOOK 4K LOWER
+1303 ff64 ef 84 STU ,X ELSE RESTORE DATA TO TEST LOCATION
+1304 ff66 10 8e df d0 LDY #LRARAM POINT TO LOGICAL/REAL ADDR. TABLE
+1305 ff6a 1f 10 TFR X,D PUT ADDR. OF PRESENT 4K BLOCK IN D
+1306 ff6c 44 LSRA PUT MS 4 BITS OF ADDR. IN LOC. D0-D3
+1307 ff6d 44 LSRA TO ALLOW STORING IT IN THE DAT RAM.
+1308 ff6e 44 LSRA
+1309 ff6f 44 LSRA
+1310 ff70 1f 89 TFR A,B SAVE OFFSET INTO LRARAM TABLE
+1311 ff72 88 0f EORA #$0F INVERT MSB OF ADDR. OF CURRENT 4K BLK
+1312 ff74 a7 a5 STA B,Y SAVE TRANSLATION FACTOR IN LRARAM TABLE
+1313 ff76 20 d5 BRA FNDRAM GO TRANSLATE ADDR. OF NEXT 4K BLK
+1314 ff78 86 f1 FINTAB LDA #$F1 DESTINED FOR IC8 AND MEM EXPANSION ?
+1315 ff7a 10 8e df d0 LDY #LRARAM POINT TO LRARAM TABLE
+1316 ff7e a7 2e STA 14,Y STORE $F1 AT $DFCE
+1317 *
+1318 * THE FOLLOWING CHECKS TO SEE IF THERE IS A 4K BLK OF
+1319 * RAM LOCATED AT $C000-$CFFF. IF NONE THERE IT LOCATES
+1320 * THE NEXT LOWER 4K BLK AN XLATES ITS ADDR SO IT
+1321 * LOGICALLY RESPONDS TO THE ADDRESS $C---.
+1322 *
+1323 *
+1324 ff80 86 0c LDA #$0C PRESET NUMBER HEX "C"
+1325 ff82 e6 a6 FINDC LDB A,Y GET ENTRY FROM LRARAM TABLE
+1326 ff84 26 05 BNE FOUNDC BRANCH IF RAM THIS PHYSICAL ADDR.
+1327 ff86 4a DECA ELSE POINT 4K LOWER
+1328 ff87 2a f9 BPL FINDC GO TRY AGAIN
+1329 ff89 20 14 BRA XFERTF
+1330 ff8b 6f a6 FOUNDC CLR A,Y CLR XLATION FACTOR OF 4K BLOCK FOUND
+1331 ff8d e7 2c STB $C,Y GIVE IT XLATION FACTOR MOVING IT TO $C---
+1332 *
+1333 * THE FOLLOWING CODE ADJUSTS THE TRANSLATION
+1334 * FACTORS SUCH THAT ALL REMAINING RAM WILL
+1335 * RESPOND TO A CONTIGUOUS BLOCK OF LOGICAL
+1336 * ADDRESSES FROM $0000 AND UP....
+1337 *
+1338 ff8f 4f CLRA START AT ZERO
+1339 ff90 1f 21 TFR Y,X START POINTER "X" START OF "LRARAM" TABLE.
+1340 ff92 e6 a6 COMPRS LDB A,Y GET ENTRY FROM "LRARAM" TABLE
+1341 ff94 27 04 BEQ PNTNXT IF IT'S ZER0 SKIP
+1342 ff96 6f a6 CLR A,Y ELSE ERASE FROM TABLE
+1343 ff98 e7 80 STB ,X+ AND ENTER ABOVE LAST ENTRY- BUMP
+1344 ff9a 4c PNTNXT INCA GET OFFSET TO NEXT ENTRY
+1345 ff9b 81 0c CMPA #$0C LAST ENTRY YET ?
+1346 ff9d 2d f3 BLT COMPRS
+1347 *
+1348 * THE FOLLOWING CODE TRANSFER THE TRANSLATION
+1349 * FACTORS FROM THE LRARAM TABLE TO IC11 ON
+1350 * THE MP-09 CPU CARD.
+1351 *
+1352 ff9f 8e ff f0 XFERTF LDX #IC11 POINT TO DAT RAM IC11
+1353 ffa2 c6 10 LDB #$10 GET NO. OF BYTES TO MOVE
+1354 ffa4 a6 a0 FETCH LDA ,Y+ GET BYTE AND POINT TO NEXT
+1355 ffa6 a7 80 STA ,X+ POKE XLATION FACTOR IN IC11
+1356 ffa8 5a DECB SUB 1 FROM BYTES TO MOVE
+1357 ffa9 26 f9 BNE FETCH CONTINUE UNTIL 16 MOVED
+1358 ffab 53 COMB SET "B" NON-ZERO
+1359 ffac f7 df e2 STB ECHO TURN ON ECHO FLAG
+1360 ffaf 16 f8 62 LBRA MONITOR INITIALIZATION IS COMPLETE
+1361 *
+1362 *
+1363 ffb2 6e 9f df c0 V1 JMP [STACK]
+1364 ffb6 6e 9f df c4 V2 JMP [SWI2]
+1365 ffba 6e 9f df c6 V3 JMP [FIRQ]
+1366 ffbe 6e 9f df c8 V4 JMP [IRQ]
+1367 ffc2 6e 9f df ca V5 JMP [SWI]
+1368 *
+1369 * SWI3 ENTRY POINT
+1370 *
+1371 ffc6 1f 43 SWI3E TFR S,U
+1372 ffc8 ae 4a LDX 10,U *$FFC8
+1373 ffca e6 80 LDB ,X+
+1374 ffcc af 4a STX 10,U
+1375 ffce 4f CLRA
+1376 ffcf 58 ASLB
+1377 ffd0 49 ROLA
+1378 ffd1 be df cc LDX SVCVO
+1379 ffd4 8c ff ff CMPX #$FFFF
+1380 ffd7 27 0f BEQ SWI3Z
+1381 ffd9 30 8b LEAX D,X
+1382 ffdb bc df ce CMPX SVCVL
+1383 ffde 22 08 BHI SWI3Z
+1384 ffe0 34 10 PSHS X
+1385 ffe2 ec c4 LDD ,U
+1386 ffe4 ae 44 LDX 4,U
+1387 ffe6 6e f1 JMP [,S++]
+1388 ffe8 37 1f SWI3Z PULU A,B,X,CC,DP
+1389 ffea ee 42 LDU 2,U
+1390 ffec 6e 9f df c2 JMP [SWI3]
+1391 *
+1392 * 6809 VECTORS
+1393 *
+1394 fff0 ff b2 FDB V1 USER-V
+1395 fff2 ff c6 FDB SWI3E SWI3-V
+1396 fff4 ff b6 FDB V2 SWI2-V
+1397 fff6 ff ba FDB V3 FIRQ-V
+1398 fff8 ff be FDB V4 IRQ-V
+1399 fffa ff c2 FDB V5 SWI-V
+1400 fffc ff b2 FDB V1 NMI-V
+1401 fffe ff 00 FDB START RESTART-V
+1402 END START
Index: tags/V10/sw/asref.man
===================================================================
--- tags/V10/sw/asref.man (nonexistent)
+++ tags/V10/sw/asref.man (revision 3)
@@ -0,0 +1,2245 @@
+
+
+
+
+
+
+
+
+
+ MOTOROLA
+
+ FREEWARE
+
+ 8-BIT CROSS ASSEMBLERS
+
+ USER'S MANUAL
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ EDITED BY
+
+ KEVIN ANDERSON
+
+ FIELD APPLICATIONS ENGINEER
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ TABLE OF CONTENTS
+
+CHAPTER 1......................................................... 1
+
+ 1.1 INTRODUCTION .......................................... 1
+ 1.2 ASSEMBLY LANGUAGE ..................................... 1
+ 1.3 OPERATING ENVIRONMENT ................................. 2
+ 1.4 ASSEMBLER PROCESSING .................................. 2
+
+CHAPTER 2 ........................................................ 3
+
+ 2.1 INTRODUCTION .......................................... 3
+ 2.2 SOURCE STATEMENT FORMAT ............................... 3
+ 2.2.1 Label Field .................................... 3
+ 2.2.2 Operation Field ................................ 4
+ 2.2.3 Operand Field .................................. 4
+ 2.2.3.1 M6800/6801 Operand Syntax ................ 5
+ 2.2.3.2 M6800/M68HC04 Operand Syntax ............. 5
+ 2.2.3.3 M6805/M68HC05 Operand Syntax ............. 5
+ 2.2.3.4 M6809 Operand Syntax ..................... 5
+ 2.2.3.5 M68HC11 Operand Syntax ................... 6
+ 2.2.3.6 Expressions .............................. 6
+ 2.2.3.7 Operators ................................ 7
+ 2.2.3.8 Symbols .................................. 7
+ 2.2.3.9 Constants ................................ 7
+ 2.2.4 Comment Field .................................. 8
+ 2.3 ASSEMBLER OUTPUT ...................................... 9
+
+CHAPTER 3 - RUNNING THE ASSEMBLERS ............................... 10
+
+ 3.1 ASSEMBLER INVOCATION .................................. 10
+ 3.2 ERROR MESSAGES ........................................ 11
+
+CHAPTER 4 - ASSEMBLER DIRECTIVES ................................. 12
+
+ 4.1 INTRODUCTION .......................................... 12
+ 4.2 BSZ - BLOCK STORAGE OF ZEROS .......................... 12
+ 4.3 EQU - EQUATE SYMBOL TO A VALUE ........................ 13
+ 4.4 FCB - FORM CONSTANT BYTE .............................. 13
+ 4.5 FCC - FORM CONSTANT CHARACTER STRING .................. 13
+ 4.6 FDB - FROM DOUBLE BYTE CONSTANT ....................... 13
+ 4.7 FILL - FILL MEMORY .................................... 14
+ 4.8 OPT - ASSEMBLER OUTPUT OPTIONS ........................ 14
+ 4.9 ORG - SET PROGRAM COUNTER TO ORIGIN ................... 14
+ 4.10 PAGE - TOP OF PAGE ................................... 15
+ 4.11 RMB - RESERVE MEMORY BYTES ........................... 15
+ 4.12 ZMB - ZERO MEMORY BYTES .............................. 15
+
+APPENDIX A - CHARACTER SET ....................................... 16
+
+APPENDIX B - ADDRESSING MODES .................................... 18
+
+ B.1 M6800/M6801 ADDRESSING MODES .......................... 18
+ B.2 M6804/68HC04 ADDRESSING MODES ......................... 19
+ B.3 M6805/68HC05 ADDRESSING MODES ......................... 21
+
+
+
+ i
+
+
+
+
+
+
+
+ TABLE OF CONTENTS
+
+ B.4 M6809 ADDRESSING MODES ................................ 22
+ B.5 M68HC11 ADDRESSING MODES .............................. 26
+
+APPENDIX C - DIRECTIVE SUMMARY ................................... 28
+
+APPENDIX D - ASSEMBLER LISTING FORMAT ............................ 29
+
+APPENDIX E - S-RECORD INFORMATION ................................ 30
+
+ E.1 INTRODUCTION .......................................... 30
+ E.2 S-RECORD CONTENT ...................................... 30
+ E.3 S-RECORD TYPES ........................................ 30
+ E.4 S-RECORD EXAMPLE ...................................... 31
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ii
+
+
+
+
+
+
+
+ CHAPTER 1
+ GENERAL INFORMATION
+
+
+1.1 INTRODUCTION
+
+This is the user's reference manual for the IBM-PC hosted Motorola
+Freeware 8 bit cross assemblers. It details the features and
+capabilities of the cross assemblers, assembler syntax and directives,
+options, and listings. It is intended as a detailed reference and an
+introduction for those unfamiliar with Motorola assembler syntax and
+format. Those experienced with Motorola assembler products may wish
+to examine the file ASEMBLER.DOC available with the cross assemblers,
+which briefly describes the differences between these assemblers and
+earlier, non-pc based versions.
+
+Assemblers are programs that process assembly language source program
+statements and translate them into executable machine language object
+files. A programmer writes his source program using any text editor
+or word processor that can produce an ASCII text output. With some
+word processors this is known as "non document" mode. Non document
+mode produces a file without the non-printable embedded control
+characters that are used in document formating. (Caution: assembling
+a file that has been formatted with embedded control characters may
+produce assembler errors. The solution is to convert the source file
+to ASCII text.) Once the source code is written, the source file is
+assembled by processing the file via the assembler.
+
+Cross assemblers (such as the Motorola Freeware Assemblers) allow
+source programs written and edited on one computer (the host) to
+generate executable code for another computer (the target). The
+executable object file can then be downloaded and run on the target
+system. In this case the host is an IBM-PC or compatible and the
+target system is based on a Motorola 8-bit microprocessor (6800, 6801,
+6803, 6805, 68HC05, 6809, or 68HC11).
+
+The assemblers are the executable programs AS*.EXE where * is any of
+0, 1, 4, 5, 9, or 11 depending on which microprocessor you are writing
+code for. The details of executing the assembler programs are found
+in Chapter 3. The assembly language format and syntax for the various
+processors is very similar with slight variations due to varied
+programming resources (instructions, addressing modes, and registers).
+These variations are explained in Appendix B.
+
+
+1.2 ASSEMBLY LANGUAGE
+
+The symbolic language used to code source programs to be processed by
+the Assembler is called assembly language. The language is a
+collection of mnemonic symbols representing: operations (i.e., machine
+instruction mnemonics or directives to the assembler), symbolic names,
+operators, and special symbols. The assembly language provides
+mnemonic operation codes for all machine instructions in the
+instruction set. The instructions are defined and explained in the
+Programming Reference Manuals for the specific devices, available from
+Motorola. The assembly language also contains mnemonic directives
+
+
+
+
+
+
+
+ Freeware Assemblers User's Manual
+
+
+which specify auxiliary actions to be performed by the Assembler.
+These directives are not always translated into machine language.
+
+
+1.3 OPERATING ENVIRONMENT
+
+These assemblers will run on any IBM-PC, XT, AT, PS-2, or true
+compatible. The assemblers may be run off of a floppy disk drive or
+they may be copied onto a hard drive for execution. DOS 2.0 or later
+is required.
+
+
+1.4 ASSEMBLER PROCESSING
+
+The Macro Assembler is a two-pass assembler. During the first pass,
+the source program is read to develop the symbol table. During the
+second pass, the object file is created (assembled) with reference to
+the table developed in pass one. It is during the second pass that
+the source program listing is also produced.
+
+Each source statement is processed completely before the next source
+statement is read. As each statement is processed, the Assembler
+examines the label, operation code, and operand fields. The operation
+code table is scanned for a match with a known opcode. During the
+processing of a standard operation code mnemonic, the standard
+machine code is inserted into the object file. If an Assembler
+directive is being processed, the proper action is taken.
+
+Any errors that are detected by the Assembler are displayed before the
+actual line containing the error is printed. If no source listing is
+being produced, error messages are still displayed to indicate that
+the assembly process did not proceed normally.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2
+
+
+
+
+ Freeware Assemblers User's Manual
+
+
+ CHAPTER 2
+ CODING ASSEMBLY LANGUAGE PROGRAMS
+
+
+2.1 INTRODUCTION
+
+Programs written in assembly language consist of a sequence of source
+statements. Each source statement consists of a sequence of ASCII
+characters ending with a carriage return. Appendix A contains a list
+of the supported character set.
+
+
+2.2 SOURCE STATEMENT FORMAT
+
+Each source statement may include up to four fields: a label (or "*"
+for a comment line), an operation (instruction mneumonic or assembler
+directive), an operand, and a comment.
+
+
+2.2.1 Label Field
+
+The label field occurs as the first field of a source statement. The
+label field can take one of the following forms:
+
+1. An asterisk (*) as the first character in the label field indicates
+that the rest of the source statement is a comment. Comments are
+ignored by the Assembler, and are printed on the source listing only
+for the programmer's information.
+
+2. A whitespace character (blank or tab) as the first character
+indicates that the label field is empty. The line has no label and is
+not a comment.
+
+3. A symbol character as the first character indicates that the line
+has a label. Symbol characters are the upper or lower case letters a-
+z, digits 0-9, and the special characters, period (.), dollar sign
+($), and underscore (_). Symbols consist of one to 15 characters, the
+first of which must be alphabetic or the special characters period (.)
+or underscore (_). All characters are significant and upper and lower
+case letters are distinct.
+
+A symbol may occur only once in the label field. If a symbol does
+occur more than once in a label field, then each reference to that
+symbol will be flagged with an error.
+
+With the exception of some directives, a label is assigned the value
+of the program counter of the first byte of the instruction or data
+being assembled. The value assigned to the label is absolute.
+Labels may optionally be ended with a colon (:). If the colon is
+used it is not part of the label but merely acts to set the label off
+from the rest of the source line. Thus the following code fragments
+are equivalent:
+
+ here: deca
+ bne here
+
+
+
+ 3
+
+
+
+
+ Freeware Assemblers User's Manual
+
+
+ here deca
+ bne here
+
+A label may appear on a line by itself. The assembler interprets this
+as set the value of the label equal to the current value of the
+program counter.
+
+The symbol table has room for at least 2000 symbols of length 8
+characters or less. Additional characters up to 15 are permissible at
+the expense of decreasing the maximum number of symbols possible in
+the table.
+
+
+2.2.2 Operation Field
+
+The operation field occurs after the label field, and must be preceded
+by at least one whitespace character. The operation field must contain
+a legal opcode mneumonic or an assembler directive. Upper case
+characters in this field are converted to lower case before being
+checked as a legal mneumonic. Thus 'nop', 'NOP', and 'NoP' are
+recognized as the same mneumonic. Entries in the operation field may
+be one of two types:
+
+Opcode. These correspond directly to the machine instructions. The
+operation code includes any register name associated with the
+instruction. These register names must not be separated from the
+opcode with any whitespace characters. Thus 'clra' means clear
+accumulator A, but 'clr a' means clear memory location identified by
+the label 'a'.
+
+Directive. These are special operation codes known to the Assembler
+which control the assembly process rather than being translated into
+machine instructions.
+
+
+2.2.3 Operand Field
+
+The operand field's interpretation is dependent on the contents of the
+operation field. The operand field, if required, must follow the
+operation field, and must be preceded by at least one whitespace
+character. The operand field may contain a symbol, an expression, or a
+combination of symbols and expressions separated by commas.
+
+The operand field of machine instructions is used to specify the
+addressing mode of the instruction, as well as the operand of the
+instruction. The following tables summarize the operand field
+formats for the various processor families. (NOTE: in these tables
+parenthesis "()" signify optional elements and angle brackets "<>"
+denote an expression is inserted. These syntax elements are present
+only for clarification of the format and are not inserted as part of
+the actual source program. All other characters are significant and
+must be used when required.)
+
+
+
+
+
+
+ 4
+
+
+
+
+ Freeware Assemblers User's Manual
+
+
+2.2.3.1 M6800/6801 Operand Syntax
+
+The format of the operand field for M6800/6801 instructions is:
+
+ Operand Format M6800/M6801 Addressing Mode
+ -------------- ---------------------------
+ no operand accumulator and inherent
+ direct, extended, or relative
+ # immediate
+ ,X indexed
+
+Details of the M6800/6801 addressing modes may be found in Appendix B.
+
+
+2.2.3.2 M6804/68HC Operand Syntax
+
+For the M6804/68HC04, the following operand formats exist:
+
+ Operand Format M6804/68HC04 Addressing Mode
+ -------------- ----------------------------
+ no operand accumulator and inherent
+ direct, extended, or relative
+ # immediate
+ bit set or clear
+ , bit test and branch
+ [ or ] register indirect
+ ,# move indirect
+
+Details of the M6804/68HC04 addressing modes may be found in Appendix
+B.
+
+
+2.2.3.3 M6805/M68HC05 Operand Syntax
+
+For the M6805/68HC05, the operand formats are:
+
+ Operand Format M6805/68HC05 Addressing Mode
+ -------------- ----------------------------
+ no operand accumulator and inherent
+ direct, extended, or relative
+ # immediate
+ ,X indexed
+ , bit set or clear
+ ,, bit test and branch
+
+Details of the M6805/68HC05 addressing modes may be found in Appendix
+B.
+
+
+2.2.3.4 M6809 Operand Syntax
+
+For the M6809, the following operand formats are used:
+
+
+
+
+
+
+ 5
+
+
+
+
+ Freeware Assemblers User's Manual
+
+
+ Operand Format M6809 Addressing Mode
+ -------------- ---------------------
+ no operand accumulator and inherent
+ direct, extended, or relative
+ # immediate
+ ,X indexed
+ < forced direct
+ > forced extended
+ ] extended indirect
+ ,R indexed
+ <,R forced 8-bit offset indexed
+ >,R forced 16-bit offset indexed
+ [,R] indexed indirect
+ <[,R] forced 8-bit offset indexed indirect
+ >[,R] forced 16-bit offset indexed indirect
+ Q+ auto increment by 1
+ Q++ auto increment by 2
+ [Q++] auto increment indirect
+ -Q auto decrement by
+ --Q auto decrement by 2
+ [--Q] auto decrement indirect
+ W1,[W2,...,Wn] immediate
+
+where R is one of the registers PCR, S, U, X, or Y, and Q is one of
+the registers S, U, X, or Y. Wi (i=1 to n) is one of the symbols A,
+B, CC, D, DP, PC, S, U, X, or Y.
+
+Details of the M6809 addressing modes may be found in Appendix B.
+
+
+2.2.3.5 M68HC11 Operand Syntax
+
+For the M68HC11, the following operand formats exist:
+
+ Operand Format M68HC11 Addressing Mode
+ -------------- -----------------------
+ no operand accumulator and inherent
+ direct, extended, or relative
+ # immediate
+ ,X indexed with X register
+ ,Y indexed with Y register
+ bit set or clear
+ bit test and branch
+
+The bit manipulation instruction operands are separated by spaces in
+this case since the HC11 allows bit manipulation instructions on
+indexed addresses. Thus a ',X' or ',Y' may be added to the final two
+formats above to form the indexed effective address calculation.
+
+Details of the M68HC11 addressing modes may be found in Appendix B.
+The operand fields of assembler directives are described in Chapter 4.
+
+
+2.2.3.6 Expressions. An expression is a combination of symbols,
+constants, algebraic operators, and parentheses. The expression is
+used to specify a value which is to be used as an operand.
+
+
+ 6
+
+
+
+
+ Freeware Assemblers User's Manual
+
+
+Expressions may consist of symbols, constants, or the character '*'
+(denoting the current value of the program counter) joined together by
+one of the operators: + - * / % & | ^ .
+
+
+2.2.3.7 Operators. The operators are the same as in c:
+
+ + add
+ - subtract
+ * multiply
+ / divide
+ % remainder after division
+ & bitwise and
+ | bitwise or
+ ^ bitwise exclusive or
+
+Expressions are evaluated left to right and there is no provision for
+parenthesized expressions. Arithmetic is carried out in signed two-
+complement integer precision (that's 16 bits on the IBM PC).
+
+
+2.2.3.8 Symbols. Each symbol is associated with a 16-bit integer
+value which is used in place of the symbol during the expression
+evaluation. The asterisk (*) used in an expression as a symbol
+represents the current value of the location counter (the first byte
+of a multi-byte instruction).
+
+
+2.2.3.9 Constants. Constants represent quantities of data that do
+not vary in value during the execution of a program. Constants may be
+presented to the assembler in one of five formats: decimal,
+hexadecimal, binary, or octal, or ASCII. The programmer indicates the
+number format to the assembler with the following prefixes:
+
+ $ HEX
+ % BINARY
+ @ OCTAL
+ ' ASCII
+
+Unprefixed constants are interpreted as decimal. The assembler
+converts all constants to binary machine code and are displayed in the
+assembly listing as hex.
+
+A decimal constant consists of a string of numeric digits. The value
+of a decimal constant must fall in the range 0-65535, inclusive. The
+following example shows both valid and invalid decimal constants:
+
+ VALID INVALID REASON INVALID
+ ----- ------- --------------
+ 12 123456 more than 5 digits
+ 12345 12.3 invalid character
+
+A hexadecimal constant consists of a maximum of four characters from
+the set of digits (0-9) and the upper case alphabetic letters (A-F),
+and is preceded by a dollar sign ($). Hexadecimal constants must be
+
+
+
+ 7
+
+
+
+
+ Freeware Assemblers User's Manual
+
+
+in the range $0000 to $FFFF. The following example shows both valid
+and invalid hexadecimal constants:
+
+ VALID INVALID REASON INVALID
+ ----- ------- --------------
+ $12 ABCD no preceding "$"
+ $ABCD $G2A invalid character
+ $001F $2F018 too many digits
+
+A binary constant consists of a maximum of 16 ones or zeros preceded
+by a percent sign (%). The following example shows both valid and
+invalid binary constants:
+
+ VALID INVALID REASON INVALID
+ ----- ------- --------------
+ %00101 1010101 missing percent
+ %1 %10011000101010111 too many digits
+ %10100 %210101 invalid digit
+
+An octal constant consists of a maximum of six numeric digits,
+excluding the digits 8 and 9, preceded by a commercial at-sign (@).
+Octal constants must be in the ranges @0 to @177777. The following
+example shows both valid and invalid octal constan
+ts:
+
+ VALID INVALID REASON INVALID
+ ----- ------- --------------
+ @17634 @2317234 too many digits
+ @377 @277272 out of range
+ @177600 @23914 invalid character
+
+A single ASCII character can be used as a constant in expressions.
+ASCII constants are preceded by a single quote ('). Any character,
+including the single quote, can be used as a character constant. The
+following example shows both valid and inval
+id character constants:
+
+ VALID INVALID REASON INVALID
+ ----- ------- --------------
+ '* 'VALID too long
+
+For the invalid case above the assembler will not indicate an error.
+Rather it will assemble the first character and ignore the remainder.
+
+
+2.2.4 Comment Field
+
+The last field of an Assembler source statement is the comment field.
+This field is optional and is only printed on the source listing for
+documentation purposes. The comment field is separated from the
+operand field (or from the operation field if no operand is required)
+by at least one whitespace character. The comment field can contain
+any printable ASCII characters.
+
+
+
+
+
+ 8
+
+
+
+
+ Freeware Assemblers User's Manual
+
+
+2.3 ASSEMBLER OUTPUT
+
+The Assembler output includes an optional listing of the source
+program and an object file which is in the Motorola S Record format.
+Details of the S Record format may be found in Appendix E. The
+Assembler will normally suppress the printing of the source listing.
+This condition, as well as others, can be overridden via options
+supplied on the command line that invoked the Assembler.
+
+Each line of the listing contains a reference line number, the address
+and bytes assembled, and the original source input line. If an input
+line causes more than 6 bytes to be output (e.g. a long FCC
+directive), additional bytes (up to 64) are listed on succeeding lines
+with no address preceding them.
+
+The assembly listing may optionally contain a symbol table or a cross
+reference table of all symbols appearing in the program. These are
+always printed at the end of the assembly listing if either the symbol
+table or cross reference table options (Paragraph 4.8) are in effect.
+The symbol table contains the name of each symbol, along with its
+defined value. The cross reference table additionally contains the
+assembler-maintained source line number of every reference to every
+symbol. The format of the cross reference table is shown in Appendix
+D.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 9
+
+
+
+
+ Freeware Assemblers User's Manual
+
+
+ CHAPTER 3
+ RUNNING THE ASSEMBLERS
+
+
+3.1 ASSEMBLER INVOCATION
+
+The Motorola Freeware Assembly programs are named as*.exe where '*' is
+any of 0, 1, 4, 5, 9, or 11 depending on which processor family you
+wish to assemble code for. For example, to generate M6800 code run
+the as0.exe program. To generate M68HC05 code run the as5.exe
+program, and so forth. To run the assembler enter the following
+command line:
+
+ as* file1 (file2 . . . ) ( - option1 option2 . . . )
+
+where file1, file2, etc are the names of the source files you wish to
+assemble. The source filenames may have extensions but the assembler
+does not check for any particular extension ( however, do not use the
+.S19 extension since that is the extension of the object file created
+by the assembler. Its creation would overwrite the source file when
+it is written to the disk).
+
+The options are one or more of the following:
+
+ l enables output listing
+ no disables output listing (default).
+ cre enables the cross reference table generation
+ s enables the symbol table generation
+ c enables cycle counting
+ noc disables cycle counting
+
+The minus sign preceding the option should be separated from the last
+file name by a space. These options may also be indicated to the
+assembler by the use of the OPT directive in the source file. The OPT
+directive is described in Paragraph 4.8.
+
+The object file created is written to disk and given the name
+'FILENAME.S19' where 'FILENAME' is the name of the first source file
+specified on the command line. Any errors and the optional listing
+(if specified) are displayed on the screen. The listing and/or error
+messages may be saved to a file for later examination or printing by
+append an i/o redirection command to the command line. On the PC i/o
+redirection is indicated with the greater-than ('>') symbol followed
+by any new or existing file name.
+
+Command line examples:
+
+The command line
+
+ as5 myfile
+
+would run the M6805/68HC05 assembler on the source file 'myfile'. The
+object file would be written to 'myfile.s19' and any errors would
+appear on the screen.
+
+
+
+
+ 10
+
+
+
+
+ Freeware Assemblers User's Manual
+
+
+The command line
+
+ as9 test.asm nexttest.s -l
+
+would run the M6809 assembler on the source files 'test.asm' and
+'nexttest.s'. The object file would be written to 'test.s19' and any
+errors and the assembly listing would appear on the screen.
+
+The command line
+
+ as9 test.asm nexttest.s -l cre s >test.lst
+
+would run the M6809 assembler on the source files 'test.asm' and
+'nexttest.s'. The object file would be written to 'test.s19'. A
+listing would be created followed by a symbol table and cross
+reference which would all be written to the file test.lst
+.
+
+3.2 ERROR MESSAGES
+
+Error diagnostic messages are placed in the listing file just before
+the line containing the error. The format of the error line is:
+
+ Line_number: Description of error
+
+ or
+
+ Line_number: Warning ---- Description of error
+
+Errors in pass one cause cancellation of pass two. Warning do not
+cause cancellation of pass two but are indications of a possible
+problem. Error messages are meant to be self-explanatory.
+
+If more than one file is being assembled, the file name precedes the
+error:
+
+ File_name,Line_number: Description of error
+
+Some errors are classed as fatal and cause an immediate termination of
+the assembly. Generally this happens when a temporary file cannot be
+created or is lost during assembly.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 11
+
+
+
+
+ Freeware Assemblers User's Manual
+
+
+ CHAPTER 4
+ ASSEMBLER DIRECTIVES
+
+
+4.1 INTRODUCTION
+
+The Assembler directives are instructions to the Assembler, rather
+than instructions to be directly translated into object code. This
+chapter describes the directives that are recognized by the Freeware
+Assemblers. Detailed descriptions of each directive are arranged
+alphabetically. The notations used in this chapter are:
+
+ ( ) Parentheses denote an optional element.
+
+ XYZ The names of the directives are printed in capital letters.
+
+ < > The element names are printed in lower case and contained in
+angle brackets. All elements outside of the angle brackets '<>' must
+be specified as-is. For example, the syntactical element (,)
+requires the comma to be specified if the optional element is
+selected. The following elements are used in the subsequent
+descriptions:
+
+
+ A statement's comment field
+
tags/V10/sw/epedit.exe
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: tags/V10/sw/as9.exe
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: tags/V10/sw/as9.exe
===================================================================
--- tags/V10/sw/as9.exe (nonexistent)
+++ tags/V10/sw/as9.exe (revision 3)
tags/V10/sw/as9.exe
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property