Line 197... |
Line 197... |
-- Version 1.19 - 25th February 2008 - John Kent
|
-- Version 1.19 - 25th February 2008 - John Kent
|
-- Enumerated separate states for FIRQ/FAST and NMIIRQ/ENTIRE
|
-- Enumerated separate states for FIRQ/FAST and NMIIRQ/ENTIRE
|
-- Enumerated separate states for MASKI and MASKIF states
|
-- Enumerated separate states for MASKI and MASKIF states
|
-- Removed code on BSR/JSR in fetch cycle
|
-- Removed code on BSR/JSR in fetch cycle
|
--
|
--
|
-- Version 1.10 - 8th October 2011 - John Kent
|
-- Version 1.20 - 8th October 2011 - John Kent
|
-- added fetch output which should go high during the fetch cycle
|
-- added fetch output which should go high during the fetch cycle
|
--
|
--
|
-- Version 1.11 - 8th October 2011 - John Kent
|
-- Version 1.21 - 8th October 2011 - John Kent
|
-- added Last Instruction Cycle signal
|
-- added Last Instruction Cycle signal
|
-- replaced fetch with ifetch (instruction fetch) signal
|
-- replaced fetch with ifetch (instruction fetch) signal
|
-- added ba & bs (bus available & bus status) signals
|
-- added ba & bs (bus available & bus status) signals
|
--
|
--
|
|
-- Version 1.22 - 2011-10-29 John Kent
|
|
-- The halt state isn't correct.
|
|
-- The halt state is entered into from the fetch_state
|
|
-- It returned to the fetch state which may re-run an execute cycle
|
|
-- on the accumulator and it won't necessarily be the last instruction cycle
|
|
-- I've changed the halt state to return to the decode1_state
|
|
--
|
|
-- Version 1.23 - 2011-10-30 John Kent
|
|
-- sample halt in the change_state process if lic is high (last instruction cycle)
|
|
--
|
|
-- Version 1.24 - 2011-11-01 John Kent
|
|
-- Handle interrupts in change_state process
|
|
-- Sample interrupt inputs on last instruction cycle
|
|
-- Remove iv_ctrl and implement iv (interrupt vector) in change_state process.
|
|
-- Generate fic (first instruction cycle) from lic (last instruction cycle)
|
|
-- and use it to complete the dual operand execute cycle before servicing
|
|
-- halt or interrupts requests.
|
|
-- rename lic to lic_out on the entity declaration so that lic can be tested internally.
|
|
-- add int_firq1_state and int_nmirq1_state to allow for the dual operand execute cycle
|
|
-- integrated nmi_ctrl into change_state process
|
|
-- Reduces the microcode state stack to one entry (saved_state)
|
|
-- imm16_state jumps directly to the fetch_state
|
|
-- pull_return_lo states jumps directly to the fetch_state
|
|
-- duplicate andcc_state as cwai_state
|
|
-- rename exg1_state as exg2 state and duplicate tfr_state as exg1_state
|
|
--
|
|
-- Version 1.25 - 2011-11-27 John Kent
|
|
-- Changed the microcode for saving registers on an interrupt into a microcode subroutine.
|
|
-- Removed SWI servicing from the change state process and made SWI, SWI2 & SWI3
|
|
-- call the interrupt microcode subroutine.
|
|
-- Added additional states for nmi, and irq for interrupt servicing.
|
|
-- Added additional states for nmi/irq, firq, and swi interrupts to mask I & F flags.
|
|
--
|
|
-- Version 1.26 - 2013-03-18 John Kent
|
|
-- pre-initialized cond_true variable to true in state sequencer
|
|
-- re-arranged change_state process slightly
|
|
--
|
|
-- Version 1.27 - 2015-05-30 John Kent
|
|
-- Added test in state machine for masked IRQ and FIRQ in Sync_state.
|
|
--
|
|
-- Version 1.28 - 2015-05-30 John Kent.
|
|
-- Moved IRQ and FIRQ test from state machine to the state sequencer Sync_state.
|
|
--
|
library ieee;
|
library ieee;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_unsigned.all;
|
use ieee.std_logic_unsigned.all;
|
|
|
entity cpu09 is
|
entity cpu09 is
|
port (
|
port (
|
clk : in std_logic; -- E clock input (falling edge)
|
clk : in std_logic; -- E clock input (falling edge)
|
rst : in std_logic; -- reset input (active high)
|
rst : in std_logic; -- reset input (active high)
|
vma : out std_logic; -- valid memory address (active high)
|
vma : out std_logic; -- valid memory address (active high)
|
lic : out std_logic; -- last instruction cycle (active high)
|
lic_out : out std_logic; -- last instruction cycle (active high)
|
ifetch : out std_logic; -- instruction fetch cycle (active high)
|
ifetch : out std_logic; -- instruction fetch cycle (active high)
|
|
opfetch : out std_logic; -- opcode fetch (active high)
|
ba : out std_logic; -- bus available (high on sync wait or DMA grant)
|
ba : out std_logic; -- bus available (high on sync wait or DMA grant)
|
bs : out std_logic; -- bus status (high on interrupt or reset vector fetch or DMA grant)
|
bs : out std_logic; -- bus status (high on interrupt or reset vector fetch or DMA grant)
|
addr : out std_logic_vector(15 downto 0); -- address bus output
|
addr : out std_logic_vector(15 downto 0); -- address bus output
|
rw : out std_logic; -- read not write output
|
rw : out std_logic; -- read not write output
|
data_out : out std_logic_vector(7 downto 0); -- data bus output
|
data_out : out std_logic_vector(7 downto 0); -- data bus output
|
Line 256... |
Line 300... |
constant RESV_VEC : std_logic_vector(2 downto 0) := "000";
|
constant RESV_VEC : std_logic_vector(2 downto 0) := "000";
|
|
|
type state_type is (-- Start off in Reset
|
type state_type is (-- Start off in Reset
|
reset_state,
|
reset_state,
|
-- Fetch Interrupt Vectors (including reset)
|
-- Fetch Interrupt Vectors (including reset)
|
vect_lo_state, vect_hi_state,
|
vect_lo_state, vect_hi_state, vect_idle_state,
|
-- Fetch Instruction Cycle
|
-- Fetch Instruction Cycle
|
fetch_state,
|
fetch_state,
|
-- Decode Instruction Cycles
|
-- Decode Instruction Cycles
|
decode1_state, decode2_state, decode3_state,
|
decode1_state, decode2_state, decode3_state,
|
-- Calculate Effective Address
|
-- Calculate Effective Address
|
Line 277... |
Line 321... |
single_op_write_state,
|
single_op_write_state,
|
-- Dual op states
|
-- Dual op states
|
dual_op_read8_state, dual_op_read16_state, dual_op_read16_2_state,
|
dual_op_read8_state, dual_op_read16_state, dual_op_read16_2_state,
|
dual_op_write8_state, dual_op_write16_state,
|
dual_op_write8_state, dual_op_write16_state,
|
--
|
--
|
sync_state, halt_state, error_state,
|
sync_state, halt_state, cwai_state,
|
--
|
--
|
andcc_state, orcc_state,
|
andcc_state, orcc_state,
|
tfr_state, exg_state, exg1_state,
|
tfr_state,
|
|
exg_state, exg1_state, exg2_state,
|
lea_state,
|
lea_state,
|
-- Multiplication
|
-- Multiplication
|
mul_state, mulea_state, muld_state,
|
mul_state, mulea_state, muld_state,
|
mul0_state, mul1_state, mul2_state, mul3_state,
|
mul0_state, mul1_state, mul2_state, mul3_state,
|
mul4_state, mul5_state, mul6_state, mul7_state,
|
mul4_state, mul5_state, mul6_state, mul7_state,
|
Line 293... |
Line 338... |
-- Jumps, Subroutine Calls and Returns
|
-- Jumps, Subroutine Calls and Returns
|
jsr_state, jmp_state,
|
jsr_state, jmp_state,
|
push_return_hi_state, push_return_lo_state,
|
push_return_hi_state, push_return_lo_state,
|
pull_return_hi_state, pull_return_lo_state,
|
pull_return_hi_state, pull_return_lo_state,
|
-- Interrupt cycles
|
-- Interrupt cycles
|
int_nmiirq_state, int_firq_state,
|
int_nmi_state, int_nmi1_state,
|
|
int_irq_state, int_irq1_state,
|
|
int_firq_state, int_firq1_state,
|
int_entire_state, int_fast_state,
|
int_entire_state, int_fast_state,
|
int_pcl_state, int_pch_state,
|
int_pcl_state, int_pch_state,
|
int_upl_state, int_uph_state,
|
int_upl_state, int_uph_state,
|
int_iyl_state, int_iyh_state,
|
int_iyl_state, int_iyh_state,
|
int_ixl_state, int_ixh_state,
|
int_ixl_state, int_ixh_state,
|
int_dp_state,
|
int_dp_state,
|
int_accb_state, int_acca_state,
|
int_accb_state, int_acca_state,
|
int_cc_state,
|
int_cc_state,
|
int_cwai_state,
|
int_cwai_state,
|
int_maski_state, int_maskif_state,
|
int_nmimask_state, int_firqmask_state, int_swimask_state, int_irqmask_state,
|
-- Return From Interrupt
|
-- Return From Interrupt
|
rti_cc_state, rti_entire_state,
|
rti_cc_state, rti_entire_state,
|
rti_acca_state, rti_accb_state,
|
rti_acca_state, rti_accb_state,
|
rti_dp_state,
|
rti_dp_state,
|
rti_ixl_state, rti_ixh_state,
|
rti_ixl_state, rti_ixh_state,
|
Line 349... |
Line 396... |
pulu_ixl_state, pulu_ixh_state,
|
pulu_ixl_state, pulu_ixh_state,
|
pulu_iyl_state, pulu_iyh_state,
|
pulu_iyl_state, pulu_iyh_state,
|
pulu_spl_state, pulu_sph_state,
|
pulu_spl_state, pulu_sph_state,
|
pulu_pcl_state, pulu_pch_state );
|
pulu_pcl_state, pulu_pch_state );
|
|
|
type stack_type is array(2 downto 0) of state_type;
|
type st_type is (reset_st, push_st, idle_st );
|
type st_type is (idle_st, push_st, pull_st );
|
type iv_type is (latch_iv, swi3_iv, swi2_iv, firq_iv, irq_iv, swi_iv, nmi_iv, reset_iv);
|
type addr_type is (idle_ad, fetch_ad, read_ad, write_ad, pushu_ad, pullu_ad, pushs_ad, pulls_ad, int_hi_ad, int_lo_ad );
|
type addr_type is (idle_ad, fetch_ad, read_ad, write_ad, pushu_ad, pullu_ad, pushs_ad, pulls_ad, int_hi_ad, int_lo_ad );
|
type dout_type is (cc_dout, acca_dout, accb_dout, dp_dout,
|
type dout_type is (cc_dout, acca_dout, accb_dout, dp_dout,
|
ix_lo_dout, ix_hi_dout, iy_lo_dout, iy_hi_dout,
|
ix_lo_dout, ix_hi_dout, iy_lo_dout, iy_hi_dout,
|
up_lo_dout, up_hi_dout, sp_lo_dout, sp_hi_dout,
|
up_lo_dout, up_hi_dout, sp_lo_dout, sp_hi_dout,
|
pc_lo_dout, pc_hi_dout, md_lo_dout, md_hi_dout );
|
pc_lo_dout, pc_hi_dout, md_lo_dout, md_hi_dout );
|
Line 369... |
Line 416... |
type sp_type is (reset_sp, latch_sp, load_sp, pull_hi_sp, pull_lo_sp );
|
type sp_type is (reset_sp, latch_sp, load_sp, pull_hi_sp, pull_lo_sp );
|
type up_type is (reset_up, latch_up, load_up, pull_hi_up, pull_lo_up );
|
type up_type is (reset_up, latch_up, load_up, pull_hi_up, pull_lo_up );
|
type pc_type is (reset_pc, latch_pc, load_pc, pull_lo_pc, pull_hi_pc, incr_pc );
|
type pc_type is (reset_pc, latch_pc, load_pc, pull_lo_pc, pull_hi_pc, incr_pc );
|
type md_type is (reset_md, latch_md, load_md, fetch_first_md, fetch_next_md, shiftl_md );
|
type md_type is (reset_md, latch_md, load_md, fetch_first_md, fetch_next_md, shiftl_md );
|
type ea_type is (reset_ea, latch_ea, load_ea, fetch_first_ea, fetch_next_ea );
|
type ea_type is (reset_ea, latch_ea, load_ea, fetch_first_ea, fetch_next_ea );
|
type iv_type is (latch_iv, reset_iv, nmi_iv, irq_iv, firq_iv, swi_iv, swi2_iv, swi3_iv, resv_iv);
|
|
type nmi_type is (reset_nmi, set_nmi, latch_nmi );
|
|
type left_type is (cc_left, acca_left, accb_left, dp_left,
|
type left_type is (cc_left, acca_left, accb_left, dp_left,
|
ix_left, iy_left, up_left, sp_left,
|
ix_left, iy_left, up_left, sp_left,
|
accd_left, md_left, pc_left, ea_left );
|
accd_left, md_left, pc_left, ea_left );
|
type right_type is (ea_right, zero_right, one_right, two_right,
|
type right_type is (ea_right, zero_right, one_right, two_right,
|
acca_right, accb_right, accd_right,
|
acca_right, accb_right, accd_right,
|
Line 408... |
Line 453... |
signal out_alu: std_logic_vector(15 downto 0);
|
signal out_alu: std_logic_vector(15 downto 0);
|
signal iv: std_logic_vector(2 downto 0);
|
signal iv: std_logic_vector(2 downto 0);
|
signal nmi_req: std_logic;
|
signal nmi_req: std_logic;
|
signal nmi_ack: std_logic;
|
signal nmi_ack: std_logic;
|
signal nmi_enable: std_logic;
|
signal nmi_enable: std_logic;
|
|
signal fic: std_logic; -- first instruction cycle
|
|
signal lic: std_logic; -- last instruction cycle
|
|
|
signal state: state_type;
|
signal state: state_type;
|
signal next_state: state_type;
|
signal next_state: state_type;
|
signal saved_state: state_type;
|
|
signal return_state: state_type;
|
signal return_state: state_type;
|
signal state_stack: stack_type;
|
signal saved_state: state_type;
|
signal st_ctrl: st_type;
|
signal st_ctrl: st_type;
|
|
signal iv_ctrl: iv_type;
|
signal pc_ctrl: pc_type;
|
signal pc_ctrl: pc_type;
|
signal ea_ctrl: ea_type;
|
signal ea_ctrl: ea_type;
|
signal op_ctrl: op_type;
|
signal op_ctrl: op_type;
|
signal pre_ctrl: pre_type;
|
signal pre_ctrl: pre_type;
|
signal md_ctrl: md_type;
|
signal md_ctrl: md_type;
|
Line 428... |
Line 475... |
signal iy_ctrl: iy_type;
|
signal iy_ctrl: iy_type;
|
signal cc_ctrl: cc_type;
|
signal cc_ctrl: cc_type;
|
signal dp_ctrl: dp_type;
|
signal dp_ctrl: dp_type;
|
signal sp_ctrl: sp_type;
|
signal sp_ctrl: sp_type;
|
signal up_ctrl: up_type;
|
signal up_ctrl: up_type;
|
signal iv_ctrl: iv_type;
|
|
signal left_ctrl: left_type;
|
signal left_ctrl: left_type;
|
signal right_ctrl: right_type;
|
signal right_ctrl: right_type;
|
signal alu_ctrl: alu_type;
|
signal alu_ctrl: alu_type;
|
signal addr_ctrl: addr_type;
|
signal addr_ctrl: addr_type;
|
signal dout_ctrl: dout_type;
|
signal dout_ctrl: dout_type;
|
signal nmi_ctrl: nmi_type;
|
|
|
|
|
|
begin
|
begin
|
|
|
----------------------------------
|
----------------------------------
|
Line 446... |
Line 491... |
-- State machine stack
|
-- State machine stack
|
--
|
--
|
----------------------------------
|
----------------------------------
|
--state_stack_proc: process( clk, hold, state_stack, st_ctrl,
|
--state_stack_proc: process( clk, hold, state_stack, st_ctrl,
|
-- return_state, fetch_state )
|
-- return_state, fetch_state )
|
state_stack_proc: process( clk, state_stack )
|
state_stack_proc: process( clk, st_ctrl, return_state )
|
begin
|
begin
|
if clk'event and clk = '0' then
|
if clk'event and clk = '0' then
|
if hold= '1' then
|
if hold = '0' then
|
state_stack(0) <= state_stack(0);
|
|
state_stack(1) <= state_stack(1);
|
|
state_stack(2) <= state_stack(2);
|
|
else
|
|
case st_ctrl is
|
case st_ctrl is
|
when idle_st =>
|
when reset_st =>
|
state_stack(0) <= state_stack(0);
|
saved_state <= fetch_state;
|
state_stack(1) <= state_stack(1);
|
|
state_stack(2) <= state_stack(2);
|
|
when push_st =>
|
when push_st =>
|
state_stack(0) <= return_state;
|
saved_state <= return_state;
|
state_stack(1) <= state_stack(0);
|
|
state_stack(2) <= state_stack(1);
|
|
when pull_st =>
|
|
state_stack(0) <= state_stack(1);
|
|
state_stack(1) <= state_stack(2);
|
|
state_stack(2) <= fetch_state;
|
|
when others =>
|
when others =>
|
state_stack(0) <= state_stack(0);
|
null;
|
state_stack(1) <= state_stack(1);
|
|
state_stack(2) <= state_stack(2);
|
|
end case;
|
end case;
|
end if;
|
end if;
|
end if;
|
end if;
|
saved_state <= state_stack(0);
|
end process;
|
|
|
|
----------------------------------
|
|
--
|
|
-- Interrupt Vector control
|
|
--
|
|
----------------------------------
|
|
--
|
|
int_vec_proc: process( clk, iv_ctrl )
|
|
begin
|
|
if clk'event and clk = '0' then
|
|
if hold = '0' then
|
|
case iv_ctrl is
|
|
when reset_iv =>
|
|
iv <= RST_VEC;
|
|
when nmi_iv =>
|
|
iv <= NMI_VEC;
|
|
when swi_iv =>
|
|
iv <= SWI_VEC;
|
|
when irq_iv =>
|
|
iv <= IRQ_VEC;
|
|
when firq_iv =>
|
|
iv <= FIRQ_VEC;
|
|
when swi2_iv =>
|
|
iv <= SWI2_VEC;
|
|
when swi3_iv =>
|
|
iv <= SWI3_VEC;
|
|
when others =>
|
|
null;
|
|
end case;
|
|
end if; -- hold
|
|
end if; -- clk
|
end process;
|
end process;
|
|
|
----------------------------------
|
----------------------------------
|
--
|
--
|
-- Program Counter Control
|
-- Program Counter Control
|
Line 487... |
Line 549... |
|
|
--pc_reg: process( clk, pc_ctrl, hold, pc, out_alu, data_in )
|
--pc_reg: process( clk, pc_ctrl, hold, pc, out_alu, data_in )
|
pc_reg: process( clk )
|
pc_reg: process( clk )
|
begin
|
begin
|
if clk'event and clk = '0' then
|
if clk'event and clk = '0' then
|
if hold= '1' then
|
if hold = '0' then
|
pc <= pc;
|
|
else
|
|
case pc_ctrl is
|
case pc_ctrl is
|
when reset_pc =>
|
when reset_pc =>
|
pc <= "0000000000000000";
|
pc <= (others=>'0');
|
when load_pc =>
|
when load_pc =>
|
pc <= out_alu(15 downto 0);
|
pc <= out_alu(15 downto 0);
|
when pull_lo_pc =>
|
when pull_lo_pc =>
|
pc(7 downto 0) <= data_in;
|
pc(7 downto 0) <= data_in;
|
when pull_hi_pc =>
|
when pull_hi_pc =>
|
pc(15 downto 8) <= data_in;
|
pc(15 downto 8) <= data_in;
|
when incr_pc =>
|
when incr_pc =>
|
pc <= pc + 1;
|
pc <= pc + 1;
|
when others =>
|
when others =>
|
-- when latch_pc =>
|
null;
|
pc <= pc;
|
|
end case;
|
end case;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
Line 520... |
Line 579... |
--ea_reg: process( clk, ea_ctrl, hold, ea, out_alu, data_in, dp )
|
--ea_reg: process( clk, ea_ctrl, hold, ea, out_alu, data_in, dp )
|
ea_reg: process( clk )
|
ea_reg: process( clk )
|
begin
|
begin
|
|
|
if clk'event and clk = '0' then
|
if clk'event and clk = '0' then
|
if hold= '1' then
|
if hold= '0' then
|
ea <= ea;
|
|
else
|
|
case ea_ctrl is
|
case ea_ctrl is
|
when reset_ea =>
|
when reset_ea =>
|
ea <= "0000000000000000";
|
ea <= (others=>'0');
|
when fetch_first_ea =>
|
when fetch_first_ea =>
|
ea(7 downto 0) <= data_in;
|
ea(7 downto 0) <= data_in;
|
ea(15 downto 8) <= dp;
|
ea(15 downto 8) <= dp;
|
when fetch_next_ea =>
|
when fetch_next_ea =>
|
ea(15 downto 8) <= ea(7 downto 0);
|
ea(15 downto 8) <= ea(7 downto 0);
|
ea(7 downto 0) <= data_in;
|
ea(7 downto 0) <= data_in;
|
when load_ea =>
|
when load_ea =>
|
ea <= out_alu(15 downto 0);
|
ea <= out_alu(15 downto 0);
|
when others =>
|
when others =>
|
-- when latch_ea =>
|
null;
|
ea <= ea;
|
|
end case;
|
end case;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
Line 551... |
Line 607... |
--------------------------------
|
--------------------------------
|
--acca_reg : process( clk, acca_ctrl, hold, out_alu, acca, data_in )
|
--acca_reg : process( clk, acca_ctrl, hold, out_alu, acca, data_in )
|
acca_reg : process( clk )
|
acca_reg : process( clk )
|
begin
|
begin
|
if clk'event and clk = '0' then
|
if clk'event and clk = '0' then
|
if hold= '1' then
|
if hold = '0' then
|
acca <= acca;
|
|
else
|
|
case acca_ctrl is
|
case acca_ctrl is
|
when reset_acca =>
|
when reset_acca =>
|
acca <= "00000000";
|
acca <= (others=>'0');
|
when load_acca =>
|
when load_acca =>
|
acca <= out_alu(7 downto 0);
|
acca <= out_alu(7 downto 0);
|
when load_hi_acca =>
|
when load_hi_acca =>
|
acca <= out_alu(15 downto 8);
|
acca <= out_alu(15 downto 8);
|
when pull_acca =>
|
when pull_acca =>
|
acca <= data_in;
|
acca <= data_in;
|
when others =>
|
when others =>
|
-- when latch_acca =>
|
null;
|
acca <= acca;
|
|
end case;
|
end case;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
Line 580... |
Line 633... |
--------------------------------
|
--------------------------------
|
--accb_reg : process( clk, accb_ctrl, hold, out_alu, accb, data_in )
|
--accb_reg : process( clk, accb_ctrl, hold, out_alu, accb, data_in )
|
accb_reg : process( clk )
|
accb_reg : process( clk )
|
begin
|
begin
|
if clk'event and clk = '0' then
|
if clk'event and clk = '0' then
|
if hold= '1' then
|
if hold = '0' then
|
accb <= accb;
|
|
else
|
|
case accb_ctrl is
|
case accb_ctrl is
|
when reset_accb =>
|
when reset_accb =>
|
accb <= "00000000";
|
accb <= (others=>'0');
|
when load_accb =>
|
when load_accb =>
|
accb <= out_alu(7 downto 0);
|
accb <= out_alu(7 downto 0);
|
when pull_accb =>
|
when pull_accb =>
|
accb <= data_in;
|
accb <= data_in;
|
when others =>
|
when others =>
|
-- when latch_accb =>
|
null;
|
accb <= accb;
|
|
end case;
|
end case;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
Line 607... |
Line 657... |
--------------------------------
|
--------------------------------
|
--ix_reg : process( clk, ix_ctrl, hold, out_alu, xreg, data_in )
|
--ix_reg : process( clk, ix_ctrl, hold, out_alu, xreg, data_in )
|
ix_reg : process( clk )
|
ix_reg : process( clk )
|
begin
|
begin
|
if clk'event and clk = '0' then
|
if clk'event and clk = '0' then
|
if hold= '1' then
|
if hold = '0' then
|
xreg <= xreg;
|
|
else
|
|
case ix_ctrl is
|
case ix_ctrl is
|
when reset_ix =>
|
when reset_ix =>
|
xreg <= "0000000000000000";
|
xreg <= (others=>'0');
|
when load_ix =>
|
when load_ix =>
|
xreg <= out_alu(15 downto 0);
|
xreg <= out_alu(15 downto 0);
|
when pull_hi_ix =>
|
when pull_hi_ix =>
|
xreg(15 downto 8) <= data_in;
|
xreg(15 downto 8) <= data_in;
|
when pull_lo_ix =>
|
when pull_lo_ix =>
|
xreg(7 downto 0) <= data_in;
|
xreg(7 downto 0) <= data_in;
|
when others =>
|
when others =>
|
-- when latch_ix =>
|
null;
|
xreg <= xreg;
|
|
end case;
|
end case;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
Line 636... |
Line 683... |
--------------------------------
|
--------------------------------
|
--iy_reg : process( clk, iy_ctrl, hold, out_alu, yreg, data_in )
|
--iy_reg : process( clk, iy_ctrl, hold, out_alu, yreg, data_in )
|
iy_reg : process( clk )
|
iy_reg : process( clk )
|
begin
|
begin
|
if clk'event and clk = '0' then
|
if clk'event and clk = '0' then
|
if hold= '1' then
|
if hold = '0' then
|
yreg <= yreg;
|
|
else
|
|
case iy_ctrl is
|
case iy_ctrl is
|
when reset_iy =>
|
when reset_iy =>
|
yreg <= "0000000000000000";
|
yreg <= (others=>'0');
|
when load_iy =>
|
when load_iy =>
|
yreg <= out_alu(15 downto 0);
|
yreg <= out_alu(15 downto 0);
|
when pull_hi_iy =>
|
when pull_hi_iy =>
|
yreg(15 downto 8) <= data_in;
|
yreg(15 downto 8) <= data_in;
|
when pull_lo_iy =>
|
when pull_lo_iy =>
|
yreg(7 downto 0) <= data_in;
|
yreg(7 downto 0) <= data_in;
|
when others =>
|
when others =>
|
-- when latch_iy =>
|
null;
|
yreg <= yreg;
|
|
end case;
|
end case;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
Line 665... |
Line 709... |
--------------------------------
|
--------------------------------
|
--sp_reg : process( clk, sp_ctrl, hold, sp, out_alu, data_in, nmi_enable )
|
--sp_reg : process( clk, sp_ctrl, hold, sp, out_alu, data_in, nmi_enable )
|
sp_reg : process( clk )
|
sp_reg : process( clk )
|
begin
|
begin
|
if clk'event and clk = '0' then
|
if clk'event and clk = '0' then
|
if hold= '1' then
|
if hold = '0' then
|
sp <= sp;
|
|
nmi_enable <= nmi_enable;
|
|
else
|
|
case sp_ctrl is
|
case sp_ctrl is
|
when reset_sp =>
|
when reset_sp =>
|
sp <= "0000000000000000";
|
sp <= (others=>'0');
|
nmi_enable <= '0';
|
nmi_enable <= '0';
|
when load_sp =>
|
when load_sp =>
|
sp <= out_alu(15 downto 0);
|
sp <= out_alu(15 downto 0);
|
nmi_enable <= '1';
|
nmi_enable <= '1';
|
when pull_hi_sp =>
|
when pull_hi_sp =>
|
sp(15 downto 8) <= data_in;
|
sp(15 downto 8) <= data_in;
|
nmi_enable <= nmi_enable;
|
|
when pull_lo_sp =>
|
when pull_lo_sp =>
|
sp(7 downto 0) <= data_in;
|
sp(7 downto 0) <= data_in;
|
nmi_enable <= '1';
|
nmi_enable <= '1';
|
when others =>
|
when others =>
|
-- when latch_sp =>
|
null;
|
sp <= sp;
|
|
nmi_enable <= nmi_enable;
|
|
end case;
|
end case;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
Line 700... |
Line 738... |
--------------------------------
|
--------------------------------
|
--up_reg : process( clk, up_ctrl, hold, up, out_alu, data_in )
|
--up_reg : process( clk, up_ctrl, hold, up, out_alu, data_in )
|
up_reg : process( clk )
|
up_reg : process( clk )
|
begin
|
begin
|
if clk'event and clk = '0' then
|
if clk'event and clk = '0' then
|
if hold= '1' then
|
if hold = '0' then
|
up <= up;
|
|
else
|
|
case up_ctrl is
|
case up_ctrl is
|
when reset_up =>
|
when reset_up =>
|
up <= "0000000000000000";
|
up <= (others=>'0');
|
when load_up =>
|
when load_up =>
|
up <= out_alu(15 downto 0);
|
up <= out_alu(15 downto 0);
|
when pull_hi_up =>
|
when pull_hi_up =>
|
up(15 downto 8) <= data_in;
|
up(15 downto 8) <= data_in;
|
when pull_lo_up =>
|
when pull_lo_up =>
|
up(7 downto 0) <= data_in;
|
up(7 downto 0) <= data_in;
|
when others =>
|
when others =>
|
-- when latch_up =>
|
null;
|
up <= up;
|
|
end case;
|
end case;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
Line 729... |
Line 764... |
--------------------------------
|
--------------------------------
|
--md_reg : process( clk, md_ctrl, hold, out_alu, data_in, md )
|
--md_reg : process( clk, md_ctrl, hold, out_alu, data_in, md )
|
md_reg : process( clk )
|
md_reg : process( clk )
|
begin
|
begin
|
if clk'event and clk = '0' then
|
if clk'event and clk = '0' then
|
if hold= '1' then
|
if hold = '0' then
|
md <= md;
|
|
else
|
|
case md_ctrl is
|
case md_ctrl is
|
when reset_md =>
|
when reset_md =>
|
md <= "0000000000000000";
|
md <= (others=>'0');
|
when load_md =>
|
when load_md =>
|
md <= out_alu(15 downto 0);
|
md <= out_alu(15 downto 0);
|
when fetch_first_md => -- sign extend md for branches
|
when fetch_first_md => -- sign extend md for branches
|
md(15 downto 8) <= data_in(7) & data_in(7) & data_in(7) & data_in(7) &
|
md(15 downto 8) <= data_in(7) & data_in(7) & data_in(7) & data_in(7) &
|
data_in(7) & data_in(7) & data_in(7) & data_in(7) ;
|
data_in(7) & data_in(7) & data_in(7) & data_in(7) ;
|
Line 748... |
Line 781... |
md(7 downto 0) <= data_in;
|
md(7 downto 0) <= data_in;
|
when shiftl_md =>
|
when shiftl_md =>
|
md(15 downto 1) <= md(14 downto 0);
|
md(15 downto 1) <= md(14 downto 0);
|
md(0) <= '0';
|
md(0) <= '0';
|
when others =>
|
when others =>
|
-- when latch_md =>
|
null;
|
md <= md;
|
|
end case;
|
end case;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
Line 766... |
Line 798... |
|
|
--cc_reg: process( clk, cc_ctrl, hold, cc_out, cc, data_in )
|
--cc_reg: process( clk, cc_ctrl, hold, cc_out, cc, data_in )
|
cc_reg: process( clk )
|
cc_reg: process( clk )
|
begin
|
begin
|
if clk'event and clk = '0' then
|
if clk'event and clk = '0' then
|
if hold= '1' then
|
if hold = '0' then
|
cc <= cc;
|
|
else
|
|
case cc_ctrl is
|
case cc_ctrl is
|
when reset_cc =>
|
when reset_cc =>
|
cc <= "11010000"; -- set EBIT, FBIT & IBIT
|
cc <= "11010000"; -- set EBIT, FBIT & IBIT
|
when load_cc =>
|
when load_cc =>
|
cc <= cc_out;
|
cc <= cc_out;
|
when pull_cc =>
|
when pull_cc =>
|
cc <= data_in;
|
cc <= data_in;
|
when others =>
|
when others =>
|
-- when latch_cc =>
|
null;
|
cc <= cc;
|
|
end case;
|
end case;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
Line 794... |
Line 823... |
|
|
--dp_reg: process( clk, dp_ctrl, hold, out_alu, dp, data_in )
|
--dp_reg: process( clk, dp_ctrl, hold, out_alu, dp, data_in )
|
dp_reg: process( clk )
|
dp_reg: process( clk )
|
begin
|
begin
|
if clk'event and clk = '0' then
|
if clk'event and clk = '0' then
|
if hold= '1' then
|
if hold = '0' then
|
dp <= dp;
|
|
else
|
|
case dp_ctrl is
|
case dp_ctrl is
|
when reset_dp =>
|
when reset_dp =>
|
dp <= "00000000";
|
dp <= (others=>'0');
|
when load_dp =>
|
when load_dp =>
|
dp <= out_alu(7 downto 0);
|
dp <= out_alu(7 downto 0);
|
when pull_dp =>
|
when pull_dp =>
|
dp <= data_in;
|
dp <= data_in;
|
when others =>
|
when others =>
|
-- when latch_dp =>
|
null;
|
dp <= dp;
|
|
end case;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
----------------------------------
|
|
--
|
|
-- interrupt vector
|
|
--
|
|
----------------------------------
|
|
|
|
--iv_mux: process( clk, iv_ctrl, hold, iv )
|
|
iv_mux: process( clk )
|
|
begin
|
|
if clk'event and clk = '0' then
|
|
if hold= '1' then
|
|
iv <= iv;
|
|
else
|
|
case iv_ctrl is
|
|
when reset_iv =>
|
|
iv <= RST_VEC;
|
|
when nmi_iv =>
|
|
iv <= NMI_VEC;
|
|
when swi_iv =>
|
|
iv <= SWI_VEC;
|
|
when irq_iv =>
|
|
iv <= IRQ_VEC;
|
|
when firq_iv =>
|
|
iv <= FIRQ_VEC;
|
|
when swi2_iv =>
|
|
iv <= SWI2_VEC;
|
|
when swi3_iv =>
|
|
iv <= SWI3_VEC;
|
|
when resv_iv =>
|
|
iv <= RESV_VEC;
|
|
when others =>
|
|
iv <= iv;
|
|
end case;
|
end case;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
Line 860... |
Line 849... |
|
|
--op_reg: process( clk, op_ctrl, hold, op_code, data_in )
|
--op_reg: process( clk, op_ctrl, hold, op_code, data_in )
|
op_reg: process( clk )
|
op_reg: process( clk )
|
begin
|
begin
|
if clk'event and clk = '0' then
|
if clk'event and clk = '0' then
|
if hold= '1' then
|
if hold = '0' then
|
op_code <= op_code;
|
|
else
|
|
case op_ctrl is
|
case op_ctrl is
|
when reset_op =>
|
when reset_op =>
|
op_code <= "00010010";
|
op_code <= "00010010";
|
when fetch_op =>
|
when fetch_op =>
|
op_code <= data_in;
|
op_code <= data_in;
|
when others =>
|
when others =>
|
-- when latch_op =>
|
null;
|
op_code <= op_code;
|
|
end case;
|
end case;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
Line 887... |
Line 873... |
|
|
--pre_reg: process( clk, pre_ctrl, hold, pre_code, data_in )
|
--pre_reg: process( clk, pre_ctrl, hold, pre_code, data_in )
|
pre_reg: process( clk )
|
pre_reg: process( clk )
|
begin
|
begin
|
if clk'event and clk = '0' then
|
if clk'event and clk = '0' then
|
if hold= '1' then
|
if hold = '0' then
|
pre_code <= pre_code;
|
|
else
|
|
case pre_ctrl is
|
case pre_ctrl is
|
when reset_pre =>
|
when reset_pre =>
|
pre_code <= "00000000";
|
pre_code <= (others=>'0');
|
when fetch_pre =>
|
when fetch_pre =>
|
pre_code <= data_in;
|
pre_code <= data_in;
|
when others =>
|
when others =>
|
-- when latch_pre =>
|
null;
|
pre_code <= pre_code;
|
|
end case;
|
end case;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
Line 914... |
Line 897... |
--change_state: process( clk, rst, state, hold, next_state )
|
--change_state: process( clk, rst, state, hold, next_state )
|
change_state: process( clk )
|
change_state: process( clk )
|
begin
|
begin
|
if clk'event and clk = '0' then
|
if clk'event and clk = '0' then
|
if rst = '1' then
|
if rst = '1' then
|
|
fic <= '0';
|
|
nmi_ack <= '0';
|
state <= reset_state;
|
state <= reset_state;
|
else
|
elsif hold = '0' then
|
if hold = '1' then
|
fic <= lic;
|
state <= state;
|
--
|
else
|
-- nmi request is not cleared until nmi input goes low
|
state <= next_state;
|
--
|
end if;
|
if (nmi_req = '0') and (nmi_ack='1') then
|
|
nmi_ack <= '0';
|
end if;
|
end if;
|
|
|
|
if (nmi_req = '1') and (nmi_ack = '0') and (state = int_nmimask_state) then
|
|
nmi_ack <= '1';
|
end if;
|
end if;
|
end process;
|
|
-- output
|
|
|
|
------------------------------------
|
if lic = '1' then
|
|
if halt = '1' then
|
|
state <= halt_state;
|
|
|
|
-- service non maskable interrupts
|
|
elsif (nmi_req = '1') and (nmi_ack = '0') then
|
|
state <= int_nmi_state;
|
--
|
--
|
-- Nmi register
|
-- FIRQ & IRQ are level sensitive
|
--
|
--
|
------------------------------------
|
elsif (firq = '1') and (cc(FBIT) = '0') then
|
|
state <= int_firq_state;
|
|
|
--nmi_reg: process( clk, nmi_ctrl, hold, nmi_ack )
|
elsif (irq = '1') and (cc(IBIT) = '0') then
|
nmi_reg: process( clk )
|
state <= int_irq_state;
|
begin
|
--
|
if clk'event and clk='0' then
|
-- Version 1.27 2015-05-30
|
if hold = '1' then
|
-- Exit sync_state on masked interrupt.
|
nmi_ack <= nmi_ack;
|
--
|
|
-- Version 1.28 2015-05-30
|
|
-- Move this code to the state sequencer
|
|
-- near line 5566.
|
|
--
|
|
-- elsif (state = sync_state) and ((firq = '1') or (irq = '1'))then
|
|
-- state <= fetch_state;
|
|
--
|
else
|
else
|
case nmi_ctrl is
|
state <= next_state;
|
when set_nmi =>
|
end if; -- halt, nmi, firq, irq
|
nmi_ack <= '1';
|
else
|
when reset_nmi =>
|
state <= next_state;
|
nmi_ack <= '0';
|
end if; -- lic
|
when others =>
|
end if; -- reset/hold
|
-- when latch_nmi =>
|
end if; -- clk
|
nmi_ack <= nmi_ack;
|
|
end case;
|
|
end if;
|
|
end if;
|
|
end process;
|
end process;
|
|
|
------------------------------------
|
------------------------------------
|
--
|
--
|
-- Detect Edge of NMI interrupt
|
-- Detect Edge of NMI interrupt
|
Line 985... |
Line 982... |
|
|
addr_mux: process( addr_ctrl, pc, ea, up, sp, iv )
|
addr_mux: process( addr_ctrl, pc, ea, up, sp, iv )
|
begin
|
begin
|
ifetch <= '0';
|
ifetch <= '0';
|
vma <= '1';
|
vma <= '1';
|
rw <= '1';
|
|
addr <= "1111111111111111";
|
|
case addr_ctrl is
|
case addr_ctrl is
|
when fetch_ad =>
|
when fetch_ad =>
|
addr <= pc;
|
addr <= pc;
|
|
rw <= '1';
|
ifetch <= '1';
|
ifetch <= '1';
|
when read_ad =>
|
when read_ad =>
|
addr <= ea;
|
addr <= ea;
|
|
rw <= '1';
|
when write_ad =>
|
when write_ad =>
|
addr <= ea;
|
addr <= ea;
|
rw <= '0';
|
rw <= '0';
|
when pushs_ad =>
|
when pushs_ad =>
|
addr <= sp;
|
addr <= sp;
|
rw <= '0';
|
rw <= '0';
|
when pulls_ad =>
|
when pulls_ad =>
|
addr <= sp;
|
addr <= sp;
|
|
rw <= '1';
|
when pushu_ad =>
|
when pushu_ad =>
|
addr <= up;
|
addr <= up;
|
rw <= '0';
|
rw <= '0';
|
when pullu_ad =>
|
when pullu_ad =>
|
addr <= up;
|
addr <= up;
|
|
rw <= '1';
|
when int_hi_ad =>
|
when int_hi_ad =>
|
addr <= "111111111111" & iv & "0";
|
addr <= "111111111111" & iv & "0";
|
|
rw <= '1';
|
when int_lo_ad =>
|
when int_lo_ad =>
|
addr <= "111111111111" & iv & "1";
|
addr <= "111111111111" & iv & "1";
|
|
rw <= '1';
|
when others =>
|
when others =>
|
|
addr <= "1111111111111111";
|
|
rw <= '1';
|
vma <= '0';
|
vma <= '0';
|
end case;
|
end case;
|
end process;
|
end process;
|
|
|
--------------------------------
|
--------------------------------
|
Line 1055... |
Line 1058... |
data_out <= md(15 downto 8);
|
data_out <= md(15 downto 8);
|
when pc_lo_dout => -- low order pc
|
when pc_lo_dout => -- low order pc
|
data_out <= pc(7 downto 0);
|
data_out <= pc(7 downto 0);
|
when pc_hi_dout => -- high order pc
|
when pc_hi_dout => -- high order pc
|
data_out <= pc(15 downto 8);
|
data_out <= pc(15 downto 8);
|
when others =>
|
|
data_out <= "00000000";
|
|
end case;
|
end case;
|
end process;
|
end process;
|
|
|
----------------------------------
|
----------------------------------
|
--
|
--
|
Line 1176... |
Line 1177... |
end case;
|
end case;
|
|
|
valid_lo := left(3 downto 0) <= 9;
|
valid_lo := left(3 downto 0) <= 9;
|
valid_hi := left(7 downto 4) <= 9;
|
valid_hi := left(7 downto 4) <= 9;
|
|
|
|
--
|
|
-- CBIT HBIT VHI VLO DAA
|
|
-- 0 0 0 0 66 (!VHI : hi_nybble>8)
|
|
-- 0 0 0 1 60
|
|
-- 0 0 1 1 00
|
|
-- 0 0 1 0 06 ( VHI : hi_nybble<=8)
|
|
--
|
|
-- 0 1 1 0 06
|
|
-- 0 1 1 1 06
|
|
-- 0 1 0 1 66
|
|
-- 0 1 0 0 66
|
|
--
|
|
-- 1 1 0 0 66
|
|
-- 1 1 0 1 66
|
|
-- 1 1 1 1 66
|
|
-- 1 1 1 0 66
|
|
--
|
|
-- 1 0 1 0 66
|
|
-- 1 0 1 1 60
|
|
-- 1 0 0 1 60
|
|
-- 1 0 0 0 66
|
|
--
|
|
-- 66 = (!VHI & !VLO) + (CBIT & HBIT) + (HBIT & !VHI) + (CBIT & !VLO)
|
|
-- = (CBIT & (HBIT + !VLO)) + (!VHI & (HBIT + !VLO))
|
|
-- = (!VLO & (CBIT + !VHI)) + (HBIT & (CBIT + !VHI))
|
|
-- 60 = (CBIT & !HBIT & VLO) + (!HBIT & !VHI & VLO)
|
|
-- = (!HBIT & VLO & (CBIT + !VHI))
|
|
-- 06 = (!CBIT & VHI & (!VLO + VHI)
|
|
-- 00 = (!CBIT & !HBIT & VHI & VLO)
|
|
--
|
if (cc(CBIT) = '0') then
|
if (cc(CBIT) = '0') then
|
if( cc(HBIT) = '1' ) then
|
-- CBIT=0
|
if valid_hi then
|
if( cc(HBIT) = '0' ) then
|
daa_reg := "00000110";
|
-- HBIT=0
|
else
|
|
daa_reg := "01100110";
|
|
end if;
|
|
else
|
|
if valid_lo then
|
if valid_lo then
|
|
-- lo <= 9 (no overflow in low nybble)
|
if valid_hi then
|
if valid_hi then
|
|
-- hi <= 9 (no overflow in either low or high nybble)
|
daa_reg := "00000000";
|
daa_reg := "00000000";
|
else
|
else
|
|
-- hi > 9 (overflow in high nybble only)
|
daa_reg := "01100000";
|
daa_reg := "01100000";
|
end if;
|
end if;
|
else
|
else
|
|
-- lo > 9 (overflow in low nybble)
|
|
--
|
|
-- since there is already an overflow in the low nybble
|
|
-- you need to make room in the high nybble for the low nybble carry
|
|
-- so compare the high nybble with 8 rather than 9
|
|
-- if the high nybble is 9 there will be an overflow on the high nybble
|
|
-- after the decimal adjust which means it will roll over to an invalid BCD digit
|
|
--
|
if( left(7 downto 4) <= 8 ) then
|
if( left(7 downto 4) <= 8 ) then
|
|
-- hi <= 8 (overflow in low nybble only)
|
daa_reg := "00000110";
|
daa_reg := "00000110";
|
else
|
else
|
|
-- hi > 8 (overflow in low and high nybble)
|
daa_reg := "01100110";
|
daa_reg := "01100110";
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
|
else
|
else
|
if ( cc(HBIT) = '1' )then
|
-- HBIT=1 (overflow in low nybble)
|
|
if valid_hi then
|
|
-- hi <= 9 (overflow in low nybble only)
|
|
daa_reg := "00000110";
|
|
else
|
|
-- hi > 9 (overflow in low and high nybble)
|
daa_reg := "01100110";
|
daa_reg := "01100110";
|
|
end if;
|
|
end if;
|
else
|
else
|
|
-- CBIT=1 (carry => overflow in high nybble)
|
|
if ( cc(HBIT) = '0' )then
|
|
-- HBIT=0 (half carry clear => may or may not be an overflow in the low nybble)
|
if valid_lo then
|
if valid_lo then
|
|
-- lo <=9 (overflow in high nybble only)
|
daa_reg := "01100000";
|
daa_reg := "01100000";
|
else
|
else
|
|
-- lo >9 (overflow in low and high nybble)
|
daa_reg := "01100110";
|
daa_reg := "01100110";
|
end if;
|
end if;
|
|
else
|
|
-- HBIT=1 (overflow in low and high nybble)
|
|
daa_reg := "01100110";
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
case alu_ctrl is
|
case alu_ctrl is
|
when alu_add8 | alu_inc |
|
when alu_add8 | alu_inc |
|
Line 1482... |
Line 1536... |
-- state sequencer
|
-- state sequencer
|
--
|
--
|
------------------------------------
|
------------------------------------
|
process( state, saved_state,
|
process( state, saved_state,
|
op_code, pre_code,
|
op_code, pre_code,
|
cc, ea, md, iv,
|
cc, ea, md, iv, fic, halt,
|
irq, firq, nmi_req, nmi_ack, halt )
|
nmi_req, firq, irq, lic )
|
variable cond_true : boolean; -- variable used to evaluate coditional branches
|
variable cond_true : boolean; -- variable used to evaluate coditional branches
|
begin
|
begin
|
|
cond_true := (1=1);
|
ba <= '0';
|
ba <= '0';
|
bs <= '0';
|
bs <= '0';
|
lic <= '0';
|
lic <= '0';
|
|
opfetch <= '0';
|
|
iv_ctrl <= latch_iv;
|
-- Registers preserved
|
-- Registers preserved
|
cc_ctrl <= latch_cc;
|
cc_ctrl <= latch_cc;
|
acca_ctrl <= latch_acca;
|
acca_ctrl <= latch_acca;
|
accb_ctrl <= latch_accb;
|
accb_ctrl <= latch_accb;
|
dp_ctrl <= latch_dp;
|
dp_ctrl <= latch_dp;
|
Line 1501... |
Line 1558... |
up_ctrl <= latch_up;
|
up_ctrl <= latch_up;
|
sp_ctrl <= latch_sp;
|
sp_ctrl <= latch_sp;
|
pc_ctrl <= latch_pc;
|
pc_ctrl <= latch_pc;
|
md_ctrl <= latch_md;
|
md_ctrl <= latch_md;
|
ea_ctrl <= latch_ea;
|
ea_ctrl <= latch_ea;
|
iv_ctrl <= latch_iv;
|
|
op_ctrl <= latch_op;
|
op_ctrl <= latch_op;
|
pre_ctrl <= latch_pre;
|
pre_ctrl <= latch_pre;
|
nmi_ctrl <= latch_nmi;
|
|
-- ALU Idle
|
-- ALU Idle
|
left_ctrl <= pc_left;
|
left_ctrl <= pc_left;
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_nop;
|
alu_ctrl <= alu_nop;
|
-- Bus idle
|
-- Bus idle
|
Line 1520... |
Line 1575... |
next_state <= fetch_state;
|
next_state <= fetch_state;
|
|
|
case state is
|
case state is
|
when reset_state => -- released from reset
|
when reset_state => -- released from reset
|
-- reset the registers
|
-- reset the registers
|
|
iv_ctrl <= reset_iv;
|
op_ctrl <= reset_op;
|
op_ctrl <= reset_op;
|
pre_ctrl <= reset_pre;
|
pre_ctrl <= reset_pre;
|
cc_ctrl <= reset_cc;
|
cc_ctrl <= reset_cc;
|
acca_ctrl <= reset_acca;
|
acca_ctrl <= reset_acca;
|
accb_ctrl <= reset_accb;
|
accb_ctrl <= reset_accb;
|
Line 1533... |
Line 1589... |
up_ctrl <= reset_up;
|
up_ctrl <= reset_up;
|
sp_ctrl <= reset_sp;
|
sp_ctrl <= reset_sp;
|
pc_ctrl <= reset_pc;
|
pc_ctrl <= reset_pc;
|
ea_ctrl <= reset_ea;
|
ea_ctrl <= reset_ea;
|
md_ctrl <= reset_md;
|
md_ctrl <= reset_md;
|
iv_ctrl <= reset_iv;
|
st_ctrl <= reset_st;
|
nmi_ctrl <= reset_nmi;
|
|
next_state <= vect_hi_state;
|
next_state <= vect_hi_state;
|
|
|
--
|
--
|
-- Jump via interrupt vector
|
-- Jump via interrupt vector
|
-- iv holds interrupt type
|
-- iv holds interrupt type
|
Line 1548... |
Line 1603... |
-- fetch pc low interrupt vector
|
-- fetch pc low interrupt vector
|
pc_ctrl <= pull_hi_pc;
|
pc_ctrl <= pull_hi_pc;
|
addr_ctrl <= int_hi_ad;
|
addr_ctrl <= int_hi_ad;
|
bs <= '1';
|
bs <= '1';
|
next_state <= vect_lo_state;
|
next_state <= vect_lo_state;
|
|
|
--
|
--
|
-- jump via interrupt vector
|
-- jump via interrupt vector
|
-- iv holds vector type
|
-- iv holds vector type
|
-- fetch PC lo from vector location
|
-- fetch PC lo from vector location
|
--
|
--
|
Line 1559... |
Line 1615... |
-- fetch the vector low byte
|
-- fetch the vector low byte
|
pc_ctrl <= pull_lo_pc;
|
pc_ctrl <= pull_lo_pc;
|
addr_ctrl <= int_lo_ad;
|
addr_ctrl <= int_lo_ad;
|
bs <= '1';
|
bs <= '1';
|
next_state <= fetch_state;
|
next_state <= fetch_state;
|
|
|
|
when vect_idle_state =>
|
|
--
|
|
-- Last Instruction Cycle for SWI, SWI2 & SWI3
|
|
--
|
|
if op_code = "00111111" then
|
|
lic <= '1';
|
|
end if;
|
|
next_state <= fetch_state;
|
|
|
--
|
--
|
-- Here to fetch an instruction
|
-- Here to fetch an instruction
|
-- PC points to opcode
|
-- PC points to opcode
|
-- Should service interrupt requests at this point
|
|
-- either from the timer
|
|
-- or from the external input.
|
|
--
|
--
|
when fetch_state =>
|
when fetch_state =>
|
-- fetch the op code
|
-- fetch the op code
|
|
opfetch <= '1';
|
op_ctrl <= fetch_op;
|
op_ctrl <= fetch_op;
|
pre_ctrl <= fetch_pre;
|
pre_ctrl <= fetch_pre;
|
ea_ctrl <= reset_ea;
|
ea_ctrl <= reset_ea;
|
-- Fetch op code
|
-- Fetch op code
|
addr_ctrl <= fetch_ad;
|
addr_ctrl <= fetch_ad;
|
|
-- Advance the PC to fetch next instruction byte
|
|
pc_ctrl <= incr_pc;
|
|
next_state <= decode1_state;
|
|
|
--
|
--
|
case op_code(7 downto 6) is
|
-- Here to decode instruction
|
when "10" => -- acca
|
-- and fetch next byte of intruction
|
|
-- whether it be necessary or not
|
|
--
|
|
when decode1_state =>
|
|
-- fetch first byte of address or immediate data
|
|
ea_ctrl <= fetch_first_ea;
|
|
md_ctrl <= fetch_first_md;
|
|
addr_ctrl <= fetch_ad;
|
|
case op_code(7 downto 4) is
|
|
--
|
|
-- direct single op (2 bytes)
|
|
-- 6809 => 6 cycles
|
|
-- cpu09 => 5 cycles
|
|
-- 1 op=(pc) / pc=pc+1
|
|
-- 2 ea_hi=dp / ea_lo=(pc) / pc=pc+1
|
|
-- 3 md_lo=(ea) / pc=pc
|
|
-- 4 alu_left=md / md=alu_out / pc=pc
|
|
-- 5 (ea)=md_lo / pc=pc
|
|
--
|
|
-- Exception is JMP
|
|
-- 6809 => 3 cycles
|
|
-- cpu09 => 3 cycles
|
|
-- 1 op=(pc) / pc=pc+1
|
|
-- 2 ea_hi=dp / ea_lo=(pc) / pc=pc+1
|
|
-- 3 pc=ea
|
|
--
|
|
when "0000" =>
|
|
-- advance the PC
|
|
pc_ctrl <= incr_pc;
|
|
|
case op_code(3 downto 0) is
|
case op_code(3 downto 0) is
|
when "0000" => -- suba
|
when "1110" => -- jmp
|
left_ctrl <= acca_left;
|
next_state <= jmp_state;
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_sub8;
|
when "1111" => -- clr
|
cc_ctrl <= load_cc;
|
next_state <= single_op_exec_state;
|
acca_ctrl <= load_acca;
|
|
when "0001" => -- cmpa
|
when others =>
|
left_ctrl <= acca_left;
|
next_state <= single_op_read_state;
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_sub8;
|
|
cc_ctrl <= load_cc;
|
|
when "0010" => -- sbca
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_sbc;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= load_acca;
|
|
when "0011" =>
|
|
case pre_code is
|
|
when "00010000" => -- page 2 -- cmpd
|
|
left_ctrl <= accd_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_sub16;
|
|
cc_ctrl <= load_cc;
|
|
when "00010001" => -- page 3 -- cmpu
|
|
left_ctrl <= up_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_sub16;
|
|
cc_ctrl <= load_cc;
|
|
when others => -- page 1 -- subd
|
|
left_ctrl <= accd_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_sub16;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= load_hi_acca;
|
|
accb_ctrl <= load_accb;
|
|
end case;
|
end case;
|
when "0100" => -- anda
|
|
left_ctrl <= acca_left;
|
-- acca / accb inherent instructions
|
right_ctrl <= md_right;
|
when "0001" =>
|
alu_ctrl <= alu_and;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= load_acca;
|
|
when "0101" => -- bita
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_and;
|
|
cc_ctrl <= load_cc;
|
|
when "0110" => -- ldaa
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_ld8;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= load_acca;
|
|
when "0111" => -- staa
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_st8;
|
|
cc_ctrl <= load_cc;
|
|
when "1000" => -- eora
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_eor;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= load_acca;
|
|
when "1001" => -- adca
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_adc;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= load_acca;
|
|
when "1010" => -- oraa
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_ora;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= load_acca;
|
|
when "1011" => -- adda
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_add8;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= load_acca;
|
|
when "1100" =>
|
|
case pre_code is
|
|
when "00010000" => -- page 2 -- cmpy
|
|
left_ctrl <= iy_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_sub16;
|
|
cc_ctrl <= load_cc;
|
|
when "00010001" => -- page 3 -- cmps
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_sub16;
|
|
cc_ctrl <= load_cc;
|
|
when others => -- page 1 -- cmpx
|
|
left_ctrl <= ix_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_sub16;
|
|
cc_ctrl <= load_cc;
|
|
end case;
|
|
when "1101" => -- bsr / jsr
|
|
null;
|
|
when "1110" => -- ldx
|
|
case pre_code is
|
|
when "00010000" => -- page 2 -- ldy
|
|
left_ctrl <= iy_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_ld16;
|
|
cc_ctrl <= load_cc;
|
|
iy_ctrl <= load_iy;
|
|
when others => -- page 1 -- ldx
|
|
left_ctrl <= ix_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_ld16;
|
|
cc_ctrl <= load_cc;
|
|
ix_ctrl <= load_ix;
|
|
end case;
|
|
when "1111" => -- stx
|
|
case pre_code is
|
|
when "00010000" => -- page 2 -- sty
|
|
left_ctrl <= iy_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_st16;
|
|
cc_ctrl <= load_cc;
|
|
when others => -- page 1 -- stx
|
|
left_ctrl <= ix_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_st16;
|
|
cc_ctrl <= load_cc;
|
|
end case;
|
|
when others =>
|
|
null;
|
|
end case;
|
|
when "11" => -- accb dual op
|
|
case op_code(3 downto 0) is
|
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;
|
|
accb_ctrl <= load_accb;
|
|
when "0001" => -- cmpb
|
|
left_ctrl <= accb_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_sub8;
|
|
cc_ctrl <= load_cc;
|
|
when "0010" => -- sbcb
|
|
left_ctrl <= accb_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_sbc;
|
|
cc_ctrl <= load_cc;
|
|
accb_ctrl <= load_accb;
|
|
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;
|
|
when "0100" => -- andb
|
|
left_ctrl <= accb_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_and;
|
|
cc_ctrl <= load_cc;
|
|
accb_ctrl <= load_accb;
|
|
when "0101" => -- bitb
|
|
left_ctrl <= accb_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_and;
|
|
cc_ctrl <= load_cc;
|
|
when "0110" => -- ldab
|
|
left_ctrl <= accb_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_ld8;
|
|
cc_ctrl <= load_cc;
|
|
accb_ctrl <= load_accb;
|
|
when "0111" => -- stab
|
|
left_ctrl <= accb_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_st8;
|
|
cc_ctrl <= load_cc;
|
|
when "1000" => -- eorb
|
|
left_ctrl <= accb_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_eor;
|
|
cc_ctrl <= load_cc;
|
|
accb_ctrl <= load_accb;
|
|
when "1001" => -- adcb
|
|
left_ctrl <= accb_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_adc;
|
|
cc_ctrl <= load_cc;
|
|
accb_ctrl <= load_accb;
|
|
when "1010" => -- orab
|
|
left_ctrl <= accb_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_ora;
|
|
cc_ctrl <= load_cc;
|
|
accb_ctrl <= load_accb;
|
|
when "1011" => -- addb
|
|
left_ctrl <= accb_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_add8;
|
|
cc_ctrl <= load_cc;
|
|
accb_ctrl <= load_accb;
|
|
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;
|
|
when "1101" => -- std
|
|
left_ctrl <= accd_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_st16;
|
|
cc_ctrl <= load_cc;
|
|
when "1110" => -- ldu
|
|
case pre_code is
|
|
when "00010000" => -- page 2 -- lds
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_ld16;
|
|
cc_ctrl <= load_cc;
|
|
sp_ctrl <= load_sp;
|
|
when others => -- page 1 -- ldu
|
|
left_ctrl <= up_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_ld16;
|
|
cc_ctrl <= load_cc;
|
|
up_ctrl <= load_up;
|
|
end case;
|
|
when "1111" =>
|
|
case pre_code is
|
|
when "00010000" => -- page 2 -- sts
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_st16;
|
|
cc_ctrl <= load_cc;
|
|
when others => -- page 1 -- stu
|
|
left_ctrl <= up_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_st16;
|
|
cc_ctrl <= load_cc;
|
|
end case;
|
|
when others =>
|
|
null;
|
|
end case;
|
|
when others =>
|
|
null;
|
|
end case;
|
|
if halt = '1' then
|
|
iv_ctrl <= reset_iv;
|
|
next_state <= halt_state;
|
|
-- service non maskable interrupts
|
|
elsif (nmi_req = '1') and (nmi_ack = '0') then
|
|
iv_ctrl <= nmi_iv;
|
|
nmi_ctrl <= set_nmi;
|
|
next_state <= int_nmiirq_state;
|
|
-- service maskable interrupts
|
|
else
|
|
--
|
--
|
-- nmi request is not cleared until nmi input goes low
|
-- Page2 pre byte
|
|
-- pre=(pc) / pc=pc+1
|
|
-- op=(pc) / pc=pc+1
|
--
|
--
|
if(nmi_req = '0') and (nmi_ack='1') then
|
when "0000" => -- page2
|
nmi_ctrl <= reset_nmi;
|
opfetch <= '1';
|
end if;
|
op_ctrl <= fetch_op;
|
|
-- advance pc
|
|
pc_ctrl <= incr_pc;
|
|
next_state <= decode2_state;
|
|
|
--
|
--
|
-- FIRQ & IRQ are level sensitive
|
-- Page3 pre byte
|
|
-- pre=(pc) / pc=pc+1
|
|
-- op=(pc) / pc=pc+1
|
--
|
--
|
if (firq = '1') and (cc(FBIT) = '0') then
|
when "0001" => -- page3
|
iv_ctrl <= firq_iv;
|
opfetch <= '1';
|
next_state <= int_firq_state;
|
op_ctrl <= fetch_op;
|
elsif (irq = '1') and (cc(IBIT) = '0') then
|
-- advance pc
|
iv_ctrl <= irq_iv;
|
|
next_state <= int_nmiirq_state;
|
|
else
|
|
-- Advance the PC to fetch next instruction byte
|
|
iv_ctrl <= reset_iv; -- default to reset
|
|
pc_ctrl <= incr_pc;
|
pc_ctrl <= incr_pc;
|
next_state <= decode1_state;
|
next_state <= decode3_state;
|
end if;
|
|
end if;
|
|
--
|
--
|
-- Here to decode instruction
|
-- nop - No operation ( 1 byte )
|
-- and fetch next byte of intruction
|
-- 6809 => 2 cycles
|
-- whether it be necessary or not
|
-- cpu09 => 2 cycles
|
--
|
-- 1 op=(pc) / pc=pc+1
|
when decode1_state =>
|
-- 2 decode
|
-- fetch first byte of address or immediate data
|
|
ea_ctrl <= fetch_first_ea;
|
|
md_ctrl <= fetch_first_md;
|
|
addr_ctrl <= fetch_ad;
|
|
case op_code(7 downto 4) is
|
|
--
|
|
-- direct single op (2 bytes)
|
|
-- 6809 => 6 cycles
|
|
-- cpu09 => 5 cycles
|
|
-- 1 op=(pc) / pc=pc+1
|
|
-- 2 ea_hi=dp / ea_lo=(pc) / pc=pc+1
|
|
-- 3 md_lo=(ea) / pc=pc
|
|
-- 4 alu_left=md / md=alu_out / pc=pc
|
|
-- 5 (ea)=md_lo / pc=pc
|
|
--
|
|
-- Exception is JMP
|
|
-- 6809 => 3 cycles
|
|
-- cpu09 => 3 cycles
|
|
-- 1 op=(pc) / pc=pc+1
|
|
-- 2 ea_hi=dp / ea_lo=(pc) / pc=pc+1
|
|
-- 3 pc=ea
|
|
--
|
|
when "0000" =>
|
|
-- advance the PC
|
|
pc_ctrl <= incr_pc;
|
|
case op_code(3 downto 0) is
|
|
when "1110" => -- jmp
|
|
next_state <= jmp_state;
|
|
when "1111" => -- clr
|
|
next_state <= single_op_exec_state;
|
|
when others =>
|
|
next_state <= single_op_read_state;
|
|
end case;
|
|
|
|
-- acca / accb inherent instructions
|
|
when "0001" =>
|
|
case op_code(3 downto 0) is
|
|
--
|
|
-- Page2 pre byte
|
|
-- pre=(pc) / pc=pc+1
|
|
-- op=(pc) / pc=pc+1
|
|
--
|
|
when "0000" => -- page2
|
|
op_ctrl <= fetch_op;
|
|
-- advance pc
|
|
pc_ctrl <= incr_pc;
|
|
next_state <= decode2_state;
|
|
|
|
--
|
|
-- Page3 pre byte
|
|
-- pre=(pc) / pc=pc+1
|
|
-- op=(pc) / pc=pc+1
|
|
--
|
|
when "0001" => -- page3
|
|
op_ctrl <= fetch_op;
|
|
-- advance pc
|
|
pc_ctrl <= incr_pc;
|
|
next_state <= decode3_state;
|
|
|
|
--
|
|
-- nop - No operation ( 1 byte )
|
|
-- 6809 => 2 cycles
|
|
-- cpu09 => 2 cycles
|
|
-- 1 op=(pc) / pc=pc+1
|
|
-- 2 decode
|
|
--
|
--
|
when "0010" => -- nop
|
when "0010" => -- nop
|
lic <= '1';
|
lic <= '1';
|
next_state <= fetch_state;
|
next_state <= fetch_state;
|
|
|
Line 1983... |
Line 1769... |
sp_ctrl <= load_sp;
|
sp_ctrl <= load_sp;
|
-- increment the pc
|
-- increment the pc
|
pc_ctrl <= incr_pc;
|
pc_ctrl <= incr_pc;
|
next_state <= lbranch_state;
|
next_state <= lbranch_state;
|
|
|
|
--
|
|
-- Decimal Adjust Accumulator
|
|
--
|
when "1001" => -- daa
|
when "1001" => -- daa
|
left_ctrl <= acca_left;
|
left_ctrl <= acca_left;
|
right_ctrl <= accb_right;
|
right_ctrl <= accb_right;
|
alu_ctrl <= alu_daa;
|
alu_ctrl <= alu_daa;
|
cc_ctrl <= load_cc;
|
cc_ctrl <= load_cc;
|
acca_ctrl <= load_acca;
|
acca_ctrl <= load_acca;
|
lic <= '1';
|
lic <= '1';
|
next_state <= fetch_state;
|
next_state <= fetch_state;
|
|
|
|
--
|
|
-- OR Condition Codes
|
|
--
|
when "1010" => -- orcc
|
when "1010" => -- orcc
|
-- increment the pc
|
-- increment the pc
|
pc_ctrl <= incr_pc;
|
pc_ctrl <= incr_pc;
|
st_ctrl <= push_st;
|
|
return_state <= fetch_state;
|
|
next_state <= orcc_state;
|
next_state <= orcc_state;
|
|
|
|
--
|
|
-- AND Condition Codes
|
|
--
|
when "1100" => -- andcc
|
when "1100" => -- andcc
|
-- increment the pc
|
-- increment the pc
|
pc_ctrl <= incr_pc;
|
pc_ctrl <= incr_pc;
|
st_ctrl <= push_st;
|
|
return_state <= fetch_state;
|
|
next_state <= andcc_state;
|
next_state <= andcc_state;
|
|
|
|
--
|
|
-- Sign Extend
|
|
--
|
when "1101" => -- sex
|
when "1101" => -- sex
|
-- have sex
|
|
left_ctrl <= accb_left;
|
left_ctrl <= accb_left;
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_sex;
|
alu_ctrl <= alu_sex;
|
cc_ctrl <= load_cc;
|
cc_ctrl <= load_cc;
|
acca_ctrl <= load_hi_acca;
|
acca_ctrl <= load_hi_acca;
|
lic <= '1';
|
lic <= '1';
|
next_state <= fetch_state;
|
next_state <= fetch_state;
|
|
|
|
--
|
|
-- Exchange Registers
|
|
--
|
when "1110" => -- exg
|
when "1110" => -- exg
|
-- increment the pc
|
-- increment the pc
|
pc_ctrl <= incr_pc;
|
pc_ctrl <= incr_pc;
|
next_state <= exg_state;
|
next_state <= exg_state;
|
|
|
|
--
|
|
-- Transfer Registers
|
|
--
|
when "1111" => -- tfr
|
when "1111" => -- tfr
|
-- increment the pc
|
-- increment the pc
|
pc_ctrl <= incr_pc;
|
pc_ctrl <= incr_pc;
|
-- call transfer as a subroutine
|
|
st_ctrl <= push_st;
|
|
return_state <= fetch_state;
|
|
next_state <= tfr_state;
|
next_state <= tfr_state;
|
|
|
when others =>
|
when others =>
|
-- increment the pc
|
-- increment the pc
|
pc_ctrl <= incr_pc;
|
pc_ctrl <= incr_pc;
|
lic <= '1';
|
lic <= '1';
|
next_state <= fetch_state;
|
next_state <= fetch_state;
|
end case;
|
end case;
|
|
|
--
|
--
|
-- Short branch conditional
|
-- Short branch conditional
|
-- 6809 => always 3 cycles
|
-- 6809 => always 3 cycles
|
-- cpu09 => always = 3 cycles
|
-- cpu09 => always = 3 cycles
|
-- 1 op=(pc) / pc=pc+1
|
-- 1 op=(pc) / pc=pc+1
|
Line 2047... |
Line 1844... |
--
|
--
|
when "0010" => -- branch conditional
|
when "0010" => -- branch conditional
|
-- increment the pc
|
-- increment the pc
|
pc_ctrl <= incr_pc;
|
pc_ctrl <= incr_pc;
|
next_state <= sbranch_state;
|
next_state <= sbranch_state;
|
|
|
--
|
--
|
-- Single byte stack operators
|
-- Single byte stack operators
|
-- Do not advance PC
|
-- Do not advance PC
|
--
|
--
|
when "0011" =>
|
when "0011" =>
|
Line 2144... |
Line 1942... |
-- 2 decode op
|
-- 2 decode op
|
-- 3 pc_hi = (sp) / sp=sp+1
|
-- 3 pc_hi = (sp) / sp=sp+1
|
-- 4 pc_lo = (sp) / sp=sp+1
|
-- 4 pc_lo = (sp) / sp=sp+1
|
--
|
--
|
when "1001" =>
|
when "1001" =>
|
st_ctrl <= push_st;
|
|
return_state <= fetch_state;
|
|
next_state <= pull_return_hi_state;
|
next_state <= pull_return_hi_state;
|
|
|
--
|
--
|
-- add accb to index register
|
-- ADD accb to index register
|
-- *** Note: this is an unsigned addition.
|
-- *** Note: this is an unsigned addition.
|
-- does not affect any condition codes
|
-- does not affect any condition codes
|
-- 6809 => 3 cycles
|
-- 6809 => 3 cycles
|
-- cpu09 => 2 cycles
|
-- cpu09 => 2 cycles
|
-- 1 op=(pc) / pc=pc+1
|
-- 1 op=(pc) / pc=pc+1
|
-- 2 alu_left=ix / alu_right=accb / ix=alu_out / pc=pc
|
-- 2 alu_left=ix / alu_right=accb / ix=alu_out / pc=pc
|
--
|
--
|
when "1010" => -- abx
|
when "1010" => -- abx
|
|
lic <= '1';
|
left_ctrl <= ix_left;
|
left_ctrl <= ix_left;
|
right_ctrl <= accb_right;
|
right_ctrl <= accb_right;
|
alu_ctrl <= alu_abx;
|
alu_ctrl <= alu_abx;
|
ix_ctrl <= load_ix;
|
ix_ctrl <= load_ix;
|
lic <= '1';
|
|
next_state <= fetch_state;
|
next_state <= fetch_state;
|
|
|
|
--
|
|
-- Return From Interrupt
|
|
--
|
when "1011" => -- rti
|
when "1011" => -- rti
|
next_state <= rti_cc_state;
|
next_state <= rti_cc_state;
|
|
|
|
--
|
|
-- CWAI
|
|
--
|
when "1100" => -- cwai #$<cc_mask>
|
when "1100" => -- cwai #$<cc_mask>
|
-- pre decrement sp
|
-- pre decrement sp
|
left_ctrl <= sp_left;
|
left_ctrl <= sp_left;
|
right_ctrl <= one_right;
|
right_ctrl <= one_right;
|
alu_ctrl <= alu_sub16;
|
alu_ctrl <= alu_sub16;
|
sp_ctrl <= load_sp;
|
sp_ctrl <= load_sp;
|
iv_ctrl <= reset_iv;
|
|
-- increment pc
|
-- increment pc
|
pc_ctrl <= incr_pc;
|
pc_ctrl <= incr_pc;
|
st_ctrl <= push_st;
|
next_state <= cwai_state;
|
return_state <= int_entire_state; -- set entire flag
|
|
next_state <= andcc_state;
|
|
|
|
|
--
|
|
-- MUL Multiply
|
|
--
|
when "1101" => -- mul
|
when "1101" => -- mul
|
next_state <= mul_state;
|
next_state <= mul_state;
|
|
|
|
--
|
|
-- SWI Software Interrupt
|
|
--
|
when "1111" => -- swi
|
when "1111" => -- swi
|
-- predecrement SP
|
-- predecrement SP
|
left_ctrl <= sp_left;
|
left_ctrl <= sp_left;
|
right_ctrl <= one_right;
|
right_ctrl <= one_right;
|
alu_ctrl <= alu_sub16;
|
alu_ctrl <= alu_sub16;
|
sp_ctrl <= load_sp;
|
sp_ctrl <= load_sp;
|
iv_ctrl <= swi_iv;
|
iv_ctrl <= swi_iv;
|
|
st_ctrl <= push_st;
|
|
return_state <= int_swimask_state;
|
next_state <= int_entire_state;
|
next_state <= int_entire_state;
|
|
|
when others =>
|
when others =>
|
lic <= '1';
|
lic <= '1';
|
next_state <= fetch_state;
|
next_state <= fetch_state;
|
Line 2212... |
Line 2019... |
-- Re-run opcode fetch cycle after decode
|
-- Re-run opcode fetch cycle after decode
|
--
|
--
|
when "0100" => -- acca single op
|
when "0100" => -- acca single op
|
left_ctrl <= acca_left;
|
left_ctrl <= acca_left;
|
case op_code(3 downto 0) is
|
case op_code(3 downto 0) is
|
|
|
when "0000" => -- neg
|
when "0000" => -- neg
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_neg;
|
alu_ctrl <= alu_neg;
|
acca_ctrl <= load_acca;
|
acca_ctrl <= load_acca;
|
cc_ctrl <= load_cc;
|
cc_ctrl <= load_cc;
|
|
|
when "0011" => -- com
|
when "0011" => -- com
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_com;
|
alu_ctrl <= alu_com;
|
acca_ctrl <= load_acca;
|
acca_ctrl <= load_acca;
|
cc_ctrl <= load_cc;
|
cc_ctrl <= load_cc;
|
|
|
when "0100" => -- lsr
|
when "0100" => -- lsr
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_lsr8;
|
alu_ctrl <= alu_lsr8;
|
acca_ctrl <= load_acca;
|
acca_ctrl <= load_acca;
|
cc_ctrl <= load_cc;
|
cc_ctrl <= load_cc;
|
|
|
when "0110" => -- ror
|
when "0110" => -- ror
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_ror8;
|
alu_ctrl <= alu_ror8;
|
acca_ctrl <= load_acca;
|
acca_ctrl <= load_acca;
|
cc_ctrl <= load_cc;
|
cc_ctrl <= load_cc;
|
|
|
when "0111" => -- asr
|
when "0111" => -- asr
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_asr8;
|
alu_ctrl <= alu_asr8;
|
acca_ctrl <= load_acca;
|
acca_ctrl <= load_acca;
|
cc_ctrl <= load_cc;
|
cc_ctrl <= load_cc;
|
|
|
when "1000" => -- asl
|
when "1000" => -- asl
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_asl8;
|
alu_ctrl <= alu_asl8;
|
acca_ctrl <= load_acca;
|
acca_ctrl <= load_acca;
|
cc_ctrl <= load_cc;
|
cc_ctrl <= load_cc;
|
|
|
when "1001" => -- rol
|
when "1001" => -- rol
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_rol8;
|
alu_ctrl <= alu_rol8;
|
acca_ctrl <= load_acca;
|
acca_ctrl <= load_acca;
|
cc_ctrl <= load_cc;
|
cc_ctrl <= load_cc;
|
|
|
when "1010" => -- dec
|
when "1010" => -- dec
|
right_ctrl <= one_right;
|
right_ctrl <= one_right;
|
alu_ctrl <= alu_dec;
|
alu_ctrl <= alu_dec;
|
acca_ctrl <= load_acca;
|
acca_ctrl <= load_acca;
|
cc_ctrl <= load_cc;
|
cc_ctrl <= load_cc;
|
|
|
when "1011" => -- undefined
|
when "1011" => -- undefined
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_nop;
|
alu_ctrl <= alu_nop;
|
acca_ctrl <= latch_acca;
|
acca_ctrl <= latch_acca;
|
cc_ctrl <= latch_cc;
|
cc_ctrl <= latch_cc;
|
|
|
when "1100" => -- inc
|
when "1100" => -- inc
|
right_ctrl <= one_right;
|
right_ctrl <= one_right;
|
alu_ctrl <= alu_inc;
|
alu_ctrl <= alu_inc;
|
acca_ctrl <= load_acca;
|
acca_ctrl <= load_acca;
|
cc_ctrl <= load_cc;
|
cc_ctrl <= load_cc;
|
|
|
when "1101" => -- tst
|
when "1101" => -- tst
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_st8;
|
alu_ctrl <= alu_st8;
|
acca_ctrl <= latch_acca;
|
acca_ctrl <= latch_acca;
|
cc_ctrl <= load_cc;
|
cc_ctrl <= load_cc;
|
|
|
when "1110" => -- jmp (not defined)
|
when "1110" => -- jmp (not defined)
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_nop;
|
alu_ctrl <= alu_nop;
|
acca_ctrl <= latch_acca;
|
acca_ctrl <= latch_acca;
|
cc_ctrl <= latch_cc;
|
cc_ctrl <= latch_cc;
|
|
|
when "1111" => -- clr
|
when "1111" => -- clr
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_clr;
|
alu_ctrl <= alu_clr;
|
acca_ctrl <= load_acca;
|
acca_ctrl <= load_acca;
|
cc_ctrl <= load_cc;
|
cc_ctrl <= load_cc;
|
|
|
when others =>
|
when others =>
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_nop;
|
alu_ctrl <= alu_nop;
|
acca_ctrl <= latch_acca;
|
acca_ctrl <= latch_acca;
|
cc_ctrl <= latch_cc;
|
cc_ctrl <= latch_cc;
|
|
|
end case;
|
end case;
|
lic <= '1';
|
lic <= '1';
|
next_state <= fetch_state;
|
next_state <= fetch_state;
|
|
|
--
|
--
|
-- Single Operand accb
|
-- Single Operand accb
|
-- source = accb, dest = accb
|
-- source = accb, dest = accb
|
-- Typically 2 cycles 1 bytes
|
-- Typically 2 cycles 1 bytes
|
-- 1 opcode fetch
|
-- 1 opcode fetch
|
Line 2303... |
Line 2126... |
when "0000" => -- neg
|
when "0000" => -- neg
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_neg;
|
alu_ctrl <= alu_neg;
|
accb_ctrl <= load_accb;
|
accb_ctrl <= load_accb;
|
cc_ctrl <= load_cc;
|
cc_ctrl <= load_cc;
|
|
|
when "0011" => -- com
|
when "0011" => -- com
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_com;
|
alu_ctrl <= alu_com;
|
accb_ctrl <= load_accb;
|
accb_ctrl <= load_accb;
|
cc_ctrl <= load_cc;
|
cc_ctrl <= load_cc;
|
|
|
when "0100" => -- lsr
|
when "0100" => -- lsr
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_lsr8;
|
alu_ctrl <= alu_lsr8;
|
accb_ctrl <= load_accb;
|
accb_ctrl <= load_accb;
|
cc_ctrl <= load_cc;
|
cc_ctrl <= load_cc;
|
|
|
when "0110" => -- ror
|
when "0110" => -- ror
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_ror8;
|
alu_ctrl <= alu_ror8;
|
accb_ctrl <= load_accb;
|
accb_ctrl <= load_accb;
|
cc_ctrl <= load_cc;
|
cc_ctrl <= load_cc;
|
|
|
when "0111" => -- asr
|
when "0111" => -- asr
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_asr8;
|
alu_ctrl <= alu_asr8;
|
accb_ctrl <= load_accb;
|
accb_ctrl <= load_accb;
|
cc_ctrl <= load_cc;
|
cc_ctrl <= load_cc;
|
|
|
when "1000" => -- asl
|
when "1000" => -- asl
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_asl8;
|
alu_ctrl <= alu_asl8;
|
accb_ctrl <= load_accb;
|
accb_ctrl <= load_accb;
|
cc_ctrl <= load_cc;
|
cc_ctrl <= load_cc;
|
|
|
when "1001" => -- rol
|
when "1001" => -- rol
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_rol8;
|
alu_ctrl <= alu_rol8;
|
accb_ctrl <= load_accb;
|
accb_ctrl <= load_accb;
|
cc_ctrl <= load_cc;
|
cc_ctrl <= load_cc;
|
|
|
when "1010" => -- dec
|
when "1010" => -- dec
|
right_ctrl <= one_right;
|
right_ctrl <= one_right;
|
alu_ctrl <= alu_dec;
|
alu_ctrl <= alu_dec;
|
accb_ctrl <= load_accb;
|
accb_ctrl <= load_accb;
|
cc_ctrl <= load_cc;
|
cc_ctrl <= load_cc;
|
|
|
when "1011" => -- undefined
|
when "1011" => -- undefined
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_nop;
|
alu_ctrl <= alu_nop;
|
accb_ctrl <= latch_accb;
|
accb_ctrl <= latch_accb;
|
cc_ctrl <= latch_cc;
|
cc_ctrl <= latch_cc;
|
|
|
when "1100" => -- inc
|
when "1100" => -- inc
|
right_ctrl <= one_right;
|
right_ctrl <= one_right;
|
alu_ctrl <= alu_inc;
|
alu_ctrl <= alu_inc;
|
accb_ctrl <= load_accb;
|
accb_ctrl <= load_accb;
|
cc_ctrl <= load_cc;
|
cc_ctrl <= load_cc;
|
|
|
when "1101" => -- tst
|
when "1101" => -- tst
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_st8;
|
alu_ctrl <= alu_st8;
|
accb_ctrl <= latch_accb;
|
accb_ctrl <= latch_accb;
|
cc_ctrl <= load_cc;
|
cc_ctrl <= load_cc;
|
|
|
when "1110" => -- jmp (undefined)
|
when "1110" => -- jmp (undefined)
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_nop;
|
alu_ctrl <= alu_nop;
|
accb_ctrl <= latch_accb;
|
accb_ctrl <= latch_accb;
|
cc_ctrl <= latch_cc;
|
cc_ctrl <= latch_cc;
|
|
|
when "1111" => -- clr
|
when "1111" => -- clr
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_clr;
|
alu_ctrl <= alu_clr;
|
accb_ctrl <= load_accb;
|
accb_ctrl <= load_accb;
|
cc_ctrl <= load_cc;
|
cc_ctrl <= load_cc;
|
|
|
when others =>
|
when others =>
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_nop;
|
alu_ctrl <= alu_nop;
|
accb_ctrl <= latch_accb;
|
accb_ctrl <= latch_accb;
|
cc_ctrl <= latch_cc;
|
cc_ctrl <= latch_cc;
|
end case;
|
end case;
|
lic <= '1';
|
lic <= '1';
|
next_state <= fetch_state;
|
next_state <= fetch_state;
|
|
|
--
|
--
|
-- Single operand indexed
|
-- Single operand indexed
|
-- Two byte instruction so advance PC
|
-- Two byte instruction so advance PC
|
-- EA should hold index offset
|
-- EA should hold index offset
|
--
|
--
|
when "0110" => -- indexed single op
|
when "0110" => -- indexed single op
|
-- increment the pc
|
-- increment the pc
|
pc_ctrl <= incr_pc;
|
pc_ctrl <= incr_pc;
|
st_ctrl <= push_st;
|
st_ctrl <= push_st;
|
|
|
case op_code(3 downto 0) is
|
case op_code(3 downto 0) is
|
when "1110" => -- jmp
|
when "1110" => -- jmp
|
return_state <= jmp_state;
|
return_state <= jmp_state;
|
|
|
when "1111" => -- clr
|
when "1111" => -- clr
|
return_state <= single_op_exec_state;
|
return_state <= single_op_exec_state;
|
|
|
when others =>
|
when others =>
|
return_state <= single_op_read_state;
|
return_state <= single_op_read_state;
|
|
|
end case;
|
end case;
|
next_state <= indexed_state;
|
next_state <= indexed_state;
|
|
|
--
|
--
|
-- Single operand extended addressing
|
-- Single operand extended addressing
|
-- three byte instruction so advance the PC
|
-- three byte instruction so advance the PC
|
-- Low order EA holds high order address
|
-- Low order EA holds high order address
|
--
|
--
|
when "0111" => -- extended single op
|
when "0111" => -- extended single op
|
-- increment PC
|
-- increment PC
|
pc_ctrl <= incr_pc;
|
pc_ctrl <= incr_pc;
|
st_ctrl <= push_st;
|
st_ctrl <= push_st;
|
|
|
case op_code(3 downto 0) is
|
case op_code(3 downto 0) is
|
when "1110" => -- jmp
|
when "1110" => -- jmp
|
return_state <= jmp_state;
|
return_state <= jmp_state;
|
|
|
when "1111" => -- clr
|
when "1111" => -- clr
|
return_state <= single_op_exec_state;
|
return_state <= single_op_exec_state;
|
|
|
when others =>
|
when others =>
|
return_state <= single_op_read_state;
|
return_state <= single_op_read_state;
|
|
|
end case;
|
end case;
|
next_state <= extended_state;
|
next_state <= extended_state;
|
|
|
when "1000" => -- acca immediate
|
when "1000" => -- acca immediate
|
-- increment the pc
|
-- increment the pc
|
pc_ctrl <= incr_pc;
|
pc_ctrl <= incr_pc;
|
|
|
case op_code(3 downto 0) is
|
case op_code(3 downto 0) is
|
when "0011" | -- subd #
|
when "0011" | -- subd #
|
"1100" | -- cmpx #
|
"1100" | -- cmpx #
|
"1110" => -- ldx #
|
"1110" => -- ldx #
|
st_ctrl <= push_st;
|
|
return_state <= fetch_state;
|
|
next_state <= imm16_state;
|
next_state <= imm16_state;
|
|
|
--
|
--
|
-- bsr offset - Branch to subroutine (2 bytes)
|
-- bsr offset - Branch to subroutine (2 bytes)
|
-- 6809 => 7 cycles
|
-- 6809 => 7 cycles
|
Line 2443... |
Line 2288... |
next_state <= push_return_lo_state;
|
next_state <= push_return_lo_state;
|
|
|
when others =>
|
when others =>
|
lic <= '1';
|
lic <= '1';
|
next_state <= fetch_state;
|
next_state <= fetch_state;
|
|
|
end case;
|
end case;
|
|
|
when "1001" => -- acca direct
|
when "1001" => -- acca direct
|
-- increment the pc
|
-- increment the pc
|
pc_ctrl <= incr_pc;
|
pc_ctrl <= incr_pc;
|
Line 2457... |
Line 2303... |
next_state <= dual_op_read16_state;
|
next_state <= dual_op_read16_state;
|
|
|
when "0111" => -- sta direct
|
when "0111" => -- sta direct
|
next_state <= dual_op_write8_state;
|
next_state <= dual_op_write8_state;
|
|
|
when "1111" => -- stx direct
|
|
-- idle ALU
|
|
left_ctrl <= ix_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
sp_ctrl <= latch_sp;
|
|
next_state <= dual_op_write16_state;
|
|
|
|
--
|
--
|
-- jsr direct - Jump to subroutine in direct page (2 bytes)
|
-- jsr direct - Jump to subroutine in direct page (2 bytes)
|
-- 6809 => 7 cycles
|
-- 6809 => 7 cycles
|
-- cpu09 => 5 cycles
|
-- cpu09 => 5 cycles
|
-- 1 op=(pc) / pc=pc+1
|
-- 1 op=(pc) / pc=pc+1
|
Line 2487... |
Line 2324... |
--
|
--
|
st_ctrl <= push_st;
|
st_ctrl <= push_st;
|
return_state <= jmp_state;
|
return_state <= jmp_state;
|
next_state <= push_return_lo_state;
|
next_state <= push_return_lo_state;
|
|
|
|
|
|
when "1111" => -- stx direct
|
|
-- idle ALU
|
|
left_ctrl <= ix_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_nop;
|
|
cc_ctrl <= latch_cc;
|
|
sp_ctrl <= latch_sp;
|
|
next_state <= dual_op_write16_state;
|
|
|
when others =>
|
when others =>
|
next_state <= dual_op_read8_state;
|
next_state <= dual_op_read8_state;
|
|
|
end case;
|
end case;
|
|
|
when "1010" => -- acca indexed
|
when "1010" => -- acca indexed
|
-- increment the pc
|
-- increment the pc
|
pc_ctrl <= incr_pc;
|
pc_ctrl <= incr_pc;
|
Line 2507... |
Line 2355... |
when "0111" => -- staa ,x
|
when "0111" => -- staa ,x
|
st_ctrl <= push_st;
|
st_ctrl <= push_st;
|
return_state <= dual_op_write8_state;
|
return_state <= dual_op_write8_state;
|
next_state <= indexed_state;
|
next_state <= indexed_state;
|
|
|
when "1111" => -- stx ,x
|
|
st_ctrl <= push_st;
|
|
return_state <= dual_op_write16_state;
|
|
next_state <= indexed_state;
|
|
|
|
when "1101" => -- jsr ,x
|
when "1101" => -- jsr ,x
|
-- DO NOT pre decrement SP
|
-- DO NOT pre decrement SP
|
st_ctrl <= push_st;
|
st_ctrl <= push_st;
|
return_state <= jsr_state;
|
return_state <= jsr_state;
|
next_state <= indexed_state;
|
next_state <= indexed_state;
|
|
|
|
when "1111" => -- stx ,x
|
|
st_ctrl <= push_st;
|
|
return_state <= dual_op_write16_state;
|
|
next_state <= indexed_state;
|
|
|
when others =>
|
when others =>
|
st_ctrl <= push_st;
|
st_ctrl <= push_st;
|
return_state <= dual_op_read8_state;
|
return_state <= dual_op_read8_state;
|
next_state <= indexed_state;
|
next_state <= indexed_state;
|
|
|
end case;
|
end case;
|
|
|
when "1011" => -- acca extended
|
when "1011" => -- acca extended
|
-- increment the pc
|
-- increment the pc
|
pc_ctrl <= incr_pc;
|
pc_ctrl <= incr_pc;
|
Line 2540... |
Line 2389... |
when "0111" => -- staa >
|
when "0111" => -- staa >
|
st_ctrl <= push_st;
|
st_ctrl <= push_st;
|
return_state <= dual_op_write8_state;
|
return_state <= dual_op_write8_state;
|
next_state <= extended_state;
|
next_state <= extended_state;
|
|
|
when "1111" => -- stx >
|
|
st_ctrl <= push_st;
|
|
return_state <= dual_op_write16_state;
|
|
next_state <= extended_state;
|
|
|
|
when "1101" => -- jsr >extended
|
when "1101" => -- jsr >extended
|
-- DO NOT pre decrement sp
|
-- DO NOT pre decrement sp
|
st_ctrl <= push_st;
|
st_ctrl <= push_st;
|
return_state <= jsr_state;
|
return_state <= jsr_state;
|
next_state <= extended_state;
|
next_state <= extended_state;
|
|
|
|
when "1111" => -- stx >
|
|
st_ctrl <= push_st;
|
|
return_state <= dual_op_write16_state;
|
|
next_state <= extended_state;
|
|
|
when others =>
|
when others =>
|
st_ctrl <= push_st;
|
st_ctrl <= push_st;
|
return_state <= dual_op_read8_state;
|
return_state <= dual_op_read8_state;
|
next_state <= extended_state;
|
next_state <= extended_state;
|
|
|
end case;
|
end case;
|
|
|
when "1100" => -- accb immediate
|
when "1100" => -- accb immediate
|
-- increment the pc
|
-- increment the pc
|
pc_ctrl <= incr_pc;
|
pc_ctrl <= incr_pc;
|
case op_code(3 downto 0) is
|
case op_code(3 downto 0) is
|
when "0011" | -- addd #
|
when "0011" | -- addd #
|
"1100" | -- ldd #
|
"1100" | -- ldd #
|
"1110" => -- ldu #
|
"1110" => -- ldu #
|
st_ctrl <= push_st;
|
|
return_state <= fetch_state;
|
|
next_state <= imm16_state;
|
next_state <= imm16_state;
|
|
|
when others =>
|
when others =>
|
lic <= '1';
|
lic <= '1';
|
next_state <= fetch_state;
|
next_state <= fetch_state;
|
|
|
end case;
|
end case;
|
|
|
|
|
when "1101" => -- accb direct
|
when "1101" => -- accb direct
|
-- increment the pc
|
-- increment the pc
|
pc_ctrl <= incr_pc;
|
pc_ctrl <= incr_pc;
|
case op_code(3 downto 0) is
|
case op_code(3 downto 0) is
|
when "0011" | -- addd
|
when "0011" | -- addd
|
Line 2595... |
Line 2442... |
when "1111" => -- stu direct
|
when "1111" => -- stu direct
|
next_state <= dual_op_write16_state;
|
next_state <= dual_op_write16_state;
|
|
|
when others =>
|
when others =>
|
next_state <= dual_op_read8_state;
|
next_state <= dual_op_read8_state;
|
|
|
end case;
|
end case;
|
|
|
when "1110" => -- accb indexed
|
when "1110" => -- accb indexed
|
-- increment the pc
|
-- increment the pc
|
pc_ctrl <= incr_pc;
|
pc_ctrl <= incr_pc;
|
Line 2627... |
Line 2475... |
|
|
when others =>
|
when others =>
|
st_ctrl <= push_st;
|
st_ctrl <= push_st;
|
return_state <= dual_op_read8_state;
|
return_state <= dual_op_read8_state;
|
next_state <= indexed_state;
|
next_state <= indexed_state;
|
|
|
end case;
|
end case;
|
|
|
when "1111" => -- accb extended
|
when "1111" => -- accb extended
|
-- increment the pc
|
-- increment the pc
|
pc_ctrl <= incr_pc;
|
pc_ctrl <= incr_pc;
|
Line 2660... |
Line 2509... |
when others =>
|
when others =>
|
st_ctrl <= push_st;
|
st_ctrl <= push_st;
|
return_state <= dual_op_read8_state;
|
return_state <= dual_op_read8_state;
|
next_state <= extended_state;
|
next_state <= extended_state;
|
end case;
|
end case;
|
|
--
|
|
-- not sure why I need this
|
|
--
|
when others =>
|
when others =>
|
null;
|
lic <= '1';
|
|
next_state <= fetch_state;
|
end case;
|
end case;
|
|
|
--
|
--
|
-- Here to decode prefix 2 instruction
|
-- Here to decode prefix 2 instruction
|
-- and fetch next byte of intruction
|
-- and fetch next byte of intruction
|
Line 2704... |
Line 2556... |
left_ctrl <= sp_left;
|
left_ctrl <= sp_left;
|
right_ctrl <= one_right;
|
right_ctrl <= one_right;
|
alu_ctrl <= alu_sub16;
|
alu_ctrl <= alu_sub16;
|
sp_ctrl <= load_sp;
|
sp_ctrl <= load_sp;
|
iv_ctrl <= swi2_iv;
|
iv_ctrl <= swi2_iv;
|
|
st_ctrl <= push_st;
|
|
return_state <= vect_hi_state;
|
next_state <= int_entire_state;
|
next_state <= int_entire_state;
|
|
|
when others =>
|
when others =>
|
lic <= '1';
|
lic <= '1';
|
next_state <= fetch_state;
|
next_state <= fetch_state;
|
Line 2718... |
Line 2572... |
pc_ctrl <= incr_pc;
|
pc_ctrl <= incr_pc;
|
case op_code(3 downto 0) is
|
case op_code(3 downto 0) is
|
when "0011" | -- cmpd #
|
when "0011" | -- cmpd #
|
"1100" | -- cmpy #
|
"1100" | -- cmpy #
|
"1110" => -- ldy #
|
"1110" => -- ldy #
|
st_ctrl <= push_st;
|
|
return_state <= fetch_state;
|
|
next_state <= imm16_state;
|
next_state <= imm16_state;
|
|
|
when others =>
|
when others =>
|
lic <= '1';
|
lic <= '1';
|
next_state <= fetch_state;
|
next_state <= fetch_state;
|
Line 2796... |
Line 2648... |
pc_ctrl <= incr_pc;
|
pc_ctrl <= incr_pc;
|
case op_code(3 downto 0) is
|
case op_code(3 downto 0) is
|
when "0011" | -- undef #
|
when "0011" | -- undef #
|
"1100" | -- undef #
|
"1100" | -- undef #
|
"1110" => -- lds #
|
"1110" => -- lds #
|
st_ctrl <= push_st;
|
|
return_state <= fetch_state;
|
|
next_state <= imm16_state;
|
next_state <= imm16_state;
|
|
|
when others =>
|
when others =>
|
next_state <= fetch_state;
|
next_state <= fetch_state;
|
|
|
Line 2894... |
Line 2744... |
left_ctrl <= sp_left;
|
left_ctrl <= sp_left;
|
right_ctrl <= one_right;
|
right_ctrl <= one_right;
|
alu_ctrl <= alu_sub16;
|
alu_ctrl <= alu_sub16;
|
sp_ctrl <= load_sp;
|
sp_ctrl <= load_sp;
|
iv_ctrl <= swi3_iv;
|
iv_ctrl <= swi3_iv;
|
|
st_ctrl <= push_st;
|
|
return_state <= vect_hi_state;
|
next_state <= int_entire_state;
|
next_state <= int_entire_state;
|
when others =>
|
when others =>
|
lic <= '1';
|
lic <= '1';
|
next_state <= fetch_state;
|
next_state <= fetch_state;
|
end case;
|
end case;
|
Line 2907... |
Line 2759... |
pc_ctrl <= incr_pc;
|
pc_ctrl <= incr_pc;
|
case op_code(3 downto 0) is
|
case op_code(3 downto 0) is
|
when "0011" | -- cmpu #
|
when "0011" | -- cmpu #
|
"1100" | -- cmps #
|
"1100" | -- cmps #
|
"1110" => -- undef #
|
"1110" => -- undef #
|
st_ctrl <= push_st;
|
|
return_state <= fetch_state;
|
|
next_state <= imm16_state;
|
next_state <= imm16_state;
|
when others =>
|
when others =>
|
lic <= '1';
|
lic <= '1';
|
next_state <= fetch_state;
|
next_state <= fetch_state;
|
end case;
|
end case;
|
Line 2922... |
Line 2772... |
pc_ctrl <= incr_pc;
|
pc_ctrl <= incr_pc;
|
case op_code(3 downto 0) is
|
case op_code(3 downto 0) is
|
when "0011" | -- cmpu <
|
when "0011" | -- cmpu <
|
"1100" | -- cmps <
|
"1100" | -- cmps <
|
"1110" => -- undef <
|
"1110" => -- undef <
|
st_ctrl <= idle_st;
|
|
return_state <= fetch_state;
|
|
next_state <= dual_op_read16_state;
|
next_state <= dual_op_read16_state;
|
|
|
when others =>
|
when others =>
|
lic <= '1';
|
lic <= '1';
|
next_state <= fetch_state;
|
next_state <= fetch_state;
|
Line 3227... |
Line 3075... |
-- increment pc
|
-- increment pc
|
pc_ctrl <= incr_pc;
|
pc_ctrl <= incr_pc;
|
-- fetch next immediate byte
|
-- fetch next immediate byte
|
md_ctrl <= fetch_next_md;
|
md_ctrl <= fetch_next_md;
|
addr_ctrl <= fetch_ad;
|
addr_ctrl <= fetch_ad;
|
st_ctrl <= pull_st;
|
|
lic <= '1';
|
lic <= '1';
|
next_state <= saved_state;
|
next_state <= fetch_state;
|
|
|
--
|
--
|
-- md & ea holds 8 bit index offset
|
-- md & ea holds 8 bit index offset
|
-- calculate the effective memory address
|
-- calculate the effective memory address
|
-- using the alu
|
-- using the alu
|
Line 3255... |
Line 3102... |
left_ctrl <= sp_left;
|
left_ctrl <= sp_left;
|
end case;
|
end case;
|
right_ctrl <= md_sign5_right;
|
right_ctrl <= md_sign5_right;
|
alu_ctrl <= alu_add16;
|
alu_ctrl <= alu_add16;
|
ea_ctrl <= load_ea;
|
ea_ctrl <= load_ea;
|
st_ctrl <= pull_st;
|
|
next_state <= saved_state;
|
next_state <= saved_state;
|
|
|
else
|
else
|
case md(3 downto 0) is
|
case md(3 downto 0) is
|
when "0000" => -- ,R+
|
when "0000" => -- ,R+
|
Line 3313... |
Line 3159... |
sp_ctrl <= load_sp;
|
sp_ctrl <= load_sp;
|
end case;
|
end case;
|
right_ctrl <= one_right;
|
right_ctrl <= one_right;
|
alu_ctrl <= alu_sub16;
|
alu_ctrl <= alu_sub16;
|
ea_ctrl <= load_ea;
|
ea_ctrl <= load_ea;
|
st_ctrl <= pull_st;
|
|
next_state <= saved_state;
|
next_state <= saved_state;
|
|
|
when "0011" => -- ,--R
|
when "0011" => -- ,--R
|
case md(6 downto 5) is
|
case md(6 downto 5) is
|
when "00" =>
|
when "00" =>
|
Line 3336... |
Line 3181... |
end case;
|
end case;
|
right_ctrl <= two_right;
|
right_ctrl <= two_right;
|
alu_ctrl <= alu_sub16;
|
alu_ctrl <= alu_sub16;
|
ea_ctrl <= load_ea;
|
ea_ctrl <= load_ea;
|
if md(4) = '0' then
|
if md(4) = '0' then
|
st_ctrl <= pull_st;
|
|
next_state <= saved_state;
|
next_state <= saved_state;
|
else
|
else
|
next_state <= indirect_state;
|
next_state <= indirect_state;
|
end if;
|
end if;
|
|
|
Line 3358... |
Line 3202... |
end case;
|
end case;
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_add16;
|
alu_ctrl <= alu_add16;
|
ea_ctrl <= load_ea;
|
ea_ctrl <= load_ea;
|
if md(4) = '0' then
|
if md(4) = '0' then
|
st_ctrl <= pull_st;
|
|
next_state <= saved_state;
|
next_state <= saved_state;
|
else
|
else
|
next_state <= indirect_state;
|
next_state <= indirect_state;
|
end if;
|
end if;
|
|
|
Line 3380... |
Line 3223... |
end case;
|
end case;
|
right_ctrl <= accb_right;
|
right_ctrl <= accb_right;
|
alu_ctrl <= alu_add16;
|
alu_ctrl <= alu_add16;
|
ea_ctrl <= load_ea;
|
ea_ctrl <= load_ea;
|
if md(4) = '0' then
|
if md(4) = '0' then
|
st_ctrl <= pull_st;
|
|
next_state <= saved_state;
|
next_state <= saved_state;
|
else
|
else
|
next_state <= indirect_state;
|
next_state <= indirect_state;
|
end if;
|
end if;
|
|
|
Line 3402... |
Line 3244... |
end case;
|
end case;
|
right_ctrl <= acca_right;
|
right_ctrl <= acca_right;
|
alu_ctrl <= alu_add16;
|
alu_ctrl <= alu_add16;
|
ea_ctrl <= load_ea;
|
ea_ctrl <= load_ea;
|
if md(4) = '0' then
|
if md(4) = '0' then
|
st_ctrl <= pull_st;
|
|
next_state <= saved_state;
|
next_state <= saved_state;
|
else
|
else
|
next_state <= indirect_state;
|
next_state <= indirect_state;
|
end if;
|
end if;
|
|
|
Line 3424... |
Line 3265... |
end case;
|
end case;
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_add16;
|
alu_ctrl <= alu_add16;
|
ea_ctrl <= load_ea;
|
ea_ctrl <= load_ea;
|
if md(4) = '0' then
|
if md(4) = '0' then
|
st_ctrl <= pull_st;
|
|
next_state <= saved_state;
|
next_state <= saved_state;
|
else
|
else
|
next_state <= indirect_state;
|
next_state <= indirect_state;
|
end if;
|
end if;
|
|
|
Line 3459... |
Line 3299... |
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_add16;
|
alu_ctrl <= alu_add16;
|
ea_ctrl <= load_ea;
|
ea_ctrl <= load_ea;
|
--
|
--
|
if md(4) = '0' then
|
if md(4) = '0' then
|
st_ctrl <= pull_st;
|
|
next_state <= saved_state;
|
next_state <= saved_state;
|
else
|
else
|
next_state <= indirect_state;
|
next_state <= indirect_state;
|
end if;
|
end if;
|
|
|
Line 3481... |
Line 3320... |
end case;
|
end case;
|
right_ctrl <= accd_right;
|
right_ctrl <= accd_right;
|
alu_ctrl <= alu_add16;
|
alu_ctrl <= alu_add16;
|
ea_ctrl <= load_ea;
|
ea_ctrl <= load_ea;
|
if md(4) = '0' then
|
if md(4) = '0' then
|
st_ctrl <= pull_st;
|
|
next_state <= saved_state;
|
next_state <= saved_state;
|
else
|
else
|
next_state <= indirect_state;
|
next_state <= indirect_state;
|
end if;
|
end if;
|
|
|
Line 3517... |
Line 3355... |
end case;
|
end case;
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_add16;
|
alu_ctrl <= alu_add16;
|
ea_ctrl <= load_ea;
|
ea_ctrl <= load_ea;
|
if md(4) = '0' then
|
if md(4) = '0' then
|
st_ctrl <= pull_st;
|
|
next_state <= saved_state;
|
next_state <= saved_state;
|
else
|
else
|
next_state <= indirect_state;
|
next_state <= indirect_state;
|
end if;
|
end if;
|
|
|
Line 3551... |
Line 3388... |
-- when "11" =>
|
-- when "11" =>
|
sp_ctrl <= load_sp;
|
sp_ctrl <= load_sp;
|
end case;
|
end case;
|
-- return to previous state
|
-- return to previous state
|
if md(4) = '0' then
|
if md(4) = '0' then
|
st_ctrl <= pull_st;
|
|
next_state <= saved_state;
|
next_state <= saved_state;
|
else
|
else
|
next_state <= indirect_state;
|
next_state <= indirect_state;
|
end if;
|
end if;
|
|
|
Line 3576... |
Line 3412... |
-- when "11" =>
|
-- when "11" =>
|
sp_ctrl <= load_sp;
|
sp_ctrl <= load_sp;
|
end case;
|
end case;
|
-- return to previous state
|
-- return to previous state
|
if md(4) = '0' then
|
if md(4) = '0' then
|
st_ctrl <= pull_st;
|
|
next_state <= saved_state;
|
next_state <= saved_state;
|
else
|
else
|
next_state <= indirect_state;
|
next_state <= indirect_state;
|
end if;
|
end if;
|
--
|
--
|
Line 3603... |
Line 3438... |
right_ctrl <= md_sign8_right;
|
right_ctrl <= md_sign8_right;
|
alu_ctrl <= alu_add16;
|
alu_ctrl <= alu_add16;
|
ea_ctrl <= load_ea;
|
ea_ctrl <= load_ea;
|
-- return to previous state
|
-- return to previous state
|
if ea(4) = '0' then
|
if ea(4) = '0' then
|
st_ctrl <= pull_st;
|
|
next_state <= saved_state;
|
next_state <= saved_state;
|
else
|
else
|
next_state <= indirect_state;
|
next_state <= indirect_state;
|
end if;
|
end if;
|
|
|
Line 3638... |
Line 3472... |
right_ctrl <= md_right;
|
right_ctrl <= md_right;
|
alu_ctrl <= alu_add16;
|
alu_ctrl <= alu_add16;
|
ea_ctrl <= load_ea;
|
ea_ctrl <= load_ea;
|
-- return to previous state
|
-- return to previous state
|
if ea(4) = '0' then
|
if ea(4) = '0' then
|
st_ctrl <= pull_st;
|
|
next_state <= saved_state;
|
next_state <= saved_state;
|
else
|
else
|
next_state <= indirect_state;
|
next_state <= indirect_state;
|
end if;
|
end if;
|
--
|
--
|
Line 3655... |
Line 3488... |
right_ctrl <= md_sign8_right;
|
right_ctrl <= md_sign8_right;
|
alu_ctrl <= alu_add16;
|
alu_ctrl <= alu_add16;
|
ea_ctrl <= load_ea;
|
ea_ctrl <= load_ea;
|
-- return to previous state
|
-- return to previous state
|
if ea(4) = '0' then
|
if ea(4) = '0' then
|
st_ctrl <= pull_st;
|
|
next_state <= saved_state;
|
next_state <= saved_state;
|
else
|
else
|
next_state <= indirect_state;
|
next_state <= indirect_state;
|
end if;
|
end if;
|
|
|
Line 3682... |
Line 3514... |
right_ctrl <= md_right;
|
right_ctrl <= md_right;
|
alu_ctrl <= alu_add16;
|
alu_ctrl <= alu_add16;
|
ea_ctrl <= load_ea;
|
ea_ctrl <= load_ea;
|
-- return to previous state
|
-- return to previous state
|
if ea(4) = '0' then
|
if ea(4) = '0' then
|
st_ctrl <= pull_st;
|
|
next_state <= saved_state;
|
next_state <= saved_state;
|
else
|
else
|
next_state <= indirect_state;
|
next_state <= indirect_state;
|
end if;
|
end if;
|
|
|
Line 3710... |
Line 3541... |
right_ctrl <= md_right;
|
right_ctrl <= md_right;
|
alu_ctrl <= alu_ld16;
|
alu_ctrl <= alu_ld16;
|
ea_ctrl <= load_ea;
|
ea_ctrl <= load_ea;
|
-- return to previous state
|
-- return to previous state
|
if ea(4) = '0' then
|
if ea(4) = '0' then
|
st_ctrl <= pull_st;
|
|
next_state <= saved_state;
|
next_state <= saved_state;
|
else
|
else
|
next_state <= indirect_state;
|
next_state <= indirect_state;
|
end if;
|
end if;
|
|
|
Line 3753... |
Line 3583... |
left_ctrl <= ea_left;
|
left_ctrl <= ea_left;
|
right_ctrl <= md_right;
|
right_ctrl <= md_right;
|
alu_ctrl <= alu_ld16;
|
alu_ctrl <= alu_ld16;
|
ea_ctrl <= load_ea;
|
ea_ctrl <= load_ea;
|
-- return to previous state
|
-- return to previous state
|
st_ctrl <= pull_st;
|
|
next_state <= saved_state;
|
next_state <= saved_state;
|
|
|
--
|
--
|
-- ea holds the low byte of the absolute address
|
-- ea holds the low byte of the absolute address
|
-- Move ea low byte into ea high byte
|
-- Move ea low byte into ea high byte
|
Line 3769... |
Line 3598... |
pc_ctrl <= incr_pc;
|
pc_ctrl <= incr_pc;
|
-- fetch next effective address bytes
|
-- fetch next effective address bytes
|
ea_ctrl <= fetch_next_ea;
|
ea_ctrl <= fetch_next_ea;
|
addr_ctrl <= fetch_ad;
|
addr_ctrl <= fetch_ad;
|
-- return to previous state
|
-- return to previous state
|
st_ctrl <= pull_st;
|
|
next_state <= saved_state;
|
next_state <= saved_state;
|
|
|
when lea_state => -- here on load effective address
|
when lea_state => -- here on load effective address
|
-- load index register with effective address
|
-- load index register with effective address
|
left_ctrl <= pc_left;
|
left_ctrl <= pc_left;
|
Line 3896... |
Line 3724... |
when "1111" => -- ble
|
when "1111" => -- ble
|
cond_true := ((cc(ZBIT) or (cc(NBIT) xor cc(VBIT))) = '1');
|
cond_true := ((cc(ZBIT) or (cc(NBIT) xor cc(VBIT))) = '1');
|
when others =>
|
when others =>
|
null;
|
null;
|
end case;
|
end case;
|
else
|
|
cond_true := (1 = 1); -- lbra, lbsr, bsr
|
|
end if;
|
end if;
|
if cond_true then
|
if cond_true then
|
pc_ctrl <= load_pc;
|
pc_ctrl <= load_pc;
|
end if;
|
end if;
|
lic <= '1';
|
lic <= '1';
|
Line 3932... |
Line 3758... |
--
|
--
|
when push_return_hi_state =>
|
when push_return_hi_state =>
|
-- write pc hi bytes
|
-- write pc hi bytes
|
addr_ctrl <= pushs_ad;
|
addr_ctrl <= pushs_ad;
|
dout_ctrl <= pc_hi_dout;
|
dout_ctrl <= pc_hi_dout;
|
st_ctrl <= pull_st;
|
|
next_state <= saved_state;
|
next_state <= saved_state;
|
|
|
|
--
|
|
-- RTS pull return address from stack
|
|
--
|
when pull_return_hi_state =>
|
when pull_return_hi_state =>
|
-- increment the sp
|
-- increment the sp
|
left_ctrl <= sp_left;
|
left_ctrl <= sp_left;
|
right_ctrl <= one_right;
|
right_ctrl <= one_right;
|
alu_ctrl <= alu_add16;
|
alu_ctrl <= alu_add16;
|
Line 3957... |
Line 3785... |
-- read pc low
|
-- read pc low
|
pc_ctrl <= pull_lo_pc;
|
pc_ctrl <= pull_lo_pc;
|
addr_ctrl <= pulls_ad;
|
addr_ctrl <= pulls_ad;
|
dout_ctrl <= pc_lo_dout;
|
dout_ctrl <= pc_lo_dout;
|
--
|
--
|
st_ctrl <= pull_st;
|
|
lic <= '1';
|
lic <= '1';
|
next_state <= saved_state;
|
next_state <= fetch_state;
|
|
|
when andcc_state =>
|
when andcc_state =>
|
-- AND CC with md
|
-- AND CC with md
|
left_ctrl <= md_left;
|
left_ctrl <= md_left;
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_andcc;
|
alu_ctrl <= alu_andcc;
|
cc_ctrl <= load_cc;
|
cc_ctrl <= load_cc;
|
--
|
--
|
st_ctrl <= pull_st;
|
|
lic <= '1';
|
lic <= '1';
|
next_state <= saved_state;
|
next_state <= fetch_state;
|
|
|
when orcc_state =>
|
when orcc_state =>
|
-- OR CC with md
|
-- OR CC with md
|
left_ctrl <= md_left;
|
left_ctrl <= md_left;
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_orcc;
|
alu_ctrl <= alu_orcc;
|
cc_ctrl <= load_cc;
|
cc_ctrl <= load_cc;
|
--
|
--
|
st_ctrl <= pull_st;
|
|
lic <= '1';
|
lic <= '1';
|
next_state <= saved_state;
|
next_state <= fetch_state;
|
|
|
when tfr_state =>
|
when tfr_state =>
|
-- select source register
|
-- select source register
|
case md(7 downto 4) is
|
case md(7 downto 4) is
|
when "0000" =>
|
when "0000" =>
|
Line 4038... |
Line 3863... |
dp_ctrl <= load_dp;
|
dp_ctrl <= load_dp;
|
when others =>
|
when others =>
|
null;
|
null;
|
end case;
|
end case;
|
--
|
--
|
st_ctrl <= pull_st;
|
|
lic <= '1';
|
lic <= '1';
|
next_state <= saved_state;
|
next_state <= fetch_state;
|
|
|
when exg_state =>
|
when exg_state =>
|
-- save destination register
|
-- save destination register
|
case md(3 downto 0) is
|
case md(3 downto 0) is
|
when "0000" =>
|
when "0000" =>
|
Line 4072... |
Line 3896... |
end case;
|
end case;
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_tfr;
|
alu_ctrl <= alu_tfr;
|
ea_ctrl <= load_ea;
|
ea_ctrl <= load_ea;
|
-- call tranfer microcode
|
-- call tranfer microcode
|
st_ctrl <= push_st;
|
next_state <= exg1_state;
|
return_state <= exg1_state;
|
|
next_state <= tfr_state;
|
|
|
|
when exg1_state =>
|
when exg1_state =>
|
-- restore destination
|
-- select source register
|
left_ctrl <= ea_left;
|
case md(7 downto 4) is
|
|
when "0000" =>
|
|
left_ctrl <= accd_left;
|
|
when "0001" =>
|
|
left_ctrl <= ix_left;
|
|
when "0010" =>
|
|
left_ctrl <= iy_left;
|
|
when "0011" =>
|
|
left_ctrl <= up_left;
|
|
when "0100" =>
|
|
left_ctrl <= sp_left;
|
|
when "0101" =>
|
|
left_ctrl <= pc_left;
|
|
when "1000" =>
|
|
left_ctrl <= acca_left;
|
|
when "1001" =>
|
|
left_ctrl <= accb_left;
|
|
when "1010" =>
|
|
left_ctrl <= cc_left;
|
|
when "1011" =>
|
|
left_ctrl <= dp_left;
|
|
when others =>
|
|
left_ctrl <= md_left;
|
|
end case;
|
right_ctrl <= zero_right;
|
right_ctrl <= zero_right;
|
alu_ctrl <= alu_tfr;
|
alu_ctrl <= alu_tfr;
|
-- save as source register
|
-- select destination register
|
case md(7 downto 4) is
|
case md(3 downto 0) is
|
|
when "0000" => -- accd
|
|
acca_ctrl <= load_hi_acca;
|
|
accb_ctrl <= load_accb;
|
|
when "0001" => -- ix
|
|
ix_ctrl <= load_ix;
|
|
when "0010" => -- iy
|
|
iy_ctrl <= load_iy;
|
|
when "0011" => -- up
|
|
up_ctrl <= load_up;
|
|
when "0100" => -- sp
|
|
sp_ctrl <= load_sp;
|
|
when "0101" => -- pc
|
|
pc_ctrl <= load_pc;
|
|
when "1000" => -- acca
|
|
acca_ctrl <= load_acca;
|
|
when "1001" => -- accb
|
|
accb_ctrl <= load_accb;
|
|
when "1010" => -- cc
|
|
cc_ctrl <= load_cc;
|
|
when "1011" => --dp
|
|
dp_ctrl <= load_dp;
|
|
when others =>
|
|
null;
|
|
end case;
|
|
next_state <= exg2_state;
|
|
|
|
when exg2_state =>
|
|
-- restore destination
|
|
left_ctrl <= ea_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_tfr;
|
|
-- save as source register
|
|
case md(7 downto 4) is
|
when "0000" => -- accd
|
when "0000" => -- accd
|
acca_ctrl <= load_hi_acca;
|
acca_ctrl <= load_hi_acca;
|
accb_ctrl <= load_accb;
|
accb_ctrl <= load_accb;
|
when "0001" => -- ix
|
when "0001" => -- ix
|
ix_ctrl <= load_ix;
|
ix_ctrl <= load_ix;
|
Line 5429... |
Line 5307... |
addr_ctrl <= pulls_ad;
|
addr_ctrl <= pulls_ad;
|
lic <= '1';
|
lic <= '1';
|
next_state <= fetch_state;
|
next_state <= fetch_state;
|
|
|
--
|
--
|
-- here on IRQ or NMI interrupt
|
-- here on NMI interrupt
|
-- pre decrement the sp
|
-- Complete execute cycle of the last instruction.
|
-- Idle bus cycle
|
-- If it was a dual operand instruction
|
--
|
--
|
when int_nmiirq_state =>
|
when int_nmi_state =>
|
-- decrement sp
|
next_state <= int_nmi1_state;
|
|
|
|
-- Idle bus cycle
|
|
when int_nmi1_state =>
|
|
-- pre decrement sp
|
left_ctrl <= sp_left;
|
left_ctrl <= sp_left;
|
right_ctrl <= one_right;
|
right_ctrl <= one_right;
|
alu_ctrl <= alu_sub16;
|
alu_ctrl <= alu_sub16;
|
sp_ctrl <= load_sp;
|
sp_ctrl <= load_sp;
|
|
iv_ctrl <= nmi_iv;
|
|
st_ctrl <= push_st;
|
|
return_state <= int_nmimask_state;
|
next_state <= int_entire_state;
|
next_state <= int_entire_state;
|
|
|
--
|
--
|
-- set Entire Flag on SWI, SWI2, SWI3 and CWAI, IRQ and NMI
|
-- here on IRQ interrupt
|
-- clear Entire Flag on FIRQ
|
-- Complete execute cycle of the last instruction.
|
-- before stacking all registers
|
-- If it was a dual operand instruction
|
--
|
--
|
when int_entire_state =>
|
when int_irq_state =>
|
-- set entire flag
|
next_state <= int_irq1_state;
|
alu_ctrl <= alu_see;
|
|
cc_ctrl <= load_cc;
|
|
next_state <= int_pcl_state;
|
|
|
|
--
|
|
-- here on FIRQ interrupt
|
|
-- pre decrement the sp
|
-- pre decrement the sp
|
-- Idle bus cycle
|
-- Idle bus cycle
|
|
when int_irq1_state =>
|
|
-- pre decrement sp
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= one_right;
|
|
alu_ctrl <= alu_sub16;
|
|
sp_ctrl <= load_sp;
|
|
iv_ctrl <= irq_iv;
|
|
st_ctrl <= push_st;
|
|
return_state <= int_irqmask_state;
|
|
next_state <= int_entire_state;
|
|
|
|
--
|
|
-- here on FIRQ interrupt
|
|
-- Complete execution cycle of the last instruction
|
|
-- if it was a dual operand instruction
|
--
|
--
|
when int_firq_state =>
|
when int_firq_state =>
|
-- decrement sp
|
next_state <= int_firq1_state;
|
|
|
|
-- Idle bus cycle
|
|
when int_firq1_state =>
|
|
-- pre decrement sp
|
left_ctrl <= sp_left;
|
left_ctrl <= sp_left;
|
right_ctrl <= one_right;
|
right_ctrl <= one_right;
|
alu_ctrl <= alu_sub16;
|
alu_ctrl <= alu_sub16;
|
sp_ctrl <= load_sp;
|
sp_ctrl <= load_sp;
|
|
iv_ctrl <= firq_iv;
|
|
st_ctrl <= push_st;
|
|
return_state <= int_firqmask_state;
|
next_state <= int_fast_state;
|
next_state <= int_fast_state;
|
|
|
|
--
|
|
-- CWAI entry point
|
|
-- stack pointer already pre-decremented
|
|
-- mask condition codes
|
|
--
|
|
when cwai_state =>
|
|
-- AND CC with md
|
|
left_ctrl <= md_left;
|
|
right_ctrl <= zero_right;
|
|
alu_ctrl <= alu_andcc;
|
|
cc_ctrl <= load_cc;
|
|
st_ctrl <= push_st;
|
|
return_state <= int_cwai_state;
|
|
next_state <= int_entire_state;
|
|
|
|
--
|
|
-- wait here for an interrupt
|
|
--
|
|
when int_cwai_state =>
|
|
if (nmi_req = '1') then
|
|
iv_ctrl <= nmi_iv;
|
|
next_state <= int_nmimask_state;
|
|
--
|
|
-- FIRQ & IRQ are level sensitive
|
|
--
|
|
elsif (firq = '1') and (cc(FBIT) = '0') then
|
|
iv_ctrl <= firq_iv;
|
|
next_state <= int_firqmask_state;
|
|
|
|
elsif (irq = '1') and (cc(IBIT) = '0') then
|
|
iv_ctrl <= irq_iv;
|
|
next_state <= int_irqmask_state;
|
|
else
|
|
next_state <= int_cwai_state;
|
|
end if;
|
|
|
|
--
|
|
-- State to mask I Flag and F Flag (NMI)
|
|
--
|
|
when int_nmimask_state =>
|
|
alu_ctrl <= alu_seif;
|
|
cc_ctrl <= load_cc;
|
|
next_state <= vect_hi_state;
|
|
|
|
--
|
|
-- State to mask I Flag and F Flag (FIRQ)
|
|
--
|
|
when int_firqmask_state =>
|
|
alu_ctrl <= alu_seif;
|
|
cc_ctrl <= load_cc;
|
|
next_state <= vect_hi_state;
|
|
|
|
|
|
--
|
|
-- State to mask I Flag and F Flag (SWI)
|
|
--
|
|
when int_swimask_state =>
|
|
alu_ctrl <= alu_seif;
|
|
cc_ctrl <= load_cc;
|
|
next_state <= vect_hi_state;
|
|
|
|
--
|
|
-- State to mask I Flag only (IRQ)
|
|
--
|
|
when int_irqmask_state =>
|
|
alu_ctrl <= alu_sei;
|
|
cc_ctrl <= load_cc;
|
|
next_state <= vect_hi_state;
|
|
|
|
--
|
|
-- set Entire Flag on SWI, SWI2, SWI3 and CWAI, IRQ and NMI
|
|
-- before stacking all registers
|
|
--
|
|
when int_entire_state =>
|
|
-- set entire flag
|
|
alu_ctrl <= alu_see;
|
|
cc_ctrl <= load_cc;
|
|
next_state <= int_pcl_state;
|
|
|
--
|
--
|
-- clear Entire Flag on FIRQ
|
-- clear Entire Flag on FIRQ
|
-- before stacking all registers
|
-- before stacking all registers
|
--
|
--
|
when int_fast_state =>
|
when int_fast_state =>
|
Line 5603... |
Line 5585... |
|
|
when int_cc_state =>
|
when int_cc_state =>
|
-- write cc
|
-- write cc
|
addr_ctrl <= pushs_ad;
|
addr_ctrl <= pushs_ad;
|
dout_ctrl <= cc_dout;
|
dout_ctrl <= cc_dout;
|
case iv is
|
next_state <= saved_state;
|
when NMI_VEC =>
|
|
next_state <= int_maskif_state;
|
|
when SWI_VEC =>
|
|
next_state <= int_maskif_state;
|
|
when FIRQ_VEC =>
|
|
next_state <= int_maskif_state;
|
|
when IRQ_VEC =>
|
|
next_state <= int_maski_state;
|
|
when SWI2_VEC =>
|
|
next_state <= vect_hi_state;
|
|
when SWI3_VEC =>
|
|
next_state <= vect_hi_state;
|
|
when others =>
|
|
if op_code = "00111100" then -- CWAI
|
|
next_state <= int_cwai_state;
|
|
else
|
|
next_state <= rti_cc_state; -- spurious interrupt, do a RTI
|
|
end if;
|
|
end case;
|
|
|
|
--
|
|
-- wait here for an inteerupt
|
|
--
|
|
when int_cwai_state =>
|
|
if (nmi_req = '1') and (nmi_ack='0') then
|
|
iv_ctrl <= nmi_iv;
|
|
nmi_ctrl <= set_nmi;
|
|
next_state <= int_maskif_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;
|
|
end if;
|
|
--
|
|
-- FIRQ is level sensitive
|
|
--
|
|
if (firq = '1') and (cc(FBIT) = '0') then
|
|
iv_ctrl <= firq_iv;
|
|
next_state <= int_maskif_state;
|
|
--
|
|
-- IRQ is level sensitive
|
|
--
|
|
elsif (irq = '1') and (cc(IBIT) = '0') then
|
|
iv_ctrl <= irq_iv;
|
|
next_state <= int_maski_state;
|
|
else
|
|
iv_ctrl <= reset_iv;
|
|
next_state <= int_cwai_state;
|
|
end if;
|
|
end if;
|
|
|
|
when int_maski_state =>
|
|
alu_ctrl <= alu_sei;
|
|
cc_ctrl <= load_cc;
|
|
next_state <= vect_hi_state;
|
|
|
|
when int_maskif_state =>
|
|
alu_ctrl <= alu_seif;
|
|
cc_ctrl <= load_cc;
|
|
next_state <= vect_hi_state;
|
|
|
|
--
|
--
|
-- According to the 6809 programming manual:
|
-- According to the 6809 programming manual:
|
-- If an interrupt is received and is masked
|
-- If an interrupt is received and is masked
|
-- or lasts for less than three cycles, the PC
|
-- or lasts for less than three cycles, the PC
|
Line 5679... |
Line 5599... |
-- will be generated.
|
-- will be generated.
|
-- Note that I don't wait 3 clock cycles.
|
-- Note that I don't wait 3 clock cycles.
|
-- John Kent 11th July 2006
|
-- John Kent 11th July 2006
|
--
|
--
|
when sync_state =>
|
when sync_state =>
|
if (nmi_req = '1') and (nmi_ack='0') then
|
|
iv_ctrl <= nmi_iv;
|
|
nmi_ctrl <= set_nmi;
|
|
next_state <= int_nmiirq_state;
|
|
else
|
|
--
|
|
-- nmi request is not cleared until nmi input goes low
|
|
--
|
|
if (nmi_req = '0') and (nmi_ack='1') then
|
|
iv_ctrl <= reset_iv;
|
|
nmi_ctrl <= reset_nmi;
|
|
end if;
|
|
--
|
|
-- FIRQ is level sensitive
|
|
--
|
|
if (firq = '1') then
|
|
if (cc(FBIT) = '0') then
|
|
iv_ctrl <= firq_iv;
|
|
next_state <= int_firq_state;
|
|
else
|
|
iv_ctrl <= reset_iv;
|
|
lic <= '1';
|
lic <= '1';
|
next_state <= fetch_state;
|
ba <= '1';
|
end if;
|
|
--
|
--
|
-- IRQ is level sensitive
|
-- Version 1.28 2015-05-30
|
|
-- Exit sync_state on interrupt.
|
|
-- If the interrupts are active
|
|
-- they will be caught in the state_machine process
|
|
-- and the interrupt service routine microcode will be executed.
|
|
-- Masked interrupts will exit the sync_state.
|
|
-- Moved from the state_machine process to the state_sequencer process
|
--
|
--
|
elsif (irq = '1') then
|
if (firq = '1') or (irq = '1') then
|
if (cc(IBIT) = '0') then
|
|
iv_ctrl <= irq_iv;
|
|
next_state <= int_nmiirq_state;
|
|
else
|
|
iv_ctrl <= reset_iv;
|
|
lic <= '1';
|
|
next_state <= fetch_state;
|
next_state <= fetch_state;
|
end if;
|
|
else
|
else
|
iv_ctrl <= reset_iv;
|
|
ba <= '1';
|
|
next_state <= sync_state;
|
next_state <= sync_state;
|
end if;
|
end if;
|
end if;
|
|
|
|
|
|
when halt_state =>
|
when halt_state =>
|
if halt = '1' then
|
--
|
|
-- 2011-10-30 John Kent
|
|
-- ba & bs should be high
|
ba <= '1';
|
ba <= '1';
|
bs <= '1';
|
bs <= '1';
|
|
if halt = '1' then
|
next_state <= halt_state;
|
next_state <= halt_state;
|
else
|
else
|
lic <= '1';
|
|
next_state <= fetch_state;
|
next_state <= fetch_state;
|
end if;
|
end if;
|
|
|
when others => -- halt on undefine states
|
|
next_state <= error_state;
|
|
end case;
|
end case;
|
|
|
|
--
|
|
-- Ver 1.23 2011-10-30 John Kent
|
|
-- First instruction cycle might be
|
|
-- fetch_state
|
|
-- halt_state
|
|
-- int_nmirq_state
|
|
-- int_firq_state
|
|
--
|
|
if fic = '1' then
|
|
--
|
|
case op_code(7 downto 6) is
|
|
when "10" => -- acca
|
|
case op_code(3 downto 0) is
|
|
when "0000" => -- suba
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_sub8;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= load_acca;
|
|
when "0001" => -- cmpa
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_sub8;
|
|
cc_ctrl <= load_cc;
|
|
when "0010" => -- sbca
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_sbc;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= load_acca;
|
|
when "0011" =>
|
|
case pre_code is
|
|
when "00010000" => -- page 2 -- cmpd
|
|
left_ctrl <= accd_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_sub16;
|
|
cc_ctrl <= load_cc;
|
|
when "00010001" => -- page 3 -- cmpu
|
|
left_ctrl <= up_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_sub16;
|
|
cc_ctrl <= load_cc;
|
|
when others => -- page 1 -- subd
|
|
left_ctrl <= accd_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_sub16;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= load_hi_acca;
|
|
accb_ctrl <= load_accb;
|
|
end case;
|
|
when "0100" => -- anda
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_and;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= load_acca;
|
|
when "0101" => -- bita
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_and;
|
|
cc_ctrl <= load_cc;
|
|
when "0110" => -- ldaa
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_ld8;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= load_acca;
|
|
when "0111" => -- staa
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_st8;
|
|
cc_ctrl <= load_cc;
|
|
when "1000" => -- eora
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_eor;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= load_acca;
|
|
when "1001" => -- adca
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_adc;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= load_acca;
|
|
when "1010" => -- oraa
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_ora;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= load_acca;
|
|
when "1011" => -- adda
|
|
left_ctrl <= acca_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_add8;
|
|
cc_ctrl <= load_cc;
|
|
acca_ctrl <= load_acca;
|
|
when "1100" =>
|
|
case pre_code is
|
|
when "00010000" => -- page 2 -- cmpy
|
|
left_ctrl <= iy_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_sub16;
|
|
cc_ctrl <= load_cc;
|
|
when "00010001" => -- page 3 -- cmps
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_sub16;
|
|
cc_ctrl <= load_cc;
|
|
when others => -- page 1 -- cmpx
|
|
left_ctrl <= ix_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_sub16;
|
|
cc_ctrl <= load_cc;
|
|
end case;
|
|
when "1101" => -- bsr / jsr
|
|
null;
|
|
when "1110" => -- ldx
|
|
case pre_code is
|
|
when "00010000" => -- page 2 -- ldy
|
|
left_ctrl <= iy_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_ld16;
|
|
cc_ctrl <= load_cc;
|
|
iy_ctrl <= load_iy;
|
|
when others => -- page 1 -- ldx
|
|
left_ctrl <= ix_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_ld16;
|
|
cc_ctrl <= load_cc;
|
|
ix_ctrl <= load_ix;
|
|
end case;
|
|
when "1111" => -- stx
|
|
case pre_code is
|
|
when "00010000" => -- page 2 -- sty
|
|
left_ctrl <= iy_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_st16;
|
|
cc_ctrl <= load_cc;
|
|
when others => -- page 1 -- stx
|
|
left_ctrl <= ix_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_st16;
|
|
cc_ctrl <= load_cc;
|
|
end case;
|
|
when others =>
|
|
null;
|
|
end case;
|
|
when "11" => -- accb dual op
|
|
case op_code(3 downto 0) is
|
|
when "0000" => -- subb
|
|
left_ctrl <= accb_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_sub8;
|
|
cc_ctrl <= load_cc;
|
|
accb_ctrl <= load_accb;
|
|
when "0001" => -- cmpb
|
|
left_ctrl <= accb_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_sub8;
|
|
cc_ctrl <= load_cc;
|
|
when "0010" => -- sbcb
|
|
left_ctrl <= accb_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_sbc;
|
|
cc_ctrl <= load_cc;
|
|
accb_ctrl <= load_accb;
|
|
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;
|
|
when "0100" => -- andb
|
|
left_ctrl <= accb_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_and;
|
|
cc_ctrl <= load_cc;
|
|
accb_ctrl <= load_accb;
|
|
when "0101" => -- bitb
|
|
left_ctrl <= accb_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_and;
|
|
cc_ctrl <= load_cc;
|
|
when "0110" => -- ldab
|
|
left_ctrl <= accb_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_ld8;
|
|
cc_ctrl <= load_cc;
|
|
accb_ctrl <= load_accb;
|
|
when "0111" => -- stab
|
|
left_ctrl <= accb_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_st8;
|
|
cc_ctrl <= load_cc;
|
|
when "1000" => -- eorb
|
|
left_ctrl <= accb_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_eor;
|
|
cc_ctrl <= load_cc;
|
|
accb_ctrl <= load_accb;
|
|
when "1001" => -- adcb
|
|
left_ctrl <= accb_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_adc;
|
|
cc_ctrl <= load_cc;
|
|
accb_ctrl <= load_accb;
|
|
when "1010" => -- orab
|
|
left_ctrl <= accb_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_ora;
|
|
cc_ctrl <= load_cc;
|
|
accb_ctrl <= load_accb;
|
|
when "1011" => -- addb
|
|
left_ctrl <= accb_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_add8;
|
|
cc_ctrl <= load_cc;
|
|
accb_ctrl <= load_accb;
|
|
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;
|
|
when "1101" => -- std
|
|
left_ctrl <= accd_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_st16;
|
|
cc_ctrl <= load_cc;
|
|
when "1110" => -- ldu
|
|
case pre_code is
|
|
when "00010000" => -- page 2 -- lds
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_ld16;
|
|
cc_ctrl <= load_cc;
|
|
sp_ctrl <= load_sp;
|
|
when others => -- page 1 -- ldu
|
|
left_ctrl <= up_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_ld16;
|
|
cc_ctrl <= load_cc;
|
|
up_ctrl <= load_up;
|
|
end case;
|
|
when "1111" =>
|
|
case pre_code is
|
|
when "00010000" => -- page 2 -- sts
|
|
left_ctrl <= sp_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_st16;
|
|
cc_ctrl <= load_cc;
|
|
when others => -- page 1 -- stu
|
|
left_ctrl <= up_left;
|
|
right_ctrl <= md_right;
|
|
alu_ctrl <= alu_st16;
|
|
cc_ctrl <= load_cc;
|
|
end case;
|
|
when others =>
|
|
null;
|
|
end case;
|
|
when others =>
|
|
null;
|
|
end case;
|
|
|
|
end if; -- first instruction cycle (fic)
|
|
lic_out <= lic;
|
end process;
|
end process;
|
|
|
end rtl;
|
end rtl;
|
|
|
|
|
No newline at end of file
|
No newline at end of file
|