mirror of
https://github.com/Gehstock/Mist_FPGA.git
synced 2026-01-23 02:37:52 +00:00
3963 lines
125 KiB
VHDL
3963 lines
125 KiB
VHDL
--===========================================================================--
|
|
--
|
|
-- S Y N T H E Z I A B L E CPU68 C O R E
|
|
--
|
|
-- www.OpenCores.Org - December 2002
|
|
-- This core adheres to the GNU public license
|
|
--
|
|
-- File name : cpu68.vhd
|
|
--
|
|
-- Purpose : Implements a 6800 compatible CPU core with some
|
|
-- additional instructions found in the 6801
|
|
--
|
|
-- Dependencies : ieee.Std_Logic_1164
|
|
-- ieee.std_logic_unsigned
|
|
--
|
|
-- Author : John E. Kent
|
|
--
|
|
--===========================================================================----
|
|
--
|
|
-- Revision History:
|
|
--
|
|
-- Date: Revision Author
|
|
-- 22 Sep 2002 0.1 John Kent
|
|
--
|
|
-- 30 Oct 2002 0.2 John Kent
|
|
-- made NMI edge triggered
|
|
--
|
|
-- 30 Oct 2002 0.3 John Kent
|
|
-- more corrections to NMI
|
|
-- added wai_wait_state to prevent stack overflow on wai.
|
|
--
|
|
-- 1 Nov 2002 0.4 John Kent
|
|
-- removed WAI states and integrated WAI with the interrupt service routine
|
|
-- replace Data out (do) and Data in (di) register with a single Memory Data (md) reg.
|
|
-- Added Multiply instruction states.
|
|
-- run ALU and CC out of CPU module for timing measurements.
|
|
--
|
|
-- 3 Nov 2002 0.5 John Kent
|
|
-- Memory Data Register was not loaded on Store instructions
|
|
-- SEV and CLV were not defined in the ALU
|
|
-- Overflow Flag on NEG was incorrect
|
|
--
|
|
-- 16th Feb 2003 0.6 John Kent
|
|
-- Rearranged the execution cycle for dual operand instructions
|
|
-- so that occurs during the following fetch cycle.
|
|
-- This allows the reduction of one clock cycle from dual operand
|
|
-- instruction. Note that this also necessitated re-arranging the
|
|
-- program counter so that it is no longer incremented in the ALU.
|
|
-- The effective address has also been re-arranged to include a
|
|
-- separate added. The STD (store accd) now sets the condition codes.
|
|
--
|
|
-- 28th Jun 2003 0.7 John Kent
|
|
-- Added Hold and Halt signals. Hold is used to steal cycles from the
|
|
-- CPU or add wait states. Halt puts the CPU in the inactive state
|
|
-- and is only honoured in the fetch cycle. Both signals are active high.
|
|
--
|
|
-- 9th Jan 2004 0.8 John Kent
|
|
-- Clear instruction did an alu_ld8 rather than an alu_clr, so
|
|
-- the carry bit was not cleared correctly.
|
|
-- This error was picked up by Michael Hassenfratz.
|
|
--
|
|
|
|
library ieee;
|
|
use IEEE.STD_LOGIC_1164.ALL;
|
|
use IEEE.STD_LOGIC_ARITH.ALL;
|
|
use IEEE.STD_LOGIC_UNSIGNED.ALL;
|
|
|
|
entity cpu68 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);
|
|
hold: in std_logic;
|
|
halt: in std_logic;
|
|
irq: 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 cpu68 is
|
|
|
|
constant SBIT : integer := 7;
|
|
constant XBIT : 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;
|
|
|
|
type state_type is (reset_state, fetch_state, decode_state,
|
|
extended_state, indexed_state, read8_state, read16_state, immediate16_state,
|
|
write8_state, write16_state,
|
|
execute_state, halt_state, error_state,
|
|
mul_state, mulea_state, muld_state,
|
|
mul0_state, mul1_state, mul2_state, mul3_state,
|
|
mul4_state, mul5_state, mul6_state, mul7_state,
|
|
jmp_state, jsr_state, jsr1_state,
|
|
branch_state, bsr_state, bsr1_state,
|
|
rts_hi_state, rts_lo_state,
|
|
int_pcl_state, int_pch_state,
|
|
int_ixl_state, int_ixh_state,
|
|
int_cc_state, int_acca_state, int_accb_state,
|
|
int_wai_state, int_mask_state,
|
|
rti_state, rti_cc_state, rti_acca_state, rti_accb_state,
|
|
rti_ixl_state, rti_ixh_state,
|
|
rti_pcl_state, rti_pch_state,
|
|
pula_state, psha_state, pulb_state, pshb_state,
|
|
pulx_lo_state, pulx_hi_state, pshx_lo_state, pshx_hi_state,
|
|
vect_lo_state, vect_hi_state );
|
|
type addr_type is (idle_ad, fetch_ad, read_ad, write_ad, push_ad, pull_ad, int_hi_ad, int_lo_ad );
|
|
type dout_type is (md_lo_dout, md_hi_dout, acca_dout, accb_dout, ix_lo_dout, ix_hi_dout, cc_dout, pc_lo_dout, pc_hi_dout );
|
|
type op_type is (reset_op, fetch_op, latch_op );
|
|
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 cc_type is (reset_cc, load_cc, pull_cc, latch_cc );
|
|
type ix_type is (reset_ix, load_ix, pull_lo_ix, pull_hi_ix, latch_ix );
|
|
type sp_type is (reset_sp, latch_sp, load_sp );
|
|
type pc_type is (reset_pc, latch_pc, load_ea_pc, add_ea_pc, pull_lo_pc, pull_hi_pc, inc_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, add_ix_ea, load_accb_ea, inc_ea, fetch_first_ea, fetch_next_ea );
|
|
type iv_type is (reset_iv, latch_iv, swi_iv, nmi_iv, irq_iv );
|
|
type nmi_type is (reset_nmi, set_nmi, latch_nmi );
|
|
type left_type is (acca_left, accb_left, accd_left, md_left, ix_left, sp_left );
|
|
type right_type is (md_right, zero_right, plus_one_right, accb_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_cpx,
|
|
alu_lsr16, alu_lsl16,
|
|
alu_ror8, alu_rol8,
|
|
alu_asr8, alu_asl8, alu_lsr8,
|
|
alu_sei, alu_cli, alu_sec, alu_clc, alu_sev, alu_clv, alu_tpa, alu_tap,
|
|
alu_ld8, alu_st8, alu_ld16, alu_st16, alu_nop, alu_daa );
|
|
|
|
signal op_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 xreg: std_logic_vector(15 downto 0);
|
|
signal sp: 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(1 downto 0);
|
|
signal nmi_req: std_logic;
|
|
signal nmi_ack: std_logic;
|
|
|
|
signal state: state_type;
|
|
signal next_state: state_type;
|
|
signal pc_ctrl: pc_type;
|
|
signal ea_ctrl: ea_type;
|
|
signal op_ctrl: op_type;
|
|
signal md_ctrl: md_type;
|
|
signal acca_ctrl: acca_type;
|
|
signal accb_ctrl: accb_type;
|
|
signal ix_ctrl: ix_type;
|
|
signal cc_ctrl: cc_type;
|
|
signal sp_ctrl: sp_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
|
|
|
|
----------------------------------
|
|
--
|
|
-- Address bus multiplexer
|
|
--
|
|
----------------------------------
|
|
|
|
addr_mux: process( clk, addr_ctrl, pc, ea, 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 push_ad =>
|
|
address <= sp;
|
|
vma <= '1';
|
|
rw <= '0';
|
|
when pull_ad =>
|
|
address <= sp;
|
|
vma <= '1';
|
|
rw <= '1';
|
|
when int_hi_ad =>
|
|
address <= "1111111111111" & iv & "0";
|
|
vma <= '1';
|
|
rw <= '1';
|
|
when int_lo_ad =>
|
|
address <= "1111111111111" & iv & "1";
|
|
vma <= '1';
|
|
rw <= '1';
|
|
when others =>
|
|
address <= "1111111111111111";
|
|
vma <= '0';
|
|
rw <= '1';
|
|
end case;
|
|
end process;
|
|
|
|
--------------------------------
|
|
--
|
|
-- Data Bus output
|
|
--
|
|
--------------------------------
|
|
dout_mux : process( clk, dout_ctrl, md, acca, accb, xreg, pc, cc )
|
|
begin
|
|
case dout_ctrl is
|
|
when md_hi_dout => -- alu output
|
|
data_out <= md(15 downto 8);
|
|
when md_lo_dout =>
|
|
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 cc_dout => -- condition codes
|
|
data_out <= cc;
|
|
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;
|
|
|
|
|
|
----------------------------------
|
|
--
|
|
-- Program Counter Control
|
|
--
|
|
----------------------------------
|
|
|
|
pc_mux: process( clk, pc_ctrl, pc, out_alu, data_in, ea, hold )
|
|
variable tempof : std_logic_vector(15 downto 0);
|
|
variable temppc : std_logic_vector(15 downto 0);
|
|
begin
|
|
case pc_ctrl is
|
|
when add_ea_pc =>
|
|
if ea(7) = '0' then
|
|
tempof := "00000000" & ea(7 downto 0);
|
|
else
|
|
tempof := "11111111" & ea(7 downto 0);
|
|
end if;
|
|
when inc_pc =>
|
|
tempof := "0000000000000001";
|
|
when others =>
|
|
tempof := "0000000000000000";
|
|
end case;
|
|
|
|
case pc_ctrl is
|
|
when reset_pc =>
|
|
temppc := "1111111111111110";
|
|
when load_ea_pc =>
|
|
temppc := ea;
|
|
when pull_lo_pc =>
|
|
temppc(7 downto 0) := data_in;
|
|
temppc(15 downto 8) := pc(15 downto 8);
|
|
when pull_hi_pc =>
|
|
temppc(7 downto 0) := pc(7 downto 0);
|
|
temppc(15 downto 8) := data_in;
|
|
when others =>
|
|
temppc := pc;
|
|
end case;
|
|
|
|
if clk'event and clk = '0' then
|
|
if hold = '1' then
|
|
pc <= pc;
|
|
else
|
|
pc <= temppc + tempof;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
----------------------------------
|
|
--
|
|
-- Effective Address Control
|
|
--
|
|
----------------------------------
|
|
|
|
ea_mux: process( clk, ea_ctrl, ea, out_alu, data_in, accb, xreg, hold )
|
|
variable tempind : std_logic_vector(15 downto 0);
|
|
variable tempea : std_logic_vector(15 downto 0);
|
|
begin
|
|
case ea_ctrl is
|
|
when add_ix_ea =>
|
|
tempind := "00000000" & ea(7 downto 0);
|
|
when inc_ea =>
|
|
tempind := "0000000000000001";
|
|
when others =>
|
|
tempind := "0000000000000000";
|
|
end case;
|
|
|
|
case ea_ctrl is
|
|
when reset_ea =>
|
|
tempea := "0000000000000000";
|
|
when load_accb_ea =>
|
|
tempea := "00000000" & accb(7 downto 0);
|
|
when add_ix_ea =>
|
|
tempea := xreg;
|
|
when fetch_first_ea =>
|
|
tempea(7 downto 0) := data_in;
|
|
tempea(15 downto 8) := "00000000";
|
|
when fetch_next_ea =>
|
|
tempea(7 downto 0) := data_in;
|
|
tempea(15 downto 8) := ea(7 downto 0);
|
|
when others =>
|
|
tempea := ea;
|
|
end case;
|
|
|
|
if clk'event and clk = '0' then
|
|
if hold = '1' then
|
|
ea <= ea;
|
|
else
|
|
ea <= tempea + tempind;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
--------------------------------
|
|
--
|
|
-- Accumulator A
|
|
--
|
|
--------------------------------
|
|
acca_mux : process( clk, acca_ctrl, out_alu, acca, data_in, hold )
|
|
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_mux : process( clk, accb_ctrl, out_alu, accb, data_in, hold )
|
|
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_mux : process( clk, ix_ctrl, out_alu, xreg, data_in, hold )
|
|
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;
|
|
|
|
--------------------------------
|
|
--
|
|
-- stack pointer
|
|
--
|
|
--------------------------------
|
|
sp_mux : process( clk, sp_ctrl, out_alu, hold )
|
|
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 others =>
|
|
-- when latch_sp =>
|
|
sp <= sp;
|
|
end case;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
--------------------------------
|
|
--
|
|
-- Memory Data
|
|
--
|
|
--------------------------------
|
|
md_mux : process( clk, md_ctrl, out_alu, data_in, md, hold )
|
|
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 =>
|
|
md(15 downto 8) <= "00000000";
|
|
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_mux: process( clk, cc_ctrl, cc_out, cc, data_in, hold )
|
|
begin
|
|
if clk'event and clk = '0' then
|
|
if hold = '1' then
|
|
cc <= cc;
|
|
else
|
|
case cc_ctrl is
|
|
when reset_cc =>
|
|
cc <= "11000000";
|
|
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;
|
|
|
|
----------------------------------
|
|
--
|
|
-- interrupt vector
|
|
--
|
|
----------------------------------
|
|
|
|
iv_mux: process( clk, iv_ctrl, hold )
|
|
begin
|
|
if clk'event and clk = '0' then
|
|
if hold = '1' then
|
|
iv <= iv;
|
|
else
|
|
case iv_ctrl is
|
|
when reset_iv =>
|
|
iv <= "11";
|
|
when nmi_iv =>
|
|
iv <= "10";
|
|
when swi_iv =>
|
|
iv <= "01";
|
|
when irq_iv =>
|
|
iv <= "00";
|
|
when others =>
|
|
iv <= iv;
|
|
end case;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
----------------------------------
|
|
--
|
|
-- op code fetch
|
|
--
|
|
----------------------------------
|
|
|
|
op_fetch: process( clk, data_in, op_ctrl, op_code, hold )
|
|
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 <= "00000001"; -- nop
|
|
when fetch_op =>
|
|
op_code <= data_in;
|
|
when others =>
|
|
-- when latch_op =>
|
|
op_code <= op_code;
|
|
end case;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
----------------------------------
|
|
--
|
|
-- Left Mux
|
|
--
|
|
----------------------------------
|
|
|
|
left_mux: process( left_ctrl, acca, accb, xreg, sp, pc, ea, md )
|
|
begin
|
|
case left_ctrl is
|
|
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 accd_left =>
|
|
left(15 downto 8) <= acca;
|
|
left(7 downto 0) <= accb;
|
|
when ix_left =>
|
|
left <= xreg;
|
|
when sp_left =>
|
|
left <= sp;
|
|
when others =>
|
|
-- when md_left =>
|
|
left <= md;
|
|
end case;
|
|
end process;
|
|
----------------------------------
|
|
--
|
|
-- Right Mux
|
|
--
|
|
----------------------------------
|
|
|
|
right_mux: process( right_ctrl, data_in, md, accb, ea )
|
|
begin
|
|
case right_ctrl is
|
|
when zero_right =>
|
|
right <= "0000000000000000";
|
|
when plus_one_right =>
|
|
right <= "0000000000000001";
|
|
when accb_right =>
|
|
right <= "00000000" & accb;
|
|
when others =>
|
|
-- when md_right =>
|
|
right <= md;
|
|
end case;
|
|
end process;
|
|
|
|
----------------------------------
|
|
--
|
|
-- Arithmetic Logic Unit
|
|
--
|
|
----------------------------------
|
|
|
|
mux_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 | alu_cpx =>
|
|
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 =>
|
|
out_alu <= left;
|
|
when alu_daa =>
|
|
out_alu <= left + ("00000000" & daa_reg);
|
|
when alu_tpa =>
|
|
out_alu <= "00000000" & cc;
|
|
when others =>
|
|
out_alu <= left; -- nop
|
|
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_sec =>
|
|
cc_out(CBIT) <= '1';
|
|
when alu_clc =>
|
|
cc_out(CBIT) <= '0';
|
|
when alu_tap =>
|
|
cc_out(CBIT) <= left(CBIT);
|
|
when others => -- carry is not affected by cpx
|
|
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 =>
|
|
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 | alu_cpx =>
|
|
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_tap =>
|
|
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 =>
|
|
cc_out(NBIT) <= out_alu(7);
|
|
when alu_add16 | alu_sub16 |
|
|
alu_lsl16 | alu_lsr16 |
|
|
alu_ld16 | alu_st16 | alu_cpx =>
|
|
cc_out(NBIT) <= out_alu(15);
|
|
when alu_tap =>
|
|
cc_out(NBIT) <= left(NBIT);
|
|
when others =>
|
|
cc_out(NBIT) <= cc(NBIT);
|
|
end case;
|
|
|
|
--
|
|
-- Interrupt mask flag
|
|
--
|
|
case alu_ctrl is
|
|
when alu_sei =>
|
|
cc_out(IBIT) <= '1'; -- set interrupt mask
|
|
when alu_cli =>
|
|
cc_out(IBIT) <= '0'; -- clear interrupt mask
|
|
when alu_tap =>
|
|
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_tap =>
|
|
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 | alu_cpx =>
|
|
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_tap =>
|
|
cc_out(VBIT) <= left(VBIT);
|
|
when alu_and | alu_ora | alu_eor | alu_com |
|
|
alu_st8 | alu_st16 | alu_ld8 | alu_ld16 |
|
|
alu_clv =>
|
|
cc_out(VBIT) <= '0';
|
|
when alu_sev =>
|
|
cc_out(VBIT) <= '1';
|
|
when others =>
|
|
cc_out(VBIT) <= cc(VBIT);
|
|
end case;
|
|
|
|
case alu_ctrl is
|
|
when alu_tap =>
|
|
cc_out(XBIT) <= cc(XBIT) and left(XBIT);
|
|
cc_out(SBIT) <= left(SBIT);
|
|
when others =>
|
|
cc_out(XBIT) <= cc(XBIT) and left(XBIT);
|
|
cc_out(SBIT) <= cc(SBIT);
|
|
end case;
|
|
|
|
test_alu <= out_alu;
|
|
test_cc <= cc_out;
|
|
end process;
|
|
|
|
------------------------------------
|
|
--
|
|
-- Detect Edge of NMI interrupt
|
|
--
|
|
------------------------------------
|
|
|
|
nmi_handler : process( clk, rst, nmi, nmi_ack )
|
|
begin
|
|
if clk'event and clk='0' then
|
|
if hold = '1' then
|
|
nmi_req <= nmi_req;
|
|
else
|
|
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 if;
|
|
end process;
|
|
|
|
------------------------------------
|
|
--
|
|
-- Nmi mux
|
|
--
|
|
------------------------------------
|
|
|
|
nmi_mux: process( clk, nmi_ctrl, nmi_ack, hold )
|
|
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;
|
|
|
|
------------------------------------
|
|
--
|
|
-- state sequencer
|
|
--
|
|
------------------------------------
|
|
process( state, op_code, cc, ea, irq, nmi_req, nmi_ack, hold, halt )
|
|
begin
|
|
case state is
|
|
when reset_state => -- released from reset
|
|
-- reset the registers
|
|
op_ctrl <= reset_op;
|
|
acca_ctrl <= reset_acca;
|
|
accb_ctrl <= reset_accb;
|
|
ix_ctrl <= reset_ix;
|
|
sp_ctrl <= reset_sp;
|
|
pc_ctrl <= reset_pc;
|
|
ea_ctrl <= reset_ea;
|
|
md_ctrl <= reset_md;
|
|
iv_ctrl <= reset_iv;
|
|
nmi_ctrl <= reset_nmi;
|
|
-- idle the ALU
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= reset_cc;
|
|
-- idle the bus
|
|
dout_ctrl <= md_lo_dout;
|
|
addr_ctrl <= idle_ad;
|
|
next_state <= vect_hi_state;
|
|
|
|
--
|
|
-- 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;
|
|
nmi_ctrl <= latch_nmi;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
md_ctrl <= latch_md;
|
|
ea_ctrl <= latch_ea;
|
|
iv_ctrl <= latch_iv;
|
|
-- idle the ALU
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
-- fetch pc low interrupt vector
|
|
pc_ctrl <= pull_hi_pc;
|
|
addr_ctrl <= int_hi_ad;
|
|
dout_ctrl <= pc_hi_dout;
|
|
next_state <= vect_lo_state;
|
|
--
|
|
-- 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;
|
|
nmi_ctrl <= latch_nmi;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
md_ctrl <= latch_md;
|
|
ea_ctrl <= latch_ea;
|
|
iv_ctrl <= latch_iv;
|
|
-- idle the ALU
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
-- fetch the vector low byte
|
|
pc_ctrl <= pull_lo_pc;
|
|
addr_ctrl <= int_lo_ad;
|
|
dout_ctrl <= pc_lo_dout;
|
|
next_state <= fetch_state;
|
|
|
|
--
|
|
-- 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 =>
|
|
case op_code(7 downto 4) is
|
|
when "0000" |
|
|
"0001" |
|
|
"0010" | -- branch conditional
|
|
"0011" |
|
|
"0100" | -- acca single op
|
|
"0101" | -- accb single op
|
|
"0110" | -- indexed single op
|
|
"0111" => -- extended single op
|
|
-- idle ALU
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
|
|
when "1000" | -- acca immediate
|
|
"1001" | -- acca direct
|
|
"1010" | -- acca indexed
|
|
"1011" => -- acca extended
|
|
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;
|
|
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;
|
|
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;
|
|
sp_ctrl <= latch_sp;
|
|
when "0011" => -- 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;
|
|
sp_ctrl <= latch_sp;
|
|
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;
|
|
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;
|
|
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;
|
|
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;
|
|
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;
|
|
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;
|
|
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;
|
|
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;
|
|
sp_ctrl <= latch_sp;
|
|
when "1100" => -- cpx
|
|
left_ctrl <= ix_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_cpx;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
when "1101" => -- bsr / jsr
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
when "1110" => -- 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;
|
|
sp_ctrl <= load_sp;
|
|
when "1111" => -- 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;
|
|
sp_ctrl <= latch_sp;
|
|
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;
|
|
sp_ctrl <= latch_sp;
|
|
end case;
|
|
when "1100" | -- accb immediate
|
|
"1101" | -- accb direct
|
|
"1110" | -- accb indexed
|
|
"1111" => -- accb extended
|
|
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;
|
|
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;
|
|
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;
|
|
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;
|
|
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;
|
|
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;
|
|
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;
|
|
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;
|
|
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;
|
|
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;
|
|
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;
|
|
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;
|
|
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;
|
|
sp_ctrl <= latch_sp;
|
|
when "1101" => -- std
|
|
left_ctrl <= accd_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_st16;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
when "1110" => -- 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;
|
|
sp_ctrl <= latch_sp;
|
|
when "1111" => -- 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;
|
|
sp_ctrl <= latch_sp;
|
|
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;
|
|
sp_ctrl <= latch_sp;
|
|
end case;
|
|
when others =>
|
|
left_ctrl <= accd_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
end case;
|
|
md_ctrl <= latch_md;
|
|
-- fetch the op code
|
|
op_ctrl <= fetch_op;
|
|
ea_ctrl <= reset_ea;
|
|
addr_ctrl <= fetch_ad;
|
|
dout_ctrl <= md_lo_dout;
|
|
iv_ctrl <= latch_iv;
|
|
if halt = '1' then
|
|
pc_ctrl <= latch_pc;
|
|
nmi_ctrl <= latch_nmi;
|
|
next_state <= halt_state;
|
|
-- service non maskable interrupts
|
|
elsif (nmi_req = '1') and (nmi_ack = '0') then
|
|
pc_ctrl <= latch_pc;
|
|
nmi_ctrl <= set_nmi;
|
|
next_state <= int_pcl_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
|
|
pc_ctrl <= latch_pc;
|
|
next_state <= int_pcl_state;
|
|
else
|
|
-- Advance the PC to fetch next instruction byte
|
|
pc_ctrl <= inc_pc;
|
|
next_state <= decode_state;
|
|
end if;
|
|
end if;
|
|
--
|
|
-- Here to decode instruction
|
|
-- and fetch next byte of intruction
|
|
-- whether it be necessary or not
|
|
--
|
|
when decode_state =>
|
|
-- fetch first byte of address or immediate data
|
|
ea_ctrl <= fetch_first_ea;
|
|
addr_ctrl <= fetch_ad;
|
|
dout_ctrl <= md_lo_dout;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
iv_ctrl <= latch_iv;
|
|
case op_code(7 downto 4) is
|
|
when "0000" =>
|
|
md_ctrl <= fetch_first_md;
|
|
sp_ctrl <= latch_sp;
|
|
pc_ctrl <= latch_pc;
|
|
case op_code(3 downto 0) is
|
|
when "0001" => -- nop
|
|
left_ctrl <= accd_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
when "0100" => -- lsrd
|
|
left_ctrl <= accd_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_lsr16;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= load_hi_acca;
|
|
accb_ctrl <= load_accb;
|
|
ix_ctrl <= latch_ix;
|
|
when "0101" => -- lsld
|
|
left_ctrl <= accd_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_lsl16;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= load_hi_acca;
|
|
accb_ctrl <= load_accb;
|
|
ix_ctrl <= latch_ix;
|
|
when "0110" => -- tap
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_tap;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
when "0111" => -- tpa
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_tpa;
|
|
cc_ctrl <= latch_cc;
|
|
acca_ctrl <= load_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
when "1000" => -- inx
|
|
left_ctrl <= ix_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_inx;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= load_ix;
|
|
when "1001" => -- dex
|
|
left_ctrl <= ix_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_dex;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= load_ix;
|
|
when "1010" => -- clv
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_clv;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
when "1011" => -- sev
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_sev;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
when "1100" => -- clc
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_clc;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
when "1101" => -- sec
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_sec;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
when "1110" => -- cli
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_cli;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
when "1111" => -- sei
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_sei;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
when others =>
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
end case;
|
|
next_state <= fetch_state;
|
|
-- acca / accb inherent instructions
|
|
when "0001" =>
|
|
md_ctrl <= fetch_first_md;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
pc_ctrl <= latch_pc;
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= accb_right;
|
|
case op_code(3 downto 0) is
|
|
when "0000" => -- sba
|
|
alu_ctrl <= alu_sub8;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= load_acca;
|
|
accb_ctrl <= latch_accb;
|
|
when "0001" => -- cba
|
|
alu_ctrl <= alu_sub8;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
when "0110" => -- tab
|
|
alu_ctrl <= alu_st8;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= load_accb;
|
|
when "0111" => -- tba
|
|
alu_ctrl <= alu_ld8;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= load_acca;
|
|
accb_ctrl <= latch_accb;
|
|
when "1001" => -- daa
|
|
alu_ctrl <= alu_daa;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= load_acca;
|
|
accb_ctrl <= latch_accb;
|
|
when "1011" => -- aba
|
|
alu_ctrl <= alu_add8;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= load_acca;
|
|
accb_ctrl <= latch_accb;
|
|
when others =>
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
end case;
|
|
next_state <= fetch_state;
|
|
when "0010" => -- branch conditional
|
|
md_ctrl <= fetch_first_md;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
-- increment the pc
|
|
pc_ctrl <= inc_pc;
|
|
case op_code(3 downto 0) is
|
|
when "0000" => -- bra
|
|
next_state <= branch_state;
|
|
when "0001" => -- brn
|
|
next_state <= fetch_state;
|
|
when "0010" => -- bhi
|
|
if (cc(CBIT) or cc(ZBIT)) = '0' then
|
|
next_state <= branch_state;
|
|
else
|
|
next_state <= fetch_state;
|
|
end if;
|
|
when "0011" => -- bls
|
|
if (cc(CBIT) or cc(ZBIT)) = '1' then
|
|
next_state <= branch_state;
|
|
else
|
|
next_state <= fetch_state;
|
|
end if;
|
|
when "0100" => -- bcc/bhs
|
|
if cc(CBIT) = '0' then
|
|
next_state <= branch_state;
|
|
else
|
|
next_state <= fetch_state;
|
|
end if;
|
|
when "0101" => -- bcs/blo
|
|
if cc(CBIT) = '1' then
|
|
next_state <= branch_state;
|
|
else
|
|
next_state <= fetch_state;
|
|
end if;
|
|
when "0110" => -- bne
|
|
if cc(ZBIT) = '0' then
|
|
next_state <= branch_state;
|
|
else
|
|
next_state <= fetch_state;
|
|
end if;
|
|
when "0111" => -- beq
|
|
if cc(ZBIT) = '1' then
|
|
next_state <= branch_state;
|
|
else
|
|
next_state <= fetch_state;
|
|
end if;
|
|
when "1000" => -- bvc
|
|
if cc(VBIT) = '0' then
|
|
next_state <= branch_state;
|
|
else
|
|
next_state <= fetch_state;
|
|
end if;
|
|
when "1001" => -- bvs
|
|
if cc(VBIT) = '1' then
|
|
next_state <= branch_state;
|
|
else
|
|
next_state <= fetch_state;
|
|
end if;
|
|
when "1010" => -- bpl
|
|
if cc(NBIT) = '0' then
|
|
next_state <= branch_state;
|
|
else
|
|
next_state <= fetch_state;
|
|
end if;
|
|
when "1011" => -- bmi
|
|
if cc(NBIT) = '1' then
|
|
next_state <= branch_state;
|
|
else
|
|
next_state <= fetch_state;
|
|
end if;
|
|
when "1100" => -- bge
|
|
if (cc(NBIT) xor cc(VBIT)) = '0' then
|
|
next_state <= branch_state;
|
|
else
|
|
next_state <= fetch_state;
|
|
end if;
|
|
when "1101" => -- blt
|
|
if (cc(NBIT) xor cc(VBIT)) = '1' then
|
|
next_state <= branch_state;
|
|
else
|
|
next_state <= fetch_state;
|
|
end if;
|
|
when "1110" => -- bgt
|
|
if (cc(ZBIT) or (cc(NBIT) xor cc(VBIT))) = '0' then
|
|
next_state <= branch_state;
|
|
else
|
|
next_state <= fetch_state;
|
|
end if;
|
|
when "1111" => -- ble
|
|
if (cc(ZBIT) or (cc(NBIT) xor cc(VBIT))) = '1' then
|
|
next_state <= branch_state;
|
|
else
|
|
next_state <= fetch_state;
|
|
end if;
|
|
when others =>
|
|
next_state <= fetch_state;
|
|
end case;
|
|
--
|
|
-- Single byte stack operators
|
|
-- Do not advance PC
|
|
--
|
|
when "0011" =>
|
|
md_ctrl <= fetch_first_md;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
pc_ctrl <= latch_pc;
|
|
case op_code(3 downto 0) is
|
|
when "0000" => -- tsx
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_add16;
|
|
cc_ctrl <= latch_cc;
|
|
ix_ctrl <= load_ix;
|
|
sp_ctrl <= latch_sp;
|
|
next_state <= fetch_state;
|
|
when "0001" => -- ins
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_add16;
|
|
cc_ctrl <= latch_cc;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= load_sp;
|
|
next_state <= fetch_state;
|
|
when "0010" => -- pula
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_add16;
|
|
cc_ctrl <= latch_cc;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= load_sp;
|
|
next_state <= pula_state;
|
|
when "0011" => -- pulb
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_add16;
|
|
cc_ctrl <= latch_cc;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= load_sp;
|
|
next_state <= pulb_state;
|
|
when "0100" => -- des
|
|
-- decrement sp
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_sub16;
|
|
cc_ctrl <= latch_cc;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= load_sp;
|
|
next_state <= fetch_state;
|
|
when "0101" => -- txs
|
|
left_ctrl <= ix_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_sub16;
|
|
cc_ctrl <= latch_cc;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= load_sp;
|
|
next_state <= fetch_state;
|
|
when "0110" => -- psha
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
next_state <= psha_state;
|
|
when "0111" => -- pshb
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
next_state <= pshb_state;
|
|
when "1000" => -- pulx
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_add16;
|
|
cc_ctrl <= latch_cc;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= load_sp;
|
|
next_state <= pulx_hi_state;
|
|
when "1001" => -- rts
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_add16;
|
|
cc_ctrl <= latch_cc;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= load_sp;
|
|
next_state <= rts_hi_state;
|
|
when "1010" => -- abx
|
|
left_ctrl <= ix_left;
|
|
right_ctrl <= accb_right;
|
|
alu_ctrl <= alu_add16;
|
|
cc_ctrl <= latch_cc;
|
|
ix_ctrl <= load_ix;
|
|
sp_ctrl <= latch_sp;
|
|
next_state <= fetch_state;
|
|
when "1011" => -- rti
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_add16;
|
|
cc_ctrl <= latch_cc;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= load_sp;
|
|
next_state <= rti_cc_state;
|
|
when "1100" => -- pshx
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
next_state <= pshx_lo_state;
|
|
when "1101" => -- mul
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= accb_right;
|
|
alu_ctrl <= alu_add16;
|
|
cc_ctrl <= latch_cc;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
next_state <= mul_state;
|
|
when "1110" => -- wai
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
next_state <= int_pcl_state;
|
|
when "1111" => -- swi
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
next_state <= int_pcl_state;
|
|
when others =>
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
next_state <= fetch_state;
|
|
end case;
|
|
--
|
|
-- Accumulator A Single operand
|
|
-- source = Acc A dest = Acc A
|
|
-- Do not advance PC
|
|
--
|
|
when "0100" => -- acca single op
|
|
md_ctrl <= fetch_first_md;
|
|
accb_ctrl <= latch_accb;
|
|
pc_ctrl <= latch_pc;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
left_ctrl <= acca_left;
|
|
case op_code(3 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 <= plus_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 <= plus_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_clr;
|
|
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;
|
|
next_state <= fetch_state;
|
|
--
|
|
-- single operand acc b
|
|
-- Do not advance PC
|
|
--
|
|
when "0101" =>
|
|
md_ctrl <= fetch_first_md;
|
|
acca_ctrl <= latch_acca;
|
|
pc_ctrl <= latch_pc;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
left_ctrl <= accb_left;
|
|
case op_code(3 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 <= plus_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 <= plus_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_clr;
|
|
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;
|
|
next_state <= fetch_state;
|
|
--
|
|
-- Single operand indexed
|
|
-- Two byte instruction so advance PC
|
|
-- EA should hold index offset
|
|
--
|
|
when "0110" => -- indexed single op
|
|
md_ctrl <= fetch_first_md;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
-- increment the pc
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
pc_ctrl <= inc_pc;
|
|
next_state <= indexed_state;
|
|
--
|
|
-- Single operand extended addressing
|
|
-- three byte instruction so advance the PC
|
|
-- Low order EA holds high order address
|
|
--
|
|
when "0111" => -- extended single op
|
|
md_ctrl <= fetch_first_md;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
-- increment the pc
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
pc_ctrl <= inc_pc;
|
|
next_state <= extended_state;
|
|
|
|
when "1000" => -- acca immediate
|
|
md_ctrl <= fetch_first_md;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
-- increment the pc
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
pc_ctrl <= inc_pc;
|
|
case op_code(3 downto 0) is
|
|
when "0011" | -- subdd #
|
|
"1100" | -- cpx #
|
|
"1110" => -- lds #
|
|
next_state <= immediate16_state;
|
|
when "1101" => -- bsr
|
|
next_state <= bsr_state;
|
|
when others =>
|
|
next_state <= fetch_state;
|
|
end case;
|
|
|
|
when "1001" => -- acca direct
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
-- increment the pc
|
|
pc_ctrl <= inc_pc;
|
|
case op_code(3 downto 0) is
|
|
when "0111" => -- staa direct
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_st8;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= load_md;
|
|
next_state <= write8_state;
|
|
when "1111" => -- sts direct
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_st16;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= load_md;
|
|
next_state <= write16_state;
|
|
when "1101" => -- jsr direct
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= fetch_first_md;
|
|
next_state <= jsr_state;
|
|
when others =>
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= fetch_first_md;
|
|
next_state <= read8_state;
|
|
end case;
|
|
|
|
when "1010" => -- acca indexed
|
|
md_ctrl <= fetch_first_md;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
-- increment the pc
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
pc_ctrl <= inc_pc;
|
|
next_state <= indexed_state;
|
|
|
|
when "1011" => -- acca extended
|
|
md_ctrl <= fetch_first_md;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
-- increment the pc
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
pc_ctrl <= inc_pc;
|
|
next_state <= extended_state;
|
|
|
|
when "1100" => -- accb immediate
|
|
md_ctrl <= fetch_first_md;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
-- increment the pc
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
pc_ctrl <= inc_pc;
|
|
case op_code(3 downto 0) is
|
|
when "0011" | -- addd #
|
|
"1100" | -- ldd #
|
|
"1110" => -- ldx #
|
|
next_state <= immediate16_state;
|
|
when others =>
|
|
next_state <= fetch_state;
|
|
end case;
|
|
|
|
when "1101" => -- accb direct
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
-- increment the pc
|
|
pc_ctrl <= inc_pc;
|
|
case op_code(3 downto 0) is
|
|
when "0111" => -- stab direct
|
|
left_ctrl <= accb_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_st8;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= load_md;
|
|
next_state <= write8_state;
|
|
when "1101" => -- std direct
|
|
left_ctrl <= accd_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_st16;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= load_md;
|
|
next_state <= write16_state;
|
|
when "1111" => -- stx direct
|
|
left_ctrl <= ix_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_st16;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= load_md;
|
|
next_state <= write16_state;
|
|
when others =>
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= fetch_first_md;
|
|
next_state <= read8_state;
|
|
end case;
|
|
|
|
when "1110" => -- accb indexed
|
|
md_ctrl <= fetch_first_md;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
-- increment the pc
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
pc_ctrl <= inc_pc;
|
|
next_state <= indexed_state;
|
|
|
|
when "1111" => -- accb extended
|
|
md_ctrl <= fetch_first_md;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
-- increment the pc
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
pc_ctrl <= inc_pc;
|
|
next_state <= extended_state;
|
|
|
|
when others =>
|
|
md_ctrl <= fetch_first_md;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
-- idle the pc
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
pc_ctrl <= latch_pc;
|
|
next_state <= fetch_state;
|
|
end case;
|
|
|
|
when immediate16_state =>
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
op_ctrl <= latch_op;
|
|
iv_ctrl <= latch_iv;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- increment pc
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
pc_ctrl <= inc_pc;
|
|
-- fetch next immediate byte
|
|
md_ctrl <= fetch_next_md;
|
|
addr_ctrl <= fetch_ad;
|
|
dout_ctrl <= md_lo_dout;
|
|
next_state <= fetch_state;
|
|
--
|
|
-- ea holds 8 bit index offet
|
|
-- calculate the effective memory address
|
|
-- using the alu
|
|
--
|
|
when indexed_state =>
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
pc_ctrl <= latch_pc;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
-- calculate effective address from index reg
|
|
-- index offest is not sign extended
|
|
ea_ctrl <= add_ix_ea;
|
|
-- idle the bus
|
|
addr_ctrl <= idle_ad;
|
|
dout_ctrl <= md_lo_dout;
|
|
-- work out next state
|
|
case op_code(7 downto 4) is
|
|
when "0110" => -- single op indexed
|
|
md_ctrl <= latch_md;
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
case op_code(3 downto 0) is
|
|
when "1011" => -- undefined
|
|
next_state <= fetch_state;
|
|
when "1110" => -- jmp
|
|
next_state <= jmp_state;
|
|
when others =>
|
|
next_state <= read8_state;
|
|
end case;
|
|
when "1010" => -- acca indexed
|
|
case op_code(3 downto 0) is
|
|
when "0111" => -- staa
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_st8;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= load_md;
|
|
next_state <= write8_state;
|
|
when "1101" => -- jsr
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= latch_md;
|
|
next_state <= jsr_state;
|
|
when "1111" => -- sts
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_st16;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= load_md;
|
|
next_state <= write16_state;
|
|
when others =>
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= latch_md;
|
|
next_state <= read8_state;
|
|
end case;
|
|
when "1110" => -- accb indexed
|
|
case op_code(3 downto 0) is
|
|
when "0111" => -- stab direct
|
|
left_ctrl <= accb_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_st8;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= load_md;
|
|
next_state <= write8_state;
|
|
when "1101" => -- std direct
|
|
left_ctrl <= accd_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_st16;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= load_md;
|
|
next_state <= write16_state;
|
|
when "1111" => -- stx direct
|
|
left_ctrl <= ix_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_st16;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= load_md;
|
|
next_state <= write16_state;
|
|
when others =>
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= latch_md;
|
|
next_state <= read8_state;
|
|
end case;
|
|
when others =>
|
|
md_ctrl <= latch_md;
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
next_state <= fetch_state;
|
|
end case;
|
|
--
|
|
-- 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;
|
|
sp_ctrl <= latch_sp;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
-- increment pc
|
|
pc_ctrl <= inc_pc;
|
|
-- fetch next effective address bytes
|
|
ea_ctrl <= fetch_next_ea;
|
|
addr_ctrl <= fetch_ad;
|
|
dout_ctrl <= md_lo_dout;
|
|
-- work out the next state
|
|
case op_code(7 downto 4) is
|
|
when "0111" => -- single op extended
|
|
md_ctrl <= latch_md;
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
case op_code(3 downto 0) is
|
|
when "1011" => -- undefined
|
|
next_state <= fetch_state;
|
|
when "1110" => -- jmp
|
|
next_state <= jmp_state;
|
|
when others =>
|
|
next_state <= read8_state;
|
|
end case;
|
|
when "1011" => -- acca extended
|
|
case op_code(3 downto 0) is
|
|
when "0111" => -- staa
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_st8;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= load_md;
|
|
next_state <= write8_state;
|
|
when "1101" => -- jsr
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= latch_md;
|
|
next_state <= jsr_state;
|
|
when "1111" => -- sts
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_st16;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= load_md;
|
|
next_state <= write16_state;
|
|
when others =>
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= latch_md;
|
|
next_state <= read8_state;
|
|
end case;
|
|
when "1111" => -- accb extended
|
|
case op_code(3 downto 0) is
|
|
when "0111" => -- stab
|
|
left_ctrl <= accb_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_st8;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= load_md;
|
|
next_state <= write8_state;
|
|
when "1101" => -- std
|
|
left_ctrl <= accd_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_st16;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= load_md;
|
|
next_state <= write16_state;
|
|
when "1111" => -- stx
|
|
left_ctrl <= ix_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_st16;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= load_md;
|
|
next_state <= write16_state;
|
|
when others =>
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= latch_md;
|
|
next_state <= read8_state;
|
|
end case;
|
|
when others =>
|
|
md_ctrl <= latch_md;
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
next_state <= fetch_state;
|
|
end case;
|
|
--
|
|
-- here if ea holds low byte (direct page)
|
|
-- can enter here from extended addressing
|
|
-- read memory location
|
|
-- note that reads may be 8 or 16 bits
|
|
--
|
|
when read8_state => -- read data
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
pc_ctrl <= latch_pc;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
--
|
|
addr_ctrl <= read_ad;
|
|
dout_ctrl <= md_lo_dout;
|
|
case op_code(7 downto 4) is
|
|
when "0110" | "0111" => -- single operand
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= fetch_first_md;
|
|
ea_ctrl <= latch_ea;
|
|
next_state <= execute_state;
|
|
|
|
when "1001" | "1010" | "1011" => -- acca
|
|
case op_code(3 downto 0) is
|
|
when "0011" | -- subd
|
|
"1110" | -- lds
|
|
"1100" => -- cpx
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= fetch_first_md;
|
|
-- increment the effective address in case of 16 bit load
|
|
ea_ctrl <= inc_ea;
|
|
next_state <= read16_state;
|
|
-- when "0111" => -- staa
|
|
-- left_ctrl <= acca_left;
|
|
-- right_ctrl <= zero_right;
|
|
-- alu_ctrl <= alu_st8;
|
|
-- cc_ctrl <= latch_cc;
|
|
-- md_ctrl <= load_md;
|
|
-- ea_ctrl <= latch_ea;
|
|
-- next_state <= write8_state;
|
|
-- when "1101" => -- jsr
|
|
-- left_ctrl <= acca_left;
|
|
-- right_ctrl <= zero_right;
|
|
-- alu_ctrl <= alu_nop;
|
|
-- cc_ctrl <= latch_cc;
|
|
-- md_ctrl <= latch_md;
|
|
-- ea_ctrl <= latch_ea;
|
|
-- next_state <= jsr_state;
|
|
-- when "1111" => -- sts
|
|
-- left_ctrl <= sp_left;
|
|
-- right_ctrl <= zero_right;
|
|
-- alu_ctrl <= alu_st16;
|
|
-- cc_ctrl <= latch_cc;
|
|
-- md_ctrl <= load_md;
|
|
-- ea_ctrl <= latch_ea;
|
|
-- next_state <= write16_state;
|
|
when others =>
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= fetch_first_md;
|
|
ea_ctrl <= latch_ea;
|
|
next_state <= fetch_state;
|
|
end case;
|
|
|
|
when "1101" | "1110" | "1111" => -- accb
|
|
case op_code(3 downto 0) is
|
|
when "0011" | -- addd
|
|
"1100" | -- ldd
|
|
"1110" => -- ldx
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= fetch_first_md;
|
|
-- increment the effective address in case of 16 bit load
|
|
ea_ctrl <= inc_ea;
|
|
next_state <= read16_state;
|
|
-- when "0111" => -- stab
|
|
-- left_ctrl <= accb_left;
|
|
-- right_ctrl <= zero_right;
|
|
-- alu_ctrl <= alu_st8;
|
|
-- cc_ctrl <= latch_cc;
|
|
-- md_ctrl <= load_md;
|
|
-- ea_ctrl <= latch_ea;
|
|
-- next_state <= write8_state;
|
|
-- when "1101" => -- std
|
|
-- left_ctrl <= accd_left;
|
|
-- right_ctrl <= zero_right;
|
|
-- alu_ctrl <= alu_st16;
|
|
-- cc_ctrl <= latch_cc;
|
|
-- md_ctrl <= load_md;
|
|
-- ea_ctrl <= latch_ea;
|
|
-- next_state <= write16_state;
|
|
-- when "1111" => -- stx
|
|
-- left_ctrl <= ix_left;
|
|
-- right_ctrl <= zero_right;
|
|
-- alu_ctrl <= alu_st16;
|
|
-- cc_ctrl <= latch_cc;
|
|
-- md_ctrl <= load_md;
|
|
-- ea_ctrl <= latch_ea;
|
|
-- next_state <= write16_state;
|
|
when others =>
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= fetch_first_md;
|
|
ea_ctrl <= latch_ea;
|
|
next_state <= execute_state;
|
|
end case;
|
|
when others =>
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= fetch_first_md;
|
|
ea_ctrl <= latch_ea;
|
|
next_state <= fetch_state;
|
|
end case;
|
|
|
|
when read16_state => -- read second data byte from ea
|
|
-- default
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
pc_ctrl <= latch_pc;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
-- idle the effective address
|
|
ea_ctrl <= latch_ea;
|
|
-- read the low byte of the 16 bit data
|
|
md_ctrl <= fetch_next_md;
|
|
addr_ctrl <= read_ad;
|
|
dout_ctrl <= md_lo_dout;
|
|
next_state <= fetch_state;
|
|
--
|
|
-- 16 bit Write state
|
|
-- write high byte of ALU output.
|
|
-- EA hold address of memory to write to
|
|
-- Advance the effective address in ALU
|
|
--
|
|
when write16_state =>
|
|
-- default
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
-- increment the effective address
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
ea_ctrl <= inc_ea;
|
|
-- write the ALU hi byte to ea
|
|
addr_ctrl <= write_ad;
|
|
dout_ctrl <= md_hi_dout;
|
|
next_state <= write8_state;
|
|
--
|
|
-- 8 bit write
|
|
-- Write low 8 bits of ALU output
|
|
--
|
|
when write8_state =>
|
|
-- default registers
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- idle the ALU
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
-- write ALU low byte output
|
|
addr_ctrl <= write_ad;
|
|
dout_ctrl <= md_lo_dout;
|
|
next_state <= fetch_state;
|
|
|
|
when jmp_state =>
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- load PC with effective address
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
pc_ctrl <= load_ea_pc;
|
|
-- idle the bus
|
|
addr_ctrl <= idle_ad;
|
|
dout_ctrl <= md_lo_dout;
|
|
next_state <= fetch_state;
|
|
|
|
when jsr_state => -- JSR
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- decrement sp
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_sub16;
|
|
cc_ctrl <= latch_cc;
|
|
sp_ctrl <= load_sp;
|
|
-- write pc low
|
|
addr_ctrl <= push_ad;
|
|
dout_ctrl <= pc_lo_dout;
|
|
next_state <= jsr1_state;
|
|
|
|
when jsr1_state => -- JSR
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- decrement sp
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_sub16;
|
|
cc_ctrl <= latch_cc;
|
|
sp_ctrl <= load_sp;
|
|
-- write pc hi
|
|
addr_ctrl <= push_ad;
|
|
dout_ctrl <= pc_hi_dout;
|
|
next_state <= jmp_state;
|
|
|
|
when branch_state => -- Bcc
|
|
-- default registers
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- calculate signed branch
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
pc_ctrl <= add_ea_pc;
|
|
-- idle the bus
|
|
addr_ctrl <= idle_ad;
|
|
dout_ctrl <= md_lo_dout;
|
|
next_state <= fetch_state;
|
|
|
|
when bsr_state => -- BSR
|
|
-- default
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- decrement sp
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_sub16;
|
|
cc_ctrl <= latch_cc;
|
|
sp_ctrl <= load_sp;
|
|
-- write pc low
|
|
addr_ctrl <= push_ad;
|
|
dout_ctrl <= pc_lo_dout;
|
|
next_state <= bsr1_state;
|
|
|
|
when bsr1_state => -- BSR
|
|
-- default registers
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- decrement sp
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_sub16;
|
|
cc_ctrl <= latch_cc;
|
|
sp_ctrl <= load_sp;
|
|
-- write pc hi
|
|
addr_ctrl <= push_ad;
|
|
dout_ctrl <= pc_hi_dout;
|
|
next_state <= branch_state;
|
|
|
|
when rts_hi_state => -- RTS
|
|
-- default
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- increment the sp
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_add16;
|
|
cc_ctrl <= latch_cc;
|
|
sp_ctrl <= load_sp;
|
|
-- read pc hi
|
|
pc_ctrl <= pull_hi_pc;
|
|
addr_ctrl <= pull_ad;
|
|
dout_ctrl <= pc_hi_dout;
|
|
next_state <= rts_lo_state;
|
|
|
|
when rts_lo_state => -- RTS1
|
|
-- default
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- idle the ALU
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
-- read pc low
|
|
pc_ctrl <= pull_lo_pc;
|
|
addr_ctrl <= pull_ad;
|
|
dout_ctrl <= pc_lo_dout;
|
|
next_state <= fetch_state;
|
|
|
|
when mul_state =>
|
|
-- default
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
pc_ctrl <= latch_pc;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- move acca to md
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_st16;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= load_md;
|
|
-- idle bus
|
|
addr_ctrl <= idle_ad;
|
|
dout_ctrl <= md_lo_dout;
|
|
next_state <= mulea_state;
|
|
|
|
when mulea_state =>
|
|
-- default
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
pc_ctrl <= latch_pc;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
md_ctrl <= latch_md;
|
|
-- idle ALU
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
-- move accb to ea
|
|
ea_ctrl <= load_accb_ea;
|
|
-- idle bus
|
|
addr_ctrl <= idle_ad;
|
|
dout_ctrl <= md_lo_dout;
|
|
next_state <= muld_state;
|
|
|
|
when muld_state =>
|
|
-- default
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
pc_ctrl <= latch_pc;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
md_ctrl <= latch_md;
|
|
-- clear accd
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_ld8;
|
|
cc_ctrl <= latch_cc;
|
|
acca_ctrl <= load_hi_acca;
|
|
accb_ctrl <= load_accb;
|
|
-- idle bus
|
|
addr_ctrl <= idle_ad;
|
|
dout_ctrl <= md_lo_dout;
|
|
next_state <= mul0_state;
|
|
|
|
when mul0_state =>
|
|
-- default
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
pc_ctrl <= latch_pc;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- if bit 0 of ea set, add accd to md
|
|
left_ctrl <= accd_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_add16;
|
|
if ea(0) = '1' 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;
|
|
next_state <= mul1_state;
|
|
|
|
when mul1_state =>
|
|
-- default
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
pc_ctrl <= latch_pc;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- if bit 1 of ea set, add accd to md
|
|
left_ctrl <= accd_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_add16;
|
|
if ea(1) = '1' 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;
|
|
next_state <= mul2_state;
|
|
|
|
when mul2_state =>
|
|
-- default
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
pc_ctrl <= latch_pc;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- if bit 2 of ea set, add accd to md
|
|
left_ctrl <= accd_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_add16;
|
|
if ea(2) = '1' 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;
|
|
next_state <= mul3_state;
|
|
|
|
when mul3_state =>
|
|
-- default
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
pc_ctrl <= latch_pc;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- if bit 3 of ea set, add accd to md
|
|
left_ctrl <= accd_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_add16;
|
|
if ea(3) = '1' 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;
|
|
next_state <= mul4_state;
|
|
|
|
when mul4_state =>
|
|
-- default
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
pc_ctrl <= latch_pc;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- if bit 4 of ea set, add accd to md
|
|
left_ctrl <= accd_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_add16;
|
|
if ea(4) = '1' 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;
|
|
next_state <= mul5_state;
|
|
|
|
when mul5_state =>
|
|
-- default
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
pc_ctrl <= latch_pc;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- if bit 5 of ea set, add accd to md
|
|
left_ctrl <= accd_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_add16;
|
|
if ea(5) = '1' 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;
|
|
next_state <= mul6_state;
|
|
|
|
when mul6_state =>
|
|
-- default
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
pc_ctrl <= latch_pc;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- if bit 6 of ea set, add accd to md
|
|
left_ctrl <= accd_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_add16;
|
|
if ea(6) = '1' 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;
|
|
next_state <= mul7_state;
|
|
|
|
when mul7_state =>
|
|
-- default
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
pc_ctrl <= latch_pc;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- if bit 7 of ea set, add accd to md
|
|
left_ctrl <= accd_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_add16;
|
|
if ea(7) = '1' 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;
|
|
next_state <= fetch_state;
|
|
|
|
when execute_state => -- execute single operand instruction
|
|
-- default
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
case op_code(7 downto 4) is
|
|
when "0110" | -- indexed single op
|
|
"0111" => -- extended single op
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
pc_ctrl <= latch_pc;
|
|
iv_ctrl <= latch_iv;
|
|
ea_ctrl <= latch_ea;
|
|
-- idle the bus
|
|
addr_ctrl <= idle_ad;
|
|
dout_ctrl <= md_lo_dout;
|
|
left_ctrl <= md_left;
|
|
case op_code(3 downto 0) is
|
|
when "0000" => -- neg
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_neg;
|
|
cc_ctrl <= load_cc;
|
|
md_ctrl <= load_md;
|
|
next_state <= write8_state;
|
|
when "0011" => -- com
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_com;
|
|
cc_ctrl <= load_cc;
|
|
md_ctrl <= load_md;
|
|
next_state <= write8_state;
|
|
when "0100" => -- lsr
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_lsr8;
|
|
cc_ctrl <= load_cc;
|
|
md_ctrl <= load_md;
|
|
next_state <= write8_state;
|
|
when "0110" => -- ror
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_ror8;
|
|
cc_ctrl <= load_cc;
|
|
md_ctrl <= load_md;
|
|
next_state <= write8_state;
|
|
when "0111" => -- asr
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_asr8;
|
|
cc_ctrl <= load_cc;
|
|
md_ctrl <= load_md;
|
|
next_state <= write8_state;
|
|
when "1000" => -- asl
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_asl8;
|
|
cc_ctrl <= load_cc;
|
|
md_ctrl <= load_md;
|
|
next_state <= write8_state;
|
|
when "1001" => -- rol
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_rol8;
|
|
cc_ctrl <= load_cc;
|
|
md_ctrl <= load_md;
|
|
next_state <= write8_state;
|
|
when "1010" => -- dec
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_dec;
|
|
cc_ctrl <= load_cc;
|
|
md_ctrl <= load_md;
|
|
next_state <= write8_state;
|
|
when "1011" => -- undefined
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= latch_md;
|
|
next_state <= fetch_state;
|
|
when "1100" => -- inc
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_inc;
|
|
cc_ctrl <= load_cc;
|
|
md_ctrl <= load_md;
|
|
next_state <= write8_state;
|
|
when "1101" => -- tst
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_st8;
|
|
cc_ctrl <= load_cc;
|
|
md_ctrl <= latch_md;
|
|
next_state <= fetch_state;
|
|
when "1110" => -- jmp
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= latch_md;
|
|
next_state <= fetch_state;
|
|
when "1111" => -- clr
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_clr;
|
|
cc_ctrl <= load_cc;
|
|
md_ctrl <= load_md;
|
|
next_state <= write8_state;
|
|
when others =>
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
md_ctrl <= latch_md;
|
|
next_state <= fetch_state;
|
|
end case;
|
|
|
|
when others =>
|
|
left_ctrl <= accd_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
ea_ctrl <= latch_ea;
|
|
-- idle the bus
|
|
addr_ctrl <= idle_ad;
|
|
dout_ctrl <= md_lo_dout;
|
|
next_state <= fetch_state;
|
|
end case;
|
|
|
|
when psha_state =>
|
|
-- default registers
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- decrement sp
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_sub16;
|
|
cc_ctrl <= latch_cc;
|
|
sp_ctrl <= load_sp;
|
|
-- write acca
|
|
addr_ctrl <= push_ad;
|
|
dout_ctrl <= acca_dout;
|
|
next_state <= fetch_state;
|
|
|
|
when pula_state =>
|
|
-- default registers
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- idle sp
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
sp_ctrl <= latch_sp;
|
|
-- read acca
|
|
acca_ctrl <= pull_acca;
|
|
addr_ctrl <= pull_ad;
|
|
dout_ctrl <= acca_dout;
|
|
next_state <= fetch_state;
|
|
|
|
when pshb_state =>
|
|
-- default registers
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- decrement sp
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_sub16;
|
|
cc_ctrl <= latch_cc;
|
|
sp_ctrl <= load_sp;
|
|
-- write accb
|
|
addr_ctrl <= push_ad;
|
|
dout_ctrl <= accb_dout;
|
|
next_state <= fetch_state;
|
|
|
|
when pulb_state =>
|
|
-- default
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- idle sp
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
sp_ctrl <= latch_sp;
|
|
-- read accb
|
|
accb_ctrl <= pull_accb;
|
|
addr_ctrl <= pull_ad;
|
|
dout_ctrl <= accb_dout;
|
|
next_state <= fetch_state;
|
|
|
|
when pshx_lo_state =>
|
|
-- default
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- decrement sp
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_sub16;
|
|
cc_ctrl <= latch_cc;
|
|
sp_ctrl <= load_sp;
|
|
-- write ix low
|
|
addr_ctrl <= push_ad;
|
|
dout_ctrl <= ix_lo_dout;
|
|
next_state <= pshx_hi_state;
|
|
|
|
when pshx_hi_state =>
|
|
-- default registers
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- decrement sp
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_sub16;
|
|
cc_ctrl <= latch_cc;
|
|
sp_ctrl <= load_sp;
|
|
-- write ix hi
|
|
addr_ctrl <= push_ad;
|
|
dout_ctrl <= ix_hi_dout;
|
|
next_state <= fetch_state;
|
|
|
|
when pulx_hi_state =>
|
|
-- default
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- increment sp
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_add16;
|
|
cc_ctrl <= latch_cc;
|
|
sp_ctrl <= load_sp;
|
|
-- pull ix hi
|
|
ix_ctrl <= pull_hi_ix;
|
|
addr_ctrl <= pull_ad;
|
|
dout_ctrl <= ix_hi_dout;
|
|
next_state <= pulx_lo_state;
|
|
|
|
when pulx_lo_state =>
|
|
-- default
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- idle sp
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
sp_ctrl <= latch_sp;
|
|
-- read ix low
|
|
ix_ctrl <= pull_lo_ix;
|
|
addr_ctrl <= pull_ad;
|
|
dout_ctrl <= ix_lo_dout;
|
|
next_state <= fetch_state;
|
|
|
|
--
|
|
-- return from interrupt
|
|
-- enter here from bogus interrupts
|
|
--
|
|
when rti_state =>
|
|
-- default registers
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- increment sp
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_add16;
|
|
sp_ctrl <= load_sp;
|
|
-- idle address bus
|
|
cc_ctrl <= latch_cc;
|
|
addr_ctrl <= idle_ad;
|
|
dout_ctrl <= cc_dout;
|
|
next_state <= rti_cc_state;
|
|
|
|
when rti_cc_state =>
|
|
-- default registers
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- increment sp
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_add16;
|
|
sp_ctrl <= load_sp;
|
|
-- read cc
|
|
cc_ctrl <= pull_cc;
|
|
addr_ctrl <= pull_ad;
|
|
dout_ctrl <= cc_dout;
|
|
next_state <= rti_accb_state;
|
|
|
|
when rti_accb_state =>
|
|
-- default registers
|
|
acca_ctrl <= latch_acca;
|
|
ix_ctrl <= latch_ix;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- increment sp
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_add16;
|
|
cc_ctrl <= latch_cc;
|
|
sp_ctrl <= load_sp;
|
|
-- read accb
|
|
accb_ctrl <= pull_accb;
|
|
addr_ctrl <= pull_ad;
|
|
dout_ctrl <= accb_dout;
|
|
next_state <= rti_acca_state;
|
|
|
|
when rti_acca_state =>
|
|
-- default registers
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- increment sp
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_add16;
|
|
cc_ctrl <= latch_cc;
|
|
sp_ctrl <= load_sp;
|
|
-- read acca
|
|
acca_ctrl <= pull_acca;
|
|
addr_ctrl <= pull_ad;
|
|
dout_ctrl <= acca_dout;
|
|
next_state <= rti_ixh_state;
|
|
|
|
when rti_ixh_state =>
|
|
-- default
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- increment sp
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_add16;
|
|
cc_ctrl <= latch_cc;
|
|
sp_ctrl <= load_sp;
|
|
-- read ix hi
|
|
ix_ctrl <= pull_hi_ix;
|
|
addr_ctrl <= pull_ad;
|
|
dout_ctrl <= ix_hi_dout;
|
|
next_state <= rti_ixl_state;
|
|
|
|
when rti_ixl_state =>
|
|
-- default
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- increment sp
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_add16;
|
|
cc_ctrl <= latch_cc;
|
|
sp_ctrl <= load_sp;
|
|
-- read ix low
|
|
ix_ctrl <= pull_lo_ix;
|
|
addr_ctrl <= pull_ad;
|
|
dout_ctrl <= ix_lo_dout;
|
|
next_state <= rti_pch_state;
|
|
|
|
when rti_pch_state =>
|
|
-- default
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- increment sp
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_add16;
|
|
cc_ctrl <= latch_cc;
|
|
sp_ctrl <= load_sp;
|
|
-- pull pc hi
|
|
pc_ctrl <= pull_hi_pc;
|
|
addr_ctrl <= pull_ad;
|
|
dout_ctrl <= pc_hi_dout;
|
|
next_state <= rti_pcl_state;
|
|
|
|
when rti_pcl_state =>
|
|
-- default
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- idle sp
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
sp_ctrl <= latch_sp;
|
|
-- pull pc low
|
|
pc_ctrl <= pull_lo_pc;
|
|
addr_ctrl <= pull_ad;
|
|
dout_ctrl <= pc_lo_dout;
|
|
next_state <= fetch_state;
|
|
|
|
--
|
|
-- here on interrupt
|
|
-- iv register hold interrupt type
|
|
--
|
|
when int_pcl_state =>
|
|
-- default
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- decrement sp
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_sub16;
|
|
cc_ctrl <= latch_cc;
|
|
sp_ctrl <= load_sp;
|
|
-- write pc low
|
|
addr_ctrl <= push_ad;
|
|
dout_ctrl <= pc_lo_dout;
|
|
next_state <= int_pch_state;
|
|
|
|
when int_pch_state =>
|
|
-- default
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- decrement sp
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_sub16;
|
|
cc_ctrl <= latch_cc;
|
|
sp_ctrl <= load_sp;
|
|
-- write pc hi
|
|
addr_ctrl <= push_ad;
|
|
dout_ctrl <= pc_hi_dout;
|
|
next_state <= int_ixl_state;
|
|
|
|
when int_ixl_state =>
|
|
-- default
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- decrement sp
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_sub16;
|
|
cc_ctrl <= latch_cc;
|
|
sp_ctrl <= load_sp;
|
|
-- write ix low
|
|
addr_ctrl <= push_ad;
|
|
dout_ctrl <= ix_lo_dout;
|
|
next_state <= int_ixh_state;
|
|
|
|
when int_ixh_state =>
|
|
-- default
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- decrement sp
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_sub16;
|
|
cc_ctrl <= latch_cc;
|
|
sp_ctrl <= load_sp;
|
|
-- write ix hi
|
|
addr_ctrl <= push_ad;
|
|
dout_ctrl <= ix_hi_dout;
|
|
next_state <= int_acca_state;
|
|
|
|
when int_acca_state =>
|
|
-- default
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- decrement sp
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_sub16;
|
|
cc_ctrl <= latch_cc;
|
|
sp_ctrl <= load_sp;
|
|
-- write acca
|
|
addr_ctrl <= push_ad;
|
|
dout_ctrl <= acca_dout;
|
|
next_state <= int_accb_state;
|
|
|
|
|
|
when int_accb_state =>
|
|
-- default
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- decrement sp
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_sub16;
|
|
cc_ctrl <= latch_cc;
|
|
sp_ctrl <= load_sp;
|
|
-- write accb
|
|
addr_ctrl <= push_ad;
|
|
dout_ctrl <= accb_dout;
|
|
next_state <= int_cc_state;
|
|
|
|
when int_cc_state =>
|
|
-- default
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- decrement sp
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_sub16;
|
|
cc_ctrl <= latch_cc;
|
|
sp_ctrl <= load_sp;
|
|
-- write cc
|
|
addr_ctrl <= push_ad;
|
|
dout_ctrl <= cc_dout;
|
|
nmi_ctrl <= latch_nmi;
|
|
--
|
|
-- nmi is edge triggered
|
|
-- nmi_req is cleared when nmi goes low.
|
|
--
|
|
if nmi_req = '1' then
|
|
iv_ctrl <= nmi_iv;
|
|
next_state <= vect_hi_state;
|
|
else
|
|
--
|
|
-- IRQ is level sensitive
|
|
--
|
|
if (irq = '1') and (cc(IBIT) = '0') then
|
|
iv_ctrl <= irq_iv;
|
|
next_state <= int_mask_state;
|
|
else
|
|
case op_code is
|
|
when "00111110" => -- WAI (wait for interrupt)
|
|
iv_ctrl <= latch_iv;
|
|
next_state <= int_wai_state;
|
|
when "00111111" => -- SWI (Software interrupt)
|
|
iv_ctrl <= swi_iv;
|
|
next_state <= vect_hi_state;
|
|
when others => -- bogus interrupt (return)
|
|
iv_ctrl <= latch_iv;
|
|
next_state <= rti_state;
|
|
end case;
|
|
end if;
|
|
end if;
|
|
|
|
when int_wai_state =>
|
|
-- default
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
op_ctrl <= latch_op;
|
|
ea_ctrl <= latch_ea;
|
|
-- enable interrupts
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= plus_one_right;
|
|
alu_ctrl <= alu_cli;
|
|
cc_ctrl <= load_cc;
|
|
sp_ctrl <= latch_sp;
|
|
-- idle bus
|
|
addr_ctrl <= idle_ad;
|
|
dout_ctrl <= cc_dout;
|
|
if (nmi_req = '1') 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;
|
|
else
|
|
iv_ctrl <= latch_iv;
|
|
next_state <= int_wai_state;
|
|
end if;
|
|
end if;
|
|
|
|
when int_mask_state =>
|
|
-- default
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- Mask IRQ
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_sei;
|
|
cc_ctrl <= load_cc;
|
|
sp_ctrl <= latch_sp;
|
|
-- idle bus cycle
|
|
addr_ctrl <= idle_ad;
|
|
dout_ctrl <= md_lo_dout;
|
|
next_state <= vect_hi_state;
|
|
|
|
when halt_state => -- halt CPU.
|
|
-- default
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- do nothing in ALU
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
-- idle bus cycle
|
|
addr_ctrl <= idle_ad;
|
|
dout_ctrl <= md_lo_dout;
|
|
if halt = '1' then
|
|
next_state <= halt_state;
|
|
else
|
|
next_state <= fetch_state;
|
|
end if;
|
|
|
|
when others => -- error state halt on undefine states
|
|
-- default
|
|
acca_ctrl <= latch_acca;
|
|
accb_ctrl <= latch_accb;
|
|
ix_ctrl <= latch_ix;
|
|
sp_ctrl <= latch_sp;
|
|
pc_ctrl <= latch_pc;
|
|
md_ctrl <= latch_md;
|
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
|
nmi_ctrl <= latch_nmi;
|
|
ea_ctrl <= latch_ea;
|
|
-- do nothing in ALU
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
-- idle bus cycle
|
|
addr_ctrl <= idle_ad;
|
|
dout_ctrl <= md_lo_dout;
|
|
next_state <= error_state;
|
|
end case;
|
|
end process;
|
|
|
|
--------------------------------
|
|
--
|
|
-- state machine
|
|
--
|
|
--------------------------------
|
|
|
|
change_state: process( clk, rst, state, hold )
|
|
begin
|
|
if clk'event and clk = '0' then
|
|
if rst = '1' then
|
|
state <= reset_state;
|
|
elsif hold = '1' then
|
|
state <= state;
|
|
else
|
|
state <= next_state;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
-- output
|
|
|
|
end CPU_ARCH;
|