📄 cpu09.vhd
字号:
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, nmi_enable )
begin
if clk'event and clk = '0' then
if hold= '1' then
sp <= sp;
nmi_enable <= nmi_enable;
else
case sp_ctrl is
when reset_sp =>
sp <= "0000000000000000";
nmi_enable <= '0';
when load_sp =>
sp <= out_alu(15 downto 0);
nmi_enable <= '1';
when pull_hi_sp =>
sp(15 downto 8) <= data_in;
nmi_enable <= nmi_enable;
when pull_lo_sp =>
sp(7 downto 0) <= data_in;
nmi_enable <= '1';
when others =>
-- when latch_sp =>
sp <= sp;
nmi_enable <= nmi_enable;
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -