OpenCores
URL https://opencores.org/ocsvn/System09/System09/trunk

Subversion Repositories System09

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /System09/tags/V10/rtl
    from Rev 3 to Rev 66
    Reverse comparison

Rev 3 → Rev 66

/vhdl/cpu09.vhd
0,0 → 1,9535
--===========================================================================----
--
-- S Y N T H E Z I A B L E CPU09 - 6809 compatible CPU Core
--
-- www.OpenCores.Org - September 2003
-- This core adheres to the GNU public license
--
-- File name : cpu09.vhd
--
-- Purpose : 6809 CPU core
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
--
-- Uses : None
--
-- Author : John E. Kent
-- dilbert57@opencores.org
--
--===========================================================================----
--
-- Revision History:
--===========================================================================--
--
-- Version 0.1 - 26 June 2003 - John Kent
-- Added extra level in state stack
-- fixed some calls to the extended addressing state
--
-- Version 0.2 - 5 Sept 2003 - John Kent
-- Fixed 16 bit indexed offset (was doing read rather than fetch)
-- Added/Fixed STY and STS instructions.
-- ORCC_STATE ANDed CC state rather than ORed it - Now fixed
-- CMPX Loaded ACCA and ACCB - Now fixed
--
-- Version 1.0 - 6 Sep 2003 - John Kent
-- Initial release to Open Cores
-- reversed clock edge
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity cpu09 is
port (
clk: in std_logic;
rst: in std_logic;
rw: out std_logic;
vma: out std_logic;
address: out std_logic_vector(15 downto 0);
data_in: in std_logic_vector(7 downto 0);
data_out: out std_logic_vector(7 downto 0);
halt: in std_logic;
hold: in std_logic;
irq: in std_logic;
firq: in std_logic;
nmi: in std_logic;
test_alu: out std_logic_vector(15 downto 0);
test_cc: out std_logic_vector(7 downto 0)
);
end;
 
architecture CPU_ARCH of cpu09 is
 
constant EBIT : integer := 7;
constant FBIT : integer := 6;
constant HBIT : integer := 5;
constant IBIT : integer := 4;
constant NBIT : integer := 3;
constant ZBIT : integer := 2;
constant VBIT : integer := 1;
constant CBIT : integer := 0;
 
--
-- Interrupt vector modifiers
--
constant RST_VEC : std_logic_vector(2 downto 0) := "111";
constant NMI_VEC : std_logic_vector(2 downto 0) := "110";
constant SWI_VEC : std_logic_vector(2 downto 0) := "101";
constant IRQ_VEC : std_logic_vector(2 downto 0) := "100";
constant FIRQ_VEC : std_logic_vector(2 downto 0) := "011";
constant SWI2_VEC : std_logic_vector(2 downto 0) := "010";
constant SWI3_VEC : std_logic_vector(2 downto 0) := "001";
constant RESV_VEC : std_logic_vector(2 downto 0) := "000";
 
type state_type is (-- Start off in Reset
reset_state,
-- Fetch Interrupt Vectors (including reset)
vect_lo_state, vect_hi_state,
-- Fetch Instruction Cycle
fetch_state,
-- Decode Instruction Cycles
decode1_state, decode2_state, decode3_state,
-- Calculate Effective Address
imm16_state,
indexed_state, index8_state, index16_state, index16_2_state,
pcrel8_state, pcrel16_state, pcrel16_2_state,
indexaddr_state, indexaddr2_state,
postincr1_state, postincr2_state,
indirect_state, indirect2_state, indirect3_state,
extended_state,
-- single ops
single_op_read_state,
single_op_exec_state,
single_op_write_state,
-- Dual op states
dual_op_read8_state, dual_op_read16_state, dual_op_read16_2_state,
dual_op_write8_state, dual_op_write16_state,
--
sync_state, halt_state, error_state,
--
andcc_state, orcc_state,
tfr_state, exg_state, exg1_state,
lea_state,
-- Multiplication
mul_state, mulea_state, muld_state,
mul0_state, mul1_state, mul2_state, mul3_state,
mul4_state, mul5_state, mul6_state, mul7_state,
-- Branches
lbranch_state, sbranch_state,
-- Jumps, Subroutine Calls and Returns
jsr_state, jmp_state,
push_return_hi_state, push_return_lo_state,
pull_return_hi_state, pull_return_lo_state,
-- Interrupt cycles
int_decr_state,
int_entire_state,
int_pcl_state, int_pch_state,
int_upl_state, int_uph_state,
int_iyl_state, int_iyh_state,
int_ixl_state, int_ixh_state,
int_cc_state,
int_acca_state, int_accb_state,
int_dp_state,
int_cwai_state, int_mask_state,
-- Return From Interrupt
rti_state,
rti_acca_state, rti_accb_state,
rti_cc_state, rti_dp_state,
rti_ixl_state, rti_ixh_state,
rti_iyl_state, rti_iyh_state,
rti_upl_state, rti_uph_state,
rti_pcl_state, rti_pch_state,
-- Push Registers using SP
pshs_state,
pshs_pcl_state, pshs_pch_state,
pshs_upl_state, pshs_uph_state,
pshs_iyl_state, pshs_iyh_state,
pshs_ixl_state, pshs_ixh_state,
pshs_dp_state,
pshs_acca_state, pshs_accb_state,
pshs_cc_state,
-- Pull Registers using SP
puls_state,
puls_cc_state,
puls_acca_state, puls_accb_state,
puls_dp_state,
puls_ixl_state, puls_ixh_state,
puls_iyl_state, puls_iyh_state,
puls_upl_state, puls_uph_state,
puls_pcl_state, puls_pch_state,
-- Push Registers using UP
pshu_state,
pshu_pcl_state, pshu_pch_state,
pshu_spl_state, pshu_sph_state,
pshu_iyl_state, pshu_iyh_state,
pshu_ixl_state, pshu_ixh_state,
pshu_dp_state,
pshu_acca_state, pshu_accb_state,
pshu_cc_state,
-- Pull Registers using UP
pulu_state,
pulu_cc_state,
pulu_acca_state, pulu_accb_state,
pulu_dp_state,
pulu_ixl_state, pulu_ixh_state,
pulu_iyl_state, pulu_iyh_state,
pulu_spl_state, pulu_sph_state,
pulu_pcl_state, pulu_pch_state );
 
type stack_type is array(2 downto 0) of state_type;
type st_type is (idle_st, push_st, pull_st );
type addr_type is (idle_ad, fetch_ad, read_ad, write_ad, pushu_ad, pullu_ad, pushs_ad, pulls_ad, int_hi_ad, int_lo_ad );
type dout_type is (cc_dout, acca_dout, accb_dout, dp_dout,
ix_lo_dout, ix_hi_dout, iy_lo_dout, iy_hi_dout,
up_lo_dout, up_hi_dout, sp_lo_dout, sp_hi_dout,
pc_lo_dout, pc_hi_dout, md_lo_dout, md_hi_dout );
type op_type is (reset_op, fetch_op, latch_op );
type pre_type is (reset_pre, fetch_pre, latch_pre );
type cc_type is (reset_cc, load_cc, pull_cc, latch_cc );
type acca_type is (reset_acca, load_acca, load_hi_acca, pull_acca, latch_acca );
type accb_type is (reset_accb, load_accb, pull_accb, latch_accb );
type dp_type is (reset_dp, load_dp, pull_dp, latch_dp );
type ix_type is (reset_ix, load_ix, pull_lo_ix, pull_hi_ix, latch_ix );
type iy_type is (reset_iy, load_iy, pull_lo_iy, pull_hi_iy, latch_iy );
type sp_type is (reset_sp, latch_sp, load_sp, pull_hi_sp, pull_lo_sp );
type up_type is (reset_up, latch_up, load_up, pull_hi_up, pull_lo_up );
type pc_type is (reset_pc, latch_pc, load_pc, pull_lo_pc, pull_hi_pc, incr_pc );
type md_type is (reset_md, latch_md, load_md, fetch_first_md, fetch_next_md, shiftl_md );
type ea_type is (reset_ea, latch_ea, load_ea, fetch_first_ea, fetch_next_ea );
type iv_type is (reset_iv, latch_iv, nmi_iv, irq_iv, firq_iv, swi_iv, swi2_iv, swi3_iv, resv_iv);
type nmi_type is (reset_nmi, set_nmi, latch_nmi );
type left_type is (cc_left, acca_left, accb_left, dp_left,
ix_left, iy_left, up_left, sp_left,
accd_left, md_left, pc_left, ea_left );
type right_type is (ea_right, zero_right, one_right, two_right,
acca_right, accb_right, accd_right,
md_right, md_sign5_right, md_sign8_right );
type alu_type is (alu_add8, alu_sub8, alu_add16, alu_sub16, alu_adc, alu_sbc,
alu_and, alu_ora, alu_eor,
alu_tst, alu_inc, alu_dec, alu_clr, alu_neg, alu_com,
alu_inx, alu_dex,
alu_lsr16, alu_lsl16,
alu_ror8, alu_rol8,
alu_asr8, alu_asl8, alu_lsr8,
alu_andcc, alu_orcc, alu_sex, alu_tfr,
alu_seif, alu_sei, alu_see, alu_cle,
alu_ld8, alu_st8, alu_ld16, alu_st16, alu_nop, alu_daa );
 
signal op_code: std_logic_vector(7 downto 0);
signal pre_code: std_logic_vector(7 downto 0);
signal acca: std_logic_vector(7 downto 0);
signal accb: std_logic_vector(7 downto 0);
signal cc: std_logic_vector(7 downto 0);
signal cc_out: std_logic_vector(7 downto 0);
signal dp: std_logic_vector(7 downto 0);
signal xreg: std_logic_vector(15 downto 0);
signal yreg: std_logic_vector(15 downto 0);
signal sp: std_logic_vector(15 downto 0);
signal up: std_logic_vector(15 downto 0);
signal ea: std_logic_vector(15 downto 0);
signal pc: std_logic_vector(15 downto 0);
signal md: std_logic_vector(15 downto 0);
signal left: std_logic_vector(15 downto 0);
signal right: std_logic_vector(15 downto 0);
signal out_alu: std_logic_vector(15 downto 0);
signal iv: std_logic_vector(2 downto 0);
signal nmi_req: std_logic;
signal nmi_ack: std_logic;
 
signal state: state_type;
signal next_state: state_type;
signal saved_state: state_type;
signal return_state: state_type;
signal state_stack: stack_type;
signal st_ctrl: st_type;
signal pc_ctrl: pc_type;
signal ea_ctrl: ea_type;
signal op_ctrl: op_type;
signal pre_ctrl: pre_type;
signal md_ctrl: md_type;
signal acca_ctrl: acca_type;
signal accb_ctrl: accb_type;
signal ix_ctrl: ix_type;
signal iy_ctrl: iy_type;
signal cc_ctrl: cc_type;
signal dp_ctrl: dp_type;
signal sp_ctrl: sp_type;
signal up_ctrl: up_type;
signal iv_ctrl: iv_type;
signal left_ctrl: left_type;
signal right_ctrl: right_type;
signal alu_ctrl: alu_type;
signal addr_ctrl: addr_type;
signal dout_ctrl: dout_type;
signal nmi_ctrl: nmi_type;
 
 
begin
 
----------------------------------
--
-- State machine stack
--
----------------------------------
state_stack_proc: process( clk, st_ctrl, state_stack, return_state, hold )
begin
if clk'event and clk = '0' then
if hold= '1' then
state_stack(0) <= state_stack(0);
state_stack(1) <= state_stack(1);
state_stack(2) <= state_stack(2);
else
case st_ctrl is
when idle_st =>
state_stack(0) <= state_stack(0);
state_stack(1) <= state_stack(1);
state_stack(2) <= state_stack(2);
when push_st =>
state_stack(0) <= return_state;
state_stack(1) <= state_stack(0);
state_stack(2) <= state_stack(1);
when pull_st =>
state_stack(0) <= state_stack(1);
state_stack(1) <= state_stack(2);
state_stack(2) <= fetch_state;
when others =>
state_stack(0) <= state_stack(0);
state_stack(1) <= state_stack(1);
state_stack(2) <= state_stack(2);
end case;
end if;
end if;
saved_state <= state_stack(0);
end process;
 
----------------------------------
--
-- Program Counter Control
--
----------------------------------
 
pc_reg: process( clk, pc_ctrl, hold, pc, out_alu, data_in )
begin
if clk'event and clk = '0' then
if hold= '1' then
pc <= pc;
else
case pc_ctrl is
when reset_pc =>
pc <= "0000000000000000";
when load_pc =>
pc <= out_alu(15 downto 0);
when pull_lo_pc =>
pc(7 downto 0) <= data_in;
when pull_hi_pc =>
pc(15 downto 8) <= data_in;
when incr_pc =>
pc <= pc + 1;
when others =>
-- when latch_pc =>
pc <= pc;
end case;
end if;
end if;
end process;
 
----------------------------------
--
-- Effective Address Control
--
----------------------------------
 
ea_reg: process( clk, ea_ctrl, hold, ea, out_alu, data_in, dp )
begin
 
if clk'event and clk = '0' then
if hold= '1' then
ea <= ea;
else
case ea_ctrl is
when reset_ea =>
ea <= "0000000000000000";
when fetch_first_ea =>
ea(7 downto 0) <= data_in;
ea(15 downto 8) <= dp;
when fetch_next_ea =>
ea(15 downto 8) <= ea(7 downto 0);
ea(7 downto 0) <= data_in;
when load_ea =>
ea <= out_alu(15 downto 0);
when others =>
-- when latch_ea =>
ea <= ea;
end case;
end if;
end if;
end process;
 
--------------------------------
--
-- Accumulator A
--
--------------------------------
acca_reg : process( clk, acca_ctrl, hold, out_alu, acca, data_in )
begin
if clk'event and clk = '0' then
if hold= '1' then
acca <= acca;
else
case acca_ctrl is
when reset_acca =>
acca <= "00000000";
when load_acca =>
acca <= out_alu(7 downto 0);
when load_hi_acca =>
acca <= out_alu(15 downto 8);
when pull_acca =>
acca <= data_in;
when others =>
-- when latch_acca =>
acca <= acca;
end case;
end if;
end if;
end process;
 
--------------------------------
--
-- Accumulator B
--
--------------------------------
accb_reg : process( clk, accb_ctrl, hold, out_alu, accb, data_in )
begin
if clk'event and clk = '0' then
if hold= '1' then
accb <= accb;
else
case accb_ctrl is
when reset_accb =>
accb <= "00000000";
when load_accb =>
accb <= out_alu(7 downto 0);
when pull_accb =>
accb <= data_in;
when others =>
-- when latch_accb =>
accb <= accb;
end case;
end if;
end if;
end process;
 
--------------------------------
--
-- X Index register
--
--------------------------------
ix_reg : process( clk, ix_ctrl, hold, out_alu, xreg, data_in )
begin
if clk'event and clk = '0' then
if hold= '1' then
xreg <= xreg;
else
case ix_ctrl is
when reset_ix =>
xreg <= "0000000000000000";
when load_ix =>
xreg <= out_alu(15 downto 0);
when pull_hi_ix =>
xreg(15 downto 8) <= data_in;
when pull_lo_ix =>
xreg(7 downto 0) <= data_in;
when others =>
-- when latch_ix =>
xreg <= xreg;
end case;
end if;
end if;
end process;
 
--------------------------------
--
-- Y Index register
--
--------------------------------
iy_reg : process( clk, iy_ctrl, hold, out_alu, yreg, data_in )
begin
if clk'event and clk = '0' then
if hold= '1' then
yreg <= yreg;
else
case iy_ctrl is
when reset_iy =>
yreg <= "0000000000000000";
when load_iy =>
yreg <= out_alu(15 downto 0);
when pull_hi_iy =>
yreg(15 downto 8) <= data_in;
when pull_lo_iy =>
yreg(7 downto 0) <= data_in;
when others =>
-- when latch_iy =>
yreg <= yreg;
end case;
end if;
end if;
end process;
 
--------------------------------
--
-- S stack pointer
--
--------------------------------
sp_reg : process( clk, sp_ctrl, hold, sp, out_alu, data_in )
begin
if clk'event and clk = '0' then
if hold= '1' then
sp <= sp;
else
case sp_ctrl is
when reset_sp =>
sp <= "0000000000000000";
when load_sp =>
sp <= out_alu(15 downto 0);
when pull_hi_sp =>
sp(15 downto 8) <= data_in;
when pull_lo_sp =>
sp(7 downto 0) <= data_in;
when others =>
-- when latch_sp =>
sp <= sp;
end case;
end if;
end if;
end process;
 
--------------------------------
--
-- U stack pointer
--
--------------------------------
up_reg : process( clk, up_ctrl, hold, up, out_alu, data_in )
begin
if clk'event and clk = '0' then
if hold= '1' then
up <= up;
else
case up_ctrl is
when reset_up =>
up <= "0000000000000000";
when load_up =>
up <= out_alu(15 downto 0);
when pull_hi_up =>
up(15 downto 8) <= data_in;
when pull_lo_up =>
up(7 downto 0) <= data_in;
when others =>
-- when latch_up =>
up <= up;
end case;
end if;
end if;
end process;
 
--------------------------------
--
-- Memory Data
--
--------------------------------
md_reg : process( clk, md_ctrl, hold, out_alu, data_in, md )
begin
if clk'event and clk = '0' then
if hold= '1' then
md <= md;
else
case md_ctrl is
when reset_md =>
md <= "0000000000000000";
when load_md =>
md <= out_alu(15 downto 0);
when fetch_first_md => -- sign extend md for branches
md(15 downto 8) <= data_in(7) & data_in(7) & data_in(7) & data_in(7) &
data_in(7) & data_in(7) & data_in(7) & data_in(7) ;
md(7 downto 0) <= data_in;
when fetch_next_md =>
md(15 downto 8) <= md(7 downto 0);
md(7 downto 0) <= data_in;
when shiftl_md =>
md(15 downto 1) <= md(14 downto 0);
md(0) <= '0';
when others =>
-- when latch_md =>
md <= md;
end case;
end if;
end if;
end process;
 
 
----------------------------------
--
-- Condition Codes
--
----------------------------------
 
cc_reg: process( clk, cc_ctrl, hold, cc_out, cc, data_in )
begin
if clk'event and clk = '0' then
if hold= '1' then
cc <= cc;
else
case cc_ctrl is
when reset_cc =>
cc <= "11010000"; -- set EBIT, FBIT & IBIT
when load_cc =>
cc <= cc_out;
when pull_cc =>
cc <= data_in;
when others =>
-- when latch_cc =>
cc <= cc;
end case;
end if;
end if;
end process;
 
----------------------------------
--
-- Direct Page register
--
----------------------------------
 
dp_reg: process( clk, dp_ctrl, hold, out_alu, dp, data_in )
begin
if clk'event and clk = '0' then
if hold= '1' then
dp <= dp;
else
case dp_ctrl is
when reset_dp =>
dp <= "00000000";
when load_dp =>
dp <= out_alu(7 downto 0);
when pull_dp =>
dp <= data_in;
when others =>
-- when latch_dp =>
dp <= dp;
end case;
end if;
end if;
end process;
 
----------------------------------
--
-- interrupt vector
--
----------------------------------
 
iv_mux: process( clk, iv_ctrl, hold, iv )
begin
if clk'event and clk = '0' then
if hold= '1' then
iv <= iv;
else
case iv_ctrl is
when reset_iv =>
iv <= RST_VEC;
when nmi_iv =>
iv <= NMI_VEC;
when swi_iv =>
iv <= SWI_VEC;
when irq_iv =>
iv <= IRQ_VEC;
when firq_iv =>
iv <= FIRQ_VEC;
when swi2_iv =>
iv <= SWI2_VEC;
when swi3_iv =>
iv <= SWI3_VEC;
when resv_iv =>
iv <= RESV_VEC;
when others =>
iv <= iv;
end case;
end if;
end if;
end process;
 
 
----------------------------------
--
-- op code register
--
----------------------------------
 
op_reg: process( clk, op_ctrl, hold, op_code, data_in )
begin
if clk'event and clk = '0' then
if hold= '1' then
op_code <= op_code;
else
case op_ctrl is
when reset_op =>
op_code <= "00010010";
when fetch_op =>
op_code <= data_in;
when others =>
-- when latch_op =>
op_code <= op_code;
end case;
end if;
end if;
end process;
 
 
----------------------------------
--
-- pre byte op code register
--
----------------------------------
 
pre_reg: process( clk, pre_ctrl, hold, pre_code, data_in )
begin
if clk'event and clk = '0' then
if hold= '1' then
pre_code <= pre_code;
else
case pre_ctrl is
when reset_pre =>
pre_code <= "00000000";
when fetch_pre =>
pre_code <= data_in;
when others =>
-- when latch_pre =>
pre_code <= pre_code;
end case;
end if;
end if;
end process;
 
--------------------------------
--
-- state machine
--
--------------------------------
 
change_state: process( clk, rst, state, hold, next_state )
begin
if clk'event and clk = '0' then
if rst = '1' then
state <= reset_state;
else
if hold = '1' then
state <= state;
else
state <= next_state;
end if;
end if;
end if;
end process;
-- output
------------------------------------
--
-- Nmi register
--
------------------------------------
 
nmi_reg: process( clk, nmi_ctrl, hold, nmi_ack )
begin
if clk'event and clk='0' then
if hold = '1' then
nmi_ack <= nmi_ack;
else
case nmi_ctrl is
when set_nmi =>
nmi_ack <= '1';
when reset_nmi =>
nmi_ack <= '0';
when others =>
-- when latch_nmi =>
nmi_ack <= nmi_ack;
end case;
end if;
end if;
end process;
 
------------------------------------
--
-- Detect Edge of NMI interrupt
--
------------------------------------
 
nmi_handler : process( clk, rst, nmi, nmi_ack, nmi_req )
begin
if clk'event and clk='0' then
if rst='1' then
nmi_req <= '0';
else
if (nmi='1') and (nmi_ack='0') then
nmi_req <= '1';
else
if (nmi='0') and (nmi_ack='1') then
nmi_req <= '0';
else
nmi_req <= nmi_req;
end if;
end if;
end if;
end if;
end process;
 
 
----------------------------------
--
-- Address output multiplexer
--
----------------------------------
 
addr_mux: process( addr_ctrl, pc, ea, up, sp, iv )
begin
case addr_ctrl is
when idle_ad =>
address <= "1111111111111111";
vma <= '0';
rw <= '1';
when fetch_ad =>
address <= pc;
vma <= '1';
rw <= '1';
when read_ad =>
address <= ea;
vma <= '1';
rw <= '1';
when write_ad =>
address <= ea;
vma <= '1';
rw <= '0';
when pushs_ad =>
address <= sp;
vma <= '1';
rw <= '0';
when pulls_ad =>
address <= sp;
vma <= '1';
rw <= '1';
when pushu_ad =>
address <= up;
vma <= '1';
rw <= '0';
when pullu_ad =>
address <= up;
vma <= '1';
rw <= '1';
when int_hi_ad =>
address <= "111111111111" & iv & "0";
vma <= '1';
rw <= '1';
when int_lo_ad =>
address <= "111111111111" & iv & "1";
vma <= '1';
rw <= '1';
when others =>
address <= "1111111111111111";
vma <= '0';
rw <= '1';
end case;
end process;
 
--------------------------------
--
-- Data Bus output
--
--------------------------------
dout_mux : process( dout_ctrl, md, acca, accb, dp, xreg, yreg, sp, up, pc, cc )
begin
case dout_ctrl is
when md_hi_dout => -- alu output
data_out <= md(15 downto 8);
when md_lo_dout => -- alu output
data_out <= md(7 downto 0);
when acca_dout => -- accumulator a
data_out <= acca;
when accb_dout => -- accumulator b
data_out <= accb;
when ix_lo_dout => -- index reg
data_out <= xreg(7 downto 0);
when ix_hi_dout => -- index reg
data_out <= xreg(15 downto 8);
when iy_lo_dout => -- index reg
data_out <= yreg(7 downto 0);
when iy_hi_dout => -- index reg
data_out <= yreg(15 downto 8);
when sp_lo_dout => -- s stack pointer
data_out <= sp(7 downto 0);
when sp_hi_dout => -- s stack pointer
data_out <= sp(15 downto 8);
when up_lo_dout => -- u stack pointer
data_out <= up(7 downto 0);
when up_hi_dout => -- u stack pointer
data_out <= up(15 downto 8);
when cc_dout => -- condition code register
data_out <= cc;
when dp_dout => -- direct page register
data_out <= dp;
when pc_lo_dout => -- low order pc
data_out <= pc(7 downto 0);
when pc_hi_dout => -- high order pc
data_out <= pc(15 downto 8);
when others =>
data_out <= "00000000";
end case;
end process;
 
----------------------------------
--
-- Left Mux
--
----------------------------------
 
left_mux: process( left_ctrl, acca, accb, cc, dp, xreg, yreg, up, sp, pc, ea, md )
begin
case left_ctrl is
when cc_left =>
left(15 downto 8) <= "00000000";
left(7 downto 0) <= cc;
when acca_left =>
left(15 downto 8) <= "00000000";
left(7 downto 0) <= acca;
when accb_left =>
left(15 downto 8) <= "00000000";
left(7 downto 0) <= accb;
when dp_left =>
left(15 downto 8) <= "00000000";
left(7 downto 0) <= dp;
when accd_left =>
left(15 downto 8) <= acca;
left(7 downto 0) <= accb;
when md_left =>
left <= md;
when ix_left =>
left <= xreg;
when iy_left =>
left <= yreg;
when sp_left =>
left <= sp;
when up_left =>
left <= up;
when pc_left =>
left <= pc;
when others =>
-- when ea_left =>
left <= ea;
end case;
end process;
 
----------------------------------
--
-- Right Mux
--
----------------------------------
 
right_mux: process( right_ctrl, md, acca, accb, ea )
begin
case right_ctrl is
when ea_right =>
right <= ea;
when zero_right =>
right <= "0000000000000000";
when one_right =>
right <= "0000000000000001";
when two_right =>
right <= "0000000000000010";
when acca_right =>
right <= "00000000" & acca;
when accb_right =>
right <= "00000000" & accb;
when accd_right =>
right <= acca & accb;
when md_sign5_right =>
if md(4) = '0' then
right <= "00000000000" & md(4 downto 0);
else
right <= "11111111111" & md(4 downto 0);
end if;
when md_sign8_right =>
if md(7) = '0' then
right <= "00000000" & md(7 downto 0);
else
right <= "11111111" & md(7 downto 0);
end if;
when others =>
-- when md_right =>
right <= md;
end case;
end process;
 
----------------------------------
--
-- Arithmetic Logic Unit
--
----------------------------------
 
alu: process( alu_ctrl, cc, left, right, out_alu, cc_out )
variable valid_lo, valid_hi : boolean;
variable carry_in : std_logic;
variable daa_reg : std_logic_vector(7 downto 0);
begin
 
case alu_ctrl is
when alu_adc | alu_sbc |
alu_rol8 | alu_ror8 =>
carry_in := cc(CBIT);
when others =>
carry_in := '0';
end case;
 
valid_lo := left(3 downto 0) <= 9;
valid_hi := left(7 downto 4) <= 9;
 
if (cc(CBIT) = '0') then
if( cc(HBIT) = '1' ) then
if valid_hi then
daa_reg := "00000110";
else
daa_reg := "01100110";
end if;
else
if valid_lo then
if valid_hi then
daa_reg := "00000000";
else
daa_reg := "01100000";
end if;
else
if( left(7 downto 4) <= 8 ) then
daa_reg := "00000110";
else
daa_reg := "01100110";
end if;
end if;
end if;
else
if ( cc(HBIT) = '1' )then
daa_reg := "01100110";
else
if valid_lo then
daa_reg := "01100000";
else
daa_reg := "01100110";
end if;
end if;
end if;
 
case alu_ctrl is
when alu_add8 | alu_inc |
alu_add16 | alu_inx |
alu_adc =>
out_alu <= left + right + ("000000000000000" & carry_in);
when alu_sub8 | alu_dec |
alu_sub16 | alu_dex |
alu_sbc =>
out_alu <= left - right - ("000000000000000" & carry_in);
when alu_and =>
out_alu <= left and right; -- and/bit
when alu_ora =>
out_alu <= left or right; -- or
when alu_eor =>
out_alu <= left xor right; -- eor/xor
when alu_lsl16 | alu_asl8 | alu_rol8 =>
out_alu <= left(14 downto 0) & carry_in; -- rol8/asl8/lsl16
when alu_lsr16 | alu_lsr8 =>
out_alu <= carry_in & left(15 downto 1); -- lsr
when alu_ror8 =>
out_alu <= "00000000" & carry_in & left(7 downto 1); -- ror
when alu_asr8 =>
out_alu <= "00000000" & left(7) & left(7 downto 1); -- asr
when alu_neg =>
out_alu <= right - left; -- neg (right=0)
when alu_com =>
out_alu <= not left;
when alu_clr | alu_ld8 | alu_ld16 =>
out_alu <= right; -- clr, ld
when alu_st8 | alu_st16 | alu_andcc | alu_orcc =>
out_alu <= left;
when alu_daa =>
out_alu <= left + ("00000000" & daa_reg);
when alu_sex =>
if left(7) = '0' then
out_alu <= "00000000" & left(7 downto 0);
else
out_alu <= "11111111" & left(7 downto 0);
end if;
when others =>
out_alu <= left; -- nop, tfr
end case;
 
--
-- carry bit
--
case alu_ctrl is
when alu_add8 | alu_adc =>
cc_out(CBIT) <= (left(7) and right(7)) or
(left(7) and not out_alu(7)) or
(right(7) and not out_alu(7));
when alu_sub8 | alu_sbc =>
cc_out(CBIT) <= ((not left(7)) and right(7)) or
((not left(7)) and out_alu(7)) or
(right(7) and out_alu(7));
when alu_add16 =>
cc_out(CBIT) <= (left(15) and right(15)) or
(left(15) and not out_alu(15)) or
(right(15) and not out_alu(15));
when alu_sub16 =>
cc_out(CBIT) <= ((not left(15)) and right(15)) or
((not left(15)) and out_alu(15)) or
(right(15) and out_alu(15));
when alu_ror8 | alu_lsr16 | alu_lsr8 | alu_asr8 =>
cc_out(CBIT) <= left(0);
when alu_rol8 | alu_asl8 =>
cc_out(CBIT) <= left(7);
when alu_lsl16 =>
cc_out(CBIT) <= left(15);
when alu_com =>
cc_out(CBIT) <= '1';
when alu_neg | alu_clr =>
cc_out(CBIT) <= out_alu(7) or out_alu(6) or out_alu(5) or out_alu(4) or
out_alu(3) or out_alu(2) or out_alu(1) or out_alu(0);
when alu_daa =>
if ( daa_reg(7 downto 4) = "0110" ) then
cc_out(CBIT) <= '1';
else
cc_out(CBIT) <= '0';
end if;
when alu_andcc =>
cc_out(CBIT) <= left(CBIT) and cc(CBIT);
when alu_orcc =>
cc_out(CBIT) <= left(CBIT) or cc(CBIT);
when alu_tfr =>
cc_out(CBIT) <= left(CBIT);
when others =>
cc_out(CBIT) <= cc(CBIT);
end case;
--
-- Zero flag
--
case alu_ctrl is
when alu_add8 | alu_sub8 |
alu_adc | alu_sbc |
alu_and | alu_ora | alu_eor |
alu_inc | alu_dec |
alu_neg | alu_com | alu_clr |
alu_rol8 | alu_ror8 | alu_asr8 | alu_asl8 | alu_lsr8 |
alu_ld8 | alu_st8 | alu_sex =>
cc_out(ZBIT) <= not( out_alu(7) or out_alu(6) or out_alu(5) or out_alu(4) or
out_alu(3) or out_alu(2) or out_alu(1) or out_alu(0) );
when alu_add16 | alu_sub16 |
alu_lsl16 | alu_lsr16 |
alu_inx | alu_dex |
alu_ld16 | alu_st16 =>
cc_out(ZBIT) <= not( out_alu(15) or out_alu(14) or out_alu(13) or out_alu(12) or
out_alu(11) or out_alu(10) or out_alu(9) or out_alu(8) or
out_alu(7) or out_alu(6) or out_alu(5) or out_alu(4) or
out_alu(3) or out_alu(2) or out_alu(1) or out_alu(0) );
when alu_andcc =>
cc_out(ZBIT) <= left(ZBIT) and cc(ZBIT);
when alu_orcc =>
cc_out(ZBIT) <= left(ZBIT) or cc(ZBIT);
when alu_tfr =>
cc_out(ZBIT) <= left(ZBIT);
when others =>
cc_out(ZBIT) <= cc(ZBIT);
end case;
 
--
-- negative flag
--
case alu_ctrl is
when alu_add8 | alu_sub8 |
alu_adc | alu_sbc |
alu_and | alu_ora | alu_eor |
alu_rol8 | alu_ror8 | alu_asr8 | alu_asl8 | alu_lsr8 |
alu_inc | alu_dec | alu_neg | alu_com | alu_clr |
alu_ld8 | alu_st8 | alu_sex =>
cc_out(NBIT) <= out_alu(7);
when alu_add16 | alu_sub16 |
alu_lsl16 | alu_lsr16 |
alu_ld16 | alu_st16 =>
cc_out(NBIT) <= out_alu(15);
when alu_andcc =>
cc_out(NBIT) <= left(NBIT) and cc(NBIT);
when alu_orcc =>
cc_out(NBIT) <= left(NBIT) or cc(NBIT);
when alu_tfr =>
cc_out(NBIT) <= left(NBIT);
when others =>
cc_out(NBIT) <= cc(NBIT);
end case;
 
--
-- Interrupt mask flag
--
case alu_ctrl is
when alu_andcc =>
cc_out(IBIT) <= left(IBIT) and cc(IBIT);
when alu_orcc =>
cc_out(IBIT) <= left(IBIT) or cc(IBIT);
when alu_seif | alu_sei =>
cc_out(IBIT) <= '1';
when alu_tfr =>
cc_out(IBIT) <= left(IBIT);
when others =>
cc_out(IBIT) <= cc(IBIT); -- interrupt mask
end case;
 
--
-- Half Carry flag
--
case alu_ctrl is
when alu_add8 | alu_adc =>
cc_out(HBIT) <= (left(3) and right(3)) or
(right(3) and not out_alu(3)) or
(left(3) and not out_alu(3));
when alu_andcc =>
cc_out(HBIT) <= left(HBIT) and cc(HBIT);
when alu_orcc =>
cc_out(HBIT) <= left(HBIT) or cc(HBIT);
when alu_tfr =>
cc_out(HBIT) <= left(HBIT);
when others =>
cc_out(HBIT) <= cc(HBIT);
end case;
 
--
-- Overflow flag
--
case alu_ctrl is
when alu_add8 | alu_adc =>
cc_out(VBIT) <= (left(7) and right(7) and (not out_alu(7))) or
((not left(7)) and (not right(7)) and out_alu(7));
when alu_sub8 | alu_sbc =>
cc_out(VBIT) <= (left(7) and (not right(7)) and (not out_alu(7))) or
((not left(7)) and right(7) and out_alu(7));
when alu_add16 =>
cc_out(VBIT) <= (left(15) and right(15) and (not out_alu(15))) or
((not left(15)) and (not right(15)) and out_alu(15));
when alu_sub16 =>
cc_out(VBIT) <= (left(15) and (not right(15)) and (not out_alu(15))) or
((not left(15)) and right(15) and out_alu(15));
when alu_inc =>
cc_out(VBIT) <= ((not left(7)) and left(6) and left(5) and left(4) and
left(3) and left(2) and left(1) and left(0));
when alu_dec | alu_neg =>
cc_out(VBIT) <= (left(7) and (not left(6)) and (not left(5)) and (not left(4)) and
(not left(3)) and (not left(2)) and (not left(1)) and (not left(0)));
when alu_asr8 =>
cc_out(VBIT) <= left(0) xor left(7);
when alu_lsr8 | alu_lsr16 =>
cc_out(VBIT) <= left(0);
when alu_ror8 =>
cc_out(VBIT) <= left(0) xor cc(CBIT);
when alu_lsl16 =>
cc_out(VBIT) <= left(15) xor left(14);
when alu_rol8 | alu_asl8 =>
cc_out(VBIT) <= left(7) xor left(6);
when alu_and | alu_ora | alu_eor | alu_com |
alu_st8 | alu_st16 | alu_ld8 | alu_ld16 | alu_sex =>
cc_out(VBIT) <= '0';
when alu_andcc =>
cc_out(VBIT) <= left(VBIT) and cc(VBIT);
when alu_orcc =>
cc_out(VBIT) <= left(VBIT) or cc(VBIT);
when alu_tfr =>
cc_out(VBIT) <= left(VBIT);
when others =>
cc_out(VBIT) <= cc(VBIT);
end case;
 
case alu_ctrl is
when alu_andcc =>
cc_out(FBIT) <= left(FBIT) and cc(FBIT);
when alu_orcc =>
cc_out(FBIT) <= left(FBIT) or cc(FBIT);
when alu_tfr =>
cc_out(FBIT) <= left(FBIT);
when alu_seif =>
cc_out(FBIT) <= '1';
when others =>
cc_out(FBIT) <= cc(FBIT);
end case;
 
case alu_ctrl is
when alu_andcc =>
cc_out(EBIT) <= left(EBIT) and cc(EBIT);
when alu_orcc =>
cc_out(EBIT) <= left(EBIT) or cc(EBIT);
when alu_tfr =>
cc_out(EBIT) <= left(EBIT);
when alu_see =>
cc_out(EBIT) <= '1';
when alu_cle =>
cc_out(EBIT) <= '0';
when others =>
cc_out(EBIT) <= cc(EBIT);
end case;
 
test_alu <= out_alu;
test_cc <= cc_out;
end process;
 
------------------------------------
--
-- state sequencer
--
------------------------------------
process( state, saved_state,
op_code, pre_code,
cc, ea, md, iv,
irq, firq, nmi_req, nmi_ack, halt )
variable cond_true : boolean; -- variable used to evaluate coditional branches
begin
case state is
when reset_state => -- released from reset
-- reset the registers
op_ctrl <= reset_op;
pre_ctrl <= reset_pre;
acca_ctrl <= reset_acca;
accb_ctrl <= reset_accb;
ix_ctrl <= reset_ix;
iy_ctrl <= reset_iy;
sp_ctrl <= reset_sp;
up_ctrl <= reset_up;
pc_ctrl <= reset_pc;
ea_ctrl <= reset_ea;
md_ctrl <= reset_md;
iv_ctrl <= reset_iv;
nmi_ctrl <= reset_nmi;
-- idle the ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= reset_cc;
dp_ctrl <= reset_dp;
-- idle the bus
dout_ctrl <= md_lo_dout;
addr_ctrl <= idle_ad;
st_ctrl <= idle_st;
return_state <= vect_hi_state;
next_state <= vect_hi_state;
 
--
-- Jump via interrupt vector
-- iv holds interrupt type
-- fetch PC hi from vector location
--
when vect_hi_state =>
-- default the registers
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
nmi_ctrl <= latch_nmi;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
sp_ctrl <= latch_sp;
up_ctrl <= latch_up;
md_ctrl <= latch_md;
ea_ctrl <= latch_ea;
iv_ctrl <= latch_iv;
-- idle the ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
dp_ctrl <= latch_dp;
-- fetch pc low interrupt vector
pc_ctrl <= pull_hi_pc;
addr_ctrl <= int_hi_ad;
dout_ctrl <= pc_hi_dout;
st_ctrl <= idle_st;
return_state <= vect_lo_state;
next_state <= vect_lo_state;
--
-- jump via interrupt vector
-- iv holds vector type
-- fetch PC lo from vector location
--
when vect_lo_state =>
-- default the registers
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
nmi_ctrl <= latch_nmi;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
sp_ctrl <= latch_sp;
up_ctrl <= latch_up;
md_ctrl <= latch_md;
ea_ctrl <= latch_ea;
iv_ctrl <= latch_iv;
-- idle the ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
dp_ctrl <= latch_dp;
-- fetch the vector low byte
pc_ctrl <= pull_lo_pc;
addr_ctrl <= int_lo_ad;
dout_ctrl <= pc_lo_dout;
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
--
-- Here to fetch an instruction
-- PC points to opcode
-- Should service interrupt requests at this point
-- either from the timer
-- or from the external input.
--
when fetch_state =>
-- fetch the op code
op_ctrl <= fetch_op;
pre_ctrl <= fetch_pre;
ea_ctrl <= reset_ea;
md_ctrl <= latch_md;
-- Fetch op code
addr_ctrl <= fetch_ad;
dout_ctrl <= md_lo_dout;
dp_ctrl <= latch_dp;
--
case op_code(7 downto 6) is
when "10" => -- acca
case op_code(3 downto 0) is
when "0000" => -- suba
left_ctrl <= acca_left;
right_ctrl <= md_right;
alu_ctrl <= alu_sub8;
cc_ctrl <= load_cc;
acca_ctrl <= load_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "0001" => -- cmpa
left_ctrl <= acca_left;
right_ctrl <= md_right;
alu_ctrl <= alu_sub8;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "0010" => -- sbca
left_ctrl <= acca_left;
right_ctrl <= md_right;
alu_ctrl <= alu_sbc;
cc_ctrl <= load_cc;
acca_ctrl <= load_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "0011" =>
case pre_code is
when "00010000" => -- page 2 -- cmpd
left_ctrl <= accd_left;
right_ctrl <= md_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "00010001" => -- page 3 -- cmpu
left_ctrl <= up_left;
right_ctrl <= md_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when others => -- page 1 -- subd
left_ctrl <= accd_left;
right_ctrl <= md_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= load_cc;
acca_ctrl <= load_hi_acca;
accb_ctrl <= load_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
end case;
when "0100" => -- anda
left_ctrl <= acca_left;
right_ctrl <= md_right;
alu_ctrl <= alu_and;
cc_ctrl <= load_cc;
acca_ctrl <= load_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "0101" => -- bita
left_ctrl <= acca_left;
right_ctrl <= md_right;
alu_ctrl <= alu_and;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "0110" => -- ldaa
left_ctrl <= acca_left;
right_ctrl <= md_right;
alu_ctrl <= alu_ld8;
cc_ctrl <= load_cc;
acca_ctrl <= load_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "0111" => -- staa
left_ctrl <= acca_left;
right_ctrl <= md_right;
alu_ctrl <= alu_st8;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "1000" => -- eora
left_ctrl <= acca_left;
right_ctrl <= md_right;
alu_ctrl <= alu_eor;
cc_ctrl <= load_cc;
acca_ctrl <= load_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "1001" => -- adca
left_ctrl <= acca_left;
right_ctrl <= md_right;
alu_ctrl <= alu_adc;
cc_ctrl <= load_cc;
acca_ctrl <= load_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "1010" => -- oraa
left_ctrl <= acca_left;
right_ctrl <= md_right;
alu_ctrl <= alu_ora;
cc_ctrl <= load_cc;
acca_ctrl <= load_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "1011" => -- adda
left_ctrl <= acca_left;
right_ctrl <= md_right;
alu_ctrl <= alu_add8;
cc_ctrl <= load_cc;
acca_ctrl <= load_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "1100" =>
case pre_code is
when "00010000" => -- page 2 -- cmpy
left_ctrl <= iy_left;
right_ctrl <= md_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "00010001" => -- page 3 -- cmps
left_ctrl <= sp_left;
right_ctrl <= md_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when others => -- page 1 -- cmpx
left_ctrl <= ix_left;
right_ctrl <= md_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
end case;
when "1101" => -- bsr / jsr
left_ctrl <= pc_left;
right_ctrl <= md_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "1110" => -- ldx
case pre_code is
when "00010000" => -- page 2 -- ldy
left_ctrl <= iy_left;
right_ctrl <= md_right;
alu_ctrl <= alu_ld16;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= load_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when others => -- page 1 -- ldx
left_ctrl <= ix_left;
right_ctrl <= md_right;
alu_ctrl <= alu_ld16;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= load_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
end case;
when "1111" => -- stx
case pre_code is
when "00010000" => -- page 2 -- sty
left_ctrl <= iy_left;
right_ctrl <= md_right;
alu_ctrl <= alu_st16;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when others => -- page 1 -- stx
left_ctrl <= ix_left;
right_ctrl <= md_right;
alu_ctrl <= alu_st16;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
end case;
when others =>
left_ctrl <= acca_left;
right_ctrl <= md_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
end case;
when "11" => -- accb dual op
case op_code(3 downto 0) is
when "0000" => -- subb
left_ctrl <= accb_left;
right_ctrl <= md_right;
alu_ctrl <= alu_sub8;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= load_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "0001" => -- cmpb
left_ctrl <= accb_left;
right_ctrl <= md_right;
alu_ctrl <= alu_sub8;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "0010" => -- sbcb
left_ctrl <= accb_left;
right_ctrl <= md_right;
alu_ctrl <= alu_sbc;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= load_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "0011" => -- addd
left_ctrl <= accd_left;
right_ctrl <= md_right;
alu_ctrl <= alu_add16;
cc_ctrl <= load_cc;
acca_ctrl <= load_hi_acca;
accb_ctrl <= load_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "0100" => -- andb
left_ctrl <= accb_left;
right_ctrl <= md_right;
alu_ctrl <= alu_and;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= load_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "0101" => -- bitb
left_ctrl <= accb_left;
right_ctrl <= md_right;
alu_ctrl <= alu_and;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "0110" => -- ldab
left_ctrl <= accb_left;
right_ctrl <= md_right;
alu_ctrl <= alu_ld8;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= load_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "0111" => -- stab
left_ctrl <= accb_left;
right_ctrl <= md_right;
alu_ctrl <= alu_st8;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "1000" => -- eorb
left_ctrl <= accb_left;
right_ctrl <= md_right;
alu_ctrl <= alu_eor;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= load_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "1001" => -- adcb
left_ctrl <= accb_left;
right_ctrl <= md_right;
alu_ctrl <= alu_adc;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= load_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "1010" => -- orab
left_ctrl <= accb_left;
right_ctrl <= md_right;
alu_ctrl <= alu_ora;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= load_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "1011" => -- addb
left_ctrl <= accb_left;
right_ctrl <= md_right;
alu_ctrl <= alu_add8;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= load_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "1100" => -- ldd
left_ctrl <= accd_left;
right_ctrl <= md_right;
alu_ctrl <= alu_ld16;
cc_ctrl <= load_cc;
acca_ctrl <= load_hi_acca;
accb_ctrl <= load_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "1101" => -- std
left_ctrl <= accd_left;
right_ctrl <= md_right;
alu_ctrl <= alu_st16;
cc_ctrl <= latch_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "1110" => -- ldu
case pre_code is
when "00010000" => -- page 2 -- lds
left_ctrl <= sp_left;
right_ctrl <= md_right;
alu_ctrl <= alu_ld16;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= load_sp;
when others => -- page 1 -- ldu
left_ctrl <= up_left;
right_ctrl <= md_right;
alu_ctrl <= alu_ld16;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= load_up;
sp_ctrl <= latch_sp;
end case;
when "1111" =>
case pre_code is
when "00010000" => -- page 2 -- sts
left_ctrl <= sp_left;
right_ctrl <= md_right;
alu_ctrl <= alu_st16;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when others => -- page 1 -- stu
left_ctrl <= up_left;
right_ctrl <= md_right;
alu_ctrl <= alu_st16;
cc_ctrl <= load_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
end case;
when others =>
left_ctrl <= accb_left;
right_ctrl <= md_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
end case;
when others =>
left_ctrl <= acca_left;
right_ctrl <= md_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
end case;
if halt = '1' then
iv_ctrl <= reset_iv;
pc_ctrl <= latch_pc;
nmi_ctrl <= latch_nmi;
st_ctrl <= push_st;
return_state <= fetch_state;
next_state <= halt_state;
-- service non maskable interrupts
elsif (nmi_req = '1') and (nmi_ack = '0') then
iv_ctrl <= nmi_iv;
pc_ctrl <= latch_pc;
nmi_ctrl <= set_nmi;
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= int_decr_state;
-- service maskable interrupts
else
--
-- nmi request is not cleared until nmi input goes low
--
if(nmi_req = '0') and (nmi_ack='1') then
nmi_ctrl <= reset_nmi;
else
nmi_ctrl <= latch_nmi;
end if;
--
-- IRQ is level sensitive
--
if (irq = '1') and (cc(IBIT) = '0') then
iv_ctrl <= irq_iv;
pc_ctrl <= latch_pc;
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= int_decr_state;
elsif (firq = '1') and (cc(FBIT) = '0') then
iv_ctrl <= firq_iv;
pc_ctrl <= latch_pc;
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= int_decr_state;
else
-- Advance the PC to fetch next instruction byte
iv_ctrl <= reset_iv; -- default to reset
pc_ctrl <= incr_pc;
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= decode1_state;
end if;
end if;
--
-- Here to decode instruction
-- and fetch next byte of intruction
-- whether it be necessary or not
--
when decode1_state =>
pre_ctrl <= latch_pre;
-- fetch first byte of address or immediate data
ea_ctrl <= fetch_first_ea;
md_ctrl <= fetch_first_md;
addr_ctrl <= fetch_ad;
dout_ctrl <= md_lo_dout;
nmi_ctrl <= latch_nmi;
dp_ctrl <= latch_dp;
case op_code(7 downto 4) is
--
-- direct single op (2 bytes)
-- 6809 => 6 cycles
-- cpu09 => 5 cycles
-- 1 op=(pc) / pc=pc+1
-- 2 ea_hi=0 / ea_lo=(pc) / pc=pc+1
-- 3 md_lo=(ea) / pc=pc
-- 4 alu_left=md / md=alu_out / pc=pc
-- 5 (ea)=md_lo / pc=pc
--
-- Exception is JMP
-- 6809 => 3 cycles
-- cpu09 => 3 cycles
-- 1 op=(pc) / pc=pc+1
-- 2 ea_hi=0 / ea_lo=(pc) / pc=pc+1
-- 3 pc=ea
--
when "0000" =>
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
sp_ctrl <= latch_sp;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= one_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
-- advance the PC
pc_ctrl <= incr_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= single_op_read_state;
 
-- acca / accb inherent instructions
when "0001" =>
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
case op_code(3 downto 0) is
--
-- Page2 pre byte
-- pre=(pc) / pc=pc+1
-- op=(pc) / pc=pc+1
--
when "0000" => -- page2
op_ctrl <= fetch_op;
acca_ctrl <= latch_acca;
--
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
-- advance pc
pc_ctrl <= incr_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= decode2_state;
 
--
-- Page3 pre byte
-- pre=(pc) / pc=pc+1
-- op=(pc) / pc=pc+1
--
when "0001" => -- page3
op_ctrl <= fetch_op;
acca_ctrl <= latch_acca;
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
-- advance pc
pc_ctrl <= incr_pc;
-- Next state
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= decode3_state;
 
--
-- nop - No operation ( 1 byte )
-- 6809 => 2 cycles
-- cpu09 => 2 cycles
-- 1 op=(pc) / pc=pc+1
-- 2 decode
--
when "0010" => -- nop
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
--
left_ctrl <= acca_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
--
pc_ctrl <= latch_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
--
-- sync - halt execution until an interrupt is received
-- interrupt may be NMI, IRQ or FIRQ
-- program execution continues if the
-- interrupt is asserted for 3 clock cycles
-- note that registers are not pushed onto the stack
-- CPU09 => Interrupts need only be asserted for one clock cycle
--
when "0011" => -- sync
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
--
left_ctrl <= acca_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
--
pc_ctrl <= latch_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= sync_state;
 
--
-- lbra -- long branch (3 bytes)
-- 6809 => 5 cycles
-- cpu09 => 4 cycles
-- 1 op=(pc) / pc=pc+1
-- 2 md_hi=sign(pc) / md_lo=(pc) / pc=pc+1
-- 3 md_hi=md_lo / md_lo=(pc) / pc=pc+1
-- 4 pc=pc+md
--
when "0110" =>
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
-- increment the pc
pc_ctrl <= incr_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= lbranch_state;
 
--
-- lbsr - long branch to subroutine (3 bytes)
-- 6809 => 9 cycles
-- cpu09 => 6 cycles
-- 1 op=(pc) /pc=pc+1
-- 2 md_hi=sign(pc) / md_lo=(pc) / pc=pc+1 / sp=sp-1
-- 3 md_hi=md_lo / md_lo=(pc) / pc=pc+1
-- 4 (sp)= pc_lo / sp=sp-1 / pc=pc
-- 5 (sp)=pc_hi / pc=pc
-- 6 pc=pc+md
--
when "0111" =>
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
-- pre decrement sp
left_ctrl <= sp_left;
right_ctrl <= one_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= latch_cc;
sp_ctrl <= load_sp;
-- increment the pc
pc_ctrl <= incr_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= lbranch_state;
 
when "1001" => -- daa
op_ctrl <= latch_op;
--
left_ctrl <= acca_left;
right_ctrl <= accb_right;
alu_ctrl <= alu_daa;
cc_ctrl <= load_cc;
acca_ctrl <= load_acca;
sp_ctrl <= latch_sp;
-- idle pc
pc_ctrl <= latch_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
when "1010" => -- orcc
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
-- increment the pc
pc_ctrl <= incr_pc;
-- next state
st_ctrl <= push_st;
return_state <= fetch_state;
next_state <= orcc_state;
 
when "1100" => -- andcc
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
-- increment the pc
pc_ctrl <= incr_pc;
--
st_ctrl <= push_st;
return_state <= fetch_state;
next_state <= andcc_state;
 
when "1101" => -- sex
op_ctrl <= latch_op;
-- have sex
left_ctrl <= accb_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_sex;
cc_ctrl <= load_cc;
acca_ctrl <= load_hi_acca;
sp_ctrl <= latch_sp;
-- idle PC
pc_ctrl <= latch_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
when "1110" => -- exg
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
-- increment the pc
pc_ctrl <= incr_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= exg_state;
 
when "1111" => -- tfr
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
-- increment the pc
pc_ctrl <= incr_pc;
-- call transfer as a subroutine
st_ctrl <= push_st;
return_state <= fetch_state;
next_state <= tfr_state;
 
when others =>
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
-- increment the pc
pc_ctrl <= incr_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
end case;
--
-- Short branch conditional
-- 6809 => always 3 cycles
-- cpu09 => always = 3 cycles
-- 1 op=(pc) / pc=pc+1
-- 2 md_hi=sign(pc) / md_lo=(pc) / pc=pc+1 / test cc
-- 3 if cc tru pc=pc+md else pc=pc
--
when "0010" => -- branch conditional
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
sp_ctrl <= latch_sp;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= one_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
-- increment the pc
pc_ctrl <= incr_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= sbranch_state;
--
-- Single byte stack operators
-- Do not advance PC
--
when "0011" =>
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
--
-- lea - load effective address (2+ bytes)
-- 6809 => 4 cycles + addressing mode
-- cpu09 => 4 cycles + addressing mode
-- 1 op=(pc) / pc=pc+1
-- 2 md_lo=(pc) / pc=pc+1
-- 3 calculate ea
-- 4 ix/iy/sp/up = ea
--
case op_code(3 downto 0) is
when "0000" | -- leax
"0001" | -- leay
"0010" | -- leas
"0011" => -- leau
left_ctrl <= pc_left;
right_ctrl <= one_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
-- advance PC
pc_ctrl <= incr_pc;
--
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
sp_ctrl <= latch_sp;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
--
st_ctrl <= push_st;
return_state <= lea_state;
next_state <= indexed_state;
 
--
-- pshs - push registers onto sp stack
-- 6809 => 5 cycles + registers
-- cpu09 => 3 cycles + registers
-- 1 op=(pc) / pc=pc+1
-- 2 ea_lo=(pc) / pc=pc+1
-- 3 if ea(7 downto 0) != "00000000" then sp=sp-1
-- 4 if ea(7) = 1 (sp)=pcl, sp=sp-1
-- 5 if ea(7) = 1 (sp)=pch
-- if ea(6 downto 0) != "0000000" then sp=sp-1
-- 6 if ea(6) = 1 (sp)=upl, sp=sp-1
-- 7 if ea(6) = 1 (sp)=uph
-- if ea(5 downto 0) != "000000" then sp=sp-1
-- 8 if ea(5) = 1 (sp)=iyl, sp=sp-1
-- 9 if ea(5) = 1 (sp)=iyh
-- if ea(4 downto 0) != "00000" then sp=sp-1
-- 10 if ea(4) = 1 (sp)=ixl, sp=sp-1
-- 11 if ea(4) = 1 (sp)=ixh
-- if ea(3 downto 0) != "0000" then sp=sp-1
-- 12 if ea(3) = 1 (sp)=dp
-- if ea(2 downto 0) != "000" then sp=sp-1
-- 13 if ea(2) = 1 (sp)=accb
-- if ea(1 downto 0) != "00" then sp=sp-1
-- 14 if ea(1) = 1 (sp)=acca
-- if ea(0 downto 0) != "0" then sp=sp-1
-- 15 if ea(0) = 1 (sp)=cc
--
when "0100" => -- pshs
--
left_ctrl <= sp_left;
right_ctrl <= one_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- advance PC
pc_ctrl <= incr_pc;
--
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
sp_ctrl <= latch_sp;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= pshs_state;
 
--
-- puls - pull registers of sp stack
-- 6809 => 5 cycles + registers
-- cpu09 => 3 cycles + registers
--
when "0101" => -- puls
left_ctrl <= pc_left;
right_ctrl <= one_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
-- advance PC
pc_ctrl <= incr_pc;
--
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
sp_ctrl <= latch_sp;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= puls_state;
 
--
-- pshu - push registers onto up stack
-- 6809 => 5 cycles + registers
-- cpu09 => 3 cycles + registers
--
when "0110" => -- pshu
-- idle UP
left_ctrl <= up_left;
right_ctrl <= one_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- advance PC
pc_ctrl <= incr_pc;
--
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
sp_ctrl <= latch_sp;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= pshu_state;
 
--
-- pulu - pull registers of up stack
-- 6809 => 5 cycles + registers
-- cpu09 => 3 cycles + registers
--
when "0111" => -- pulu
left_ctrl <= pc_left;
right_ctrl <= one_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
-- advance PC
pc_ctrl <= incr_pc;
--
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
sp_ctrl <= latch_sp;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= pulu_state;
 
--
-- rts - return from subroutine
-- 6809 => 5 cycles
-- cpu09 => 4 cycles
-- 1 op=(pc) / pc=pc+1
-- 2 decode op
-- 3 pc_hi = (sp) / sp=sp+1
-- 4 pc_lo = (sp) / sp=sp+1
--
when "1001" =>
left_ctrl <= sp_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- idle PC
pc_ctrl <= latch_pc;
--
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
sp_ctrl <= latch_sp;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
--
st_ctrl <= push_st;
return_state <= fetch_state;
next_state <= pull_return_hi_state;
 
--
-- abx - add accb to index register
-- 6809 => 3 cycles
-- cpu09 => 2 cycles
-- 1 op=(pc) / pc=pc+1
-- 2 alu_left=ix / alu_right=accb / ix=alu_out / pc=pc
--
when "1010" => -- abx
left_ctrl <= ix_left;
right_ctrl <= accb_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
ix_ctrl <= load_ix;
--
pc_ctrl <= latch_pc;
iy_ctrl <= latch_iy;
sp_ctrl <= latch_sp;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
when "1011" => -- rti
-- idle ALU
left_ctrl <= sp_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
--
pc_ctrl <= latch_pc;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
sp_ctrl <= latch_sp;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= rti_cc_state;
 
when "1100" => -- cwai
-- pre decrement sp
left_ctrl <= sp_left;
right_ctrl <= one_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= latch_cc;
sp_ctrl <= load_sp;
--
pc_ctrl <= latch_pc;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
--
st_ctrl <= idle_st;
return_state <= int_entire_state; -- set entire flag
next_state <= andcc_state;
 
when "1101" => -- mul
left_ctrl <= acca_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
--
pc_ctrl <= latch_pc;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
sp_ctrl <= latch_sp;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= mul_state;
 
when "1111" => -- swi
-- predecrement SP
left_ctrl <= sp_left;
right_ctrl <= one_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= latch_cc;
sp_ctrl <= load_sp;
--
pc_ctrl <= latch_pc;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
iv_ctrl <= swi_iv;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= int_entire_state;
 
when others =>
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- idle PC
pc_ctrl <= latch_pc;
--
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
sp_ctrl <= latch_sp;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
end case;
--
-- Accumulator A Single operand
-- source = acca, dest = acca
-- Do not advance PC
-- Typically 2 cycles 1 bytes
-- 1 opcode fetch
-- 2 post byte fetch / instruction decode
-- Note that there is no post byte
-- so do not advance PC in decode cycle
-- Re-run opcode fetch cycle after decode
--
when "0100" => -- acca single op
op_ctrl <= latch_op;
accb_ctrl <= latch_accb;
pc_ctrl <= latch_pc;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
left_ctrl <= acca_left;
case op_code(3 downto 0) is
when "0000" => -- neg
right_ctrl <= zero_right;
alu_ctrl <= alu_neg;
acca_ctrl <= load_acca;
cc_ctrl <= load_cc;
when "0011" => -- com
right_ctrl <= zero_right;
alu_ctrl <= alu_com;
acca_ctrl <= load_acca;
cc_ctrl <= load_cc;
when "0100" => -- lsr
right_ctrl <= zero_right;
alu_ctrl <= alu_lsr8;
acca_ctrl <= load_acca;
cc_ctrl <= load_cc;
when "0110" => -- ror
right_ctrl <= zero_right;
alu_ctrl <= alu_ror8;
acca_ctrl <= load_acca;
cc_ctrl <= load_cc;
when "0111" => -- asr
right_ctrl <= zero_right;
alu_ctrl <= alu_asr8;
acca_ctrl <= load_acca;
cc_ctrl <= load_cc;
when "1000" => -- asl
right_ctrl <= zero_right;
alu_ctrl <= alu_asl8;
acca_ctrl <= load_acca;
cc_ctrl <= load_cc;
when "1001" => -- rol
right_ctrl <= zero_right;
alu_ctrl <= alu_rol8;
acca_ctrl <= load_acca;
cc_ctrl <= load_cc;
when "1010" => -- dec
right_ctrl <= one_right;
alu_ctrl <= alu_dec;
acca_ctrl <= load_acca;
cc_ctrl <= load_cc;
when "1011" => -- undefined
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
acca_ctrl <= latch_acca;
cc_ctrl <= latch_cc;
when "1100" => -- inc
right_ctrl <= one_right;
alu_ctrl <= alu_inc;
acca_ctrl <= load_acca;
cc_ctrl <= load_cc;
when "1101" => -- tst
right_ctrl <= zero_right;
alu_ctrl <= alu_st8;
acca_ctrl <= latch_acca;
cc_ctrl <= load_cc;
when "1110" => -- jmp
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
acca_ctrl <= latch_acca;
cc_ctrl <= latch_cc;
when "1111" => -- clr
right_ctrl <= zero_right;
alu_ctrl <= alu_ld8;
acca_ctrl <= load_acca;
cc_ctrl <= load_cc;
when others =>
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
acca_ctrl <= latch_acca;
cc_ctrl <= latch_cc;
end case;
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
--
-- Single Operand accb
-- source = accb, dest = accb
-- Typically 2 cycles 1 bytes
-- 1 opcode fetch
-- 2 post byte fetch / instruction decode
-- Note that there is no post byte
-- so do not advance PC in decode cycle
-- Re-run opcode fetch cycle after decode
--
when "0101" =>
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
pc_ctrl <= latch_pc;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
left_ctrl <= accb_left;
case op_code(3 downto 0) is
when "0000" => -- neg
right_ctrl <= zero_right;
alu_ctrl <= alu_neg;
accb_ctrl <= load_accb;
cc_ctrl <= load_cc;
when "0011" => -- com
right_ctrl <= zero_right;
alu_ctrl <= alu_com;
accb_ctrl <= load_accb;
cc_ctrl <= load_cc;
when "0100" => -- lsr
right_ctrl <= zero_right;
alu_ctrl <= alu_lsr8;
accb_ctrl <= load_accb;
cc_ctrl <= load_cc;
when "0110" => -- ror
right_ctrl <= zero_right;
alu_ctrl <= alu_ror8;
accb_ctrl <= load_accb;
cc_ctrl <= load_cc;
when "0111" => -- asr
right_ctrl <= zero_right;
alu_ctrl <= alu_asr8;
accb_ctrl <= load_accb;
cc_ctrl <= load_cc;
when "1000" => -- asl
right_ctrl <= zero_right;
alu_ctrl <= alu_asl8;
accb_ctrl <= load_accb;
cc_ctrl <= load_cc;
when "1001" => -- rol
right_ctrl <= zero_right;
alu_ctrl <= alu_rol8;
accb_ctrl <= load_accb;
cc_ctrl <= load_cc;
when "1010" => -- dec
right_ctrl <= one_right;
alu_ctrl <= alu_dec;
accb_ctrl <= load_accb;
cc_ctrl <= load_cc;
when "1011" => -- undefined
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
accb_ctrl <= latch_accb;
cc_ctrl <= latch_cc;
when "1100" => -- inc
right_ctrl <= one_right;
alu_ctrl <= alu_inc;
accb_ctrl <= load_accb;
cc_ctrl <= load_cc;
when "1101" => -- tst
right_ctrl <= zero_right;
alu_ctrl <= alu_st8;
accb_ctrl <= latch_accb;
cc_ctrl <= load_cc;
when "1110" => -- jmp
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
accb_ctrl <= latch_accb;
cc_ctrl <= latch_cc;
when "1111" => -- clr
right_ctrl <= zero_right;
alu_ctrl <= alu_ld8;
accb_ctrl <= load_accb;
cc_ctrl <= load_cc;
when others =>
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
accb_ctrl <= latch_accb;
cc_ctrl <= latch_cc;
end case;
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
--
-- Single operand indexed
-- Two byte instruction so advance PC
-- EA should hold index offset
--
when "0110" => -- indexed single op
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= one_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
-- increment the pc
pc_ctrl <= incr_pc;
-- next state
case op_code(3 downto 0) is
when "1110" => -- jmp
return_state <= jmp_state;
when "1111" => -- clr
return_state <= single_op_exec_state;
when others =>
return_state <= single_op_read_state;
end case;
st_ctrl <= push_st;
next_state <= indexed_state;
--
-- Single operand extended addressing
-- three byte instruction so advance the PC
-- Low order EA holds high order address
--
when "0111" => -- extended single op
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= one_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
-- increment PC
pc_ctrl <= incr_pc;
--
case op_code(3 downto 0) is
when "1110" => -- jmp
return_state <= jmp_state;
when "1111" => -- clr
return_state <= single_op_exec_state;
when others =>
return_state <= single_op_read_state;
end case;
st_ctrl <= push_st;
next_state <= extended_state;
 
when "1000" => -- acca immediate
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- subd #
"1100" | -- cmpx #
"1110" => -- ldx #
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
--
st_ctrl <= push_st;
return_state <= fetch_state;
next_state <= imm16_state;
 
--
-- bsr offset - Branch to subroutine (2 bytes)
-- 6809 => 7 cycles
-- cpu09 => 5 cycles
-- 1 op=(pc) / pc=pc+1
-- 2 md_hi=sign(pc) / md_lo=(pc) / sp=sp-1 / pc=pc+1
-- 3 (sp)=pc_lo / sp=sp-1
-- 4 (sp)=pc_hi
-- 5 pc=pc+md
--
when "1101" => -- bsr
-- pre decrement SP
left_ctrl <= sp_left;
right_ctrl <= one_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= latch_cc;
sp_ctrl <= load_sp;
--
st_ctrl <= push_st;
return_state <= sbranch_state;
next_state <= push_return_lo_state;
 
when others =>
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
end case;
 
when "1001" => -- acca direct
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- subd
"1100" | -- cmpx
"1110" => -- ldx
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= one_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= dual_op_read16_state;
 
when "0111" => -- sta direct
-- idle ALU
left_ctrl <= acca_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= dual_op_write8_state;
 
when "1111" => -- stx direct
-- idle ALU
left_ctrl <= ix_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= dual_op_write16_state;
 
--
-- jsr direct - Jump to subroutine in direct page (2 bytes)
-- 6809 => 7 cycles
-- cpu09 => 5 cycles
-- 1 op=(pc) / pc=pc+1
-- 2 ea_hi=0 / ea_lo=(pc) / sp=sp-1 / pc=pc+1
-- 3 (sp)=pc_lo / sp=sp-1
-- 4 (sp)=pc_hi
-- 5 pc=ea
--
when "1101" => -- jsr direct
-- pre decrement sp
left_ctrl <= sp_left;
right_ctrl <= one_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= latch_cc;
sp_ctrl <= load_sp;
--
st_ctrl <= push_st;
return_state <= jmp_state;
next_state <= push_return_lo_state;
 
when others =>
-- idle ALU
left_ctrl <= acca_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= dual_op_read8_state;
end case;
 
when "1010" => -- acca indexed
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- subd
"1100" | -- cmpx
"1110" => -- ldx
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
--
st_ctrl <= push_st;
return_state <= dual_op_read16_state;
next_state <= indexed_state;
 
when "0111" => -- staa ,x
-- idle ALU
left_ctrl <= acca_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
--
st_ctrl <= push_st;
return_state <= dual_op_write8_state;
next_state <= indexed_state;
 
when "1111" => -- stx ,x
-- idle ALU
left_ctrl <= ix_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
--
st_ctrl <= push_st;
return_state <= dual_op_write16_state;
next_state <= indexed_state;
 
when "1101" => -- jsr ,x
-- pre decrement SP
left_ctrl <= sp_left;
right_ctrl <= one_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= latch_cc;
sp_ctrl <= load_sp;
--
st_ctrl <= push_st;
return_state <= jsr_state;
next_state <= indexed_state;
 
when others =>
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= one_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
--
st_ctrl <= push_st;
return_state <= dual_op_read8_state;
next_state <= indexed_state;
end case;
 
when "1011" => -- acca extended
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- subd
"1100" | -- cmpx
"1110" => -- ldx
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= one_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
--
st_ctrl <= push_st;
return_state <= dual_op_read16_state;
next_state <= extended_state;
 
when "0111" => -- staa >
-- idle ALU
left_ctrl <= acca_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
--
st_ctrl <= push_st;
return_state <= dual_op_write8_state;
next_state <= extended_state;
 
when "1111" => -- stx >
-- idle ALU
left_ctrl <= ix_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
--
st_ctrl <= push_st;
return_state <= dual_op_write16_state;
next_state <= extended_state;
 
when "1101" => -- jsr >extended
-- pre decrement sp
left_ctrl <= sp_left;
right_ctrl <= one_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= latch_cc;
sp_ctrl <= load_sp;
--
st_ctrl <= push_st;
return_state <= jsr_state;
next_state <= extended_state;
 
when others =>
-- idle ALU
left_ctrl <= acca_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_st8;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
--
st_ctrl <= push_st;
return_state <= dual_op_read8_state;
next_state <= extended_state;
end case;
 
when "1100" => -- accb immediate
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
--
left_ctrl <= pc_left;
right_ctrl <= one_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- addd #
"1100" | -- ldd #
"1110" => -- ldu #
st_ctrl <= push_st;
return_state <= fetch_state;
next_state <= imm16_state;
 
when others =>
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
end case;
 
 
when "1101" => -- accb direct
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- increment the pc
pc_ctrl <= incr_pc;
--
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
--
case op_code(3 downto 0) is
when "0011" | -- addd
"1100" | -- ldd
"1110" => -- ldu
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= dual_op_read16_state;
 
when "0111" => -- stab direct
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= dual_op_write8_state;
 
when "1101" => -- std direct
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= dual_op_write16_state;
 
when "1111" => -- stu direct
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= dual_op_write16_state;
 
when others =>
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= dual_op_read8_state;
end case;
 
when "1110" => -- accb indexed
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- increment the pc
pc_ctrl <= incr_pc;
--
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
--
case op_code(3 downto 0) is
when "0011" | -- addd
"1100" | -- ldd
"1110" => -- ldu
st_ctrl <= push_st;
return_state <= dual_op_read16_state;
next_state <= indexed_state;
 
when "0111" => -- stab indexed
st_ctrl <= push_st;
return_state <= dual_op_write8_state;
next_state <= indexed_state;
 
when "1101" => -- std indexed
st_ctrl <= push_st;
return_state <= dual_op_write16_state;
next_state <= indexed_state;
 
when "1111" => -- stu indexed
st_ctrl <= push_st;
return_state <= dual_op_write16_state;
next_state <= indexed_state;
 
when others =>
st_ctrl <= push_st;
return_state <= dual_op_read8_state;
next_state <= indexed_state;
end case;
 
when "1111" => -- accb extended
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- increment the pc
pc_ctrl <= incr_pc;
--
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
--
case op_code(3 downto 0) is
when "0011" | -- addd
"1100" | -- ldd
"1110" => -- ldu
st_ctrl <= push_st;
return_state <= dual_op_read16_state;
next_state <= extended_state;
 
when "0111" => -- stab extended
st_ctrl <= push_st;
return_state <= dual_op_write8_state;
next_state <= extended_state;
 
when "1101" => -- std extended
st_ctrl <= push_st;
return_state <= dual_op_write16_state;
next_state <= extended_state;
 
when "1111" => -- stu extended
st_ctrl <= push_st;
return_state <= dual_op_write16_state;
next_state <= extended_state;
 
when others =>
st_ctrl <= push_st;
return_state <= dual_op_read8_state;
next_state <= extended_state;
end case;
 
when others =>
op_ctrl <= latch_op;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- idle the ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- idle the pc
pc_ctrl <= latch_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
end case;
 
--
-- Here to decode prefix 2 instruction
-- and fetch next byte of intruction
-- whether it be necessary or not
--
when decode2_state =>
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
-- fetch first byte of address or immediate data
ea_ctrl <= fetch_first_ea;
md_ctrl <= fetch_first_md;
addr_ctrl <= fetch_ad;
dout_ctrl <= md_lo_dout;
nmi_ctrl <= latch_nmi;
dp_ctrl <= latch_dp;
case op_code(7 downto 4) is
--
-- lbcc -- long branch conditional
-- 6809 => branch 6 cycles, no branch 5 cycles
-- cpu09 => always 5 cycles
-- 1 pre=(pc) / pc=pc+1
-- 2 op=(pc) / pc=pc+1
-- 3 md_hi=sign(pc) / md_lo=(pc) / pc=pc+1
-- 4 md_hi=md_lo / md_lo=(pc) / pc=pc+1
-- 5 if cond pc=pc+md else pc=pc
--
when "0010" =>
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
sp_ctrl <= latch_sp;
up_ctrl <= latch_up;
iv_ctrl <= latch_iv;
-- increment the pc
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
pc_ctrl <= incr_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= lbranch_state;
 
--
-- Single byte stack operators
-- Do not advance PC
--
when "0011" =>
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
pc_ctrl <= latch_pc;
case op_code(3 downto 0) is
when "1111" => -- swi 2
-- predecrement sp
left_ctrl <= sp_left;
right_ctrl <= one_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= latch_cc;
sp_ctrl <= load_sp;
iv_ctrl <= swi2_iv;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= int_entire_state;
 
when others =>
left_ctrl <= sp_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
end case;
 
when "1000" => -- acca immediate
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- Idle the ALU
left_ctrl <= pc_left;
right_ctrl <= one_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- cmpd #
"1100" | -- cmpy #
"1110" => -- ldy #
st_ctrl <= push_st;
return_state <= fetch_state;
next_state <= imm16_state;
 
when others =>
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
end case;
 
when "1001" => -- acca direct
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- idle the ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- cmpd <
"1100" | -- cmpy <
"1110" => -- ldy <
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= dual_op_read16_state;
 
when "1111" => -- sty <
st_ctrl <= push_st;
return_state <= fetch_state;
next_state <= dual_op_write16_state;
 
when others =>
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
end case;
 
when "1010" => -- acca indexed
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- idle the ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- cmpd ,ind
"1100" | -- cmpy ,ind
"1110" => -- ldy ,ind
st_ctrl <= push_st;
return_state <= dual_op_read16_state;
next_state <= indexed_state;
 
when "1111" => -- sty ,ind
st_ctrl <= push_st;
return_state <= dual_op_write16_state;
next_state <= indexed_state;
 
when others =>
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
end case;
 
when "1011" => -- acca extended
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- idle the ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- cmpd <
"1100" | -- cmpy <
"1110" => -- ldy <
st_ctrl <= push_st;
return_state <= dual_op_read16_state;
next_state <= extended_state;
 
when "1111" => -- sty >
st_ctrl <= push_st;
return_state <= dual_op_write16_state;
next_state <= extended_state;
 
when others =>
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
end case;
 
when "1100" => -- accb immediate
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- idle the alu
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- undef #
"1100" | -- undef #
"1110" => -- lds #
st_ctrl <= push_st;
return_state <= fetch_state;
next_state <= imm16_state;
 
when others =>
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
end case;
 
when "1101" => -- accb direct
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- idle the alu
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- undef <
"1100" | -- undef <
"1110" => -- lds <
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= dual_op_read16_state;
 
when "1111" => -- sts <
st_ctrl <= push_st;
return_state <= fetch_state;
next_state <= dual_op_write16_state;
 
when others =>
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
end case;
 
when "1110" => -- accb indexed
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
md_ctrl <= latch_md;
iv_ctrl <= latch_iv;
-- idle the alu
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- undef ,ind
"1100" | -- undef ,ind
"1110" => -- lds ,ind
st_ctrl <= push_st;
return_state <= dual_op_read16_state;
next_state <= indexed_state;
 
when "1111" => -- sts ,ind
st_ctrl <= push_st;
return_state <= dual_op_write16_state;
next_state <= indexed_state;
 
when others =>
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
end case;
 
when "1111" => -- accb extended
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- idle the alu
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- undef >
"1100" | -- undef >
"1110" => -- lds >
st_ctrl <= push_st;
return_state <= dual_op_read16_state;
next_state <= extended_state;
 
when "1111" => -- sts >
st_ctrl <= push_st;
return_state <= dual_op_write16_state;
next_state <= extended_state;
 
when others =>
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
end case;
 
when others =>
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- idle the alu
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- idle the pc
pc_ctrl <= latch_pc;
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
end case;
--
-- Here to decode instruction
-- and fetch next byte of intruction
-- whether it be necessary or not
--
when decode3_state =>
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
ea_ctrl <= fetch_first_ea;
md_ctrl <= fetch_first_md;
addr_ctrl <= fetch_ad;
dout_ctrl <= md_lo_dout;
nmi_ctrl <= latch_nmi;
dp_ctrl <= latch_dp;
case op_code(7 downto 4) is
--
-- Single byte stack operators
-- Do not advance PC
--
when "0011" =>
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
pc_ctrl <= latch_pc;
--
case op_code(3 downto 0) is
when "1111" => -- swi3
-- predecrement sp
left_ctrl <= sp_left;
right_ctrl <= one_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= latch_cc;
sp_ctrl <= load_sp;
iv_ctrl <= swi3_iv;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= int_entire_state;
when others =>
left_ctrl <= sp_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
end case;
 
when "1000" => -- acca immediate
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- idle the alu
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- cmpu #
"1100" | -- cmps #
"1110" => -- undef #
st_ctrl <= push_st;
return_state <= fetch_state;
next_state <= imm16_state;
when others =>
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
end case;
 
when "1001" => -- acca direct
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- idle the alu
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- cmpu <
"1100" | -- cmps <
"1110" => -- undef <
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= dual_op_read16_state;
 
when others =>
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
end case;
 
when "1010" => -- acca indexed
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- idle the alu
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- cmpu ,X
"1100" | -- cmps ,X
"1110" => -- undef ,X
st_ctrl <= push_st;
return_state <= dual_op_read16_state;
next_state <= indexed_state;
 
when others =>
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
end case;
 
when "1011" => -- acca extended
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- idle the alu
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- increment the pc
pc_ctrl <= incr_pc;
case op_code(3 downto 0) is
when "0011" | -- cmpu >
"1100" | -- cmps >
"1110" => -- undef >
st_ctrl <= push_st;
return_state <= dual_op_read16_state;
next_state <= extended_state;
when others =>
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
end case;
 
when others =>
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
-- idle the alu
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- idle the pc
pc_ctrl <= latch_pc;
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
end case;
 
--
-- here if ea holds low byte
-- Direct
-- Extended
-- Indexed
-- read memory location
--
when single_op_read_state =>
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
pc_ctrl <= latch_pc;
iv_ctrl <= latch_iv;
dp_ctrl <= latch_dp;
nmi_ctrl <= latch_nmi;
-- idle ALU
left_ctrl <= ea_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
ea_ctrl <= latch_ea;
-- read memory into md
md_ctrl <= fetch_first_md;
addr_ctrl <= read_ad;
dout_ctrl <= md_lo_dout;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= single_op_exec_state;
 
when single_op_exec_state =>
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
dp_ctrl <= latch_dp;
nmi_ctrl <= latch_nmi;
iv_ctrl <= latch_iv;
ea_ctrl <= latch_ea;
-- idle the bus
addr_ctrl <= idle_ad;
dout_ctrl <= md_lo_dout;
st_ctrl <= idle_st;
return_state <= fetch_state;
case op_code(3 downto 0) is
when "0000" => -- neg
left_ctrl <= md_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_neg;
cc_ctrl <= load_cc;
md_ctrl <= load_md;
pc_ctrl <= latch_pc;
next_state <= single_op_write_state;
when "0011" => -- com
left_ctrl <= md_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_com;
cc_ctrl <= load_cc;
md_ctrl <= load_md;
pc_ctrl <= latch_pc;
next_state <= single_op_write_state;
when "0100" => -- lsr
left_ctrl <= md_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_lsr8;
cc_ctrl <= load_cc;
md_ctrl <= load_md;
pc_ctrl <= latch_pc;
next_state <= single_op_write_state;
when "0110" => -- ror
left_ctrl <= md_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_ror8;
cc_ctrl <= load_cc;
md_ctrl <= load_md;
pc_ctrl <= latch_pc;
next_state <= single_op_write_state;
when "0111" => -- asr
left_ctrl <= md_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_asr8;
cc_ctrl <= load_cc;
md_ctrl <= load_md;
pc_ctrl <= latch_pc;
next_state <= single_op_write_state;
when "1000" => -- asl
left_ctrl <= md_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_asl8;
cc_ctrl <= load_cc;
md_ctrl <= load_md;
pc_ctrl <= latch_pc;
next_state <= single_op_write_state;
when "1001" => -- rol
left_ctrl <= md_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_rol8;
cc_ctrl <= load_cc;
md_ctrl <= load_md;
pc_ctrl <= latch_pc;
next_state <= single_op_write_state;
when "1010" => -- dec
left_ctrl <= md_left;
right_ctrl <= one_right;
alu_ctrl <= alu_dec;
cc_ctrl <= load_cc;
md_ctrl <= load_md;
pc_ctrl <= latch_pc;
next_state <= single_op_write_state;
when "1011" => -- undefined
left_ctrl <= md_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
md_ctrl <= latch_md;
pc_ctrl <= latch_pc;
next_state <= fetch_state;
when "1100" => -- inc
left_ctrl <= md_left;
right_ctrl <= one_right;
alu_ctrl <= alu_inc;
cc_ctrl <= load_cc;
md_ctrl <= load_md;
pc_ctrl <= latch_pc;
next_state <= single_op_write_state;
when "1101" => -- tst
left_ctrl <= md_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_st8;
cc_ctrl <= load_cc;
md_ctrl <= latch_md;
pc_ctrl <= latch_pc;
next_state <= fetch_state;
when "1110" => -- jmp
left_ctrl <= md_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_ld16;
cc_ctrl <= latch_cc;
md_ctrl <= latch_md;
pc_ctrl <= load_pc;
next_state <= fetch_state;
when "1111" => -- clr
left_ctrl <= md_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_ld8;
cc_ctrl <= load_cc;
md_ctrl <= load_md;
pc_ctrl <= latch_pc;
next_state <= single_op_write_state;
when others =>
left_ctrl <= md_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
md_ctrl <= latch_md;
pc_ctrl <= latch_pc;
next_state <= fetch_state;
end case;
--
-- single operand 8 bit write
-- Write low 8 bits of ALU output
-- EA holds address
-- MD holds data
--
when single_op_write_state =>
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
pc_ctrl <= latch_pc;
md_ctrl <= latch_md;
iv_ctrl <= latch_iv;
dp_ctrl <= latch_dp;
nmi_ctrl <= latch_nmi;
ea_ctrl <= latch_ea;
-- idle the ALU
left_ctrl <= acca_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
-- write ALU low byte output
addr_ctrl <= write_ad;
dout_ctrl <= md_lo_dout;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
--
-- here if ea holds address of low byte
-- read memory location
--
when dual_op_read8_state =>
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
pc_ctrl <= latch_pc;
iv_ctrl <= latch_iv;
dp_ctrl <= latch_dp;
nmi_ctrl <= latch_nmi;
left_ctrl <= ea_left;
-- Leave the ea alone
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
ea_ctrl <= latch_ea;
-- read first data byte from ea
md_ctrl <= fetch_first_md;
addr_ctrl <= read_ad;
dout_ctrl <= md_lo_dout;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
--
-- Here to read a 16 bit value into MD
-- pointed to by the EA register
-- The first byte is read
-- and the EA is incremented
--
when dual_op_read16_state =>
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
cc_ctrl <= latch_cc;
dp_ctrl <= latch_dp;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
pc_ctrl <= latch_pc;
iv_ctrl <= latch_iv;
nmi_ctrl <= latch_nmi;
-- increment the effective address
left_ctrl <= ea_left;
right_ctrl <= one_right;
alu_ctrl <= alu_add16;
ea_ctrl <= load_ea;
-- read the low byte of the 16 bit data
md_ctrl <= fetch_first_md;
addr_ctrl <= read_ad;
dout_ctrl <= md_lo_dout;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= dual_op_read16_2_state;
 
--
-- here to read the second byte
-- pointed to by EA into MD
--
when dual_op_read16_2_state =>
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
cc_ctrl <= latch_cc;
dp_ctrl <= latch_dp;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
pc_ctrl <= latch_pc;
iv_ctrl <= latch_iv;
nmi_ctrl <= latch_nmi;
-- idle the effective address
left_ctrl <= ea_left;
right_ctrl <= one_right;
alu_ctrl <= alu_nop;
ea_ctrl <= latch_ea;
-- read the low byte of the 16 bit data
md_ctrl <= fetch_next_md;
addr_ctrl <= read_ad;
dout_ctrl <= md_lo_dout;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
--
-- 16 bit Write state
-- EA hold address of memory to write to
-- Advance the effective address in ALU
-- decode op_code to determine which
-- register to write
--
when dual_op_write16_state =>
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
pc_ctrl <= latch_pc;
md_ctrl <= latch_md;
iv_ctrl <= latch_iv;
dp_ctrl <= latch_dp;
nmi_ctrl <= latch_nmi;
-- increment the effective address
left_ctrl <= ea_left;
right_ctrl <= one_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
ea_ctrl <= load_ea;
-- write the ALU hi byte at ea
addr_ctrl <= write_ad;
if op_code(6) = '0' then
case op_code(3 downto 0) is
when "1111" => -- stx / sty
case pre_code is
when "00010000" => -- page 2 -- sty
dout_ctrl <= iy_hi_dout;
when others => -- page 1 -- stx
dout_ctrl <= ix_hi_dout;
end case;
when others =>
dout_ctrl <= md_hi_dout;
end case;
else
case op_code(3 downto 0) is
when "1101" => -- std
dout_ctrl <= acca_dout; -- acca is high byte of ACCD
when "1111" => -- stu / sts
case pre_code is
when "00010000" => -- page 2 -- sts
dout_ctrl <= sp_hi_dout;
when others => -- page 1 -- stu
dout_ctrl <= up_hi_dout;
end case;
when others =>
dout_ctrl <= md_hi_dout;
end case;
end if;
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= dual_op_write8_state;
 
--
-- Dual operand 8 bit write
-- Write 8 bit accumulator
-- or low byte of 16 bit register
-- EA holds address
-- decode opcode to determine
-- which register to apply to the bus
-- Also set the condition codes here
--
when dual_op_write8_state =>
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
pc_ctrl <= latch_pc;
iv_ctrl <= latch_iv;
dp_ctrl <= latch_dp;
nmi_ctrl <= latch_nmi;
md_ctrl <= latch_md;
-- idle ALU
left_ctrl <= ea_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
ea_ctrl <= latch_ea;
--
if op_code(6) = '0' then -- '0' = acca line
case op_code(3 downto 0) is
when "0111" => -- sta
dout_ctrl <= acca_dout;
when "1111" => -- stx / sty
case pre_code is
when "00010000" => -- page 2 -- sty
dout_ctrl <= iy_lo_dout;
when others => -- page 1 -- stx
dout_ctrl <= ix_lo_dout;
end case;
when others =>
dout_ctrl <= md_lo_dout;
end case;
else -- '1' = accb line
case op_code(3 downto 0) is
when "0111" => -- stb
dout_ctrl <= accb_dout;
when "1101" => -- std
dout_ctrl <= accb_dout; -- accb is low byte of accd
when "1111" => -- stu / sts
case pre_code is
when "00010000" => -- page 2 -- sts
dout_ctrl <= sp_lo_dout;
when others => -- page 1 -- stu
dout_ctrl <= up_lo_dout;
end case;
when others =>
dout_ctrl <= md_lo_dout;
end case;
end if;
-- write ALU low byte output
addr_ctrl <= write_ad;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= fetch_state;
 
--
-- 16 bit immediate addressing mode
--
when imm16_state =>
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
cc_ctrl <= latch_cc;
dp_ctrl <= latch_dp;
--
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
--
iv_ctrl <= latch_iv;
nmi_ctrl <= latch_nmi;
ea_ctrl <= latch_ea;
-- increment pc
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
pc_ctrl <= incr_pc;
-- fetch next immediate byte
md_ctrl <= fetch_next_md;
addr_ctrl <= fetch_ad;
dout_ctrl <= md_lo_dout;
-- return to caller
st_ctrl <= pull_st;
return_state <= fetch_state;
next_state <= saved_state;
 
--
-- ea holds 8 bit index offet
-- calculate the effective memory address
-- using the alu
--
when indexed_state =>
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
iv_ctrl <= latch_iv;
dp_ctrl <= latch_dp;
nmi_ctrl <= latch_nmi;
dout_ctrl <= md_lo_dout;
--
-- decode indexing mode
--
if md(7) = '0' then
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
case md(6 downto 5) is
when "00" =>
left_ctrl <= ix_left;
when "01" =>
left_ctrl <= iy_left;
when "10" =>
left_ctrl <= up_left;
when others =>
-- when "11" =>
left_ctrl <= sp_left;
end case;
right_ctrl <= md_sign5_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
ea_ctrl <= load_ea;
--
md_ctrl <= latch_md;
addr_ctrl <= idle_ad;
pc_ctrl <= latch_pc;
--
st_ctrl <= pull_st;
return_state <= fetch_state;
next_state <= saved_state;
 
else
case md(3 downto 0) is
when "0000" => -- ,R+
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
case md(6 downto 5) is
when "00" =>
left_ctrl <= ix_left;
when "01" =>
left_ctrl <= iy_left;
when "10" =>
left_ctrl <= up_left;
when others =>
left_ctrl <= sp_left;
end case;
--
right_ctrl <= zero_right;
alu_ctrl <= alu_st16;
cc_ctrl <= latch_cc;
ea_ctrl <= load_ea;
--
md_ctrl <= latch_md;
addr_ctrl <= idle_ad;
pc_ctrl <= latch_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= postincr1_state;
 
when "0001" => -- ,R++
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
case md(6 downto 5) is
when "00" =>
left_ctrl <= ix_left;
when "01" =>
left_ctrl <= iy_left;
when "10" =>
left_ctrl <= up_left;
when others =>
-- when "11" =>
left_ctrl <= sp_left;
end case;
right_ctrl <= zero_right;
alu_ctrl <= alu_st16;
cc_ctrl <= latch_cc;
ea_ctrl <= load_ea;
--
md_ctrl <= latch_md;
addr_ctrl <= idle_ad;
pc_ctrl <= latch_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= postincr2_state;
 
when "0010" => -- ,-R
case md(6 downto 5) is
when "00" =>
left_ctrl <= ix_left;
ix_ctrl <= load_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "01" =>
left_ctrl <= iy_left;
ix_ctrl <= latch_ix;
iy_ctrl <= load_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "10" =>
left_ctrl <= up_left;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= load_up;
sp_ctrl <= latch_sp;
when others =>
-- when "11" =>
left_ctrl <= sp_left;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= load_sp;
end case;
right_ctrl <= one_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= latch_cc;
ea_ctrl <= load_ea;
--
md_ctrl <= latch_md;
addr_ctrl <= idle_ad;
pc_ctrl <= latch_pc;
--
st_ctrl <= pull_st;
return_state <= fetch_state;
next_state <= saved_state;
 
when "0011" => -- ,--R
case md(6 downto 5) is
when "00" =>
left_ctrl <= ix_left;
ix_ctrl <= load_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "01" =>
left_ctrl <= iy_left;
ix_ctrl <= latch_ix;
iy_ctrl <= load_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "10" =>
left_ctrl <= up_left;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= load_up;
sp_ctrl <= latch_sp;
when others =>
-- when "11" =>
left_ctrl <= sp_left;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= load_sp;
end case;
right_ctrl <= two_right;
alu_ctrl <= alu_sub16;
cc_ctrl <= latch_cc;
ea_ctrl <= load_ea;
--
md_ctrl <= latch_md;
addr_ctrl <= idle_ad;
pc_ctrl <= latch_pc;
--
if md(4) = '0' then
st_ctrl <= pull_st;
return_state <= fetch_state;
next_state <= saved_state;
else
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= indirect_state;
end if;
 
when "0100" => -- ,R (zero offset)
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
case md(6 downto 5) is
when "00" =>
left_ctrl <= ix_left;
when "01" =>
left_ctrl <= iy_left;
when "10" =>
left_ctrl <= up_left;
when others =>
-- when "11" =>
left_ctrl <= sp_left;
end case;
right_ctrl <= zero_right;
alu_ctrl <= alu_st16;
cc_ctrl <= latch_cc;
ea_ctrl <= load_ea;
--
md_ctrl <= latch_md;
addr_ctrl <= idle_ad;
pc_ctrl <= latch_pc;
--
if md(4) = '0' then
st_ctrl <= pull_st;
return_state <= fetch_state;
next_state <= saved_state;
else
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= indirect_state;
end if;
 
when "0101" => -- ACCB,R
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
case md(6 downto 5) is
when "00" =>
left_ctrl <= ix_left;
when "01" =>
left_ctrl <= iy_left;
when "10" =>
left_ctrl <= up_left;
when others =>
-- when "11" =>
left_ctrl <= sp_left;
end case;
right_ctrl <= accb_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
ea_ctrl <= load_ea;
--
md_ctrl <= latch_md;
addr_ctrl <= idle_ad;
pc_ctrl <= latch_pc;
--
if md(4) = '0' then
st_ctrl <= pull_st;
return_state <= fetch_state;
next_state <= saved_state;
else
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= indirect_state;
end if;
 
when "0110" => -- ACCA,R
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
case md(6 downto 5) is
when "00" =>
left_ctrl <= ix_left;
when "01" =>
left_ctrl <= iy_left;
when "10" =>
left_ctrl <= up_left;
when others =>
-- when "11" =>
left_ctrl <= sp_left;
end case;
right_ctrl <= acca_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
ea_ctrl <= load_ea;
--
md_ctrl <= latch_md;
addr_ctrl <= idle_ad;
pc_ctrl <= latch_pc;
--
if md(4) = '0' then
st_ctrl <= pull_st;
return_state <= fetch_state;
next_state <= saved_state;
else
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= indirect_state;
end if;
 
when "0111" => -- undefined
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
case md(6 downto 5) is
when "00" =>
left_ctrl <= ix_left;
when "01" =>
left_ctrl <= iy_left;
when "10" =>
left_ctrl <= up_left;
when others =>
-- when "11" =>
left_ctrl <= sp_left;
end case;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
ea_ctrl <= latch_ea;
--
md_ctrl <= latch_md;
addr_ctrl <= idle_ad;
pc_ctrl <= latch_pc;
--
if md(4) = '0' then
st_ctrl <= pull_st;
return_state <= fetch_state;
next_state <= saved_state;
else
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= indirect_state;
end if;
 
when "1000" => -- offset8,R
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
--
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
ea_ctrl <= latch_ea;
--
md_ctrl <= fetch_first_md; -- pick up 8 bit offset
addr_ctrl <= fetch_ad;
pc_ctrl <= incr_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= index8_state;
 
when "1001" => -- offset16,R
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
--
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
ea_ctrl <= latch_ea;
--
md_ctrl <= fetch_first_md; -- pick up first byte of 16 bit offset
addr_ctrl <= fetch_ad;
pc_ctrl <= incr_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= index16_state;
 
when "1010" => -- undefined
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
case md(6 downto 5) is
when "00" =>
left_ctrl <= ix_left;
when "01" =>
left_ctrl <= iy_left;
when "10" =>
left_ctrl <= up_left;
when others =>
-- when "11" =>
left_ctrl <= sp_left;
end case;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
ea_ctrl <= latch_ea;
--
md_ctrl <= latch_md;
addr_ctrl <= idle_ad;
pc_ctrl <= latch_pc;
--
if md(4) = '0' then
st_ctrl <= pull_st;
return_state <= fetch_state;
next_state <= saved_state;
else
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= indirect_state;
end if;
 
when "1011" => -- ACCD,R
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
case md(6 downto 5) is
when "00" =>
left_ctrl <= ix_left;
when "01" =>
left_ctrl <= iy_left;
when "10" =>
left_ctrl <= up_left;
when others =>
-- when "11" =>
left_ctrl <= sp_left;
end case;
right_ctrl <= accd_right;
alu_ctrl <= alu_add16;
cc_ctrl <= latch_cc;
ea_ctrl <= load_ea;
--
md_ctrl <= latch_md;
addr_ctrl <= idle_ad;
pc_ctrl <= latch_pc;
--
if md(4) = '0' then
st_ctrl <= pull_st;
return_state <= fetch_state;
next_state <= saved_state;
else
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= indirect_state;
end if;
 
when "1100" => -- offset8,PC
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
--
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
ea_ctrl <= latch_ea;
-- fetch 8 bit offset
md_ctrl <= fetch_first_md;
addr_ctrl <= fetch_ad;
pc_ctrl <= incr_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= pcrel8_state;
 
when "1101" => -- offset16,PC
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
--
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
ea_ctrl <= latch_ea;
-- fetch offset
md_ctrl <= fetch_first_md;
addr_ctrl <= fetch_ad;
pc_ctrl <= incr_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= pcrel16_state;
 
when "1110" => -- undefined
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
case md(6 downto 5) is
when "00" =>
left_ctrl <= ix_left;
when "01" =>
left_ctrl <= iy_left;
when "10" =>
left_ctrl <= up_left;
when others =>
-- when "11" =>
left_ctrl <= sp_left;
end case;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
ea_ctrl <= load_ea;
--
md_ctrl <= latch_md;
addr_ctrl <= idle_ad;
pc_ctrl <= latch_pc;
--
if md(4) = '0' then
st_ctrl <= pull_st;
return_state <= fetch_state;
next_state <= saved_state;
else
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= indirect_state;
end if;
 
when others =>
-- when "1111" => -- [,address]
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
-- idle ALU
left_ctrl <= pc_left;
right_ctrl <= zero_right;
alu_ctrl <= alu_nop;
cc_ctrl <= latch_cc;
ea_ctrl <= latch_ea;
-- advance PC to pick up address
md_ctrl <= fetch_first_md;
addr_ctrl <= fetch_ad;
pc_ctrl <= incr_pc;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= indexaddr_state;
end case;
end if;
 
-- load index register with ea plus one
when postincr1_state =>
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
cc_ctrl <= latch_cc;
dp_ctrl <= latch_dp;
iv_ctrl <= latch_iv;
nmi_ctrl <= latch_nmi;
pc_ctrl <= latch_pc;
md_ctrl <= latch_md;
ea_ctrl <= latch_ea;
--
left_ctrl <= ea_left;
right_ctrl <= one_right;
alu_ctrl <= alu_add16;
case md(6 downto 5) is
when "00" =>
ix_ctrl <= load_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "01" =>
ix_ctrl <= latch_ix;
iy_ctrl <= load_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "10" =>
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= load_up;
sp_ctrl <= latch_sp;
when others =>
-- when "11" =>
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= load_sp;
end case;
addr_ctrl <= idle_ad;
dout_ctrl <= md_lo_dout;
-- return to previous state
if md(4) = '0' then
st_ctrl <= pull_st;
return_state <= fetch_state;
next_state <= saved_state;
else
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= indirect_state;
end if;
 
-- load index register with ea plus two
when postincr2_state =>
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
cc_ctrl <= latch_cc;
dp_ctrl <= latch_dp;
iv_ctrl <= latch_iv;
nmi_ctrl <= latch_nmi;
pc_ctrl <= latch_pc;
md_ctrl <= latch_md;
ea_ctrl <= latch_ea;
-- increment register by two (address)
left_ctrl <= ea_left;
right_ctrl <= two_right;
alu_ctrl <= alu_add16;
case md(6 downto 5) is
when "00" =>
ix_ctrl <= load_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "01" =>
ix_ctrl <= latch_ix;
iy_ctrl <= load_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
when "10" =>
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= load_up;
sp_ctrl <= latch_sp;
when others =>
-- when "11" =>
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= load_sp;
end case;
addr_ctrl <= idle_ad;
dout_ctrl <= md_lo_dout;
-- return to previous state
if md(4) = '0' then
st_ctrl <= pull_st;
return_state <= fetch_state;
next_state <= saved_state;
else
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= indirect_state;
end if;
--
-- ea = index register + md (8 bit signed offset)
-- ea holds post byte
--
when index8_state =>
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
cc_ctrl <= latch_cc;
dp_ctrl <= latch_dp;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
nmi_ctrl <= latch_nmi;
pc_ctrl <= latch_pc;
md_ctrl <= latch_md;
case ea(6 downto 5) is
when "00" =>
left_ctrl <= ix_left;
when "01" =>
left_ctrl <= iy_left;
when "10" =>
left_ctrl <= up_left;
when others =>
-- when "11" =>
left_ctrl <= sp_left;
end case;
-- ea = index reg + md
right_ctrl <= md_sign8_right;
alu_ctrl <= alu_add16;
ea_ctrl <= load_ea;
-- idle bus
addr_ctrl <= idle_ad;
dout_ctrl <= md_lo_dout;
-- return to previous state
if ea(4) = '0' then
st_ctrl <= pull_st;
return_state <= fetch_state;
next_state <= saved_state;
else
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= indirect_state;
end if;
 
-- fetch low byte of 16 bit indexed offset
when index16_state =>
op_ctrl <= latch_op;
pre_ctrl <= latch_pre;
acca_ctrl <= latch_acca;
accb_ctrl <= latch_accb;
cc_ctrl <= latch_cc;
dp_ctrl <= latch_dp;
ix_ctrl <= latch_ix;
iy_ctrl <= latch_iy;
up_ctrl <= latch_up;
sp_ctrl <= latch_sp;
iv_ctrl <= latch_iv;
nmi_ctrl <= latch_nmi;
-- advance pc
left_ctrl <= pc_left;
right_ctrl <= one_right;
alu_ctrl <= alu_add16;
pc_ctrl <= incr_pc;
-- fetch low byte
ea_ctrl <= latch_ea;
md_ctrl <= fetch_next_md;
addr_ctrl <= fetch_ad;
dout_ctrl <= md_lo_dout;
--
st_ctrl <= idle_st;
return_state <= fetch_state;
next_state <= index16_2_state;
 
-- ea = index register + md (16 bit offset)
-- ea holds post byte
when index16_2_state =>
op_ctrl <= latch_op;
+ acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + iv_ctrl <= latch_iv; + nmi_ctrl <= latch_nmi; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + case ea(6 downto 5) is + when "00" => + left_ctrl <= ix_left; + when "01" => + left_ctrl <= iy_left; + when "10" => + left_ctrl <= up_left; + when others => + -- when "11" => + left_ctrl <= sp_left; + end case; + -- ea = index reg + md + right_ctrl <= md_right; + alu_ctrl <= alu_add16; + ea_ctrl <= load_ea; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- return to previous state + if ea(4) = '0' then + st_ctrl <= pull_st; + return_state <= fetch_state; + next_state <= saved_state; + else + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= indirect_state; + end if; + -- + -- pc relative with 8 bit signed offest + -- md holds signed offset + -- + when pcrel8_state => + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + iv_ctrl <= latch_iv; + nmi_ctrl <= latch_nmi; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + -- ea = pc + signed md + left_ctrl <= pc_left; + right_ctrl <= md_sign8_right; + alu_ctrl <= alu_add16; + ea_ctrl <= load_ea; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- return to previous state + if ea(4) = '0' then + st_ctrl <= pull_st; + return_state <= fetch_state; + next_state <= saved_state; + else + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= indirect_state; + end if; + + -- pc relative addressing with 16 bit offset + -- pick up the low byte of the offset in md + -- advance the pc + when pcrel16_state => + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + iv_ctrl <= latch_iv; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- advance pc + left_ctrl <= pc_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_nop; + pc_ctrl <= incr_pc; + -- fetch low byte + ea_ctrl <= latch_ea; + md_ctrl <= fetch_next_md; + addr_ctrl <= fetch_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= pcrel16_2_state; + + -- pc relative with16 bit signed offest + -- md holds signed offset + when pcrel16_2_state => + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + iv_ctrl <= latch_iv; + nmi_ctrl <= latch_nmi; + pc_ctrl <= latch_pc; + -- ea = pc + md + left_ctrl <= pc_left; + right_ctrl <= md_right; + alu_ctrl <= alu_add16; + ea_ctrl <= load_ea; + md_ctrl <= latch_md; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- return to previous state + if ea(4) = '0' then + st_ctrl <= pull_st; + return_state <= fetch_state; + next_state <= saved_state; + else + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= indirect_state; + end if; + + -- indexed to absolute address + -- md holds address + -- ea hold indexing mode byte + when indexaddr2_state => + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + iv_ctrl <= latch_iv; + nmi_ctrl <= latch_nmi; + pc_ctrl <= latch_pc; + -- ea = md + left_ctrl <= pc_left; + right_ctrl <= md_right; + alu_ctrl <= alu_ld16; + ea_ctrl <= load_ea; + md_ctrl <= latch_md; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- return to previous state + if ea(4) = '0' then + st_ctrl <= pull_st; + return_state <= fetch_state; + next_state <= saved_state; + else + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= indirect_state; + end if; + + -- indexed to address + -- pick up the low byte of the address + -- advance the pc + when indexaddr_state => + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- advance pc + left_ctrl <= pc_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_nop; + pc_ctrl <= incr_pc; + -- fetch low byte + md_ctrl <= fetch_next_md; + addr_ctrl <= read_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= indexaddr2_state; + -- + -- load md with high byte of indirect address + -- pointed to by ea + -- increment ea + -- + when indirect_state => + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + pc_ctrl <= latch_pc; + -- increment ea + left_ctrl <= ea_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + ea_ctrl <= load_ea; + -- fetch high byte + md_ctrl <= fetch_first_md; + addr_ctrl <= read_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= indirect2_state; + -- + -- load md with low byte of indirect address + -- pointed to by ea + -- ea has previously been incremented + -- + when indirect2_state => + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + pc_ctrl <= latch_pc; + -- idle ea + left_ctrl <= ea_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_nop; + ea_ctrl <= latch_ea; + -- fetch high byte + md_ctrl <= fetch_next_md; + addr_ctrl <= read_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= indirect3_state; + -- + -- complete idirect addressing + -- by loading ea with md + -- + when indirect3_state => + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + pc_ctrl <= latch_pc; + -- load ea with md + left_ctrl <= ea_left; + right_ctrl <= md_right; + alu_ctrl <= alu_ld16; + ea_ctrl <= load_ea; + -- idle cycle + md_ctrl <= latch_md; + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- return to previous state + st_ctrl <= pull_st; + return_state <= fetch_state; + next_state <= saved_state; + + -- + -- ea holds the low byte of the absolute address + -- Move ea low byte into ea high byte + -- load new ea low byte to for absolute 16 bit address + -- advance the program counter + -- + when extended_state => -- fetch ea low byte + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + -- increment pc + left_ctrl <= pc_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_nop; + cc_ctrl <= latch_cc; + pc_ctrl <= incr_pc; + -- fetch next effective address bytes + ea_ctrl <= fetch_next_ea; + addr_ctrl <= fetch_ad; + dout_ctrl <= md_lo_dout; + -- return to previous state + st_ctrl <= pull_st; + return_state <= fetch_state; + next_state <= saved_state; + + when lea_state => -- here on load effective address + op_ctrl <= latch_op; + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + iv_ctrl <= latch_iv; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + md_ctrl <= latch_md; + ea_ctrl <= latch_ea; + pc_ctrl <= latch_pc; + -- load index register with effective address + left_ctrl <= pc_left; + right_ctrl <= ea_right; + alu_ctrl <= alu_ld16; + case op_code(3 downto 0) is + when "0000" => -- leax + ix_ctrl <= load_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + when "0001" => -- leay + ix_ctrl <= latch_ix; + iy_ctrl <= load_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + when "0010" => -- leas + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= load_sp; + when "0011" => -- leau + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= load_up; + sp_ctrl <= latch_sp; + when others => + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + end case; + -- idle the bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= fetch_state; + + -- + -- jump to subroutine + -- (sp)=pc_lo + -- sp=sp-1 + -- call push_return_hi_state to save hi pc + -- return to jmp_state + -- + when jsr_state => + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + md_ctrl <= latch_md; + ea_ctrl <= latch_ea; + pc_ctrl <= latch_pc; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write pc lo byte + addr_ctrl <= pushs_ad; + dout_ctrl <= pc_lo_dout; + -- call second half of push_return_state + st_ctrl <= push_st; + return_state <= jmp_state; + next_state <= push_return_hi_state; + + -- + -- Load pc with ea + -- (JMP) + -- + when jmp_state => + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + md_ctrl <= latch_md; + ea_ctrl <= latch_ea; + -- load PC with effective address + left_ctrl <= pc_left; + right_ctrl <= ea_right; + alu_ctrl <= alu_ld16; + pc_ctrl <= load_pc; + -- idle the bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= fetch_state; + + -- + -- long branch or branch to subroutine + -- pick up next md byte + -- md_hi = md_lo + -- md_lo = (pc) + -- pc=pc+1 + -- if a lbsr push return address + -- continue to sbranch_state + -- to evaluate conditional branches + -- + when lbranch_state => + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- + left_ctrl <= pc_left; + right_ctrl <= ea_right; + alu_ctrl <= alu_ld16; + pc_ctrl <= incr_pc; + -- fetch the next byte into md_lo + md_ctrl <= fetch_next_md; + addr_ctrl <= fetch_ad; + dout_ctrl <= md_lo_dout; + -- if lbsr - push return address + -- then continue on to short branch + if op_code = "00010111" then + st_ctrl <= push_st; + return_state <= sbranch_state; + next_state <= push_return_lo_state; + else + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= sbranch_state; + end if; + + -- + -- here to execute conditional branch + -- short conditional branch md = signed 8 bit offset + -- long branch md = 16 bit offset + -- + when sbranch_state => + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + md_ctrl <= latch_md; + -- + left_ctrl <= pc_left; + right_ctrl <= md_right; + alu_ctrl <= alu_add16; + -- + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= fetch_state; + if op_code(7 downto 4) = "0010" then -- conditional branch + case op_code(3 downto 0) is + when "0000" => -- bra + cond_true := (1 = 1); + when "0001" => -- brn + cond_true := (1 = 0); + when "0010" => -- bhi + cond_true := ((cc(CBIT) or cc(ZBIT)) = '0'); + when "0011" => -- bls + cond_true := ((cc(CBIT) or cc(ZBIT)) = '1'); + when "0100" => -- bcc/bhs + cond_true := (cc(CBIT) = '0'); + when "0101" => -- bcs/blo + cond_true := (cc(CBIT) = '1'); + when "0110" => -- bne + cond_true := (cc(ZBIT) = '0'); + when "0111" => -- beq + cond_true := (cc(ZBIT) = '1'); + when "1000" => -- bvc + cond_true := (cc(VBIT) = '0'); + when "1001" => -- bvs + cond_true := (cc(VBIT) = '1'); + when "1010" => -- bpl + cond_true := (cc(NBIT) = '0'); + when "1011" => -- bmi + cond_true := (cc(NBIT) = '1'); + when "1100" => -- bge + cond_true := ((cc(NBIT) xor cc(VBIT)) = '0'); + when "1101" => -- blt + cond_true := ((cc(NBIT) xor cc(VBIT)) = '1'); + when "1110" => -- bgt + cond_true := ((cc(ZBIT) or (cc(NBIT) xor cc(VBIT))) = '0'); + when "1111" => -- ble + cond_true := ((cc(ZBIT) or (cc(NBIT) xor cc(VBIT))) = '1'); + when others => + cond_true := (1 = 1); + end case; + else + cond_true := (1 = 1); -- lbra, lbsr, bsr + end if; + if cond_true then + pc_ctrl <= load_pc; + else + pc_ctrl <= latch_pc; + end if; + + -- + -- push return address onto the S stack + -- + -- (sp) = pc_lo + -- sp = sp - 1 + -- + when push_return_lo_state => + -- default + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement the sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + cc_ctrl <= latch_cc; + sp_ctrl <= load_sp; + -- write PC low + pc_ctrl <= latch_pc; + addr_ctrl <= pushs_ad; + dout_ctrl <= pc_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= push_return_hi_state; + + -- + -- push program counter hi byte onto the stack + -- (sp) = pc_hi + -- sp = sp + -- return to originating state + -- + when push_return_hi_state => + -- default + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- idle the SP + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + cc_ctrl <= latch_cc; + sp_ctrl <= latch_sp; + -- write pc hi bytes + pc_ctrl <= latch_pc; + addr_ctrl <= pushs_ad; + dout_ctrl <= pc_hi_dout; + -- + st_ctrl <= pull_st; + return_state <= fetch_state; + next_state <= saved_state; + + when pull_return_hi_state => + -- default + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment the sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + cc_ctrl <= latch_cc; + sp_ctrl <= load_sp; + -- read pc hi + pc_ctrl <= pull_hi_pc; + addr_ctrl <= pulls_ad; + dout_ctrl <= pc_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= pull_return_lo_state; + + when pull_return_lo_state => + -- default + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment the SP + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + cc_ctrl <= latch_cc; + sp_ctrl <= load_sp; + -- read pc low + pc_ctrl <= pull_lo_pc; + addr_ctrl <= pulls_ad; + dout_ctrl <= pc_lo_dout; + -- + st_ctrl <= pull_st; + return_state <= fetch_state; + next_state <= saved_state; + + when andcc_state => + -- default + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + md_ctrl <= latch_md; + -- AND CC with md + left_ctrl <= md_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_andcc; + cc_ctrl <= load_cc; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= pull_st; + return_state <= fetch_state; + next_state <= saved_state; + + when orcc_state => + -- default + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + md_ctrl <= latch_md; + -- OR CC with md + left_ctrl <= md_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_orcc; + cc_ctrl <= load_cc; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= pull_st; + return_state <= fetch_state; + next_state <= saved_state; + + when tfr_state => + -- default + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + md_ctrl <= latch_md; + -- select source register + case md(7 downto 4) is + when "0000" => + left_ctrl <= accd_left; + when "0001" => + left_ctrl <= ix_left; + when "0010" => + left_ctrl <= iy_left; + when "0011" => + left_ctrl <= up_left; + when "0100" => + left_ctrl <= sp_left; + when "0101" => + left_ctrl <= pc_left; + when "1000" => + left_ctrl <= acca_left; + when "1001" => + left_ctrl <= accb_left; + when "1010" => + left_ctrl <= cc_left; + when "1011" => + left_ctrl <= dp_left; + when others => + left_ctrl <= md_left; + end case; + right_ctrl <= zero_right; + alu_ctrl <= alu_tfr; + -- select destination register + case md(3 downto 0) is + when "0000" => -- accd + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + when "0001" => -- ix + ix_ctrl <= load_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + when "0010" => -- iy + ix_ctrl <= latch_ix; + iy_ctrl <= load_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + when "0011" => -- up + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= load_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + when "0100" => -- sp + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= load_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + when "0101" => -- pc + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= load_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + when "1000" => -- acca + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= load_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + when "1001" => -- accb + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= load_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + when "1010" => -- cc + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= load_cc; + dp_ctrl <= latch_dp; + when "1011" => --dp + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= load_dp; + when others => + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + end case; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= pull_st; + return_state <= fetch_state; + next_state <= saved_state; + + when exg_state => + -- default + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + md_ctrl <= latch_md; + -- save destination register + case md(3 downto 0) is + when "0000" => + left_ctrl <= accd_left; + when "0001" => + left_ctrl <= ix_left; + when "0010" => + left_ctrl <= iy_left; + when "0011" => + left_ctrl <= up_left; + when "0100" => + left_ctrl <= sp_left; + when "0101" => + left_ctrl <= pc_left; + when "1000" => + left_ctrl <= acca_left; + when "1001" => + left_ctrl <= accb_left; + when "1010" => + left_ctrl <= cc_left; + when "1011" => + left_ctrl <= dp_left; + when others => + left_ctrl <= md_left; + end case; + right_ctrl <= zero_right; + alu_ctrl <= alu_tfr; + ea_ctrl <= load_ea; + + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- call tranfer microcode + st_ctrl <= push_st; + return_state <= exg1_state; + next_state <= tfr_state; + + when exg1_state => + -- default + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + md_ctrl <= latch_md; + -- restore destination + left_ctrl <= ea_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_tfr; + -- save as source register + case md(7 downto 4) is + when "0000" => -- accd + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + when "0001" => -- ix + ix_ctrl <= load_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + when "0010" => -- iy + ix_ctrl <= latch_ix; + iy_ctrl <= load_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + when "0011" => -- up + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= load_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + when "0100" => -- sp + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= load_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + when "0101" => -- pc + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= load_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + when "1000" => -- acca + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= load_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + when "1001" => -- accb + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= load_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + when "1010" => -- cc + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= load_cc; + dp_ctrl <= latch_dp; + when "1011" => --dp + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= load_dp; + when others => + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + dp_ctrl <= latch_dp; + end case; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= fetch_state; + + when mul_state => + -- default + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- move acca to md + left_ctrl <= acca_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_st16; + cc_ctrl <= latch_cc; + md_ctrl <= load_md; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= mulea_state; + + when mulea_state => + -- default + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + md_ctrl <= latch_md; + -- move accb to ea + left_ctrl <= accb_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_st16; + cc_ctrl <= latch_cc; + ea_ctrl <= load_ea; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= muld_state; + + when muld_state => + -- default + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + md_ctrl <= latch_md; + -- clear accd + left_ctrl <= acca_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_ld8; + cc_ctrl <= latch_cc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= mul0_state; + + when mul0_state => + -- default + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- if bit 0 of ea set, add accd to md + left_ctrl <= accd_left; + right_ctrl <= md_right; + alu_ctrl <= alu_add16; + if ea(0) = '1' then + cc_ctrl <= load_cc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + else + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + end if; + md_ctrl <= shiftl_md; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= mul1_state; + + when mul1_state => + -- default + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- if bit 1 of ea set, add accd to md + left_ctrl <= accd_left; + right_ctrl <= md_right; + alu_ctrl <= alu_add16; + if ea(1) = '1' then + cc_ctrl <= load_cc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + else + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + end if; + md_ctrl <= shiftl_md; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= mul2_state; + + when mul2_state => + -- default + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- if bit 2 of ea set, add accd to md + left_ctrl <= accd_left; + right_ctrl <= md_right; + alu_ctrl <= alu_add16; + if ea(2) = '1' then + cc_ctrl <= load_cc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + else + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + end if; + md_ctrl <= shiftl_md; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= mul3_state; + + when mul3_state => + -- default + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- if bit 3 of ea set, add accd to md + left_ctrl <= accd_left; + right_ctrl <= md_right; + alu_ctrl <= alu_add16; + if ea(3) = '1' then + cc_ctrl <= load_cc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + else + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + end if; + md_ctrl <= shiftl_md; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= mul4_state; + + when mul4_state => + -- default + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + nmi_ctrl <= latch_nmi; + pre_ctrl <= latch_pre; + ea_ctrl <= latch_ea; + -- if bit 4 of ea set, add accd to md + left_ctrl <= accd_left; + right_ctrl <= md_right; + alu_ctrl <= alu_add16; + if ea(4) = '1' then + cc_ctrl <= load_cc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + else + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + end if; + md_ctrl <= shiftl_md; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= mul5_state; + + when mul5_state => + -- default + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- if bit 5 of ea set, add accd to md + left_ctrl <= accd_left; + right_ctrl <= md_right; + alu_ctrl <= alu_add16; + if ea(5) = '1' then + cc_ctrl <= load_cc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + else + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + end if; + md_ctrl <= shiftl_md; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= mul6_state; + + when mul6_state => + -- default + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- if bit 6 of ea set, add accd to md + left_ctrl <= accd_left; + right_ctrl <= md_right; + alu_ctrl <= alu_add16; + if ea(6) = '1' then + cc_ctrl <= load_cc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + else + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + end if; + md_ctrl <= shiftl_md; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= mul7_state; + + when mul7_state => + -- default + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- if bit 7 of ea set, add accd to md + left_ctrl <= accd_left; + right_ctrl <= md_right; + alu_ctrl <= alu_add16; + if ea(7) = '1' then + cc_ctrl <= load_cc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + else + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + end if; + md_ctrl <= shiftl_md; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= fetch_state; + + -- + -- Enter here on pushs + -- ea holds post byte + -- + when pshs_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp if any registers to be pushed + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(7 downto 0) = "00000000" then + sp_ctrl <= latch_sp; + else + sp_ctrl <= load_sp; + end if; + -- write idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(7) = '1' then + next_state <= pshs_pcl_state; + elsif ea(6) = '1' then + next_state <= pshs_upl_state; + elsif ea(5) = '1' then + next_state <= pshs_iyl_state; + elsif ea(4) = '1' then + next_state <= pshs_ixl_state; + elsif ea(3) = '1' then + next_state <= pshs_dp_state; + elsif ea(2) = '1' then + next_state <= pshs_accb_state; + elsif ea(1) = '1' then + next_state <= pshs_acca_state; + elsif ea(0) = '1' then + next_state <= pshs_cc_state; + else + next_state <= fetch_state; + end if; + + when pshs_pcl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write pc low + addr_ctrl <= pushs_ad; + dout_ctrl <= pc_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= pshs_pch_state; + + when pshs_pch_state => + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(6 downto 0) = "0000000" then + sp_ctrl <= latch_sp; + else + sp_ctrl <= load_sp; + end if; + -- write pc hi + addr_ctrl <= pushs_ad; + dout_ctrl <= pc_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(6) = '1' then + next_state <= pshs_upl_state; + elsif ea(5) = '1' then + next_state <= pshs_iyl_state; + elsif ea(4) = '1' then + next_state <= pshs_ixl_state; + elsif ea(3) = '1' then + next_state <= pshs_dp_state; + elsif ea(2) = '1' then + next_state <= pshs_accb_state; + elsif ea(1) = '1' then + next_state <= pshs_acca_state; + elsif ea(0) = '1' then + next_state <= pshs_cc_state; + else + next_state <= fetch_state; + end if; + + + when pshs_upl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write pc low + addr_ctrl <= pushs_ad; + dout_ctrl <= up_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= pshs_uph_state; + + when pshs_uph_state => + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(5 downto 0) = "000000" then + sp_ctrl <= latch_sp; + else + sp_ctrl <= load_sp; + end if; + -- write pc hi + addr_ctrl <= pushs_ad; + dout_ctrl <= up_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(5) = '1' then + next_state <= pshs_iyl_state; + elsif ea(4) = '1' then + next_state <= pshs_ixl_state; + elsif ea(3) = '1' then + next_state <= pshs_dp_state; + elsif ea(2) = '1' then + next_state <= pshs_accb_state; + elsif ea(1) = '1' then + next_state <= pshs_acca_state; + elsif ea(0) = '1' then + next_state <= pshs_cc_state; + else + next_state <= fetch_state; + end if; + + when pshs_iyl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write iy low + addr_ctrl <= pushs_ad; + dout_ctrl <= iy_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= pshs_iyh_state; + + when pshs_iyh_state => + -- default registers + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(4 downto 0) = "00000" then + sp_ctrl <= latch_sp; + else + sp_ctrl <= load_sp; + end if; + -- write iy hi + addr_ctrl <= pushs_ad; + dout_ctrl <= iy_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(4) = '1' then + next_state <= pshs_ixl_state; + elsif ea(3) = '1' then + next_state <= pshs_dp_state; + elsif ea(2) = '1' then + next_state <= pshs_accb_state; + elsif ea(1) = '1' then + next_state <= pshs_acca_state; + elsif ea(0) = '1' then + next_state <= pshs_cc_state; + else + next_state <= fetch_state; + end if; + + when pshs_ixl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write ix low + addr_ctrl <= pushs_ad; + dout_ctrl <= ix_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= pshs_ixh_state; + + when pshs_ixh_state => + -- default registers + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(3 downto 0) = "0000" then + sp_ctrl <= latch_sp; + else + sp_ctrl <= load_sp; + end if; + -- write ix hi + addr_ctrl <= pushs_ad; + dout_ctrl <= ix_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(3) = '1' then + next_state <= pshs_dp_state; + elsif ea(2) = '1' then + next_state <= pshs_accb_state; + elsif ea(1) = '1' then + next_state <= pshs_acca_state; + elsif ea(0) = '1' then + next_state <= pshs_cc_state; + else + next_state <= fetch_state; + end if; + + when pshs_dp_state => + -- default registers + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(2 downto 0) = "000" then + sp_ctrl <= latch_sp; + else + sp_ctrl <= load_sp; + end if; + -- write dp + addr_ctrl <= pushs_ad; + dout_ctrl <= dp_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(2) = '1' then + next_state <= pshs_accb_state; + elsif ea(1) = '1' then + next_state <= pshs_acca_state; + elsif ea(0) = '1' then + next_state <= pshs_cc_state; + else + next_state <= fetch_state; + end if; + + when pshs_accb_state => + -- default registers + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(1 downto 0) = "00" then + sp_ctrl <= latch_sp; + else + sp_ctrl <= load_sp; + end if; + -- write accb + addr_ctrl <= pushs_ad; + dout_ctrl <= accb_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(1) = '1' then + next_state <= pshs_acca_state; + elsif ea(0) = '1' then + next_state <= pshs_cc_state; + else + next_state <= fetch_state; + end if; + + when pshs_acca_state => + -- default registers + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(0) = '1' then + sp_ctrl <= load_sp; + else + sp_ctrl <= latch_sp; + end if; + -- write acca + addr_ctrl <= pushs_ad; + dout_ctrl <= acca_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(0) = '1' then + next_state <= pshs_cc_state; + else + next_state <= fetch_state; + end if; + + when pshs_cc_state => + -- default registers + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- idle sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_nop; + sp_ctrl <= latch_sp; + -- write cc + addr_ctrl <= pushs_ad; + dout_ctrl <= cc_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= fetch_state; + + -- + -- enter here on PULS + -- ea hold register mask + -- + when puls_state => + -- default registers + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- idle SP + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= latch_sp; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(0) = '1' then + next_state <= puls_cc_state; + elsif ea(1) = '1' then + next_state <= puls_acca_state; + elsif ea(2) = '1' then + next_state <= puls_accb_state; + elsif ea(3) = '1' then + next_state <= puls_dp_state; + elsif ea(4) = '1' then + next_state <= puls_ixh_state; + elsif ea(5) = '1' then + next_state <= puls_iyh_state; + elsif ea(6) = '1' then + next_state <= puls_uph_state; + elsif ea(7) = '1' then + next_state <= puls_pch_state; + else + next_state <= fetch_state; + end if; + + when puls_cc_state => + -- default registers + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- Increment SP + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read cc + cc_ctrl <= pull_cc; + addr_ctrl <= pulls_ad; + dout_ctrl <= cc_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(1) = '1' then + next_state <= puls_acca_state; + elsif ea(2) = '1' then + next_state <= puls_accb_state; + elsif ea(3) = '1' then + next_state <= puls_dp_state; + elsif ea(4) = '1' then + next_state <= puls_ixh_state; + elsif ea(5) = '1' then + next_state <= puls_iyh_state; + elsif ea(6) = '1' then + next_state <= puls_uph_state; + elsif ea(7) = '1' then + next_state <= puls_pch_state; + else + next_state <= fetch_state; + end if; + + when puls_acca_state => + -- default registers + cc_ctrl <= latch_cc; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- Increment SP + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read acca + acca_ctrl <= pull_acca; + addr_ctrl <= pulls_ad; + dout_ctrl <= acca_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(2) = '1' then + next_state <= puls_accb_state; + elsif ea(3) = '1' then + next_state <= puls_dp_state; + elsif ea(4) = '1' then + next_state <= puls_ixh_state; + elsif ea(5) = '1' then + next_state <= puls_iyh_state; + elsif ea(6) = '1' then + next_state <= puls_uph_state; + elsif ea(7) = '1' then + next_state <= puls_pch_state; + else + next_state <= fetch_state; + end if; + + when puls_accb_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- Increment SP + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read accb + accb_ctrl <= pull_accb; + addr_ctrl <= pulls_ad; + dout_ctrl <= accb_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(3) = '1' then + next_state <= puls_dp_state; + elsif ea(4) = '1' then + next_state <= puls_ixh_state; + elsif ea(5) = '1' then + next_state <= puls_iyh_state; + elsif ea(6) = '1' then + next_state <= puls_uph_state; + elsif ea(7) = '1' then + next_state <= puls_pch_state; + else + next_state <= fetch_state; + end if; + + when puls_dp_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- idle sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read dp + dp_ctrl <= pull_dp; + addr_ctrl <= pulls_ad; + dout_ctrl <= dp_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(4) = '1' then + next_state <= puls_ixh_state; + elsif ea(5) = '1' then + next_state <= puls_iyh_state; + elsif ea(6) = '1' then + next_state <= puls_uph_state; + elsif ea(7) = '1' then + next_state <= puls_pch_state; + else + next_state <= fetch_state; + end if; + + when puls_ixh_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- pull ix hi + ix_ctrl <= pull_hi_ix; + addr_ctrl <= pulls_ad; + dout_ctrl <= ix_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= puls_ixl_state; + + when puls_ixl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- idle sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read ix low + ix_ctrl <= pull_lo_ix; + addr_ctrl <= pulls_ad; + dout_ctrl <= ix_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(5) = '1' then + next_state <= puls_iyh_state; + elsif ea(6) = '1' then + next_state <= puls_uph_state; + elsif ea(7) = '1' then + next_state <= puls_pch_state; + else + next_state <= fetch_state; + end if; + + when puls_iyh_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- pull iy hi + iy_ctrl <= pull_hi_iy; + addr_ctrl <= pulls_ad; + dout_ctrl <= iy_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= puls_iyl_state; + + when puls_iyl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read iy low + iy_ctrl <= pull_lo_iy; + addr_ctrl <= pulls_ad; + dout_ctrl <= iy_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(6) = '1' then + next_state <= puls_uph_state; + elsif ea(7) = '1' then + next_state <= puls_pch_state; + else + next_state <= fetch_state; + end if; + + when puls_uph_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- pull up hi + up_ctrl <= pull_hi_up; + addr_ctrl <= pulls_ad; + dout_ctrl <= up_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= puls_upl_state; + + when puls_upl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read up low + up_ctrl <= pull_lo_up; + addr_ctrl <= pulls_ad; + dout_ctrl <= up_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(7) = '1' then + next_state <= puls_pch_state; + else + next_state <= fetch_state; + end if; + + when puls_pch_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- pull pc hi + pc_ctrl <= pull_hi_pc; + addr_ctrl <= pulls_ad; + dout_ctrl <= pc_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= puls_pcl_state; + + when puls_pcl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read pc low + pc_ctrl <= pull_lo_pc; + addr_ctrl <= pulls_ad; + dout_ctrl <= pc_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= fetch_state; + + -- + -- Enter here on pshu + -- ea holds post byte + -- + when pshu_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + dp_ctrl <= latch_dp; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp if any registers to be pushed + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(7 downto 0) = "00000000" then + up_ctrl <= latch_up; + else + up_ctrl <= load_up; + end if; + -- write idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(7) = '1' then + next_state <= pshu_pcl_state; + elsif ea(6) = '1' then + next_state <= pshu_spl_state; + elsif ea(5) = '1' then + next_state <= pshu_iyl_state; + elsif ea(4) = '1' then + next_state <= pshu_ixl_state; + elsif ea(3) = '1' then + next_state <= pshu_dp_state; + elsif ea(2) = '1' then + next_state <= pshu_accb_state; + elsif ea(1) = '1' then + next_state <= pshu_acca_state; + elsif ea(0) = '1' then + next_state <= pshu_cc_state; + else + next_state <= fetch_state; + end if; + -- + -- push PC onto U stack + -- + when pshu_pcl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + up_ctrl <= load_up; + -- write pc low + addr_ctrl <= pushs_ad; + dout_ctrl <= pc_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= pshu_pch_state; + + when pshu_pch_state => + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(6 downto 0) = "0000000" then + up_ctrl <= latch_up; + else + up_ctrl <= load_up; + end if; + -- write pc hi + addr_ctrl <= pushu_ad; + dout_ctrl <= pc_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(6) = '1' then + next_state <= pshu_spl_state; + elsif ea(5) = '1' then + next_state <= pshu_iyl_state; + elsif ea(4) = '1' then + next_state <= pshu_ixl_state; + elsif ea(3) = '1' then + next_state <= pshu_dp_state; + elsif ea(2) = '1' then + next_state <= pshu_accb_state; + elsif ea(1) = '1' then + next_state <= pshu_acca_state; + elsif ea(0) = '1' then + next_state <= pshu_cc_state; + else + next_state <= fetch_state; + end if; + + when pshu_spl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + up_ctrl <= load_up; + -- write pc low + addr_ctrl <= pushu_ad; + dout_ctrl <= sp_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= pshu_sph_state; + + when pshu_sph_state => + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(5 downto 0) = "000000" then + up_ctrl <= latch_up; + else + up_ctrl <= load_up; + end if; + -- write sp hi + addr_ctrl <= pushu_ad; + dout_ctrl <= sp_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(5) = '1' then + next_state <= pshu_iyl_state; + elsif ea(4) = '1' then + next_state <= pshu_ixl_state; + elsif ea(3) = '1' then + next_state <= pshu_dp_state; + elsif ea(2) = '1' then + next_state <= pshu_accb_state; + elsif ea(1) = '1' then + next_state <= pshu_acca_state; + elsif ea(0) = '1' then + next_state <= pshu_cc_state; + else + next_state <= fetch_state; + end if; + + when pshu_iyl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + up_ctrl <= load_up; + -- write iy low + addr_ctrl <= pushu_ad; + dout_ctrl <= iy_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= pshu_iyh_state; + + when pshu_iyh_state => + -- default registers + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(4 downto 0) = "00000" then + up_ctrl <= latch_up; + else + up_ctrl <= load_up; + end if; + -- write iy hi + addr_ctrl <= pushu_ad; + dout_ctrl <= iy_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(4) = '1' then + next_state <= pshu_ixl_state; + elsif ea(3) = '1' then + next_state <= pshu_dp_state; + elsif ea(2) = '1' then + next_state <= pshu_accb_state; + elsif ea(1) = '1' then + next_state <= pshu_acca_state; + elsif ea(0) = '1' then + next_state <= pshu_cc_state; + else + next_state <= fetch_state; + end if; + + when pshu_ixl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + up_ctrl <= load_up; + -- write ix low + addr_ctrl <= pushu_ad; + dout_ctrl <= ix_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= pshu_ixh_state; + + when pshu_ixh_state => + -- default registers + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(3 downto 0) = "0000" then + up_ctrl <= latch_up; + else + up_ctrl <= load_up; + end if; + -- write ix hi + addr_ctrl <= pushu_ad; + dout_ctrl <= ix_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(3) = '1' then + next_state <= pshu_dp_state; + elsif ea(2) = '1' then + next_state <= pshu_accb_state; + elsif ea(1) = '1' then + next_state <= pshu_acca_state; + elsif ea(0) = '1' then + next_state <= pshu_cc_state; + else + next_state <= fetch_state; + end if; + + when pshu_dp_state => + -- default registers + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(2 downto 0) = "000" then + up_ctrl <= latch_up; + else + up_ctrl <= load_up; + end if; + -- write accb + addr_ctrl <= pushu_ad; + dout_ctrl <= dp_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(2) = '1' then + next_state <= pshu_accb_state; + elsif ea(1) = '1' then + next_state <= pshu_acca_state; + elsif ea(0) = '1' then + next_state <= pshu_cc_state; + else + next_state <= fetch_state; + end if; + + when pshu_accb_state => + -- default registers + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(1 downto 0) = "00" then + up_ctrl <= latch_up; + else + up_ctrl <= load_up; + end if; + -- write accb + addr_ctrl <= pushu_ad; + dout_ctrl <= accb_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(1) = '1' then + next_state <= pshu_acca_state; + elsif ea(0) = '1' then + next_state <= pshu_cc_state; + else + next_state <= fetch_state; + end if; + + when pshu_acca_state => + -- default registers + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(0) = '0' then + up_ctrl <= latch_up; + else + up_ctrl <= load_up; + end if; + -- write acca + addr_ctrl <= pushu_ad; + dout_ctrl <= acca_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(0) = '1' then + next_state <= pshu_cc_state; + else + next_state <= fetch_state; + end if; + + when pshu_cc_state => + -- default registers + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- idle sp + left_ctrl <= up_left; + right_ctrl <= one_right; + cc_ctrl <= latch_cc; + alu_ctrl <= alu_nop; + up_ctrl <= latch_up; + -- write cc + addr_ctrl <= pushu_ad; + dout_ctrl <= cc_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= fetch_state; + + -- + -- enter here on PULU + -- ea hold register mask + -- + when pulu_state => + -- default registers + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- idle UP + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= latch_up; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(0) = '1' then + next_state <= pulu_cc_state; + elsif ea(1) = '1' then + next_state <= pulu_acca_state; + elsif ea(2) = '1' then + next_state <= pulu_accb_state; + elsif ea(3) = '1' then + next_state <= pulu_dp_state; + elsif ea(4) = '1' then + next_state <= pulu_ixh_state; + elsif ea(5) = '1' then + next_state <= pulu_iyh_state; + elsif ea(6) = '1' then + next_state <= pulu_sph_state; + elsif ea(7) = '1' then + next_state <= pulu_pch_state; + else + next_state <= fetch_state; + end if; + + when pulu_cc_state => + -- default registers + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- read cc + cc_ctrl <= pull_cc; + addr_ctrl <= pullu_ad; + dout_ctrl <= cc_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(1) = '1' then + next_state <= pulu_acca_state; + elsif ea(2) = '1' then + next_state <= pulu_accb_state; + elsif ea(3) = '1' then + next_state <= pulu_dp_state; + elsif ea(4) = '1' then + next_state <= pulu_ixh_state; + elsif ea(5) = '1' then + next_state <= pulu_iyh_state; + elsif ea(6) = '1' then + next_state <= pulu_sph_state; + elsif ea(7) = '1' then + next_state <= pulu_pch_state; + else + next_state <= fetch_state; + end if; + + when pulu_acca_state => + -- default registers + cc_ctrl <= latch_cc; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- read acca + acca_ctrl <= pull_acca; + addr_ctrl <= pullu_ad; + dout_ctrl <= acca_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(2) = '1' then + next_state <= pulu_accb_state; + elsif ea(3) = '1' then + next_state <= pulu_dp_state; + elsif ea(4) = '1' then + next_state <= pulu_ixh_state; + elsif ea(5) = '1' then + next_state <= pulu_iyh_state; + elsif ea(6) = '1' then + next_state <= pulu_sph_state; + elsif ea(7) = '1' then + next_state <= pulu_pch_state; + else + next_state <= fetch_state; + end if; + + when pulu_accb_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- read accb + accb_ctrl <= pull_accb; + addr_ctrl <= pullu_ad; + dout_ctrl <= accb_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(3) = '1' then + next_state <= pulu_dp_state; + elsif ea(4) = '1' then + next_state <= pulu_ixh_state; + elsif ea(5) = '1' then + next_state <= pulu_iyh_state; + elsif ea(6) = '1' then + next_state <= pulu_sph_state; + elsif ea(7) = '1' then + next_state <= pulu_pch_state; + else + next_state <= fetch_state; + end if; + + when pulu_dp_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- read dp + dp_ctrl <= pull_dp; + addr_ctrl <= pullu_ad; + dout_ctrl <= dp_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(4) = '1' then + next_state <= pulu_ixh_state; + elsif ea(5) = '1' then + next_state <= pulu_iyh_state; + elsif ea(6) = '1' then + next_state <= pulu_sph_state; + elsif ea(7) = '1' then + next_state <= pulu_pch_state; + else + next_state <= fetch_state; + end if; + + when pulu_ixh_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- pull ix hi + ix_ctrl <= pull_hi_ix; + addr_ctrl <= pullu_ad; + dout_ctrl <= ix_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= pulu_ixl_state; + + when pulu_ixl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- read ix low + ix_ctrl <= pull_lo_ix; + addr_ctrl <= pullu_ad; + dout_ctrl <= ix_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(5) = '1' then + next_state <= pulu_iyh_state; + elsif ea(6) = '1' then + next_state <= pulu_sph_state; + elsif ea(7) = '1' then + next_state <= pulu_pch_state; + else + next_state <= fetch_state; + end if; + + when pulu_iyh_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- pull iy hi + iy_ctrl <= pull_hi_iy; + addr_ctrl <= pullu_ad; + dout_ctrl <= iy_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= pulu_iyl_state; + + when pulu_iyl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- read iy low + iy_ctrl <= pull_lo_iy; + addr_ctrl <= pullu_ad; + dout_ctrl <= iy_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(6) = '1' then + next_state <= pulu_sph_state; + elsif ea(7) = '1' then + next_state <= pulu_pch_state; + else + next_state <= fetch_state; + end if; + + when pulu_sph_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- pull sp hi + sp_ctrl <= pull_hi_sp; + addr_ctrl <= pullu_ad; + dout_ctrl <= up_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= pulu_spl_state; + + when pulu_spl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- read sp low + sp_ctrl <= pull_lo_sp; + addr_ctrl <= pullu_ad; + dout_ctrl <= up_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if ea(7) = '1' then + next_state <= pulu_pch_state; + else + next_state <= fetch_state; + end if; + + when pulu_pch_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- pull pc hi + pc_ctrl <= pull_hi_pc; + addr_ctrl <= pullu_ad; + dout_ctrl <= pc_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= pulu_pcl_state; + + when pulu_pcl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + sp_ctrl <= latch_sp; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- read pc low + pc_ctrl <= pull_lo_pc; + addr_ctrl <= pullu_ad; + dout_ctrl <= pc_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= fetch_state; + + when rti_cc_state => + -- default registers + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read cc + cc_ctrl <= pull_cc; + addr_ctrl <= pulls_ad; + dout_ctrl <= cc_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + -- + -- CC is clocked at the end of this cycle + -- so this test tests the current state + -- of the condition codes, not the popped value + -- Mind you, the Entire flag is set before + -- the registers are pushed, so it should not matter + -- + if cc(EBIT) = '1' then + next_state <= rti_acca_state; + else + next_state <= rti_pch_state; + end if; + + when rti_acca_state => + -- default registers + cc_ctrl <= latch_cc; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read acca + acca_ctrl <= pull_acca; + addr_ctrl <= pulls_ad; + dout_ctrl <= acca_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= rti_accb_state; + + when rti_accb_state => + -- default registers + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read accb + accb_ctrl <= pull_accb; + addr_ctrl <= pulls_ad; + dout_ctrl <= accb_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= rti_dp_state; + + when rti_dp_state => + -- default registers + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read dp + dp_ctrl <= pull_dp; + addr_ctrl <= pulls_ad; + dout_ctrl <= dp_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= rti_ixh_state; + + when rti_ixh_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read ix hi + ix_ctrl <= pull_hi_ix; + addr_ctrl <= pulls_ad; + dout_ctrl <= ix_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= rti_ixl_state; + + when rti_ixl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read ix low + ix_ctrl <= pull_lo_ix; + addr_ctrl <= pulls_ad; + dout_ctrl <= ix_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= rti_iyh_state; + + when rti_iyh_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read iy hi + iy_ctrl <= pull_hi_iy; + addr_ctrl <= pulls_ad; + dout_ctrl <= iy_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= rti_iyl_state; + + when rti_iyl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read iy low + iy_ctrl <= pull_lo_iy; + addr_ctrl <= pulls_ad; + dout_ctrl <= iy_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= rti_uph_state; + + + when rti_uph_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read up hi + up_ctrl <= pull_hi_up; + addr_ctrl <= pulls_ad; + dout_ctrl <= up_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= rti_upl_state; + + when rti_upl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + iy_ctrl <= latch_iy; + ix_ctrl <= latch_ix; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read up low + up_ctrl <= pull_lo_up; + addr_ctrl <= pulls_ad; + dout_ctrl <= up_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= rti_pch_state; + + when rti_pch_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- pull pc hi + pc_ctrl <= pull_hi_pc; + addr_ctrl <= pulls_ad; + dout_ctrl <= pc_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= rti_pcl_state; + + when rti_pcl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- pull pc low + pc_ctrl <= pull_lo_pc; + addr_ctrl <= pulls_ad; + dout_ctrl <= pc_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= fetch_state; + + -- + -- here on IRQ, NMI or FIRQ interrupt + -- pre decrement the sp + -- + when int_decr_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= pc_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= int_entire_state; + + -- + -- set Entire Flag on SWI, SWI2, SWI3 and CWAI, IRQ and NMI + -- clear Entire Flag on FIRQ + -- before stacking all registers + -- + when int_entire_state => + -- default + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- + left_ctrl <= sp_left; + right_ctrl <= zero_right; + if iv = FIRQ_VEC then + -- clear entire flag + alu_ctrl <= alu_cle; + else + -- set entire flag + alu_ctrl <= alu_see; + end if; + cc_ctrl <= load_cc; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= pc_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= int_pcl_state; + + when int_pcl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write pc low + addr_ctrl <= pushs_ad; + dout_ctrl <= pc_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= int_pch_state; + + when int_pch_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write pc hi + addr_ctrl <= pushs_ad; + dout_ctrl <= pc_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + if cc(EBIT) = '1' then + next_state <= int_upl_state; + else + next_state <= int_cc_state; + end if; + + when int_upl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write up low + addr_ctrl <= pushs_ad; + dout_ctrl <= up_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= int_uph_state; + + when int_uph_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write ix hi + addr_ctrl <= pushs_ad; + dout_ctrl <= up_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= int_iyl_state; + + when int_iyl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write ix low + addr_ctrl <= pushs_ad; + dout_ctrl <= iy_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= int_iyh_state; + + when int_iyh_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write ix hi + addr_ctrl <= pushs_ad; + dout_ctrl <= iy_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= int_ixl_state; + + when int_ixl_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write ix low + addr_ctrl <= pushs_ad; + dout_ctrl <= ix_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= int_ixh_state; + + when int_ixh_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write ix hi + addr_ctrl <= pushs_ad; + dout_ctrl <= ix_hi_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= int_dp_state; + + when int_dp_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write accb + addr_ctrl <= pushs_ad; + dout_ctrl <= dp_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= int_accb_state; + + when int_accb_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write accb + addr_ctrl <= pushs_ad; + dout_ctrl <= accb_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= int_acca_state; + + when int_acca_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write acca + addr_ctrl <= pushs_ad; + dout_ctrl <= acca_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= int_cc_state; + + when int_cc_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + iv_ctrl <= latch_iv; + ea_ctrl <= latch_ea; + -- idle sp + left_ctrl <= sp_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_nop; + sp_ctrl <= latch_sp; + -- write cc + addr_ctrl <= pushs_ad; + dout_ctrl <= cc_dout; + nmi_ctrl <= latch_nmi; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + case iv is + when NMI_VEC => + next_state <= int_mask_state; + when SWI_VEC => + next_state <= int_mask_state; + when IRQ_VEC => + next_state <= int_mask_state; + when SWI2_VEC => + next_state <= vect_hi_state; + when FIRQ_VEC => + next_state <= int_mask_state; + when SWI3_VEC => + next_state <= vect_hi_state; + when others => + if op_code = "00111100" then -- CWAI + next_state <= int_cwai_state; + else + next_state <= rti_state; + end if; + end case; + + -- + -- wait here for an inteerupt + -- + when int_cwai_state => + -- default + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + ea_ctrl <= latch_ea; + -- + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_nop; + cc_ctrl <= latch_cc; + sp_ctrl <= latch_sp; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= cc_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + -- + if (nmi_req = '1') and (nmi_ack='0') then + iv_ctrl <= nmi_iv; + nmi_ctrl <= set_nmi; + next_state <= vect_hi_state; + else + -- + -- nmi request is not cleared until nmi input goes low + -- + if (nmi_req = '0') and (nmi_ack='1') then + nmi_ctrl <= reset_nmi; + else + nmi_ctrl <= latch_nmi; + end if; + -- + -- IRQ is level sensitive + -- + if (irq = '1') and (cc(IBIT) = '0') then + iv_ctrl <= irq_iv; + next_state <= int_mask_state; + elsif (firq = '1') and (cc(FBIT) = '0') then + -- + -- FIRQ is level sensitive + -- + iv_ctrl <= firq_iv; + next_state <= int_mask_state; + else + iv_ctrl <= latch_iv; + next_state <= int_cwai_state; + end if; + end if; + + when int_mask_state => + -- default + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- Mask IRQ and FIRQ + left_ctrl <= sp_left; + right_ctrl <= zero_right; + -- + -- FIRQ can interrupt an IRQ service routine + -- + if iv = IRQ_VEC then + alu_ctrl <= alu_sei; + else + alu_ctrl <= alu_seif; + end if; + cc_ctrl <= load_cc; + sp_ctrl <= latch_sp; + -- idle bus cycle + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= vect_hi_state; + + when sync_state => + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + ea_ctrl <= latch_ea; + -- + left_ctrl <= pc_left; + right_ctrl <= one_right; + alu_ctrl <= alu_nop; + -- idle bus + addr_ctrl <= idle_ad; + dout_ctrl <= cc_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + -- + if (nmi_req = '1') and (nmi_ack='0') then + iv_ctrl <= nmi_iv; + nmi_ctrl <= set_nmi; + next_state <= fetch_state; + else + -- + -- nmi request is not cleared until nmi input goes low + -- + if (nmi_req = '0') and (nmi_ack='1') then + nmi_ctrl <= reset_nmi; + else + nmi_ctrl <= latch_nmi; + end if; + -- + -- IRQ is level sensitive + -- + if (irq = '1') and (cc(IBIT) = '0') then + iv_ctrl <= irq_iv; + next_state <= fetch_state; + elsif (firq = '1') and (cc(FBIT) = '0') then + -- + -- FIRQ is level sensitive + -- + iv_ctrl <= firq_iv; + next_state <= fetch_state; + else + iv_ctrl <= latch_iv; + next_state <= sync_state; + end if; + end if; + + + when halt_state => + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- idle ALU + left_ctrl <= acca_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_nop; + sp_ctrl <= latch_sp; + -- idle bus cycle + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + if halt <= '1' then + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= halt_state; + else + st_ctrl <= pull_st; + return_state <= fetch_state; + next_state <= saved_state; + end if; + + when others => -- halt on undefine states + -- default + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + iv_ctrl <= latch_iv; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + nmi_ctrl <= latch_nmi; + ea_ctrl <= latch_ea; + -- do nothing in ALU + left_ctrl <= acca_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_nop; + -- idle bus cycle + addr_ctrl <= idle_ad; + dout_ctrl <= md_lo_dout; + -- + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= error_state; + end case; +end process; + +end CPU_ARCH; +
/vhdl/sbug.vhd
0,0 → 1,2096
--===========================================================================----
--
-- S Y N T H E Z I A B L E SBUG - Monitor ROM for System09.
--
-- www.OpenCores.Org - September 2003
-- This core adheres to the GNU public license
--
-- FILE NAME: sbug.vhd
-- ENTITY NAME: boot_rom
-- ARCHITECTURE NAME: basic
-- VERSION: 1.0
-- AUTHOR: John E. Kent
-- DATE: 15 December 2002
-- DEPENDENCIES: ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
-- ieee.std_logic_arith
-- DESCRIPTION: 2048 byte x 8 bit ROM Monitor program
-- for the System09 using slices
-- Sits at $F800
-- ACIA at $E004
-- DAT at $FFF0
--
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
entity boot_rom is
port (
addr : in std_logic_vector(10 downto 0);
data : out std_logic_vector(7 downto 0)
);
end;
 
architecture basic of boot_rom is
constant width : integer := 8;
constant memsize : integer := 2048;
 
type rom_array is array(0 to memsize-1) of std_logic_vector(width-1 downto 0);
 
constant rom_data : rom_array :=
(
"11111000",
"00010100",
"11111000",
"01100001",
"11111101",
"11001111",
"11111101",
"11001001",
"11111101",
"11011111",
"11111101",
"11101110",
"11111101",
"10111101",
"11111101",
"10110001",
"11111101",
"10101101",
"11111011",
"10000001",
"10001110",
"11111110",
"01001111",
"00010000",
"10001110",
"11011111",
"11000000",
"11000110",
"00010000",
"10100110",
"10000000",
"10100111",
"10100000",
"01011010",
"00100110",
"11111001",
"10001110",
"11100000",
"00000100",
"10111111",
"11011111",
"11100000",
"00010111",
"00000010",
"01111010",
"11000110",
"00001100",
"01101111",
"11100010",
"01011010",
"00100110",
"11111011",
"00110000",
"10001100",
"11011101",
"10101111",
"01101010",
"10000110",
"11010000",
"10100111",
"11100100",
"00011111",
"01000011",
"00010111",
"00000101",
"10111110",
"10001110",
"11111110",
"01011111",
"00010111",
"00000101",
"01110101",
"10001110",
"11011111",
"11010000",
"01001111",
"11000110",
"00001101",
"01101101",
"10000101",
"00100111",
"00000011",
"10001011",
"00000100",
"00011001",
"01011010",
"00101010",
"11110110",
"00010111",
"00000101",
"00100110",
"10001110",
"11111110",
"01110100",
"00010111",
"00000101",
"01011100",
"10001110",
"11111110",
"01111011",
"00010111",
"00000101",
"01000110",
"00010111",
"00000101",
"01100101",
"10000100",
"01111111",
"10000001",
"00001101",
"00100111",
"11110001",
"00011111",
"10001001",
"10000001",
"00100000",
"00101100",
"00001001",
"10000110",
"01011110",
"00010111",
"00000101",
"01110011",
"00011111",
"10011000",
"10001011",
"01000000",
"00010111",
"00000101",
"01101100",
"00010111",
"00000101",
"01100111",
"11000001",
"01100000",
"00101111",
"00000010",
"11000000",
"00100000",
"10001110",
"11111110",
"00010011",
"11100001",
"10000000",
"00100111",
"00001111",
"00110000",
"00000010",
"10001100",
"11111110",
"01001111",
"00100110",
"11110101",
"10001110",
"11111110",
"01111101",
"00010111",
"00000101",
"00011110",
"00100000",
"11000000",
"10101101",
"10010100",
"00100000",
"10111100",
"00011111",
"00110100",
"00111011",
"10001110",
"11111110",
"10000011",
"00010111",
"00000100",
"11111111",
"00010111",
"00000100",
"00010001",
"00010111",
"00000100",
"00011001",
"00010111",
"00000100",
"00100001",
"00010111",
"00000100",
"00101001",
"00010111",
"00000100",
"00110001",
"10001110",
"11111110",
"10000011",
"00010111",
"00000100",
"11101010",
"00010111",
"00000100",
"00110011",
"00010111",
"00000100",
"00111010",
"00010111",
"00000100",
"01000001",
"00010110",
"00000100",
"01001000",
"00010111",
"00000100",
"00100111",
"00010111",
"00000101",
"00010111",
"00010111",
"00000100",
"01010111",
"00101001",
"00000010",
"10101111",
"01001010",
"00111001",
"00010111",
"00000011",
"11101101",
"00010111",
"00000101",
"00001001",
"00010111",
"00000100",
"01001001",
"00101001",
"00000010",
"10101111",
"01001000",
"00111001",
"00010111",
"00000100",
"00000000",
"00010111",
"00000100",
"11111011",
"00010111",
"00000100",
"00111011",
"00101001",
"00000010",
"10101111",
"01000110",
"00111001",
"00010111",
"00000011",
"11100111",
"00010111",
"00000100",
"11101101",
"00010111",
"00000100",
"00101101",
"00101001",
"00000010",
"10101111",
"01000100",
"00111001",
"00010111",
"00000011",
"11001110",
"00010111",
"00000100",
"11011111",
"00010111",
"00000100",
"00110000",
"00101001",
"00000010",
"10100111",
"01000011",
"00111001",
"00010111",
"00000011",
"11110101",
"00010111",
"00000100",
"11010001",
"00010111",
"00000100",
"00100010",
"00101001",
"00000010",
"10100111",
"01000010",
"00111001",
"00010111",
"00000011",
"11011101",
"00010111",
"00000100",
"11000011",
"00010111",
"00000100",
"00010100",
"00101001",
"00000010",
"10100111",
"01000001",
"00111001",
"00010111",
"00000011",
"11100011",
"00010111",
"00000100",
"10110101",
"00010111",
"00000100",
"00000110",
"00101001",
"00000100",
"10001010",
"10000000",
"10100111",
"11000100",
"00111001",
"00010111",
"00000011",
"11101011",
"00101001",
"00101101",
"00011111",
"00010010",
"10001110",
"11111110",
"10000011",
"00010111",
"00000100",
"01011111",
"00011111",
"00100001",
"00010111",
"00000100",
"00100110",
"00010111",
"00000100",
"10010110",
"10100110",
"10100100",
"00010111",
"00000100",
"00100110",
"00010111",
"00000100",
"10001110",
"00010111",
"00000011",
"11011111",
"00101000",
"00010001",
"10000001",
"00001000",
"00100111",
"11100001",
"10000001",
"00011000",
"00100111",
"11011101",
"10000001",
"01011110",
"00100111",
"00010111",
"10000001",
"00001101",
"00100110",
"00001111",
"00111001",
"10100111",
"10100100",
"10100001",
"10100100",
"00100111",
"00001000",
"00010111",
"00000100",
"01101111",
"10000110",
"00111111",
"00010111",
"00000100",
"01101100",
"00110001",
"00100001",
"00100000",
"11000010",
"00110001",
"00111111",
"00100000",
"10111110",
"00010111",
"00000011",
"00110101",
"00011111",
"00110010",
"10001110",
"11011111",
"11000000",
"00110000",
"00011111",
"00100000",
"00000101",
"00010111",
"00000011",
"10001011",
"00101001",
"00000110",
"00110100",
"00100000",
"10101100",
"11100001",
"00100100",
"00000001",
"00111001",
"00011111",
"00010000",
"11000011",
"00000000",
"00010000",
"11000100",
"11110000",
"00110100",
"00000110",
"00011111",
"00100000",
"11000100",
"11110000",
"00011111",
"00000001",
"10101100",
"11100100",
"00100111",
"00000101",
"00010111",
"00000100",
"00100111",
"00100111",
"00000011",
"00110010",
"01100010",
"00111001",
"00110100",
"00010000",
"10001110",
"11111110",
"10000011",
"00010111",
"00000011",
"11101000",
"10101110",
"11100100",
"00010111",
"00000011",
"10101111",
"11000110",
"00010000",
"10100110",
"10000000",
"00010111",
"00000011",
"10110000",
"00010111",
"00000100",
"00011000",
"01011010",
"00100110",
"11110101",
"00010111",
"00000100",
"00010000",
"10101110",
"11100001",
"11000110",
"00010000",
"10100110",
"10000000",
"10000001",
"00100000",
"00100101",
"00000100",
"10000001",
"01111110",
"00100011",
"00000010",
"10000110",
"00101110",
"00010111",
"00000100",
"00000001",
"01011010",
"00100110",
"11101110",
"00100000",
"10111111",
"01101111",
"11100010",
"01101111",
"11100010",
"00010111",
"00000011",
"00101011",
"00110100",
"00110000",
"00101001",
"01111011",
"10101100",
"01100010",
"00100101",
"01110111",
"00010111",
"00000011",
"11101000",
"00011111",
"00100000",
"11100011",
"01100100",
"00110100",
"00000100",
"10101011",
"11100000",
"10100111",
"10100000",
"00010000",
"10101100",
"11100100",
"00100101",
"11110001",
"00010000",
"10101110",
"01100010",
"00011111",
"00100000",
"11100011",
"01100100",
"00110100",
"00000010",
"11101011",
"11100000",
"11101000",
"10100000",
"00100111",
"00111100",
"10001110",
"11111110",
"10000011",
"00010111",
"00000011",
"10000101",
"00110000",
"00111111",
"00010111",
"00000011",
"01001100",
"00110100",
"00010000",
"10001110",
"11111110",
"10100001",
"00010111",
"00000011",
"10001000",
"00110101",
"00010000",
"00010111",
"00000001",
"01000111",
"00010111",
"00000011",
"01010000",
"00010111",
"00000011",
"00111001",
"10001110",
"11111110",
"10000111",
"00010111",
"00000011",
"01110111",
"10101110",
"01100100",
"00010111",
"00000011",
"00101110",
"10001110",
"11111110",
"10001111",
"00010111",
"00000011",
"01101100",
"00011111",
"10011000",
"10001110",
"11111110",
"10100110",
"00010111",
"00000011",
"00111110",
"00010111",
"00000011",
"10000011",
"00100110",
"00011010",
"00010000",
"10101100",
"11100100",
"00100101",
"10110011",
"10000110",
"00101011",
"00010111",
"00000011",
"10000110",
"00010111",
"00000011",
"01110100",
"00100110",
"00001011",
"00010000",
"10101110",
"01100010",
"01101100",
"01100101",
"00100110",
"10010000",
"01101100",
"01100100",
"00100110",
"10001100",
"00110010",
"01100110",
"00111001",
"00010111",
"00000010",
"10110001",
"00101001",
"00011110",
"10001100",
"11011111",
"11000000",
"00100100",
"00011010",
"00110100",
"00010000",
"10001110",
"11111111",
"11111111",
"10001101",
"01010101",
"00110101",
"00010000",
"00100111",
"00001111",
"10100110",
"10000100",
"10000001",
"00111111",
"00100111",
"00001001",
"10100111",
"10100000",
"10101111",
"10100100",
"10000110",
"00111111",
"10100111",
"10000100",
"00111001",
"00010111",
"00000011",
"01001010",
"10000110",
"00111111",
"00010110",
"00000011",
"01000111",
"00010000",
"10001110",
"11011111",
"11100011",
"11000110",
"00001000",
"10001101",
"00011000",
"01011010",
"00100110",
"11111011",
"00111001",
"00011111",
"01000011",
"10101110",
"01001010",
"00110000",
"00011111",
"10001101",
"00100110",
"00100111",
"00000100",
"10101111",
"01001010",
"10001101",
"00000110",
"00010111",
"11111101",
"11100100",
"00010110",
"11111101",
"10011010",
"10101110",
"00100001",
"10001100",
"11011111",
"11000000",
"00100100",
"00001010",
"10100110",
"10000100",
"10000001",
"00111111",
"00100110",
"00000100",
"10100110",
"10100100",
"10100111",
"10000100",
"10000110",
"11111111",
"10100111",
"10100000",
"10100111",
"10100000",
"10100111",
"10100000",
"00111001",
"00010000",
"10001110",
"11011111",
"11100011",
"11000110",
"00001000",
"10100110",
"10100000",
"10101100",
"10100001",
"00100111",
"00000100",
"01011010",
"00100110",
"11110111",
"00111001",
"00110001",
"00111101",
"00111001",
"10000110",
"11011110",
"10110111",
"11110000",
"00100100",
"10000110",
"11111111",
"10110111",
"11110000",
"00010100",
"10110111",
"11110000",
"00010000",
"10110111",
"11110000",
"00010101",
"10110111",
"11110000",
"00010110",
"01111101",
"11110000",
"00010000",
"10000110",
"11011000",
"10110111",
"11110000",
"00100000",
"00010111",
"00000000",
"10010111",
"10110110",
"11110000",
"00100000",
"00101011",
"11111011",
"10000110",
"00001001",
"10110111",
"11110000",
"00100000",
"00010111",
"00000000",
"10001010",
"10110110",
"11110000",
"00100000",
"10000101",
"00000001",
"00100110",
"11111001",
"10000101",
"00010000",
"00100110",
"11001010",
"10001110",
"11000000",
"00000000",
"10001101",
"01010010",
"10001010",
"00010000",
"10110111",
"11110000",
"01000000",
"00011111",
"00010000",
"01000011",
"01010011",
"11111101",
"11110000",
"00000000",
"10001110",
"11111110",
"11111111",
"10111111",
"11110000",
"00000010",
"10000110",
"11111111",
"10110111",
"11110000",
"00010000",
"10000110",
"11111110",
"10110111",
"11110000",
"00010100",
"10000110",
"00000001",
"10110111",
"11110000",
"00100010",
"10000110",
"10001100",
"10110111",
"11110000",
"00100000",
"10001101",
"01010010",
"01011111",
"00110100",
"00000100",
"01011111",
"01111101",
"11110000",
"00010000",
"00101010",
"00001010",
"01011010",
"00100110",
"11111000",
"00110101",
"00000100",
"01011010",
"00100110",
"11110000",
"00100000",
"10001010",
"00110101",
"00000100",
"10110110",
"11110000",
"00100000",
"10000101",
"00011100",
"00100111",
"00000001",
"00111001",
"11000110",
"11011110",
"11110111",
"11110000",
"00100100",
"10001110",
"11000000",
"00000000",
"10101111",
"01001010",
"00011111",
"00110100",
"00111011",
"00110100",
"00110110",
"10100110",
"01100010",
"01000100",
"01000100",
"01000100",
"01000100",
"00010000",
"10001110",
"11011111",
"11010000",
"11100110",
"10100110",
"01010100",
"01010100",
"01010100",
"01010100",
"11100111",
"11100100",
"11100110",
"10100110",
"01010011",
"01011000",
"01011000",
"01011000",
"01011000",
"10100110",
"01100010",
"10000100",
"00001111",
"10100111",
"01100010",
"11101010",
"01100010",
"11100111",
"01100010",
"00110101",
"00110110",
"00111001",
"00110100",
"00000100",
"11000110",
"00100000",
"01011010",
"00100110",
"11111101",
"00110101",
"00000100",
"00111001",
"01111101",
"11100000",
"00011000",
"01111111",
"11100000",
"00010100",
"11000110",
"00000011",
"10001110",
"00000000",
"00000000",
"00110000",
"00000001",
"10001100",
"00000000",
"00000000",
"00100110",
"11111001",
"01011010",
"00100110",
"11110110",
"10000110",
"00001111",
"10110111",
"11100000",
"00011000",
"10001101",
"00110111",
"11110110",
"11100000",
"00011000",
"11000101",
"00000001",
"00100110",
"11111001",
"10000110",
"00000001",
"10110111",
"11100000",
"00011010",
"10001101",
"00101001",
"10000110",
"10001100",
"10110111",
"11100000",
"00011000",
"10001101",
"00100010",
"10001110",
"11000000",
"00000000",
"00100000",
"00001001",
"11000101",
"00000010",
"00100111",
"00000101",
"10110110",
"11100000",
"00011011",
"10100111",
"10000000",
"11110110",
"11100000",
"00011000",
"11000101",
"00000001",
"00100110",
"11110000",
"11000101",
"00101100",
"00100111",
"00000001",
"00111001",
"10001110",
"11000000",
"00000000",
"10101111",
"01001010",
"00011111",
"00110100",
"00111011",
"11000110",
"00100000",
"01011010",
"00100110",
"11111101",
"00111001",
"10000110",
"00010001",
"00010111",
"00000001",
"11011101",
"01111111",
"11011111",
"11100010",
"00010111",
"00000001",
"10101101",
"10000001",
"01010011",
"00100110",
"11111001",
"00010111",
"00000001",
"10100110",
"10000001",
"00111001",
"00100111",
"00111101",
"10000001",
"00110001",
"00100110",
"11110001",
"00010111",
"00000001",
"00010111",
"00110100",
"00000010",
"00101001",
"00100110",
"00010111",
"00000000",
"11111111",
"00101001",
"00100001",
"00110100",
"00010000",
"11100110",
"11100000",
"11101011",
"11100000",
"11101011",
"11100100",
"01101010",
"11100100",
"01101010",
"11100100",
"00110100",
"00000100",
"00010111",
"00000000",
"11111101",
"00110101",
"00000100",
"00101001",
"00001100",
"00110100",
"00000010",
"11101011",
"11100000",
"01101010",
"11100100",
"00100111",
"00000101",
"10100111",
"10000000",
"00100000",
"11101011",
"01011111",
"00110101",
"00000010",
"11000001",
"11111111",
"00100111",
"10110010",
"10000110",
"00111111",
"00010111",
"00000001",
"10001111",
"01110011",
"11011111",
"11100010",
"10000110",
"00010011",
"00010110",
"00000001",
"10000111",
"01101111",
"11100010",
"00010111",
"00000000",
"10111000",
"00110100",
"00110000",
"00101001",
"01001010",
"10101100",
"01100010",
"00100101",
"01000110",
"00110000",
"00000001",
"10101111",
"11100100",
"10000110",
"00010010",
"00010111",
"00000001",
"01110001",
"11101100",
"11100100",
"10100011",
"01100010",
"00100111",
"00000110",
"00010000",
"10000011",
"00000000",
"00100000",
"00100011",
"00000010",
"11000110",
"00100000",
"11100111",
"01100100",
"10001110",
"11111110",
"11101011",
"00010111",
"00000001",
"00011010",
"11001011",
"00000011",
"00011111",
"10011000",
"00010111",
"00000000",
"11100111",
"10101110",
"01100010",
"00010111",
"00000000",
"11011010",
"11101011",
"01100010",
"11101011",
"01100011",
"11101011",
"10000100",
"10100110",
"10000000",
"00010111",
"00000000",
"11010111",
"01101010",
"01100100",
"00100110",
"11110101",
"01010011",
"00011111",
"10011000",
"00010111",
"00000000",
"11001101",
"10101111",
"01100010",
"10101100",
"11100100",
"00100110",
"11000011",
"10000110",
"00010100",
"00010111",
"00000001",
"00101111",
"00110010",
"01100101",
"00111001",
"10001110",
"11111110",
"10101110",
"00010111",
"00000000",
"11110101",
"00011111",
"00110001",
"00010110",
"00000000",
"10101100",
"10001110",
"11111110",
"10111010",
"00010111",
"00000000",
"11101010",
"10101110",
"01001000",
"00010110",
"00000000",
"10100001",
"10001110",
"11111110",
"11001100",
"00010111",
"00000000",
"11011111",
"10100110",
"01000011",
"00010110",
"00000000",
"10011110",
"10001110",
"11111110",
"11000110",
"00010111",
"00000000",
"11010100",
"10101110",
"01000100",
"00010110",
"00000000",
"10001011",
"10001110",
"11111110",
"11000000",
"00010111",
"00000000",
"11001001",
"10101110",
"01000110",
"00010110",
"00000000",
"10000000",
"10001110",
"11111110",
"10110100",
"00010111",
"00000000",
"10111110",
"10101110",
"01001010",
"00100000",
"01110110",
"10001110",
"11111110",
"11010010",
"00010111",
"00000000",
"10110100",
"10100110",
"01000001",
"00100000",
"01110100",
"10001110",
"11111110",
"11010111",
"00010111",
"00000000",
"10101010",
"10100110",
"01000010",
"00100000",
"01101010",
"10001110",
"11111110",
"11011100",
"00010111",
"00000000",
"10100000",
"10100110",
"11000100",
"10001110",
"11111110",
"11100011",
"00100000",
"01110011",
"10001101",
"00001001",
"00101001",
"01001110",
"00011111",
"00010010",
"10000110",
"00101101",
"00010111",
"00000000",
"10111111",
"10001101",
"00001111",
"00101001",
"01000011",
"00011111",
"00000001",
"10001101",
"00001001",
"00101001",
"00111101",
"00110100",
"00010000",
"10100111",
"01100001",
"00110101",
"00010000",
"00111001",
"10001101",
"00010001",
"00101001",
"00110010",
"01001000",
"01001000",
"01001000",
"01001000",
"00011111",
"10001001",
"10001101",
"00000111",
"00101001",
"00101000",
"00110100",
"00000100",
"10101011",
"11100000",
"00111001",
"10001101",
"01101111",
"10000001",
"00110000",
"00100101",
"00011101",
"10000001",
"00111001",
"00100010",
"00000011",
"10000000",
"00110000",
"00111001",
"10000001",
"01000001",
"00100101",
"00010010",
"10000001",
"01000110",
"00100010",
"00000011",
"10000000",
"00110111",
"00111001",
"10000001",
"01100001",
"00100101",
"00000111",
"10000001",
"01100110",
"00100010",
"00000011",
"10000000",
"01010111",
"00111001",
"00011010",
"00000010",
"00111001",
"00110100",
"00010000",
"00110101",
"00000010",
"10001101",
"00000010",
"00110101",
"00000010",
"00110100",
"00000010",
"01000100",
"01000100",
"01000100",
"01000100",
"10001101",
"00000100",
"00110101",
"00000010",
"10000100",
"00001111",
"10001011",
"00110000",
"10000001",
"00111001",
"00101111",
"00000010",
"10001011",
"00000111",
"00100000",
"01010111",
"00110100",
"00000010",
"11000110",
"00001000",
"10100110",
"10000000",
"01101000",
"11100100",
"00100101",
"00000010",
"10000110",
"00101101",
"10001101",
"01001001",
"10001101",
"01000101",
"01011010",
"00100110",
"11110001",
"00110101",
"00000010",
"00111001",
"10001101",
"00000010",
"00100000",
"00001100",
"00110100",
"00010000",
"10001110",
"11111110",
"01110101",
"10001101",
"00000101",
"00110101",
"00010000",
"00111001",
"10001101",
"00110001",
"10100110",
"10000000",
"10000001",
"00000100",
"00100110",
"11111000",
"00111001",
"01111101",
"11011111",
"11100010",
"00100111",
"00000110",
"10001101",
"00000100",
"10000100",
"01111111",
"00100000",
"00011111",
"00110100",
"00010000",
"10111110",
"11011111",
"11100000",
"10100110",
"10000100",
"10000101",
"00000001",
"00100111",
"11111010",
"10100110",
"00000001",
"00110101",
"00010000",
"00111001",
"00110100",
"00000010",
"10100110",
"10011111",
"11011111",
"11100000",
"10000101",
"00000001",
"00110101",
"00000010",
"00111001",
"10001101",
"00000000",
"10000110",
"00100000",
"00110100",
"00010010",
"10111110",
"11011111",
"11100000",
"10100110",
"10000100",
"10000101",
"00000010",
"00100111",
"11111010",
"00110101",
"00000010",
"10100111",
"00000001",
"00110101",
"00010000",
"00111001",
"10111110",
"11011111",
"11100000",
"10000110",
"00000011",
"10100111",
"10000100",
"10000110",
"00010001",
"10100111",
"10000100",
"01101101",
"00000001",
"10000110",
"11111111",
"10110111",
"11011111",
"11100010",
"00111001",
"00000001",
"11111001",
"00100011",
"00000010",
"11111001",
"00010101",
"00000011",
"11111001",
"00110001",
"00000100",
"11111001",
"00000111",
"00010000",
"11111000",
"11001111",
"00010101",
"11111000",
"11011101",
"00011000",
"11111000",
"11111001",
"00011001",
"11111000",
"11101011",
"01000010",
"11111010",
"01111011",
"01000100",
"11111010",
"11110100",
"01000101",
"11111001",
"10010110",
"01000111",
"11111000",
"10100101",
"01001100",
"11111100",
"00001100",
"01001101",
"11111001",
"01000001",
"01010000",
"11111100",
"01100111",
"01010001",
"11111001",
"11110010",
"01010010",
"11111000",
"10101000",
"01010011",
"11111001",
"10001010",
"01010101",
"11111011",
"10110011",
"01011000",
"11111010",
"10100111",
"11111010",
"10110011",
"11111000",
"10100111",
"11111000",
"10100111",
"11111000",
"10100111",
"11111000",
"10100111",
"11111010",
"10110011",
"11111111",
"11111111",
"11111111",
"11111111",
"00000000",
"00000000",
"00000000",
"00001101",
"00001010",
"00000000",
"00000000",
"00000000",
"01010011",
"00101101",
"01000010",
"01010101",
"01000111",
"00100000",
"00110001",
"00101110",
"00111000",
"00100000",
"00101101",
"00100000",
"00000100",
"01001011",
"00001101",
"00001010",
"00000000",
"00000000",
"00000000",
"00000100",
"00111110",
"00000100",
"01010111",
"01001000",
"01000001",
"01010100",
"00111111",
"00000100",
"00100000",
"00101101",
"00100000",
"00000100",
"00101100",
"00100000",
"01010000",
"01000001",
"01010011",
"01010011",
"00100000",
"00000100",
"00101100",
"00100000",
"01000010",
"01001001",
"01010100",
"01010011",
"00100000",
"01001001",
"01001110",
"00100000",
"01000101",
"01010010",
"01010010",
"01001111",
"01010010",
"00111010",
"00100000",
"00000100",
"00100000",
"00111101",
"00111110",
"00100000",
"00000100",
"00110111",
"00110110",
"00110101",
"00110100",
"00110011",
"00110010",
"00110001",
"00110000",
"00100000",
"00100000",
"01010011",
"01010000",
"00111101",
"00000100",
"00100000",
"00100000",
"01010000",
"01000011",
"00111101",
"00000100",
"00100000",
"00100000",
"01010101",
"01010011",
"00111101",
"00000100",
"00100000",
"00100000",
"01001001",
"01011001",
"00111101",
"00000100",
"00100000",
"00100000",
"01001001",
"01011000",
"00111101",
"00000100",
"00100000",
"00100000",
"01000100",
"01010000",
"00111101",
"00000100",
"00100000",
"00100000",
"01000001",
"00111101",
"00000100",
"00100000",
"00100000",
"01000010",
"00111101",
"00000100",
"00100000",
"00100000",
"01000011",
"01000011",
"00111010",
"00100000",
"00000100",
"01000101",
"01000110",
"01001000",
"01001001",
"01001110",
"01011010",
"01010110",
"01000011",
"01010011",
"00110001",
"00000100",
"11111111",
"11111111",
"11111111",
"11111111",
"11111111",
"11111111",
"11111111",
"11111111",
"11111111",
"11111111",
"11111111",
"11111111",
"11111111",
"11111111",
"11111111",
"00000000",
"00000000",
"00000000",
"10001110",
"11111111",
"11110000",
"10000110",
"00001111",
"10100111",
"10000000",
"01001010",
"00100110",
"11111011",
"10000110",
"11110000",
"10100111",
"10000100",
"10001110",
"11010000",
"10100000",
"00010000",
"10001110",
"01010101",
"10101010",
"11101110",
"10000100",
"00010000",
"10101111",
"10000100",
"00010000",
"10101100",
"10000100",
"00100111",
"00001011",
"00110000",
"10001001",
"11110000",
"00000000",
"10001100",
"11110000",
"10100000",
"00100110",
"11101101",
"00100000",
"11010110",
"11101111",
"10000100",
"00011111",
"00010000",
"01000011",
"01000100",
"01000100",
"01000100",
"01000100",
"10110111",
"11111111",
"11111101",
"00010000",
"11001110",
"11011111",
"11000000",
"00010000",
"10001110",
"11011111",
"11010000",
"10100111",
"00101101",
"01101111",
"00101110",
"10000110",
"11110000",
"10100111",
"00101111",
"10000110",
"00001100",
"01101111",
"10100110",
"01001010",
"00101010",
"11111011",
"00110000",
"10001001",
"11110000",
"00000000",
"10001100",
"11110000",
"10100000",
"00100111",
"00100010",
"11101110",
"10000100",
"00010000",
"10001110",
"01010101",
"10101010",
"00010000",
"10101111",
"10000100",
"00010000",
"10101100",
"10000100",
"00100110",
"11101001",
"11101111",
"10000100",
"00010000",
"10001110",
"11011111",
"11010000",
"00011111",
"00010000",
"01000100",
"01000100",
"01000100",
"01000100",
"00011111",
"10001001",
"10001000",
"00001111",
"10100111",
"10100101",
"00100000",
"11010101",
"10000110",
"11110001",
"00010000",
"10001110",
"11011111",
"11010000",
"10100111",
"00101110",
"10000110",
"00001100",
"11100110",
"10100110",
"00100110",
"00000101",
"01001010",
"00101010",
"11111001",
"00100000",
"00010100",
"01101111",
"10100110",
"11100111",
"00101100",
"01001111",
"00011111",
"00100001",
"11100110",
"10100110",
"00100111",
"00000100",
"01101111",
"10100110",
"11100111",
"10000000",
"01001100",
"10000001",
"00001100",
"00101101",
"11110011",
"10001110",
"11111111",
"11110000",
"11000110",
"00010000",
"10100110",
"10100000",
"10100111",
"10000000",
"01011010",
"00100110",
"11111001",
"01010011",
"11110111",
"11011111",
"11100010",
"00010110",
"11111000",
"01100010",
"01101110",
"10011111",
"11011111",
"11000000",
"01101110",
"10011111",
"11011111",
"11000100",
"01101110",
"10011111",
"11011111",
"11000110",
"01101110",
"10011111",
"11011111",
"11001000",
"01101110",
"10011111",
"11011111",
"11001010",
"00011111",
"01000011",
"10101110",
"01001010",
"11100110",
"10000000",
"10101111",
"01001010",
"01001111",
"01011000",
"01001001",
"10111110",
"11011111",
"11001100",
"10001100",
"11111111",
"11111111",
"00100111",
"00001111",
"00110000",
"10001011",
"10111100",
"11011111",
"11001110",
"00100010",
"00001000",
"00110100",
"00010000",
"11101100",
"11000100",
"10101110",
"01000100",
"01101110",
"11110001",
"00110111",
"00011111",
"11101110",
"01000010",
"01101110",
"10011111",
"11011111",
"11000010",
"11111111",
"10110010",
"11111111",
"11000110",
"11111111",
"10110110",
"11111111",
"10111010",
"11111111",
"10111110",
"11111111",
"11000010",
"11111111",
"10110010",
"11111111",
"00000000"
);
begin
data <= rom_data(conv_integer(addr));
end;
 
/vhdl/testbench1.vhd
0,0 → 1,180
--===========================================================================----
--
-- T E S T B E N C H tesetbench1 - CPU09 Testbench.
--
-- www.OpenCores.Org - September 2003
-- This core adheres to the GNU public license
--
-- File name : Testbench1.vhd
--
-- Purpose : cpu09 Microprocessor Test Bench 1
-- Contains ROM to print out "Hello World"
-- on a none existant Uart
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
-- ieee.std_logic_arith
-- ieee.numeric_std
--
-- Uses : cpu09 (cpu09.vhd) CPU core
--
-- Author : John E. Kent
-- dilbert57@opencores.org
--
--===========================================================================----
--
-- Revision History:
--===========================================================================--
--
-- Version 0.1 - 12st April 2003 - John Kent
-- First version
--
-- Version 1.0- 6 Sep 2003 - John Kent
-- Initial release to Open Cores
--
--===========================================================================--
 
library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.all;
-- library work;
-- use work.UART_Def.all;
-- use work.typedefines.all;
-- use work.memory.all;
 
entity my_testbench is
end my_testbench;
 
-------------------------------------------------------------------------------
-- Architecture for memio Controller Unit
-------------------------------------------------------------------------------
architecture behavior of my_testbench is
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
-- CPU Interface signals
signal SysClk : Std_Logic;
signal cpu_reset : Std_Logic;
signal cpu_rw : Std_Logic;
signal cpu_vma : Std_Logic;
signal cpu_addr : Std_Logic_Vector(15 downto 0);
signal cpu_data_in : Std_Logic_Vector(7 downto 0);
signal cpu_data_out: Std_Logic_Vector(7 downto 0);
signal cpu_alu : Std_Logic_Vector(15 downto 0);
signal cpu_cc : Std_Logic_Vector(7 downto 0);
signal cpu_irq : Std_Logic;
signal cpu_nmi : std_logic;
signal cpu_firq : Std_Logic;
 
 
constant width : integer := 8;
constant memsize : integer := 64;
 
type rom_array is array(0 to memsize-1) of std_logic_vector(width-1 downto 0);
 
constant rom_data : rom_array :=
(
"10001110", "11111000", "00101000", -- F800 - 8E F828 RESET LDX #MSG
"10000110", "00010001", -- F803 - 86 11 LDA #$11
"10110111", "11100000", "00000100", -- F805 - B7 E004 STA UARTCR
"10110110", "11100000", "00000100", -- F808 - B6 E004 POLL1 LDA UARTCR
"10000101", "00000010", -- F80B - 85 02 BITA #TXBE
"00100110", "11111001", -- F80D - 26 F9 BNE POLL1
"10100110", "10000000", -- F80F - A6 80 LDA ,X+
"00100111", "00000110", -- F811 - 27 06 BEQ POLL2
"00010010", -- F813 - 12 NOP
"10110111", "11100000", "00000101", -- F814 - B7 E005 STA UARTDR
"00100110", "11101111", -- F817 - 26 EF BNE POLL1
"10110110", "11100000", "00000100", -- F819 - B6 E004 POLL2 LDA UARTCR
"10000101", "00000001", -- F81C - 85 01 BITA #RXBF
"00100111", "11111001", -- F81E - 27 F9 BEQ POLL2
"10110110", "11100000", "00000101", -- F820 - B6 E005 LDA UARTDR
"01111110", "11111000", "00000000", -- F823 - 7E F800 JMP RESET
"00000000", "00000000", -- F826 - 00 00 fcb $00,$00
"01001000", "01100101", "01101100", -- F828 - 48 65 6c MSG FCC "Hel"
"01101100", "01101111", "00100000", -- F82B - 6c 6f 20 FCC "lo "
"01010111", "01101111", "01110010", -- F82E - 57 6f 72 FCC "Wor"
"01101100", "01100100", -- F831 - 6c 64 FCC "ld"
"00001010", "00001101", "00000000", -- F833 - 0a 0d 00 FCB LF,CR,NULL
"00000000", "00000000", -- F836 - 00 00 fcb null,null
"11111000", "00000000", -- F838 - F8 00 fdb $F800 ; Timer irq
"11111000", "00000000", -- F83A - F8 00 fdb $F800 ; Ext IRQ
"11111000", "00000000", -- F83C - F8 00 fcb $F800 ; SWI
"11111000", "00000000" -- F83E - F8 00 fdb $F800 ; Reset
);
 
component cpu09
port (
clk: in std_logic;
rst: in std_logic;
rw: out std_logic; -- Asynchronous memory interface
vma: out std_logic;
address: out std_logic_vector(15 downto 0);
data_in: in std_logic_vector(7 downto 0);
data_out: out std_logic_vector(7 downto 0);
halt: in std_logic;
hold: in std_logic;
irq: in std_logic;
nmi: in std_logic;
firq: in std_logic;
test_alu: out std_logic_vector(15 downto 0);
test_cc: out std_logic_vector(7 downto 0)
);
end component cpu09;
 
 
begin
cpu : cpu09 port map (
clk => SysClk,
rst => cpu_reset,
rw => cpu_rw,
vma => cpu_vma,
address => cpu_addr(15 downto 0),
data_in => cpu_data_in,
data_out => cpu_data_out,
halt => '0',
hold => '0',
irq => cpu_irq,
nmi => cpu_nmi,
firq => cpu_firq,
test_alu => cpu_alu,
test_cc => cpu_cc
);
 
-- *** Test Bench - User Defined Section ***
tb : PROCESS
variable count : integer;
BEGIN
 
cpu_reset <= '0';
SysClk <= '0';
cpu_irq <= '0';
cpu_nmi <= '0';
cpu_firq <= '0';
 
for count in 0 to 512 loop
SysClk <= '0';
if count = 0 then
cpu_reset <= '1';
elsif count = 1 then
cpu_reset <= '0';
end if;
wait for 100 ns;
SysClk <= '1';
wait for 100 ns;
end loop;
 
wait; -- will wait forever
END PROCESS;
-- *** End Test Bench - User Defined Section ***
 
 
rom : PROCESS( cpu_addr )
begin
cpu_data_in <= rom_data(conv_integer(cpu_addr(5 downto 0)));
end process;
 
end behavior; --===================== End of architecture =======================--
 
/vhdl/testbench2.vhd
0,0 → 1,304
--===========================================================================----
--
-- T E S T B E N C H tesetbench2 - CPU09 Testbench.
--
-- www.OpenCores.Org - September 2003
-- This core adheres to the GNU public license
--
-- File name : Testbench2.vhd
--
-- Purpose : cpu09 Microprocessor Test Bench 2
-- Contains ROM to read sector from
-- a none existant Compact Flash module
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
-- ieee.std_logic_arith
-- ieee.numeric_std
--
-- Uses : cpu09 (cpu09.vhd) CPU core
--
-- Author : John E. Kent
-- dilbert57@opencores.org
--
--===========================================================================----
--
-- Revision History:
--===========================================================================--
--
-- Version 0.1 - 12st April 2003 - John Kent
-- First version
--
-- Version 1.0- 6 Sep 2003 - John Kent
-- Initial release to Open Cores
--
--===========================================================================--
 
library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.all;
 
entity my_testbench is
end my_testbench;
 
-------------------------------------------------------------------------------
-- Architecture for memio Controller Unit
-------------------------------------------------------------------------------
architecture behavior of my_testbench is
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
 
-- CPU Interface signals
signal SysClk : Std_Logic;
signal cpu_reset : Std_Logic;
signal cpu_rw : Std_Logic;
signal cpu_vma : Std_Logic;
signal cpu_addr : Std_Logic_Vector(15 downto 0);
signal cpu_data_in : Std_Logic_Vector(7 downto 0);
signal cpu_data_out: Std_Logic_Vector(7 downto 0);
signal cpu_alu : Std_Logic_Vector(15 downto 0);
signal cpu_cc : Std_Logic_Vector(7 downto 0);
signal cpu_irq : Std_Logic;
signal cpu_nmi : Std_Logic;
signal cpu_firq : std_logic;
 
constant width : integer := 8;
constant memsize : integer := 128;
 
type rom_array is array(0 to memsize-1) of std_logic_vector(width-1 downto 0);
 
constant rom_data : rom_array :=
(
"00010000", -- $F800 LDS #$F878 (Point to dummy return to test stack)
"11001110",
"11111000",
"01111000",
"10000110", -- $F804 LDA #$E0 *** START
"11100000",
"00011111", -- $F806 TFR A,DPR
"10001011",
---------------------------
-- "10001101", -- $F80E BSR WAITRDY $F86A
-- "01100000",
"10001101", -- $F808 BSR $F874 -- test sub call
"01101010",
---------------------------
"10000110", -- $F80A LDA #$E0
"11100000",
"10010111", -- $F80C STA <$E016
"00010110",
---------------------------
-- "10001101", -- $F80E BSR WAITRDY $F86A
-- "01011010",
"10001101", -- $F80E BSR $F810
"00000000",
--------------------------
"10000110", -- $F810 LDA #$01
"00000001",
"10010111", -- $F812 STA <$E011
"00010001",
"10000110", -- $F814 LDA #$EF
"11101111",
"10010111", -- $F816 STA <$E017
"00010111",
--------------------------
-- "10001101", -- $F818 BSR WAITRDY $F86A
-- "01010000",
"10001101", -- $F818 BSR $F816
"00000000",
--------------------------
"00010000", -- $F81A LDY #$F800
"10001110",
"11111000",
"00000000",
"11000110", -- $F81E LDB #$7C
"01111100",
"10000110", -- $F820 LDA #$01 *** RDLP1
"00000001",
"10010111", -- $F822 STA <$E012
"00010010",
"11010111", -- $F824 STB <$E013
"00010011",
"10000110", -- $F826 LDA #$F4
"11110100",
"10010111", -- $F828 STA <$E014
"00010100",
"01001111", -- $F82A CLRA
"10010111", -- $F82B STA <$E015
"00010101",
"10001110", -- $F82D LDX #512
"00000010",
"00000000",
"10000110", -- $F830 LDA #$20
"00100000",
"10010111", -- $F832 STA <$E017
"00010111",
--------------------------
-- "10001101", -- $F834 BSR WAITRDY $F86A
-- "00110100",
"10001101", -- $F834 BSR *
"00000000",
--------------------------
"10010110", -- $F836 LDA <$E017 *** WAITDRQ
"00010111",
"10000101", -- $F838 BITA #$08
"00001000",
"00100111", -- $F83A BEQ WAITDRQ
"11111010",
"10010110", -- $F83C LDA <$E010
"00010000",
"10100111", -- $F83E STA ,Y+
"10100000",
"00110000", -- $F840 LEAX -1,X
"00011111",
"10001100", -- $F842 CMPX #$0000
"00000000",
"00000000",
"00100110", -- $F845 BNE RDLP2
"11110011",
--------------------------
-- "10001101", -- $F847 BSR WAITRDY $F86A
-- "00100001",
"10001101", -- $F847 BSR $F841
"00000000",
--------------------------
"01011100", -- $F849 INCB
"11000001", -- $F84A CMPB #$80
"10000000",
"00100110", -- $F84C BNE RDLP1
"11010110",
"10001110", -- $F84E LDX #$FF97
"11111111",
"10010111",
"00010000", -- $F851 LDY #$F000
"10001110",
"11110000",
"00000000",
"11000110", -- $F855 LDB #$61
"01100001",
"10100110", -- $F857 LDA 0,X+ *** MOVELP
"10000000",
"10100111", -- $F859 STA 0,Y+
"10100000",
"01011010", -- $F85B DECB
----------------------------
-- "00100110", -- $F85C BNE MOVELP
-- "11111001",
"00100110", --$F85C BNE $F861
"00000011",
----------------------------
"01111110", -- $F85E JMP $F000
"11110000",
"00000000",
"00001111", -- $F861 CLR <$E030
"00110000",
"01001111", -- $F863 CLRA
"00011111", -- $F864 TFR A,DPR
"10001011",
"01101110", -- $F866 JMP [$FFFE]
"10011111",
"11111111",
"11111110",
--
-- Wait for Ready
--
"10010110", -- $F86A LDA <$E017 *** WAITRDY
"00010111",
"00101011", -- $F86C BMI WAITRDY
"11111100",
"10010110", -- $F86E LDA <$E017
"00010111",
"10000101", -- $F870 BITA #$40
"01000000",
"00100111", -- $F872 BNE WAITRQY
"11110110",
"00111001", -- $F874 RTS
"00010010", -- $F875 NOP
"11111000", -- $F876 FDB $F80A -- dummy sub return
"00001010",
"11111000", -- $F878 FDB $F800
"00000000",
"11111000", -- $F87A FDB $F800
"00000000",
"11111000", -- $F87C FDB $F800
"00000000",
"11111000", -- $F87E FDB $F800
"00000000"
);
 
component cpu09
port (
clk: in std_logic;
rst: in std_logic;
rw: out std_logic; -- Asynchronous memory interface
vma: out std_logic;
address: out std_logic_vector(15 downto 0);
data_in: in std_logic_vector(7 downto 0);
data_out: out std_logic_vector(7 downto 0);
halt: in std_logic;
hold: in std_logic;
irq: in std_logic;
nmi: in std_logic;
firq: in std_logic;
test_alu: out std_logic_vector(15 downto 0);
test_cc: out std_logic_vector(7 downto 0)
);
end component cpu09;
 
 
begin
cpu : cpu09 port map (
clk => SysClk,
rst => cpu_reset,
rw => cpu_rw,
vma => cpu_vma,
address => cpu_addr(15 downto 0),
data_in => cpu_data_in,
data_out => cpu_data_out,
halt => '0',
hold => '0',
irq => cpu_irq,
nmi => cpu_nmi,
firq => cpu_firq,
test_alu => cpu_alu,
test_cc => cpu_cc
);
 
-- *** Test Bench - User Defined Section ***
tb : PROCESS
variable count : integer;
BEGIN
 
cpu_reset <= '0';
SysClk <= '0';
cpu_irq <= '0';
cpu_nmi <= '0';
cpu_firq <= '0';
 
for count in 0 to 512 loop
SysClk <= '0';
if count = 0 then
cpu_reset <= '1';
elsif count = 1 then
cpu_reset <= '0';
end if;
wait for 100 ns;
SysClk <= '1';
wait for 100 ns;
end loop;
 
wait; -- will wait forever
END PROCESS;
-- *** End Test Bench - User Defined Section ***
 
 
rom : PROCESS( cpu_addr )
begin
cpu_data_in <= rom_data(conv_integer(cpu_addr(6 downto 0)));
end process;
 
end behavior; --===================== End of architecture =======================--
 
/vhdl/testbench3.vhd
0,0 → 1,186
--===========================================================================----
--
-- T E S T B E N C H tesetbench3 - CPU09 Testbench.
--
-- www.OpenCores.Org - September 2003
-- This core adheres to the GNU public license
--
-- File name : Testbench3.vhd
--
-- Purpose : cpu09 Microprocessor Test Bench 3
-- Contains ROM to test interrupts
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
-- ieee.std_logic_arith
-- ieee.numeric_std
--
-- Uses : cpu09 (cpu09.vhd) CPU core
--
-- Author : John E. Kent
-- dilbert57@opencores.org
--
--===========================================================================----
--
-- Revision History:
--===========================================================================--
--
-- Version 0.1 - 12st April 2003 - John Kent
-- First version
--
-- Version 1.0 - 6 Sep 2003 - John Kent
-- Initial release to Open Cores
--
--===========================================================================--
 
library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.all;
 
entity my_testbench is
end my_testbench;
 
-------------------------------------------------------------------------------
-- Architecture for memio Controller Unit
-------------------------------------------------------------------------------
architecture behavior of my_testbench is
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
signal cpu_irq : std_Logic;
signal cpu_firq : std_logic;
signal cpu_nmi : std_logic;
 
-- CPU Interface signals
signal SysClk : Std_Logic;
signal cpu_reset : Std_Logic;
signal cpu_rw : Std_Logic;
signal cpu_vma : Std_Logic;
signal cpu_addr : Std_Logic_Vector(15 downto 0);
signal cpu_data_in : Std_Logic_Vector(7 downto 0);
signal cpu_data_out: Std_Logic_Vector(7 downto 0);
signal cpu_alu : Std_Logic_Vector(15 downto 0);
signal cpu_cc : Std_Logic_Vector(7 downto 0);
 
constant width : integer := 8;
constant memsize : integer := 64;
 
type rom_array is array(0 to memsize-1) of std_logic_vector(width-1 downto 0);
 
constant rom_data : rom_array :=
(
"00010000", "11001110", "11111000", "00110000", -- F800 - 10CE F830 RET1 LDS #STACK
"00111111", -- F804 - 3F SWI
"00010000", "00111111", -- F805 - 103F SWIVEC SWI2
"00010001", "00111111", -- F807 - 113F SWI2VEC SWI3
"00111011", -- F809 - 3B SWI3VEC RTI
"00100000", "11111110", -- F80A - 20 FE BRA *
"10110001", -- F80C - B1 STACK3 FCB $B1 ; CC
"00110010", -- F80D - 32 FCB $32 ; ACCA
"00110011", -- F8OE - 33 FCB $33 ; ACCB
"00110100", -- F8OF - 34 FCB $34 ; DPR
"00110101", "00110110", -- F810 - 3536 FDB $3536 ; IX
"00110111", "00111000", -- F812 - 3738 FDB $3738 ; IY
"00111001", "00111010", -- F814 - 393A FDB $393A ; UP
"11111000", "00001001", -- F816 - F809 FDB SWI3VEC ; PC
"10100001", -- F818 - A1 STACK2 FCB $A1 ; CC
"00100010", -- F819 - 22 FCB $22 ; ACCA
"00100011", -- F81A - 23 FCB $23 ; ACCB
"00100100", -- F81B - 24 FCB $24 ; DPR
"00100101", "00100110", -- F81C - 2526 FDB $2526 ; IX
"00100111", "00101000", -- F81E - 2728 FDB $2728 ; IY
"00101001", "00101010", -- F820 - 292A FDB $292A ; UP
"11111000", "00001001", -- F822 - F809 FDB SWI3VEC ; PC
"10010001", -- F824 - 91 STACK1 FCB $91 ; CC
"00010010", -- F825 - 12 FCB $12 ; ACCA
"00010011", -- F826 - 13 FCB $13 ; ACCB
"00010100", -- F827 - 14 FCB $14 ; DPR
"00010101", "00010110", -- F828 - 1516 FDB $1516 ; IX
"00010111", "00011000", -- F82A - 1718 FDB $1718 ; IY
"00011001", "00011010", -- F82C - 191A FDB $191A ; UP
"11111000", "00000000", -- F82E - F800 FDB RESET ; PC
"11111000", "00000000", -- F830 - F800 STACK FDB RESET ; RESV
"11111000", "00001001", -- F832 - F809 FDB SWIVEC3 ; SWI3
"11111000", "00000111", -- F834 - F807 FDB SWIVEC2 ; SWI2
"11111000", "00000000", -- F836 - F800 fdb RESET ; FIRQ
"11111000", "00000000", -- F838 - F800 fdb RESET ; IRQ
"11111000", "00000101", -- F83A - F805 fdb SWIVEC ; SWI
"11111000", "00000000", -- F83C - F800 fcb RESET ; NMI
"11111000", "00000000" -- F83E - F800 fdb RESET ; Reset
);
 
component cpu09
port (
clk: in std_logic;
rst: in std_logic;
rw: out std_logic; -- Asynchronous memory interface
vma: out std_logic;
address: out std_logic_vector(15 downto 0);
data_in: in std_logic_vector(7 downto 0);
data_out: out std_logic_vector(7 downto 0);
halt: in std_logic;
hold: in std_logic;
irq: in std_logic;
nmi: in std_logic;
firq: in std_logic;
test_alu: out std_logic_vector(15 downto 0);
test_cc: out std_logic_vector(7 downto 0)
);
end component cpu09;
 
 
begin
cpu : cpu09 port map (
clk => SysClk,
rst => cpu_reset,
rw => cpu_rw,
vma => cpu_vma,
address => cpu_addr(15 downto 0),
data_in => cpu_data_in,
data_out => cpu_data_out,
halt => '0',
hold => '0',
irq => cpu_irq,
nmi => cpu_nmi,
firq => cpu_firq,
test_alu => cpu_alu,
test_cc => cpu_cc
);
 
-- *** Test Bench - User Defined Section ***
tb : PROCESS
variable count : integer;
BEGIN
 
cpu_reset <= '0';
SysClk <= '0';
cpu_irq <= '0';
cpu_nmi <= '0';
cpu_firq <= '0';
 
for count in 0 to 512 loop
SysClk <= '0';
if count = 0 then
cpu_reset <= '1';
elsif count = 1 then
cpu_reset <= '0';
end if;
wait for 100 ns;
SysClk <= '1';
wait for 100 ns;
end loop;
 
wait; -- will wait forever
END PROCESS;
-- *** End Test Bench - User Defined Section ***
 
 
rom : PROCESS( cpu_addr )
begin
cpu_data_in <= rom_data(conv_integer(cpu_addr(5 downto 0)));
end process;
 
end behavior; --===================== End of architecture =======================--
 
/vhdl/testbench4.vhd
0,0 → 1,161
--===========================================================================--
--
-- MC6809 Microprocessor Test Bench 4
-- Test Software - SBUG ROM
--
--
-- John Kent 12st April 2003
--
--
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use ieee.numeric_std.all;
 
entity my_testbench is
end my_testbench;
 
-------------------------------------------------------------------------------
-- Architecture for memio Controller Unit
-------------------------------------------------------------------------------
architecture behavior of my_testbench is
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
signal cpu_irq : std_Logic;
signal cpu_firq : std_logic;
signal cpu_nmi : std_logic;
 
-- CPU Interface signals
signal SysClk : Std_Logic;
signal cpu_reset : Std_Logic;
signal cpu_rw : Std_Logic;
signal cpu_vma : Std_Logic;
signal cpu_addr : Std_Logic_Vector(15 downto 0);
signal cpu_data_in : Std_Logic_Vector(7 downto 0);
signal cpu_data_out: Std_Logic_Vector(7 downto 0);
signal cpu_halt : Std_logic;
signal cpu_hold : Std_logic;
signal cpu_alu : Std_Logic_Vector(15 downto 0);
signal cpu_cc : Std_Logic_Vector(7 downto 0);
signal rom_data_out: Std_Logic_Vector(7 downto 0);
signal ram_data_out: Std_Logic_Vector(7 downto 0);
signal ram_cs : Std_Logic;
component cpu09
port (
clk: in std_logic;
rst: in std_logic;
rw: out std_logic; -- Asynchronous memory interface
vma: out std_logic;
address: out std_logic_vector(15 downto 0);
data_in: in std_logic_vector(7 downto 0);
data_out: out std_logic_vector(7 downto 0);
halt: in std_logic;
hold: in std_logic;
irq: in std_logic;
nmi: in std_logic;
firq: in std_logic;
test_alu: out std_logic_vector(15 downto 0);
test_cc: out std_logic_vector(7 downto 0)
);
end component;
 
 
component sbug_rom
Port (
MEMclk : in std_logic;
MEMaddr : in std_logic_vector (10 downto 0);
MEMrdata : out std_logic_vector (7 downto 0)
);
end component;
 
component block_ram
Port (
MEMclk : in std_logic;
MEMcs : in std_logic;
MEMrw : in std_logic;
MEMaddr : in std_logic_vector (10 downto 0);
MEMrdata : out std_logic_vector (7 downto 0);
MEMwdata : in std_logic_vector (7 downto 0)
);
end component;
 
begin
my_cpu : cpu09 port map (
clk => SysClk,
rst => cpu_reset,
rw => cpu_rw,
vma => cpu_vma,
address => cpu_addr(15 downto 0),
data_in => cpu_data_in,
data_out => cpu_data_out,
halt => cpu_halt,
hold => cpu_hold,
irq => cpu_irq,
nmi => cpu_nmi,
firq => cpu_firq,
test_alu => cpu_alu,
test_cc => cpu_cc
);
 
 
my_ram : block_ram port map (
MEMclk => SysClk,
MEMcs => ram_cs,
MEMrw => cpu_rw,
MEMaddr => cpu_addr(10 downto 0),
MEMrdata => ram_data_out,
MEMwdata => cpu_data_out
);
 
my_rom : sbug_rom port map (
MEMclk => SysClk,
MEMaddr => cpu_addr(10 downto 0),
MEMrdata => rom_data_out
);
 
-- *** Test Bench - User Defined Section ***
tb : PROCESS
variable count : integer;
BEGIN
 
cpu_reset <= '0';
SysClk <= '0';
cpu_irq <= '0';
cpu_nmi <= '0';
cpu_firq <= '0';
cpu_halt <= '0';
cpu_hold <= '0';
 
for count in 0 to 512 loop
SysClk <= '0';
if count = 0 then
cpu_reset <= '1';
elsif count = 1 then
cpu_reset <= '0';
end if;
wait for 100 ns;
SysClk <= '1';
wait for 100 ns;
end loop;
 
wait; -- will wait forever
END PROCESS;
-- *** End Test Bench - User Defined Section ***
 
 
rom : PROCESS( cpu_addr, rom_data_out, ram_data_out )
begin
if( cpu_addr(15 downto 11) = "11111" ) then
cpu_data_in <= rom_data_out;
ram_cs <= '0';
else
cpu_data_in <= ram_data_out;
ram_cs <= '1';
end if;
end process;
 
end behavior; --===================== End of architecture =======================--
 
/vhdl/System09.npl
0,0 → 1,37
JDF E
// Created by ISE ver 1.0
PROJECT System09
DESIGN system09 Normal
DEVKIT xc2s300e-6pq208
DEVFAM spartan2e
FLOW XST VHDL
STIMULUS testbench1.vhd Normal
STIMULUS testbench2.vhd Normal
STIMULUS testbench3.vhd Normal
STIMULUS System09_tb.vhd Normal
MODULE ioport.vhd
MODSTYLE ioport Normal
MODULE rxunit2.vhd
MODSTYLE rxunit Normal
MODULE txunit2.vhd
MODSTYLE txunit Normal
MODULE cpu09.vhd
MODSTYLE cpu09 Normal
MODULE clkunit2.vhd
MODSTYLE clkunit Normal
MODULE datram.vhd
MODSTYLE dat_ram Normal
MODULE timer.vhd
MODSTYLE timer Normal
MODULE System09.vhd
MODSTYLE system09 Normal
MODULE sbug.vhd
MODSTYLE boot_rom Normal
MODULE miniUART2.vhd
MODSTYLE miniuart Normal
 
[STRATEGY-LIST]
Normal=True, 1062166682
 
[Normal]
p_impactConfigMode=xstvhd, SPARTAN2E, Implementation.t_impactProgrammingTool, 1031246025, Slave Serial
/vhdl/datram.vhd
0,0 → 1,184
--===========================================================================--
--
-- S Y N T H E Z I A B L E Dynamic Address Translation Registers
--
-- www.OpenCores.Org - December 2002
-- This core adheres to the GNU public license
--
-- File name : datram.vhd
--
-- entity name : dat_ram
--
-- Purpose : Implements a Dynamic Address Translation RAM module
-- Maps the high order 4 address bits to 8 address lines
-- extending the memory addressing range to 1 Mbytes
-- Memory segments are mapped on 4 KByte boundaries
-- The DAT registers map to the top of memory
-- ($FFF0 - $FFFF) and are write only so can map over ROM.
-- Since the DAT is not supported by SWTBUG for the 6800,
-- the resgisters reset state map the bottom 64K of RAM.
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
--
-- Author : John E. Kent
--
--===========================================================================----
--
-- Revision History:
--
-- Date Revision Author
-- 10 Nov 2002 0.1 John Kent
--
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity dat_ram is
port (
clk : in std_logic;
rst : in std_logic;
cs : in std_logic;
rw : in std_logic;
addr_hi : in std_logic_vector(3 downto 0);
addr_lo : in std_logic_vector(3 downto 0);
data_in : in std_logic_vector(7 downto 0);
data_out : out std_logic_vector(7 downto 0));
end;
 
architecture datram_arch of dat_ram is
signal dat_reg0 : std_logic_vector(7 downto 0);
signal dat_reg1 : std_logic_vector(7 downto 0);
signal dat_reg2 : std_logic_vector(7 downto 0);
signal dat_reg3 : std_logic_vector(7 downto 0);
signal dat_reg4 : std_logic_vector(7 downto 0);
signal dat_reg5 : std_logic_vector(7 downto 0);
signal dat_reg6 : std_logic_vector(7 downto 0);
signal dat_reg7 : std_logic_vector(7 downto 0);
signal dat_reg8 : std_logic_vector(7 downto 0);
signal dat_reg9 : std_logic_vector(7 downto 0);
signal dat_reg10 : std_logic_vector(7 downto 0);
signal dat_reg11 : std_logic_vector(7 downto 0);
signal dat_reg12 : std_logic_vector(7 downto 0);
signal dat_reg13 : std_logic_vector(7 downto 0);
signal dat_reg14 : std_logic_vector(7 downto 0);
signal dat_reg15 : std_logic_vector(7 downto 0);
 
begin
 
---------------------------------
--
-- Write DAT RAM
--
---------------------------------
 
dat_write : process( clk, rst, addr_lo, cs, rw, data_in )
begin
if clk'event and clk = '0' then
if rst = '1' then
dat_reg0 <= "00000000";
dat_reg1 <= "00000001";
dat_reg2 <= "00000010";
dat_reg3 <= "00000011";
dat_reg4 <= "00000100";
dat_reg5 <= "00000101";
dat_reg6 <= "00000110";
dat_reg7 <= "00000111";
dat_reg8 <= "00001000";
dat_reg9 <= "00001001";
dat_reg10 <= "00001010";
dat_reg11 <= "00001011";
dat_reg12 <= "00001100";
dat_reg13 <= "00001101";
dat_reg14 <= "00001110";
dat_reg15 <= "00001111";
else
if cs = '1' and rw = '0' then
case addr_lo is
when "0000" =>
dat_reg0 <= data_in;
when "0001" =>
dat_reg1 <= data_in;
when "0010" =>
dat_reg2 <= data_in;
when "0011" =>
dat_reg3 <= data_in;
when "0100" =>
dat_reg4 <= data_in;
when "0101" =>
dat_reg5 <= data_in;
when "0110" =>
dat_reg6 <= data_in;
when "0111" =>
dat_reg7 <= data_in;
when "1000" =>
dat_reg8 <= data_in;
when "1001" =>
dat_reg9 <= data_in;
when "1010" =>
dat_reg10 <= data_in;
when "1011" =>
dat_reg11 <= data_in;
when "1100" =>
dat_reg12 <= data_in;
when "1101" =>
dat_reg13 <= data_in;
when "1110" =>
dat_reg14 <= data_in;
when "1111" =>
dat_reg15 <= data_in;
when others =>
null;
end case;
end if;
end if;
end if;
end process;
 
dat_read : process( addr_hi,
dat_reg0, dat_reg1, dat_reg2, dat_reg3,
dat_reg4, dat_reg5, dat_reg6, dat_reg7,
dat_reg8, dat_reg9, dat_reg10, dat_reg11,
dat_reg12, dat_reg13, dat_reg14, dat_reg15 )
begin
case addr_hi is
when "0000" =>
data_out <= dat_reg0;
when "0001" =>
data_out <= dat_reg1;
when "0010" =>
data_out <= dat_reg2;
when "0011" =>
data_out <= dat_reg3;
when "0100" =>
data_out <= dat_reg4;
when "0101" =>
data_out <= dat_reg5;
when "0110" =>
data_out <= dat_reg6;
when "0111" =>
data_out <= dat_reg7;
when "1000" =>
data_out <= dat_reg8;
when "1001" =>
data_out <= dat_reg9;
when "1010" =>
data_out <= dat_reg10;
when "1011" =>
data_out <= dat_reg11;
when "1100" =>
data_out <= dat_reg12;
when "1101" =>
data_out <= dat_reg13;
when "1110" =>
data_out <= dat_reg14;
when "1111" =>
data_out <= dat_reg15;
when others =>
null;
end case;
end process;
 
end datram_arch;
/vhdl/miniUART2.vhd
0,0 → 1,288
--===========================================================================--
--
-- S Y N T H E Z I A B L E miniUART C O R E
--
-- www.OpenCores.Org - January 2000
-- This core adheres to the GNU public license
--
-- Design units : miniUART core for the System68
--
-- File name : miniuart2.vhd
--
-- Purpose : Implements an miniUART device for communication purposes
-- between the CPU68 processor and the Host computer through
-- an RS-232 communication protocol.
--
-- Dependencies : ieee.std_logic_1164
-- ieee.numeric_std
--
--===========================================================================--
-------------------------------------------------------------------------------
-- Revision list
-- Version Author Date Changes
--
-- 0.1 Ovidiu Lupas 15 January 2000 New model
-- 1.0 Ovidiu Lupas January 2000 Synthesis optimizations
-- 2.0 Ovidiu Lupas April 2000 Bugs removed - RSBusCtrl
-- the RSBusCtrl did not process all possible situations
--
-- olupas@opencores.org
--
-- 3.0 John Kent October 2002 Changed Status bits to match mc6805
-- Added CTS, RTS, Baud rate control
-- & Software Reset
-- 3.1 John Kent 5 January 2003 Added Word Format control a'la mc6850
-- 3.2 John Kent 19 July 2003 Latched Data input to UART
-- 3.3 John Kent 6 September 2003 Changed Clock Edge.
-- dilbert57@opencores.org
--
-------------------------------------------------------------------------------
-- Entity for miniUART Unit - 9600 baudrate --
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
entity miniUART is
port (
SysClk : in Std_Logic; -- System Clock
rst : in Std_Logic; -- Reset input (active high)
cs : in Std_Logic;
rw : in Std_Logic;
RxD : in Std_Logic;
TxD : out Std_Logic;
CTS_n : in Std_Logic;
RTS_n : out Std_Logic;
Irq : out Std_Logic; -- interrupt
Addr : in Std_Logic; -- Register Select
DataIn : in Std_Logic_Vector(7 downto 0); --
DataOut : out Std_Logic_Vector(7 downto 0)); --
end; --================== End of entity ==============================--
-------------------------------------------------------------------------------
-- Architecture for miniUART Controller Unit
-------------------------------------------------------------------------------
architecture uart of miniUART is
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
signal RxData : Std_Logic_Vector(7 downto 0); --
signal TxData : Std_Logic_Vector(7 downto 0); --
signal StatReg : Std_Logic_Vector(7 downto 0); -- status register
-- StatReg detailed
-----------+--------+--------+--------+--------+--------+--------+--------+
-- Irq | PErr | ORErr | FErr | CTS | DCD | TBufE | DRdy |
-----------+--------+--------+--------+--------+--------+--------+--------+
signal CtrlReg : Std_Logic_Vector(7 downto 0); -- control register
-- CtrlReg detailed
-----------+--------+--------+--------+--------+--------+--------+--------+
-- IrqEnb |TxCtl(1)|TxCtl(0)|WdFmt(2)|WdFmt(1)|WdFmt(0)|BdCtl(1)|BdCtl(0)|
-----------+--------+--------+--------+--------+--------+--------+--------+
-- IrqEnb
-- 0 - Rx Interrupt disabled
-- 1 - Rx Interrupt enabled
-- TxCtl
-- 0 1 - Tx Interrupt Enable
-- 1 0 - RTS high
-- WdFmt
-- 0 0 0 - 7 data, even parity, 2 stop
-- 0 0 1 - 7 data, odd parity, 2 stop
-- 0 1 0 - 7 data, even parity, 1 stop
-- 0 1 1 - 7 data, odd parity, 1 stop
-- 1 0 0 - 8 data, no parity, 2 stop
-- 1 0 1 - 8 data, no parity, 1 stop
-- 1 1 0 - 8 data, even parity, 1 stop
-- 1 1 1 - 8 data, odd parity, 1 stop
-- BdCtl
-- 0 0 - Baud Clk divide by 1 (not implemented)
-- 0 1 - Baud Clk divide by 16
-- 1 0 - Baud Clk divide by 64
-- 1 1 - reset
signal EnabRx : Std_Logic; -- Enable RX unit
signal EnabTx : Std_Logic; -- Enable TX unit
signal DRdy : Std_Logic; -- Receive Data ready
signal TBufE : Std_Logic; -- Transmit buffer empty
signal FErr : Std_Logic; -- Frame error
signal OErr : Std_Logic; -- Output error
signal PErr : Std_Logic; -- Parity Error
signal Read : Std_Logic; -- Read receive buffer
signal Load : Std_Logic; -- Load transmit buffer
signal Int : Std_Logic; -- Interrupt bit
signal Reset : Std_Logic; -- Reset (Software & Hardware)
-----------------------------------------------------------------------------
-- Baud rate Generator
-----------------------------------------------------------------------------
component ClkUnit
port (
Clk : in Std_Logic; -- System Clock
Reset : in Std_Logic; -- Reset input
EnableRX : out Std_Logic; -- Control signal
EnableTX : out Std_Logic; -- Control signal
BaudRate : in Std_Logic_Vector(1 downto 0));
end component;
-----------------------------------------------------------------------------
-- Receive Unit
-----------------------------------------------------------------------------
component RxUnit
port (
Clk : in Std_Logic; -- Clock signal
Reset : in Std_Logic; -- Reset input
Enable : in Std_Logic; -- Enable input
RxD : in Std_Logic; -- RS-232 data input
ReadD : in Std_Logic; -- Read data signal
Format : in Std_Logic_Vector(2 downto 0); -- word format
FRErr : out Std_Logic; -- Status signal
ORErr : out Std_Logic; -- Status signal
PAErr : out Std_logic; -- Status signal
DARdy : out Std_Logic; -- Status signal
DAOut : out Std_Logic_Vector(7 downto 0));
end component;
-----------------------------------------------------------------------------
-- Transmitter Unit
-----------------------------------------------------------------------------
component TxUnit
port (
Clk : in Std_Logic; -- Clock signal
Reset : in Std_Logic; -- Reset input
Enable : in Std_Logic; -- Enable input
LoadD : in Std_Logic; -- Load transmit data
Format : in Std_Logic_Vector(2 downto 0); -- word format
TxD : out Std_Logic; -- RS-232 data output
TBE : out Std_Logic; -- Tx buffer empty
DataO : in Std_Logic_Vector(7 downto 0));
end component;
begin
-----------------------------------------------------------------------------
-- Instantiation of internal components
-----------------------------------------------------------------------------
 
ClkDiv : ClkUnit port map (
Clk => SysClk,
EnableRx => EnabRX,
EnableTx => EnabTX,
BaudRate => CtrlReg(1 downto 0),
Reset => Reset);
TxDev : TxUnit port map (
Clk => SysClk,
Reset => Reset,
Enable => EnabTX,
LoadD => Load,
Format => CtrlReg(4 downto 2),
TxD => TxD,
TBE => TBufE,
DataO => TxData);
 
RxDev : RxUnit port map (
Clk => SysClk,
Reset => Reset,
Enable => EnabRX,
RxD => RxD,
ReadD => Read,
Format => CtrlReg(4 downto 2),
FRErr => FErr,
ORErr => OErr,
PAErr => PErr,
DARdy => DRdy,
DAOut => RxData);
 
-----------------------------------------------------------------------------
-- Implements the controller for Rx&Tx units
-----------------------------------------------------------------------------
RSBusCtrl : process(SysClk, Reset, DRdy, TBufE, FErr, OErr, CTS_n, PErr, Int, CtrlReg)
variable StatM : Std_Logic_Vector(7 downto 0);
begin
if SysClk'event and SysClk='0' then
if Reset = '1' then
StatM := "00000000";
Int <= '0';
else
StatM(0) := DRdy;
StatM(1) := TBufE;
StatM(2) := '0'; -- DCD
StatM(3) := CTS_n;
StatM(4) := FErr; -- Framing error
StatM(5) := OErr; -- Overrun error
StatM(6) := PErr; -- Parity error
StatM(7) := Int;
Int <= (CtrlReg(7) and DRdy) or
((not CtrlReg(6)) and CtrlReg(5) and TBufE);
end if;
 
RTS_n <= CtrlReg(6) and not CtrlReg(5);
Irq <= Int;
StatReg <= StatM;
end if;
end process;
 
-----------------------------------------------------------------------------
-- Combinational section
-----------------------------------------------------------------------------
 
control_strobe: process(SysClk, Reset, cs, rw, Addr, DataIn, CtrlReg, TxData )
begin
if SysClk'event and SysClk='0' then
if (reset = '1') then
CtrlReg <= "00000000";
Load <= '0';
Read <= '0';
else
if cs = '1' then
if Addr = '1' then
CtrlReg <= CtrlReg;
if rw = '0' then -- write data register
TxData <= DataIn;
Load <= '1';
Read <= '0';
else -- read Data Register
TxData <= TxData;
Load <= '0';
Read <= '1';
end if; -- rw
else -- read Status Register
TxData <= TxData;
Load <= '0';
Read <= '0';
if rw = '0' then -- write control register
CtrlReg <= DataIn;
else -- read control Register
CtrlReg <= CtrlReg;
end if; -- rw
end if; -- Addr
else -- not selected
Load <= '0';
Read <= '0';
CtrlReg <= CtrlReg;
end if; -- cs
end if; -- reset
end if; -- SysClk
end process;
 
---------------------------------------------------------------
--
-- set data output mux
--
--------------------------------------------------------------
 
data_port: process(Addr, StatReg, RxData )
begin
if Addr = '1' then
DataOut <= RxData; -- read data register
else
DataOut <= StatReg; -- read status register
end if; -- Addr
end process;
 
---------------------------------------------------------------
--
-- reset may be hardware or software
--
---------------------------------------------------------------
 
uart_reset: process(CtrlReg, rst )
begin
Reset <= (CtrlReg(1) and CtrlReg(0)) or rst;
end process;
 
end uart; --===================== End of architecture =======================--
 
/vhdl/rxunit2.vhd
0,0 → 1,341
--===========================================================================--
--
-- S Y N T H E Z I A B L E miniUART C O R E
--
-- www.OpenCores.Org - January 2000
-- This core adheres to the GNU public license
--
-- Design units : miniUART core for the System68
--
-- File name : rxunit2.vhd
--
-- Purpose : Implements an miniUART device for communication purposes
-- between the cpu68 cpu and the Host computer through
-- an RS-232 communication protocol.
--
-- Dependencies : ieee.std_logic_1164.all;
-- ieee.numeric_std.all;
--
--===========================================================================--
-------------------------------------------------------------------------------
-- Revision list
-- Version Author Date Changes
--
-- 0.1 Ovidiu Lupas 15 January 2000 New model
-- 2.0 Ovidiu Lupas 17 April 2000 samples counter cleared for bit 0
-- olupas@opencores.org
--
-- 3.0 John Kent 5 January 2003 Added 6850 word format control
-- 3.1 John Kent 12 January 2003 Significantly revamped receive code.
-- 3.3 John Kent 6 September 2003 Changed Clock Edge.
-- dilbert57@opencores.org
-------------------------------------------------------------------------------
-- Description : Implements the receive unit of the miniUART core. Samples
-- 16 times the RxD line and retain the value in the middle of
-- the time interval.
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
-------------------------------------------------------------------------------
-- Receive unit
-------------------------------------------------------------------------------
entity RxUnit is
port (
Clk : in Std_Logic; -- system clock signal
Reset : in Std_Logic; -- Reset input
Enable : in Std_Logic; -- Enable input
RxD : in Std_Logic; -- RS-232 data input
ReadD : in Std_Logic; -- Read data signal
Format : in Std_Logic_Vector(2 downto 0);
FRErr : out Std_Logic; -- Status signal
ORErr : out Std_Logic; -- Status signal
PAErr : out Std_logic; -- Status Signal
DARdy : out Std_Logic; -- Status signal
DAOut : out Std_Logic_Vector(7 downto 0)
);
end; --================== End of entity ==============================--
-------------------------------------------------------------------------------
-- Architecture for receive Unit
-------------------------------------------------------------------------------
architecture Behaviour of RxUnit is
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
signal RxStart : Std_Logic; -- Start Receive Request
signal RxFinish : Std_Logic; -- Receive finished
signal RxValid : Std_Logic; -- Receive data valid
signal RxFalse : Std_Logic; -- False start flag
signal tmpRxD : Std_Logic; -- RxD buffer
signal tmpRxC : Std_Logic; -- Rx clock
signal tmpDRdy : Std_Logic; -- Data Ready flag
signal tmpRxVal : Std_Logic; -- Rx Data Valid
signal tmpRxFin : Std_Logic; -- Rx Finish
signal outErr : Std_Logic; -- Over run error bit
signal frameErr : Std_Logic; -- Framing error bit
signal ParityErr : Std_Logic; -- Parity Error Bit
signal RxParity : Std_Logic; -- Calculated RX parity bit
signal RxState : Std_Logic_Vector(3 downto 0); -- receive bit state
signal SampleCnt : Std_Logic_Vector(3 downto 0); -- samples on one bit counter
signal ShtReg : Std_Logic_Vector(7 downto 0); -- Shift Register
signal DataOut : Std_Logic_Vector(7 downto 0); -- Data Output register
 
constant CntOne : Std_Logic_Vector(3 downto 0):= "0001";
constant CntZero : Std_Logic_Vector(3 downto 0):= "0000";
 
begin
---------------------------------------------------------------------
-- Receiver Read process
---------------------------------------------------------------------
RcvRead : process(Clk, Reset, ReadD, RxValid, tmpRxVal, tmpDRdy )
begin
if Clk'event and Clk='0' then
if Reset = '1' then
tmpDRdy <= '0';
tmpRxVal <= '0';
else
if ReadD = '1' then
tmpDRdy <= '0'; -- Data was read
tmpRxVal <= tmpRxVal;
else
if RxValid = '1' and tmpRxVal = '0' then
tmpDRdy <= '1'; -- Data was received
tmpRxVal <= '1';
else
tmpDRdy <= tmpDRdy;
if RxValid = '0' and tmpRxVal = '1' then
tmpRxVal <= '0';
else
tmpRxVal <= tmpRxVal;
end if;
end if; -- RxValid
end if; -- ReadD
end if; -- reset
end if; -- clk
end process;
 
---------------------------------------------------------------------
-- Receiver Synchronisation process
---------------------------------------------------------------------
RcvSync : process(Clk, Reset, Enable, RxStart, RxFalse, RxFinish, RxD, SampleCnt )
variable CntIni : Std_Logic_Vector(3 downto 0);
variable CntAdd : Std_Logic_Vector(3 downto 0);
begin
if Clk'event and Clk='0' then
if Reset = '1' then
RxStart <= '0';
SampleCnt <= "0000";
CntIni := SampleCnt;
CntAdd := CntZero;
else
if Enable = '1' then
if RxFinish = '1' and RxStart = '0' then -- Are we looking for a start bit ?
if RxD = '0' then -- yes, look for Start Edge
RxStart <= '1'; -- we have a start edge
CntIni := CntZero;
CntAdd := CntZero;
else
RxStart <= '0'; -- no start, spin sample count
CntIni := SampleCnt;
CntAdd := CntOne;
end if;
else
if RxFinish = '0' and RxStart = '1' then -- have we received a start bit ?
RxStart <= '0'; -- yes, reset start request
else
if RxFalse = '1' and RxStart = '1' then -- false start ?
RxStart <= '0'; -- yep, reset start request
else
RxStart <= RxStart;
end if;
end if;
CntIni := SampleCnt;
CntAdd := CntOne;
end if; -- RxStart
else
CntIni := SampleCnt;
CntAdd := CntZero;
RxStart <= RxStart;
end if; -- enable
end if; -- reset
SampleCnt <= CntIni + CntAdd;
end if; -- clk
end process;
 
 
---------------------------------------------------------------------
-- Receiver Clock process
---------------------------------------------------------------------
RcvClock : process(Clk, Reset, SampleCnt, RxD, tmpRxD )
begin
if Clk'event and Clk='0' then
if Reset = '1' then
tmpRxC <= '0';
tmpRxD <= '1';
else
if SampleCnt = "1000" then
tmpRxD <= RxD;
else
tmpRxD <= tmpRxD;
end if;
 
if SampleCnt = "1111" then
tmpRxC <= '1';
else
tmpRxC <= '0';
end if;
end if; -- reset
end if; -- clk
end process;
 
---------------------------------------------------------------------
-- Receiver process
---------------------------------------------------------------------
RcvProc : process(Clk, Reset, RxState, tmpRxC, Enable, tmpRxD, RxStart,
frameErr, outErr, DataOut, tmpDRdy,
ShtReg, RxParity, parityErr, Format,
RxValid, RxFalse, RxFinish
)
begin
if Clk'event and Clk='0' then
if Reset = '1' then
frameErr <= '0';
outErr <= '0';
parityErr <= '0';
 
ShtReg <= "00000000"; -- Shift register
RxParity <= '0'; -- Parity bit
RxFinish <= '1'; -- Data RX finish flag
RxValid <= '0'; -- Data RX data valid flag
RxFalse <= '0';
RxState <= "1111";
DataOut <= "00000000";
else
if tmpRxC = '1' and Enable = '1' then
case RxState is
when "0000" | "0001" | "0010" | "0011" |
"0100" | "0101" | "0110" => -- data bits 0 to 6
ShtReg <= tmpRxD & ShtReg(7 downto 1);
RxParity <= RxParity xor tmpRxD;
parityErr <= parityErr;
frameErr <= frameErr;
outErr <= outErr;
RxValid <= '0';
DataOut <= DataOut;
RxFalse <= '0';
RxFinish <= '0';
if RxState = "0110" then
if Format(2) = '0' then
RxState <= "1000"; -- 7 data + parity
else
RxState <= "0111"; -- 8 data bits
end if; -- Format(2)
else
RxState <= RxState + CntOne;
end if; -- RxState
when "0111" => -- data bit 7
ShtReg <= tmpRxD & ShtReg(7 downto 1);
RxParity <= RxParity xor tmpRxD;
parityErr <= parityErr;
frameErr <= frameErr;
outErr <= outErr;
RxValid <= '0';
DataOut <= DataOut;
RxFalse <= '0';
RxFinish <= '0';
if Format(1) = '1' then -- parity bit ?
RxState <= "1000"; -- yes, go to parity
else
RxState <= "1001"; -- no, must be 2 stop bit bits
end if;
when "1000" => -- parity bit
if Format(2) = '0' then
ShtReg <= tmpRxD & ShtReg(7 downto 1); -- 7 data + parity
else
ShtReg <= ShtReg; -- 8 data + parity
end if;
RxParity <= RxParity;
if Format(0) = '0' then -- parity polarity ?
if RxParity = tmpRxD then -- check even parity
parityErr <= '1';
else
parityErr <= '0';
end if;
else
if RxParity = tmpRxD then -- check for odd parity
parityErr <= '0';
else
parityErr <= '1';
end if;
end if;
frameErr <= frameErr;
outErr <= outErr;
RxValid <= '0';
DataOut <= DataOut;
RxFalse <= '0';
RxFinish <= '0';
RxState <= "1001";
when "1001" => -- stop bit (Only one required for RX)
ShtReg <= ShtReg;
RxParity <= RxParity;
parityErr <= parityErr;
if tmpRxD = '1' then -- stop bit expected
frameErr <= '0'; -- yes, no framing error
else
frameErr <= '1'; -- no, framing error
end if;
if tmpDRdy = '1' then -- Has previous data been read ?
outErr <= '1'; -- no, overrun error
else
outErr <= '0'; -- yes, no over run error
end if;
RxValid <= '1';
DataOut <= ShtReg;
RxFalse <= '0';
RxFinish <= '1';
RxState <= "1111";
when others => -- this is the idle state
ShtReg <= ShtReg;
RxParity <= RxParity;
parityErr <= parityErr;
frameErr <= frameErr;
outErr <= outErr;
RxValid <= '0';
DataOut <= DataOut;
if RxStart = '1' and tmpRxD = '0' then -- look for start request
RxFalse <= '0';
RxFinish <= '0';
RxState <= "0000"; -- yes, read data
else
if RxStart = '1' and tmpRxD = '1' then -- start request, but no start bit
RxFalse <= '1';
else
RxFalse <= '0';
end if;
RxFinish <= '1';
RxState <= "1111"; -- otherwise idle
end if;
end case; -- RxState
else
ShtReg <= ShtReg;
RxParity <= RxParity;
parityErr <= parityErr;
frameErr <= frameErr;
outErr <= outErr;
RxValid <= RxValid;
DataOut <= DataOut;
RxFalse <= RxFalse;
RxFinish <= RxFinish;
RxState <= RxState;
end if; -- tmpRxC
end if; -- reset
end if; -- clk
end process;
 
DARdy <= tmpDRdy;
DAOut <= DataOut;
FRErr <= frameErr;
ORErr <= outErr;
PAErr <= parityErr;
 
end Behaviour; --==================== End of architecture ====================--
/vhdl/ioport.vhd
0,0 → 1,194
--===========================================================================----
--
-- S Y N T H E Z I A B L E ioport - 2 x 8 bit parallel I/O port
--
-- www.OpenCores.Org - September 2003
-- This core adheres to the GNU public license
--
-- File name : ioport.vhd
--
-- Purpose : dual 8 bit I/O module for System09
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
--
-- Uses : None
--
-- Author : John E. Kent
-- dilbert57@opencores.org
--
--===========================================================================----
--
-- Revision History:
--===========================================================================--
--
-- Version 0.1 - 11 Oct 2002
-- Used a loop counter for data direction & read port signals
-- Version 0.2 - 5 Sept 2003
-- Reduced to 2 x 8 bit ports
-- Version 1.0 - 6 Sept 2003 - John Kent
-- Realeased to open Cores
-- changed Clock Edge
--
--===========================================================================
--
--
-- John Kent - 6 Sept 2002
--
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity ioport is
port (
clk : in std_logic;
rst : in std_logic;
cs : in std_logic;
rw : in std_logic;
addr : in std_logic_vector(1 downto 0);
data_in : in std_logic_vector(7 downto 0);
data_out : out std_logic_vector(7 downto 0);
porta_io : inout std_logic_vector(7 downto 0);
portb_io : inout std_logic_vector(7 downto 0)
);
end;
 
architecture ioport_arch of ioport is
signal porta_ddr : std_logic_vector(7 downto 0);
signal portb_ddr : std_logic_vector(7 downto 0);
signal porta_data : std_logic_vector(7 downto 0);
signal portb_data : std_logic_vector(7 downto 0);
 
begin
 
 
--------------------------------
--
-- read I/O port
--
--------------------------------
 
ioport_read : process( addr,
porta_ddr, portb_ddr,
porta_data, portb_data,
porta_io, portb_io )
variable count : integer;
begin
case addr is
when "00" =>
for count in 0 to 7 loop
if porta_ddr(count) = '1' then
data_out(count) <= porta_data(count);
else
data_out(count) <= porta_io(count);
end if;
end loop;
 
when "01" =>
for count in 0 to 7 loop
if portb_ddr(count) = '1' then
data_out(count) <= portb_data(count);
else
data_out(count) <= portb_io(count);
end if;
end loop;
 
when "10" =>
data_out <= porta_ddr;
when "11" =>
data_out <= portb_ddr;
when others =>
data_out <= "00000000";
end case;
end process;
 
---------------------------------
--
-- Write I/O ports
--
---------------------------------
 
ioport_write : process( clk, rst, addr, cs, rw, data_in,
porta_data, portb_data,
porta_ddr, portb_ddr )
begin
if clk'event and clk = '0' then
if rst = '1' then
porta_data <= "00000000";
portb_data <= "00000000";
porta_ddr <= "00000000";
portb_ddr <= "00000000";
elsif cs = '1' and rw = '0' then
case addr is
when "00" =>
porta_data <= data_in;
portb_data <= portb_data;
porta_ddr <= porta_ddr;
portb_ddr <= portb_ddr;
when "01" =>
porta_data <= porta_data;
portb_data <= data_in;
porta_ddr <= porta_ddr;
portb_ddr <= portb_ddr;
when "10" =>
porta_data <= porta_data;
portb_data <= portb_data;
porta_ddr <= data_in;
portb_ddr <= portb_ddr;
when "11" =>
porta_data <= porta_data;
portb_data <= portb_data;
porta_ddr <= porta_ddr;
portb_ddr <= data_in;
when others =>
porta_data <= porta_data;
portb_data <= portb_data;
porta_ddr <= porta_ddr;
portb_ddr <= portb_ddr;
end case;
else
porta_data <= porta_data;
portb_data <= portb_data;
porta_ddr <= porta_ddr;
portb_ddr <= portb_ddr;
end if;
end if;
end process;
 
---------------------------------
--
-- direction control port a
--
---------------------------------
porta_direction : process ( porta_data, porta_ddr )
variable count : integer;
begin
for count in 0 to 7 loop
if porta_ddr(count) = '1' then
porta_io(count) <= porta_data(count);
else
porta_io(count) <= 'Z';
end if;
end loop;
end process;
---------------------------------
--
-- direction control port b
--
---------------------------------
portb_direction : process ( portb_data, portb_ddr )
variable count : integer;
begin
for count in 0 to 7 loop
if portb_ddr(count) = '1' then
portb_io(count) <= portb_data(count);
else
portb_io(count) <= 'Z';
end if;
end loop;
end process;
---------------------------------
 
end ioport_arch;
/vhdl/txunit2.vhd
0,0 → 1,232
--===========================================================================--
--
-- S Y N T H E Z I A B L E miniUART C O R E
--
-- www.OpenCores.Org - January 2000
-- This core adheres to the GNU public license
--
-- Design units : miniUART core for the System68
--
-- File name : txunit2.vhd
--
-- Purpose : Implements an miniUART device for communication purposes
-- between the CPU68 processor and the Host computer through
-- an RS-232 communication protocol.
--
-- Dependencies : IEEE.Std_Logic_1164
--
--===========================================================================--
-------------------------------------------------------------------------------
-- Revision list
-- Version Author Date Changes
--
-- 0.1 Ovidiu Lupas 15 January 2000 New model
-- 2.0 Ovidiu Lupas 17 April 2000 unnecessary variable removed
-- olupas@opencores.org
--
-- 3.0 John Kent 5 January 2003 added 6850 word format control
-- 3.1 John Kent 12 January 2003 Rearranged state machine code
-- 3.2 John Kent 30 March 2003 Revamped State machine
-- 3.3 John Kent 6 September 2003 Changed Clock Edge.
--
-- dilbert57@opencores.org
--
-------------------------------------------------------------------------------
-- Description :
-------------------------------------------------------------------------------
-- Entity for the Tx Unit --
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
 
-------------------------------------------------------------------------------
-- Transmitter unit
-------------------------------------------------------------------------------
entity TxUnit is
port (
Clk : in Std_Logic; -- Clock signal
Reset : in Std_Logic; -- Reset input
Enable : in Std_Logic; -- Enable input
LoadD : in Std_Logic; -- Load transmit data
Format : in Std_Logic_Vector(2 downto 0); -- word format
TxD : out Std_Logic; -- RS-232 data output
TBE : out Std_Logic; -- Tx buffer empty
DataO : in Std_Logic_Vector(7 downto 0));
end; --================== End of entity ==============================--
-------------------------------------------------------------------------------
-- Architecture for TxUnit
-------------------------------------------------------------------------------
architecture Behaviour of TxUnit is
type TxStateType is (TxReset_State, TxIdle_State, Start_State, Data_State, Parity_State, Stop_State );
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
signal TBuff : Std_Logic_Vector(7 downto 0); -- transmit buffer
signal tmpTBufE : Std_Logic; -- Transmit Buffer Empty
 
signal TReg : Std_Logic_Vector(7 downto 0); -- transmit register
signal TxParity : Std_logic; -- Parity Bit
signal DataCnt : Std_Logic_Vector(3 downto 0); -- Data Bit Counter
signal tmpTRegE : Std_Logic; -- Transmit Register empty
signal TxState : TxStateType;
 
signal NextTReg : Std_Logic_Vector(7 downto 0); -- transmit register
signal NextTxParity : Std_logic; -- Parity Bit
signal NextDataCnt : Std_Logic_Vector(3 downto 0); -- Data Bit Counter
signal NextTRegE : Std_Logic; -- Transmit Register empty
signal NextTxState : TxStateType;
begin
---------------------------------------------------------------------
-- Transmitter activation process
---------------------------------------------------------------------
TxSync : process(Clk, Reset, Enable, LoadD, DataO, tmpTBufE, tmpTRegE, TBuff )
begin
if Clk'event and Clk = '0' then
if Reset = '1' then
tmpTBufE <= '1';
TBuff <= "00000000";
else
if LoadD = '1' then
TBuff <= DataO;
tmpTBufE <= '0';
else
TBuff <= TBuff;
if (Enable = '1') and (tmpTBufE = '0') and (tmpTRegE = '1') then
tmpTBufE <= '1';
else
tmpTBufE <= tmpTBufE;
end if;
end if;
end if; -- reset
end if; -- clk
TBE <= tmpTBufE;
 
end process;
 
-----------------------------------------------------------------------------
-- Implements the Tx unit
-----------------------------------------------------------------------------
TxProc : process(TxState, TBuff, TReg, TxParity, DataCnt, Format, tmpTRegE, tmpTBufE)
begin
case TxState is
when TxReset_State =>
TxD <= '1';
NextTReg <= "00000000";
NextTxParity <= '0';
NextDataCnt <= "0000";
NextTRegE <= '1';
NextTxState <= TxIdle_State;
 
when Start_State =>
TxD <= '0'; -- Start bit
NextTReg <= TReg;
NextTxParity <= '0';
if Format(2) = '0' then
NextDataCnt <= "0110"; -- 7 data + parity
else
NextDataCnt <= "0111"; -- 8 data
end if;
NextTRegE <= '0';
NextTxState <= Data_State;
 
when Data_State =>
TxD <= TReg(0);
NextTReg <= '1' & TReg(7 downto 1);
NextTxParity <= TxParity xor TReg(0);
NextTRegE <= '0';
NextDataCnt <= DataCnt - "0001";
if DataCnt = "0000" then
if (Format(2) = '1') and (Format(1) = '0') then
if Format(0) = '0' then -- 8 data bits
NextTxState <= Stop_State; -- 2 stops
else
NextTxState <= TxIdle_State; -- 1 stop
end if;
else
NextTxState <= Parity_State; -- parity
end if;
else
NextTxState <= Data_State;
end if;
 
when Parity_State => -- 7/8 data + parity bit
if Format(0) = '0' then
TxD <= not( TxParity ); -- even parity
else
TXD <= TxParity; -- odd parity
end if;
NextTreg <= Treg;
NextTxParity <= '0';
NextTRegE <= '0';
NextDataCnt <= "0000";
if Format(1) = '0' then
NextTxState <= Stop_State; -- 2 stops
else
NextTxState <= TxIdle_State; -- 1 stop
end if;
 
when Stop_State => -- first stop bit
TxD <= '1'; -- 2 stop bits
NextTreg <= Treg;
NextTxParity <= '0';
NextDataCnt <= "0000";
NextTRegE <= '0';
NextTxState <= TxIdle_State;
 
when others => -- TxIdle_State (2nd Stop bit)
TxD <= '1';
NextTreg <= TBuff;
NextTxParity <= '0';
NextDataCnt <= "0000";
if (tmpTBufE = '0') and (tmpTRegE = '1') then
NextTRegE <= '0';
NextTxState <= Start_State;
else
NextTRegE <= '1';
NextTxState <= TxIdle_State;
end if;
 
end case; -- TxState
 
end process;
 
--
-- Tx State Machine
-- Slowed down by "Enable"
--
TX_State_Machine: process( Clk, Reset, Enable,
Treg, NextTReg,
TxParity, NextTxParity,
DataCnt, NextDataCnt,
tmpTRegE, NextTRegE,
TxState, NextTxState )
begin
if Clk'event and Clk = '0' then
if Reset = '1' then
Treg <= "00000000";
TxParity <= '0';
DataCnt <= "0000";
tmpTRegE <= '1';
TxState <= TxReset_State;
else
if Enable = '1' then
Treg <= NextTreg;
TxParity <= NextTxParity;
DataCnt <= NextDataCnt;
tmpTRegE <= NextTRegE;
TxState <= NextTxState;
else
Treg <= Treg;
TxParity <= TxParity;
DataCnt <= DataCnt;
tmpTRegE <= tmpTRegE;
TxState <= TxState;
end if;
end if;
end if;
 
end process;
 
end Behaviour; --=================== End of architecture ====================--
/vhdl/timer.vhd
0,0 → 1,256
--===========================================================================----
--
-- S Y N T H E Z I A B L E timer - 9 bit timer
--
-- www.OpenCores.Org - September 2003
-- This core adheres to the GNU public license
--
-- File name : timer.vhd
--
-- Purpose : 9 bit timer module for System 09
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
--
-- Uses : None
--
-- Author : John E. Kent
-- dilbert57@opencores.org
--
--===========================================================================----
--
-- Revision History:
--===========================================================================--
--
-- Version 0.1 - 6 Sept 2002 - John Kent
-- converted to a single timer
-- made syncronous with system clock
--
-- Version 1.0 - 6 Sept 2003 - John Kent
-- Realeased to open Cores
-- changed Clock Edge
--
--===========================================================================
--
-- Register Addressing:
-- addr=0 rw=1 down count
-- addr=0 rw=0 preset count
-- addr=1 rw=1 status
-- addr=0 rw=0 control
--
-- Control register
-- b0 = counter enable
-- b1 = mode (0 = counter, 1 = timer)
-- b7 = interrupt enable
--
-- Status register
-- b6 = timer output
-- b7 = interrupt flag
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity timer is
port (
clk : in std_logic;
rst : in std_logic;
cs : in std_logic;
rw : in std_logic;
addr : in std_logic;
data_in : in std_logic_vector(7 downto 0);
data_out : out std_logic_vector(7 downto 0);
irq : out std_logic;
timer_in : in std_logic;
timer_out : out std_logic
);
end;
 
architecture timer_arch of timer is
signal timer_ctrl : std_logic_vector(7 downto 0);
signal timer_stat : std_logic_vector(7 downto 0);
signal timer_reg : std_logic_vector(7 downto 0);
signal timer_count : std_logic_vector(7 downto 0);
signal timer_int : std_logic; -- Timer interrupt
signal timer_term : std_logic; -- Timer terminal count
signal timer_tog : std_logic; -- Timer output
--
-- control/status register bits
--
constant T_enab : integer := 0; -- 0=disable, 1=enabled
constant T_mode : integer := 1; -- 0=counter, 1=timer
constant T_out : integer := 6; -- 0=disabled, 1=enabled
constant T_irq : integer := 7; -- 0=disabled, 1-enabled
 
begin
 
--------------------------------
--
-- write control registers
-- doesn't do anything yet
--
--------------------------------
timer_write : process( clk, rst, cs, rw, addr, data_in,
timer_reg, timer_ctrl, timer_term, timer_count )
begin
if clk'event and clk = '0' then
if rst = '1' then
timer_reg <= "00000000";
timer_ctrl <= "00000000";
elsif cs = '1' and rw = '0' then
if addr='0' then
timer_reg <= data_in;
timer_ctrl <= timer_ctrl;
timer_term <= '0';
else
timer_reg <= timer_reg;
timer_ctrl <= data_in;
timer_term <= timer_term;
end if;
else
timer_ctrl <= timer_ctrl;
timer_reg <= timer_reg;
if (timer_ctrl(T_enab) = '1') then
if (timer_count = "00000000" ) then
timer_term <= '1';
elsif timer_ctrl(T_mode) = '0' then
timer_term <= '0'; -- counter mode, reset on non zero
else
timer_term <= timer_term; -- timer mode, keep as is
end if;
else
timer_term <= timer_term;
end if;
end if;
end if;
end process;
 
--
-- timer data output mux
--
timer_read : process( addr, timer_count, timer_stat )
begin
if addr='0' then
data_out <= timer_count;
else
data_out <= timer_stat;
end if;
end process;
 
--------------------------------
--
-- counters
--
--------------------------------
 
my_counter: process( clk, rst, timer_ctrl, timer_count, timer_reg, timer_in )
variable timer_tmp : std_logic;
begin
if clk'event and clk = '0' then
if rst = '1' then
timer_count <= "00000000";
timer_tmp := '0';
else
if timer_ctrl( T_enab ) = '1' then
if timer_in = '0' and timer_tmp = '1' then
timer_tmp := '0';
if timer_count = "00000000" then
timer_count <= timer_reg;
else
timer_count <= timer_count - 1;
end if;
elsif timer_in = '1' and timer_tmp = '0' then
timer_tmp := '1';
timer_count <= timer_count;
else
timer_tmp := timer_tmp;
timer_count <= timer_count;
end if;
else
timer_tmp := timer_tmp;
timer_count <= timer_count;
end if; -- timer_ctrl
end if; -- rst
end if; -- clk
end process;
 
--
-- read timer strobe to reset interrupts
--
timer_interrupt : process( Clk, rst, cs, rw, addr,
timer_term, timer_int, timer_ctrl )
begin
if clk'event and clk = '0' then
if rst = '1' then
timer_int <= '0';
elsif cs = '1' and rw = '1' then
if addr = '0' then
timer_int <= '0'; -- reset interrupt on read count
else
timer_int <= timer_int;
end if;
else
if timer_term = '1' then
timer_int <= '1';
else
timer_int <= timer_int;
end if;
end if;
end if;
 
if timer_ctrl( T_irq ) = '1' then
irq <= timer_int;
else
irq <= '0';
end if;
end process;
 
--
-- timer status register
--
timer_status : process( timer_ctrl, timer_int, timer_tog )
begin
timer_stat(5 downto 0) <= timer_ctrl(5 downto 0);
timer_stat(T_out) <= timer_tog;
timer_stat(T_irq) <= timer_int;
end process;
 
--
-- timer output
--
timer_output : process( Clk, rst, timer_term, timer_ctrl, timer_tog )
variable timer_tmp : std_logic; -- tracks change in terminal count
begin
if clk'event and clk = '0' then
if rst = '1' then
timer_tog <= '0';
timer_tmp := '0';
elsif timer_ctrl(T_mode) = '0' then -- free running ?
if (timer_term = '1') and (timer_tmp = '0') then
timer_tmp := '1';
timer_tog <= not timer_tog;
elsif (timer_term = '0') and (timer_tmp = '1') then
timer_tmp := '0';
timer_tog <= timer_tog;
else
timer_tmp := timer_tmp;
timer_tog <= timer_tog;
end if;
else -- one shot timer mode, follow terminal count
if (timer_term = '1') and (timer_tmp = '0') then
timer_tmp := '1';
timer_tog <= '1';
elsif (timer_term = '0') and (timer_tmp = '1') then
timer_tmp := '0';
timer_tog <= '0';
else
timer_tmp := timer_tmp;
timer_tog <= timer_tog;
end if;
end if;
end if;
timer_out <= timer_tog and timer_ctrl(T_out);
end process;
 
end timer_arch;
/vhdl/System09_tb.vhd
0,0 → 1,601
--===========================================================================----
--
-- T E S T B E N C H System09_tb - SOC Testbench.
--
-- www.OpenCores.Org - September 2003
-- This core adheres to the GNU public license
--
-- File name : System09_tb.vhd
--
-- Purpose : Test Bench for system 09
-- Top level file for 6809 compatible system on a chip
-- Designed with Xilinx XC2S300e Spartan 2+ FPGA.
-- Implemented With BurchED B5-X300 FPGA board,
-- B3-SRAM module, B5-CF module and B3-FPGA-CPU-IO module
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
-- ieee.std_logic_arith
-- ieee.numeric_std
--
-- Uses : boot_rom (sbug.vhd) Monitor ROM
-- cpu09 (cpu09.vhd) CPU core
-- dat_ram (datram.vhd) Dynamic Address Translation
-- miniuart (minitUART2.vhd) ACIA / MiniUART
-- (rxunit2.vhd)
-- (tx_unit2.vhd)
-- (clkunit2.vhd)
-- timer (timer.vhd) Timer module
--
-- Author : John E. Kent
-- dilbert57@opencores.org
--
--===========================================================================----
--
-- Revision History:
--===========================================================================--
--
-- Version 1.0
-- John Kent - 6 Sep 2003 - Initial release to Open Cores
--
--===========================================================================--
library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.all;
 
entity System09 is
port(
LED : out std_logic; -- Diagnostic LED Flasher
 
-- Memory Interface signals
ram_csn : out Std_Logic;
ram_wrln : out Std_Logic;
ram_wrun : out Std_Logic;
ram_addr : out Std_Logic_Vector(16 downto 0);
ram_data : inout Std_Logic_Vector(15 downto 0);
 
-- Stuff on the peripheral board
-- aux_clock : in Std_Logic; -- FPGA-CPU-IO clock
 
-- PS/2 Mouse interface
-- mouse_clock : in Std_Logic;
-- mouse_data : in Std_Logic;
 
-- Uart Interface
rxbit : in Std_Logic;
txbit : out Std_Logic;
rts_n : out Std_Logic;
cts_n : in Std_Logic;
 
-- CRTC output signals
-- v_drive : out Std_Logic;
-- h_drive : out Std_Logic;
-- blue_lo : out std_logic;
-- blue_hi : out std_logic;
-- green_lo : out std_logic;
-- green_hi : out std_logic;
-- red_lo : out std_logic;
-- red_hi : out std_logic;
-- buzzer : out std_logic;
 
-- Compact Flash
cf_rst_n : out std_logic;
cf_cs0_n : out std_logic;
cf_cs1_n : out std_logic;
cf_rd_n : out std_logic;
cf_wr_n : out std_logic;
cf_cs16_n : out std_logic;
cf_a : out std_logic_vector(2 downto 0);
cf_d : inout std_logic_vector(15 downto 0);
 
-- Test Pins
 
test_alu : out std_logic_vector(15 downto 0);
test_cc : out std_logic_vector(7 downto 0)
);
end;
 
-------------------------------------------------------------------------------
-- Architecture for memio Controller Unit
-------------------------------------------------------------------------------
architecture my_computer of System09 is
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
signal SysClk : std_logic;
signal reset_n : std_logic;
 
-- BOOT ROM
signal rom_data_out : Std_Logic_Vector(7 downto 0);
 
-- UART Interface signals
signal uart_data_out : Std_Logic_Vector(7 downto 0);
signal uart_cs : Std_Logic;
signal uart_irq : Std_Logic;
 
-- timer
signal timer_data_out : std_logic_vector(7 downto 0);
signal timer_cs : std_logic;
signal timer_irq : std_logic;
signal timer_out : std_logic;
 
-- compact flash port
signal cf_data_out : std_logic_vector(7 downto 0);
signal cf_cs : std_logic;
signal cf_rd : std_logic;
signal cf_wr : std_logic;
 
-- RAM
signal ram_cs : std_logic; -- memory chip select
signal ram_wrl : std_logic; -- memory write lower
signal ram_wru : std_logic; -- memory write upper
signal ram_data_out : std_logic_vector(7 downto 0);
 
-- CPU Interface signals
signal cpu_reset : Std_Logic;
signal cpu_clk : Std_Logic;
signal cpu_rw : std_logic;
signal cpu_vma : std_logic;
signal cpu_halt : std_logic;
signal cpu_hold : std_logic;
signal cpu_firq : std_logic;
signal cpu_irq : std_logic;
signal cpu_nmi : std_logic;
signal cpu_addr : std_logic_vector(15 downto 0);
signal cpu_data_in : std_logic_vector(7 downto 0);
signal cpu_data_out: std_logic_vector(7 downto 0);
 
-- Dynamic address translation
signal dat_cs : std_logic;
signal dat_addr : std_logic_vector(7 downto 0);
 
-- Boot ROM Map switch
-- signal map_cs : Std_Logic;
-- signal map_sw : Std_Logic;
 
-- synchronous RAM
signal xram_data_out : std_logic_vector(7 downto 0);
signal xram_cs : std_logic;
 
-- Flashing Led test signals
signal countL : std_logic_vector(23 downto 0);
 
-----------------------------------------------------------------
--
-- CPU09 CPU core
--
-----------------------------------------------------------------
 
component cpu09
port (
clk: in std_logic;
rst: in std_logic;
rw: out std_logic; -- Asynchronous memory interface
vma: out std_logic;
address: out std_logic_vector(15 downto 0);
data_in: in std_logic_vector(7 downto 0);
data_out: out std_logic_vector(7 downto 0);
halt: in std_logic;
hold: in std_logic;
irq: in std_logic;
nmi: in std_logic;
firq: in std_logic;
test_alu: out std_logic_vector(15 downto 0);
test_cc: out std_logic_vector(7 downto 0)
);
end component;
 
-----------------------------------------------------------------
--
-- Open Cores Mini UART
--
-----------------------------------------------------------------
 
component miniUART
port (
SysClk : in Std_Logic; -- System Clock
rst : in Std_Logic; -- Reset input
cs : in Std_Logic;
rw : in Std_Logic;
RxD : in Std_Logic;
TxD : out Std_Logic;
CTS_n : in Std_Logic;
RTS_n : out Std_Logic;
Irq : out Std_logic;
Addr : in Std_Logic;
DataIn : in Std_Logic_Vector(7 downto 0); --
DataOut : out Std_Logic_Vector(7 downto 0)); --
end component;
 
----------------------------------------
--
-- Timer module
--
----------------------------------------
 
component timer
port (
clk : in std_logic;
rst : in std_logic;
cs : in std_logic;
rw : in std_logic;
addr : in std_logic;
data_in : in std_logic_vector(7 downto 0);
data_out : out std_logic_vector(7 downto 0);
irq : out std_logic;
timer_in : in std_logic;
timer_out : out std_logic
);
end component;
 
 
component boot_rom
port (
addr : in Std_Logic_Vector(10 downto 0); -- 2K byte boot rom
data : out Std_Logic_Vector(7 downto 0));
end component;
 
--component sbug_rom
-- Port (
-- MEMclk : in std_logic;
-- MEMaddr : in std_logic_vector (10 downto 0);
-- MEMrdata : out std_logic_vector (7 downto 0)
-- );
--end component sbug_rom;
 
component dat_ram
port (
clk: in std_logic;
rst: in std_logic;
cs: in std_logic;
rw: in std_logic;
addr_lo: in std_logic_vector(3 downto 0);
addr_hi: in std_logic_vector(3 downto 0);
data_in: in std_logic_vector(7 downto 0);
data_out: out std_logic_vector(7 downto 0)
);
end component;
 
 
-- component block_ram
-- Port (
-- MEMclk : in std_logic;
-- MEMcs : in std_logic;
-- MEMrw : in std_logic;
-- MEMaddr : in std_logic_vector (10 downto 0);
-- MEMrdata : out std_logic_vector (7 downto 0);
-- MEMwdata : in std_logic_vector (7 downto 0)
-- );
--end component;
 
 
-- component BUFG
-- port (
-- i: in std_logic;
-- o: out std_logic
-- );
-- end component;
 
begin
-----------------------------------------------------------------------------
-- Instantiation of internal components
-----------------------------------------------------------------------------
 
my_cpu : cpu09 port map (
clk => SysClk,
rst => cpu_reset,
rw => cpu_rw,
vma => cpu_vma,
address => cpu_addr(15 downto 0),
data_in => cpu_data_in,
data_out => cpu_data_out,
halt => cpu_halt,
hold => cpu_hold,
irq => cpu_irq,
nmi => cpu_nmi,
firq => cpu_firq,
test_alu => test_alu,
test_cc => test_cc
);
 
 
my_uart : miniUART port map (
SysClk => SysClk,
rst => cpu_reset,
cs => uart_cs,
rw => cpu_rw,
RxD => rxbit,
TxD => txbit,
CTS_n => cts_n,
RTS_n => rts_n,
Irq => uart_irq,
Addr => cpu_addr(0),
Datain => cpu_data_out,
DataOut => uart_data_out
);
 
my_timer : timer port map (
clk => SysClk,
rst => cpu_reset,
cs => timer_cs,
rw => cpu_rw,
addr => cpu_addr(0),
data_in => cpu_data_out,
data_out => timer_data_out,
irq => timer_irq,
timer_in => CountL(5),
timer_out => timer_out
);
 
my_rom : boot_rom port map (
addr => cpu_addr(10 downto 0),
data => rom_data_out
);
 
--my_rom : sbug_rom port map (
-- MEMclk => SysClk,
-- MEMaddr => cpu_addr(10 downto 0),
-- MEMrdata => rom_data_out
-- );
 
 
my_dat : dat_ram port map (
clk => SysClk,
rst => cpu_reset,
cs => dat_cs,
rw => cpu_rw,
addr_hi => cpu_addr(15 downto 12),
addr_lo => cpu_addr(3 downto 0),
data_in => cpu_data_out,
data_out => dat_addr(7 downto 0)
);
 
 
--my_ram : block_ram port map (
-- MEMclk => SysClk,
-- MEMcs => xram_cs,
-- MEMrw => cpu_rw,
-- MEMaddr => cpu_addr(10 downto 0),
-- MEMwdata => cpu_data_out,
-- MEMrdata => xram_data_out
-- );
 
-- clk_buffer : BUFG port map(
-- i => e_clk,
-- o => cpu_clk
-- );
----------------------------------------------------------------------
--
-- Process to decode memory map
--
----------------------------------------------------------------------
 
mem_decode: process(
cpu_addr, cpu_vma,
-- map_cs, map_sw,
rom_data_out, ram_data_out,
-- xram_data_out,
cf_data_out,
timer_data_out,
uart_data_out )
begin
--
-- Memory map
--
case cpu_addr(15 downto 11) is
when "11111" => -- $F800 - $FFFF
cpu_data_in <= rom_data_out; -- read ROM
dat_cs <= cpu_vma; -- write DAT
ram_cs <= '0';
uart_cs <= '0';
cf_cs <= '0';
timer_cs <= '0';
-- xram_cs <= '0';
-- map_cs <= '0';
-- when "11101" => -- $E800 - $EFFF
-- when "11111" => -- $F800 - $FFFF
-- if map_sw = '1' then
-- cpu_data_in <= rom_data_out; -- read ROM
-- dat_cs <= '0'; -- disable write to DAT
-- ram_cs <= cpu_vma; -- enable write to RAM
-- else
-- cpu_data_in <= ram_data_out; -- read RAM
-- dat_cs <= cpu_vma; -- enable write DAT
-- ram_cs <= cpu_vma and cpu_rw; -- disable write to RAM
-- end if;
-- uart_cs <= '0';
-- cf_cs <= '0';
-- timer_cs <= '0';
-- map_cs <= '0';
-- when "11110" => -- $F000 - $F7FF
-- cpu_data_in <= xram_data_out;
-- dat_cs <= '0';
-- ram_cs <= '0';
-- uart_cs <= '0';
-- cf_cs <= '0';
-- xram_cs <= cpu_vma;
when "11100" => -- $E000 - $E7FF
dat_cs <= '0';
ram_cs <= '0';
-- xram_cs <= '0';
case cpu_addr(7 downto 4) is
when "0000" => -- $E000
cpu_data_in <= uart_data_out;
uart_cs <= cpu_vma;
cf_cs <= '0';
timer_cs <= '0';
-- map_cs <= '0';
when "0001" => -- $E010
cpu_data_in <= cf_data_out;
uart_cs <= '0';
cf_cs <= cpu_vma;
timer_cs <= '0';
-- map_cs <= '0';
when "0010" => -- $E020
cpu_data_in <= timer_data_out;
uart_cs <= '0';
cf_cs <= '0';
timer_cs <= cpu_vma;
map_cs <= '0';
when "0011" => -- $E030
cpu_data_in <= "00000000";
uart_cs <= '0';
cf_cs <= '0';
timer_cs <= '0';
-- map_cs <= cpu_vma;
when others => -- $E040 to $E7FF
cpu_data_in <= "00000000";
uart_cs <= '0';
cf_cs <= '0';
timer_cs <= '0';
-- map_cs <= '0';
end case;
when others =>
cpu_data_in <= ram_data_out;
ram_cs <= cpu_vma;
-- xram_cs <= '0';
dat_cs <= '0';
uart_cs <= '0';
cf_cs <= '0';
timer_cs <= '0';
-- map_cs <= '0';
end case;
end process;
 
--
-- B3-SRAM Control
-- Processes to read and write memory based on bus signals
--
ram_process: process( SysClk, Reset_n,
cpu_addr, cpu_rw, cpu_data_out,
dat_addr,
ram_cs, ram_wrl, ram_wru, ram_data )
begin
ram_csn <= not( ram_cs and Reset_n );
ram_wrl <= (not dat_addr(5)) and (not cpu_rw) and (not SysClk);
ram_wrln <= not (ram_wrl);
ram_wru <= dat_addr(5) and (not cpu_rw) and (not SysClk);
ram_wrun <= not (ram_wru);
ram_addr(16 downto 12) <= dat_addr(4 downto 0);
ram_addr(11 downto 0) <= cpu_addr(11 downto 0);
 
if ram_wrl = '1' then
ram_data(7 downto 0) <= cpu_data_out;
else
ram_data(7 downto 0) <= "ZZZZZZZZ";
end if;
 
if ram_wru = '1' then
ram_data(15 downto 8) <= cpu_data_out;
else
ram_data(15 downto 8) <= "ZZZZZZZZ";
end if;
 
if dat_addr(5) = '1' then
ram_data_out <= ram_data(15 downto 8);
else
ram_data_out <= ram_data(7 downto 0);
end if;
end process;
 
--
-- Compact Flash Control
--
compact_flash: process( Reset_n,
cpu_addr, cpu_rw, cpu_data_out,
cf_cs, cf_rd, cf_wr, cf_d )
begin
cf_rst_n <= Reset_n;
cf_cs0_n <= not( cf_cs ) or cpu_addr(3);
cf_cs1_n <= not( cf_cs and cpu_addr(3));
cf_cs16_n <= '1';
cf_wr <= cf_cs and (not cpu_rw);
cf_rd <= cf_cs and cpu_rw;
cf_wr_n <= not cf_wr;
cf_rd_n <= not cf_rd;
cf_a <= cpu_addr(2 downto 0);
if cf_wr = '1' then
cf_d(7 downto 0) <= cpu_data_out;
else
cf_d(7 downto 0) <= "ZZZZZZZZ";
end if;
cf_data_out <= cf_d(7 downto 0);
cf_d(15 downto 8) <= "ZZZZZZZZ";
end process;
 
--
-- ROM Map switch
-- The Map switch output is initially set
-- On a Write to the Map Switch port, clear the Map Switch
-- and map the RAM in place of the boot ROM.
--
--map_proc : process( SysClk, Reset_n, map_cs, cpu_rw )
--begin
-- if SysClk'event and SysClk = '1' then
-- if Reset_n = '0' then
-- map_sw <= '1';
-- else
-- if (map_cs = '1') and (cpu_rw = '0') then
-- map_sw <= '0';
-- else
-- map_sw <= map_sw;
-- end if;
-- end if;
-- end if;
--end process;
 
--
-- Interrupts and other bus control signals
--
interrupts : process( Reset_n, uart_irq
-- ,timer_irq
)
begin
cpu_reset <= not Reset_n; -- CPU reset is active high
cpu_irq <= uart_irq;
cpu_nmi <= timer_irq;
-- cpu_nmi <= '0';
cpu_firq <= '0';
cpu_halt <= '0';
cpu_hold <= '0';
end process;
 
--
-- flash led to indicate code is working
--
increment: process (SysClk, CountL )
begin
if(SysClk'event and SysClk = '1') then
countL <= countL + 1;
end if;
LED <= countL(21);
end process;
-- *** Test Bench - User Defined Section ***
tb : PROCESS
variable count : integer;
BEGIN
 
SysClk <= '0';
Reset_n <= '0';
 
for count in 0 to 512 loop
SysClk <= '0';
if count = 0 then
Reset_n <= '0';
elsif count = 1 then
Reset_n <= '1';
end if;
wait for 100 ns;
SysClk <= '1';
wait for 100 ns;
end loop;
 
wait; -- will wait forever
END PROCESS;
end; --===================== End of architecture =======================--
 
/vhdl/system09.ucf
0,0 → 1,288
#### UCF file created by Project Navigator
#
NET "reset_n" LOC = "p57" ;
NET "sysclk" LOC = "p77" ;
#
# For B5-Compact-Flash:
# Connector A
#
#NET "pin2" LOC = "P3" ; #J1-2
#NET "pin3" LOC = "P4" ; #J1-3
#NET "cf_intrq" LOC = "P5" ; #J1-4
NET "cf_wr_n" LOC = "P6" ; #J1-5
NET "cf_rd_n" LOC = "P7" ; #J1-6
NET "cf_cs1_n" LOC = "P8" ; #J1-7
NET "cf_d<15>" LOC = "P9" ; #J1-8
NET "cf_d<14>" LOC = "P10" ; #J1-9
NET "cf_d<13>" LOC = "P11" ; #J1-10
NET "cf_d<12>" LOC = "P15" ; #J1-11
NET "cf_d<11>" LOC = "P16" ; #J1-12
#NET "cf_present" LOC = "P17" ; #J1-13
NET "cf_d<3>" LOC = "P18" ; #J1-14
NET "cf_d<4>" LOC = "P20" ; #J1-15
NET "cf_d<5>" LOC = "P21" ; #J1-16
NET "cf_d<6>" LOC = "P22" ; #J1-17
NET "cf_d<7>" LOC = "P23" ; #J1-18
NET "cf_cs0_n" LOC = "P24" ; #J1-19
#
# For B5-Compact-Flash:
# Connector B
#
NET "cf_a<2>" LOC = "P33" ; #J2-6
NET "cf_a<1>" LOC = "P34" ; #J2-7
NET "cf_a<0>" LOC = "P35" ; #J2-8
NET "cf_d<0>" LOC = "P36" ; #J2-9
NET "cf_d<1>" LOC = "P40" ; #J2-10
NET "cf_d<2>" LOC = "P41" ; #J2-11
NET "cf_cs16_n" LOC = "P42" ; #J2-12
NET "cf_d<10>" LOC = "P43" ; #J2-13
NET "cf_d<9>" LOC = "P44" ; #J2-14
NET "cf_d<8>" LOC = "P45" ; #J2-15
#NET "cf_pdiag" LOC = "P46" ; #J2-16
#NET "cf_dase" LOC = "P47" ; #J2-17
#NET "cf_iordy" LOC = "P48" ; #J2-18
NET "cf_rst_n" LOC = "P49" ; #J2-19
#
# I/O Port
# Connector C
#
#NET "porta<0>" LOC = "p55" ; #pin 3
#NET "porta<1>" LOC = "p56" ; #pin 4
#NET "porta<2>" LOC = "p58" ; #pin 5
#NET "porta<3>" LOC = "p59" ; #pin 6
#NET "porta<4>" LOC = "p60" ; #pin 7
#NET "porta<5>" LOC = "p61" ; #pin 8
#NET "porta<6>" LOC = "p62" ; #pin 8
#NET "porta<7>" LOC = "p63" ; #pin 10
#NET "portb<0>" LOC = "p64" ; #pin 11
#NET "portb<1>" LOC = "p68" ; #pin 12
#NET "portb<2>" LOC = "p69" ; #pin 13
#NET "portb<3>" LOC = "p70" ; #pin 14
#NET "portb<4>" LOC = "p71" ; #pin 15
#NET "portb<5>" LOC = "p73" ; #pin 16
#NET "portb<6>" LOC = "p74" ; #pin 17
#NET "portb<7>" LOC = "p75" ; #pin 18
#NET "timer_out" LOC = "p81" ; #pin 19
#
# For B3-FPGA-CPU-IO
# Connector D
#
#NET "aux_clock" LOC = "p80" ; #pin 2
#NET "buzzer" LOC = "p82" ; #pin 3
NET "led" LOC = "p82" ; #pin 3
#NET "mouse_clock" LOC = "p83" ; #pin 4
#NET "mouse_data" LOC = "p84" ; #pin 5
NET "cts_n" LOC = "p86" ; #pin 6
NET "rts_n" LOC = "p87" ; #pin 7
NET "txbit" LOC = "p88" ; #pin 8
NET "rxbit" LOC = "p89" ; #pin 9
#NET "kb_clock" LOC = "p93" ; #pin 10
#NET "kb_data" LOC = "p94" ; #pin 11
#NET "v_drive" LOC = "p95" ; #pin 12
#NET "h_drive" LOC = "p96" ; #pin 13
#NET "blue_lo" LOC = "p97" ; #pin 14
#NET "blue_hi" LOC = "p98" ; #pin 15
#NET "green_lo" LOC = "p99" ; #pin 16
#NET "green_hi" LOC = "p100"; #pin 17
#NET "red_lo" LOC = "p101"; #pin 18
#NET "red_hi" LOC = "p102"; #pin 19
#
# For modified B3-SRAM
# Connector E
#
NET "ram_addr<0>" LOC = "p108"; #J1.2
NET "ram_addr<1>" LOC = "p109"; #J1.3
NET "ram_addr<2>" LOC = "p110"; #J1.4
NET "ram_addr<3>" LOC = "p111"; #J1.5
NET "ram_addr<4>" LOC = "p112"; #J1.6
NET "ram_addr<5>" LOC = "p113"; #J1.7
NET "ram_addr<6>" LOC = "p114"; #J1.8
NET "ram_addr<7>" LOC = "p115"; #J1.9
NET "ram_csn" LOC = "p116"; #J1.10
NET "ram_addr<8>" LOC = "p120"; #J1.11
NET "ram_addr<9>" LOC = "p121"; #J1.12
NET "ram_addr<10>" LOC = "p122"; #J1.13
NET "ram_addr<11>" LOC = "p123"; #J1.14
NET "ram_addr<12>" LOC = "p125"; #J1.15
NET "ram_addr<13>" LOC = "p126"; #J1.16
NET "ram_addr<14>" LOC = "p127"; #J1.17
NET "ram_addr<15>" LOC = "p129"; #J1.18
NET "ram_addr<16>" LOC = "p132"; #J1.19
#
# For modified B3-SRAM
# Connector F
#
NET "ram_data<0>" LOC = "p133"; #J2.2
NET "ram_data<1>" LOC = "p134"; #J2.3
NET "ram_data<2>" LOC = "p135"; #J2.4
NET "ram_data<3>" LOC = "p136"; #J2.5
NET "ram_data<4>" LOC = "p138"; #J2.6
NET "ram_data<5>" LOC = "p139"; #J2.7
NET "ram_data<6>" LOC = "p140"; #J2.8
NET "ram_data<7>" LOC = "p141"; #J2.9
NET "ram_data<8>" LOC = "p145"; #J2.10
NET "ram_data<9>" LOC = "p146"; #J2.11
NET "ram_data<10>" LOC = "p147"; #J2.12
NET "ram_data<11>" LOC = "p148"; #J2.13
NET "ram_data<12>" LOC = "p149"; #J2.14
NET "ram_data<13>" LOC = "p150"; #J2.15
NET "ram_data<14>" LOC = "p151"; #J2.16
NET "ram_data<15>" LOC = "p152"; #J2.17
NET "ram_wrun" LOC = "p153"; #J2.18
NET "ram_wrln" LOC = "p154"; #J2.19
#
# Connector G
#
#NET "pin2" LOC = "p182"; #pin 2 (clk input)
NET "test_alu<0>" LOC = "p160"; #pin 3
NET "test_alu<1>" LOC = "p161"; #pin 4
NET "test_alu<2>" LOC = "p162"; #pin 5
NET "test_alu<3>" LOC = "p163"; #pin 6
NET "test_alu<4>" LOC = "p164"; #pin 7
NET "test_alu<5>" LOC = "p165"; #pin 8
NET "test_alu<6>" LOC = "p166"; #pin 9
NET "test_alu<7>" LOC = "p167"; #pin 10
NET "test_alu<8>" LOC = "p168"; #pin 11
NET "test_alu<9>" LOC = "p169"; #pin 12
NET "test_alu<10>" LOC = "p173"; #pin 13
NET "test_alu<11>" LOC = "p174"; #pin 14
NET "test_alu<12>" LOC = "p175"; #pin 15
NET "test_alu<13>" LOC = "p176"; #pin 16
NET "test_alu<14>" LOC = "p178"; #pin 17
NET "test_alu<15>" LOC = "p179"; #pin 18
#NET "pin19" LOC = "p180"; #pin 19
#
# Connector H
#
#NET "pin2" LOC = "p185"; #pin 2 (clk input)
#NET "pin3" LOC = "p181"; #pin 3
#NET "uart_csn" LOC = "p187"; #pin 4
#NET "test_rw" LOC = "p188"; #pin 5
#NET "test_d0" LOC = "p189"; #pin 6
#NET "test_d1" LOC = "p191"; #pin 7
#NET "pin8" LOC = "p192"; #pin 8
#NET "pin9" LOC = "p193"; #pin 9
#NET "pin10" LOC = "p194"; #pin 10
NET "test_cc<0>" LOC = "p198"; #pin 11
NET "test_cc<1>" LOC = "p199"; #pin 12
NET "test_cc<2>" LOC = "p200"; #pin 13
NET "test_cc<3>" LOC = "p201"; #pin 14
NET "test_cc<4>" LOC = "p202"; #pin 15
NET "test_cc<5>" LOC = "p203"; #pin 16
NET "test_cc<6>" LOC = "p204"; #pin 17
NET "test_cc<7>" LOC = "p205"; #pin 18
#NET "pin19" LOC = "p206"; #pin 19
#
# Timing Groups
#
INST "ram_addr<0>" TNM = "ram_addr";
INST "ram_addr<1>" TNM = "ram_addr";
INST "ram_addr<2>" TNM = "ram_addr";
INST "ram_addr<3>" TNM = "ram_addr";
INST "ram_addr<4>" TNM = "ram_addr";
INST "ram_addr<5>" TNM = "ram_addr";
INST "ram_addr<6>" TNM = "ram_addr";
INST "ram_addr<7>" TNM = "ram_addr";
INST "ram_addr<8>" TNM = "ram_addr";
INST "ram_addr<9>" TNM = "ram_addr";
INST "ram_addr<10>" TNM = "ram_addr";
INST "ram_addr<11>" TNM = "ram_addr";
INST "ram_addr<12>" TNM = "ram_addr";
INST "ram_addr<13>" TNM = "ram_addr";
INST "ram_addr<14>" TNM = "ram_addr";
INST "ram_addr<15>" TNM = "ram_addr";
INST "ram_addr<16>" TNM = "ram_addr";
INST "ram_data<0>" TNM = "ram_data";
INST "ram_data<1>" TNM = "ram_data";
INST "ram_data<2>" TNM = "ram_data";
INST "ram_data<3>" TNM = "ram_data";
INST "ram_data<4>" TNM = "ram_data";
INST "ram_data<5>" TNM = "ram_data";
INST "ram_data<6>" TNM = "ram_data";
INST "ram_data<7>" TNM = "ram_data";
INST "ram_data<8>" TNM = "ram_data";
INST "ram_data<9>" TNM = "ram_data";
INST "ram_data<10>" TNM = "ram_data";
INST "ram_data<11>" TNM = "ram_data";
INST "ram_data<12>" TNM = "ram_data";
INST "ram_data<13>" TNM = "ram_data";
INST "ram_data<14>" TNM = "ram_data";
INST "ram_data<15>" TNM = "ram_data";
INST "ram_wrln" TNM = "ram_wr";
INST "ram_wrun" TNM = "ram_wr";
INST "ram_csn" TNM = "ram_cs";
INST "test_alu<0>" TNM = "test_alu";
INST "test_alu<1>" TNM = "test_alu";
INST "test_alu<2>" TNM = "test_alu";
INST "test_alu<3>" TNM = "test_alu";
INST "test_alu<4>" TNM = "test_alu";
INST "test_alu<5>" TNM = "test_alu";
INST "test_alu<6>" TNM = "test_alu";
INST "test_alu<7>" TNM = "test_alu";
INST "test_alu<8>" TNM = "test_alu";
INST "test_alu<9>" TNM = "test_alu";
INST "test_alu<10>" TNM = "test_alu";
INST "test_alu<11>" TNM = "test_alu";
INST "test_alu<12>" TNM = "test_alu";
INST "test_alu<13>" TNM = "test_alu";
INST "test_alu<14>" TNM = "test_alu";
INST "test_alu<15>" TNM = "test_alu";
INST "test_cc<0>" TNM = "test_cc";
INST "test_cc<1>" TNM = "test_cc";
INST "test_cc<2>" TNM = "test_cc";
INST "test_cc<3>" TNM = "test_cc";
INST "test_cc<4>" TNM = "test_cc";
INST "test_cc<5>" TNM = "test_cc";
INST "test_cc<6>" TNM = "test_cc";
INST "test_cc<7>" TNM = "test_cc";
#
# Timing Constraints
#
TIMEGRP "ram_cs" OFFSET = OUT 40 ns AFTER "sysclk";
TIMEGRP "ram_wr" OFFSET = OUT 40 ns AFTER "sysclk";
TIMEGRP "ram_addr" OFFSET = OUT 40 ns AFTER "sysclk";
TIMEGRP "ram_data" OFFSET = OUT 40 ns AFTER "sysclk";
TIMEGRP "ram_data" OFFSET = IN 15 ns BEFORE "sysclk";
TIMEGRP "test_alu" OFFSET = OUT 90 ns AFTER "sysclk";
TIMEGRP "test_cc" OFFSET = OUT 95 ns AFTER "sysclk";
NET "sysclk" TNM_NET = "sysclk";
TIMESPEC "TS_sysclk" = PERIOD "sysclk" 100 ns LOW 50 %;
#
# Fast I/O Pins
#
NET "ram_addr<0>" FAST;
NET "ram_addr<1>" FAST;
NET "ram_addr<2>" FAST;
NET "ram_addr<3>" FAST;
NET "ram_addr<4>" FAST;
NET "ram_addr<5>" FAST;
NET "ram_addr<6>" FAST;
NET "ram_addr<7>" FAST;
NET "ram_addr<8>" FAST;
NET "ram_addr<9>" FAST;
NET "ram_addr<10>" FAST;
NET "ram_addr<11>" FAST;
NET "ram_addr<12>" FAST;
NET "ram_addr<13>" FAST;
NET "ram_addr<14>" FAST;
NET "ram_addr<15>" FAST;
NET "ram_addr<16>" FAST;
NET "ram_csn" FAST;
NET "ram_data<0>" FAST;
NET "ram_data<1>" FAST;
NET "ram_data<2>" FAST;
NET "ram_data<3>" FAST;
NET "ram_data<4>" FAST;
NET "ram_data<5>" FAST;
NET "ram_data<6>" FAST;
NET "ram_data<7>" FAST;
NET "ram_data<8>" FAST;
NET "ram_data<9>" FAST;
NET "ram_data<10>" FAST;
NET "ram_data<11>" FAST;
NET "ram_data<12>" FAST;
NET "ram_data<13>" FAST;
NET "ram_data<14>" FAST;
NET "ram_data<15>" FAST;
NET "ram_wrln" FAST;
NET "ram_wrun" FAST;
/vhdl/clkunit2.vhd
0,0 → 1,138
--===========================================================================--
--
-- S Y N T H E Z I A B L E miniUART C O R E
--
-- www.OpenCores.Org - January 2000
-- This core adheres to the GNU public license
 
-- Design units : miniUART core for the System68
--
-- File name : clkunit2.vhd
--
-- Purpose : Implements an miniUART device for communication purposes
-- between the CPU68 processor and the Host computer through
-- an RS-232 communication protocol.
--
-- Dependencies : ieee.std_logic_1164
-- ieee.numeric_std
--
--===========================================================================--
-------------------------------------------------------------------------------
-- Revision list
-- Version Author Date Changes
--
-- 0.1 Ovidiu Lupas 15 January 2000 New model
-- olupas@opencores.org
--
-- 2.0 John Kent 10 November 2002 Added programmable baud rate
-- 3.0 John Kent 15 December 2002 Fix TX clock divider
-- 3.1 John kent 12 January 2003 Changed divide by 1 for 38.4Kbps
-- 3.3 John Kent 6 September 2003 Changed Clock Edge.
-- dilbert57@opencores.org
-------------------------------------------------------------------------------
-- Description : Generates the Baud clock and enable signals for RX & TX
-- units.
-------------------------------------------------------------------------------
-- Entity for Baud rate generator Unit - 9600 baudrate --
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
-------------------------------------------------------------------------------
-- Baud rate generator
-------------------------------------------------------------------------------
entity ClkUnit is
port (
Clk : in Std_Logic; -- System Clock
Reset : in Std_Logic; -- Reset input
EnableRx : out Std_Logic; -- Control signal
EnableTx : out Std_Logic; -- Control signal
BaudRate : in Std_Logic_Vector(1 downto 0));
end; --================== End of entity ==============================--
-------------------------------------------------------------------------------
-- Architecture for Baud rate generator Unit
-------------------------------------------------------------------------------
architecture Behaviour of ClkUnit is
signal tmpEnRx : std_logic;
 
begin
-----------------------------------------------------------------------------
-- Divides the system clock of 40 MHz div 260 gives 153KHz for 9600bps
-- 48 MHz div 156 gives 306KHz for 19.2Kbps
-- 24 MHz div 156 gives 153KHz for 9600bps
-- 9.8304MHz div 32 gives 306KHz for 19.2Kbps
-- 4.9152MHz div 32 gives 153KHz for 9600bps
-----------------------------------------------------------------------------
DivClk : process(Clk,Reset,tmpEnRx, BaudRate)
variable Count : unsigned(7 downto 0);
constant CntOne : Unsigned(7 downto 0):="00000001";
begin
if Clk'event and Clk = '0' then
if Reset = '1' then
Count := "00000000";
tmpEnRx <= '0';
else
if Count = "00000000" then
tmpEnRx <= '1';
case BaudRate is
when "00" =>
-- 6850 divide by 1 ((1*2)-1) (synchronous)
-- miniUart 9.83MHz div 16 = 38.4Kbps
Count := "00001111";
when "01" =>
-- 6850 divide by 16 ((16*2)-1) (9600 Baud)
-- miniUart 9.83MHz div 32 = 19.2Kbps
Count := "00011111";
when "10" =>
-- 6850 divide by 64 ((64*2)-1) (2400 Baud)
-- miniUart 9.83MHz div 128 = 4800bps
Count := "01111111";
when others =>
-- when "11" => -- reset
Count := "00000000";
null;
end case;
else
tmpEnRx <= '0';
Count := Count - CntOne;
end if;
end if;
end if;
EnableRx <= tmpEnRx;
end process;
 
-----------------------------------------------------------------------------
-- Provides the EnableTX signal, at 9.6 KHz
-- Divide by 16
-- Except it wasn't ... it counted up to "10010" (18)
-----------------------------------------------------------------------------
DivClk16 : process(Clk,Reset,tmpEnRX)
variable Cnt16 : unsigned(4 downto 0);
constant CntOne : Unsigned(4 downto 0):="00001";
begin
if Clk'event and Clk = '0' then
if Reset = '1' then
Cnt16 := "00000";
EnableTX <= '0';
else
case Cnt16 is
when "00000" =>
if tmpEnRx = '1' then
Cnt16 := "01111";
EnableTx <='1';
else
Cnt16 := Cnt16;
EnableTx <= '0';
end if;
when others =>
if tmpEnRx = '1' then
Cnt16 := Cnt16 - CntOne;
else
Cnt16 := Cnt16;
end if;
EnableTX <= '0';
end case;
end if;
end if;
end process;
end Behaviour; --==================== End of architecture ===================--
/vhdl/System09.vhd
0,0 → 1,691
--===========================================================================----
--
-- S Y N T H E Z I A B L E System09 - SOC.
--
-- www.OpenCores.Org - September 2003
-- This core adheres to the GNU public license
--
-- File name : System09.vhd
--
-- Purpose : Top level file for 6809 compatible system on a chip
-- Designed with Xilinx XC2S300e Spartan 2+ FPGA.
-- Implemented With BurchED B5-X300 FPGA board,
-- B3-SRAM module, B5-CF module and B3-FPGA-CPU-IO module
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
-- ieee.std_logic_arith
-- ieee.numeric_std
--
-- Uses : boot_rom (sbug.vhd) Monitor ROM
-- cpu09 (cpu09.vhd) CPU core
-- dat_ram (datram.vhd) Dynamic Address Translation
-- miniuart (minitUART2.vhd) ACIA / MiniUART
-- (rxunit2.vhd)
-- (tx_unit2.vhd)
-- (clkunit2.vhd)
-- timer (timer.vhd) Timer module
--
-- Author : John E. Kent
-- dilbert57@opencores.org
--
--===========================================================================----
--
-- Revision History:
--===========================================================================--
-- Version 0.1 - 20 March 2003
-- Version 0.2 - 30 March 2003
-- Version 0.3 - 29 April 2003
-- Version 0.4 - 29 June 2003
-- Version 0.5 - 19 July 2003
-- prints out "Hello World"
-- Version 0.6 - 5 September 2003
-- Runs SBUG
-- Version 1.0- 6 Sep 2003 - John Kent
-- Inverted SysClk
-- Initial release to Open Cores
--
--===========================================================================--
library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.all;
 
entity System09 is
port(
SysClk : in Std_Logic; -- System Clock input
Reset_n : in Std_logic; -- Master Reset input (active low)
LED : out std_logic; -- Diagnostic LED Flasher
 
-- Memory Interface signals
ram_csn : out Std_Logic;
ram_wrln : out Std_Logic;
ram_wrun : out Std_Logic;
ram_addr : out Std_Logic_Vector(16 downto 0);
ram_data : inout Std_Logic_Vector(15 downto 0);
 
-- Stuff on the peripheral board
-- aux_clock : in Std_Logic; -- FPGA-CPU-IO clock
 
-- PS/2 Mouse interface
-- mouse_clock : in Std_Logic;
-- mouse_data : in Std_Logic;
 
-- Uart Interface
rxbit : in Std_Logic;
txbit : out Std_Logic;
rts_n : out Std_Logic;
cts_n : in Std_Logic;
 
-- CRTC output signals
-- v_drive : out Std_Logic;
-- h_drive : out Std_Logic;
-- blue_lo : out std_logic;
-- blue_hi : out std_logic;
-- green_lo : out std_logic;
-- green_hi : out std_logic;
-- red_lo : out std_logic;
-- red_hi : out std_logic;
-- buzzer : out std_logic;
 
-- Compact Flash
cf_rst_n : out std_logic;
cf_cs0_n : out std_logic;
cf_cs1_n : out std_logic;
cf_rd_n : out std_logic;
cf_wr_n : out std_logic;
cf_cs16_n : out std_logic;
cf_a : out std_logic_vector(2 downto 0);
cf_d : inout std_logic_vector(15 downto 0);
 
-- Parallel I/O port
-- porta : inout std_logic_vector(7 downto 0);
-- portb : inout std_logic_vector(7 downto 0);
-- timer_out : out std_logic;
 
-- Test Pins
test_alu : out std_logic_vector(15 downto 0);
test_cc : out std_logic_vector(7 downto 0)
);
end System09;
 
-------------------------------------------------------------------------------
-- Architecture for memio Controller Unit
-------------------------------------------------------------------------------
architecture my_computer of System09 is
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
-- BOOT ROM
signal rom_data_out : Std_Logic_Vector(7 downto 0);
 
-- UART Interface signals
signal uart_data_out : Std_Logic_Vector(7 downto 0);
signal uart_cs : Std_Logic;
signal uart_irq : Std_Logic;
 
-- timer
-- signal timer_data_out : std_logic_vector(7 downto 0);
-- signal timer_cs : std_logic;
-- signal timer_irq : std_logic;
 
-- Parallel I/O port
-- signal ioport_data_out : std_logic_vector(7 downto 0);
-- signal ioport_cs : std_logic;
 
-- compact flash port
signal cf_data_out : std_logic_vector(7 downto 0);
signal cf_cs : std_logic;
signal cf_rd : std_logic;
signal cf_wr : std_logic;
 
-- RAM
signal ram_cs : std_logic; -- memory chip select
signal ram_wrl : std_logic; -- memory write lower
signal ram_wru : std_logic; -- memory write upper
signal ram_data_out : std_logic_vector(7 downto 0);
 
-- CPU Interface signals
signal cpu_reset : Std_Logic;
signal cpu_clk : Std_Logic;
signal cpu_rw : std_logic;
signal cpu_vma : std_logic;
signal cpu_halt : std_logic;
signal cpu_hold : std_logic;
signal cpu_firq : std_logic;
signal cpu_irq : std_logic;
signal cpu_nmi : std_logic;
signal cpu_addr : std_logic_vector(15 downto 0);
signal cpu_data_in : std_logic_vector(7 downto 0);
signal cpu_data_out: std_logic_vector(7 downto 0);
 
-- Dynamic address translation
signal dat_cs : std_logic;
signal dat_addr : std_logic_vector(7 downto 0);
 
-- Boot ROM Map switch
-- signal map_cs : Std_Logic;
-- signal map_sw : Std_Logic;
 
-- synchronous RAM
-- signal xram_data_out : std_logic_vector(7 downto 0);
-- signal xram_cs : std_logic;
 
-- Flashing Led test signals
signal countL : std_logic_vector(23 downto 0);
 
-----------------------------------------------------------------
--
-- CPU09 CPU core
--
-----------------------------------------------------------------
 
component cpu09
port (
clk: in std_logic;
rst: in std_logic;
rw: out std_logic; -- Asynchronous memory interface
vma: out std_logic;
address: out std_logic_vector(15 downto 0);
data_in: in std_logic_vector(7 downto 0);
data_out: out std_logic_vector(7 downto 0);
halt: in std_logic;
hold: in std_logic;
irq: in std_logic;
nmi: in std_logic;
firq: in std_logic;
test_alu: out std_logic_vector(15 downto 0);
test_cc: out std_logic_vector(7 downto 0)
);
end component;
 
-----------------------------------------------------------------
--
-- Open Cores Mini UART
--
-----------------------------------------------------------------
 
component miniUART
port (
SysClk : in Std_Logic; -- System Clock
rst : in Std_Logic; -- Reset input
cs : in Std_Logic;
rw : in Std_Logic;
RxD : in Std_Logic;
TxD : out Std_Logic;
CTS_n : in Std_Logic;
RTS_n : out Std_Logic;
Irq : out Std_logic;
Addr : in Std_Logic;
DataIn : in Std_Logic_Vector(7 downto 0); --
DataOut : out Std_Logic_Vector(7 downto 0)); --
end component;
 
----------------------------------------
--
-- Timer module
--
----------------------------------------
 
--component timer
-- port (
-- clk : in std_logic;
-- rst : in std_logic;
-- cs : in std_logic;
-- rw : in std_logic;
-- addr : in std_logic;
-- data_in : in std_logic_vector(7 downto 0);
-- data_out : out std_logic_vector(7 downto 0);
-- irq : out std_logic;
-- timer_in : in std_logic;
-- timer_out : out std_logic
-- );
--end component;
 
----------------------------------------
--
-- Dual 8 bit Parallel I/O module
--
----------------------------------------
--component ioport
-- port (
-- clk : in std_logic;
-- rst : in std_logic;
-- cs : in std_logic;
-- rw : in std_logic;
-- addr : in std_logic_vector(1 downto 0);
-- data_in : in std_logic_vector(7 downto 0);
-- data_out : out std_logic_vector(7 downto 0);
-- porta_io : inout std_logic_vector(7 downto 0);
-- portb_io : inout std_logic_vector(7 downto 0)
-- );
--end component;
 
----------------------------------------
--
-- SBUG Slice Monitor ROM
--
----------------------------------------
component boot_rom
port (
addr : in Std_Logic_Vector(10 downto 0); -- 2K byte boot rom
data : out Std_Logic_Vector(7 downto 0));
end component;
 
----------------------------------------
--
-- SBUG Block RAM Monitor ROM
--
----------------------------------------
--component sbug_rom
-- Port (
-- MEMclk : in std_logic;
-- MEMaddr : in std_logic_vector (10 downto 0);
-- MEMrdata : out std_logic_vector (7 downto 0)
-- );
--end component;
 
----------------------------------------
--
-- Dynamic Address Translation Registers
--
----------------------------------------
component dat_ram
port (
clk: in std_logic;
rst: in std_logic;
cs: in std_logic;
rw: in std_logic;
addr_lo: in std_logic_vector(3 downto 0);
addr_hi: in std_logic_vector(3 downto 0);
data_in: in std_logic_vector(7 downto 0);
data_out: out std_logic_vector(7 downto 0)
);
end component;
 
----------------------------------------
--
-- Block RAM module
--
----------------------------------------
-- component block_ram
-- Port (
-- MEMclk : in std_logic;
-- MEMcs : in std_logic;
-- MEMrw : in std_logic;
-- MEMaddr : in std_logic_vector (10 downto 0);
-- MEMrdata : out std_logic_vector (7 downto 0);
-- MEMwdata : in std_logic_vector (7 downto 0)
-- );
--end component;
 
 
-- component BUFG
-- port (
-- i: in std_logic;
-- o: out std_logic
-- );
-- end component;
 
begin
-----------------------------------------------------------------------------
-- Instantiation of internal components
-----------------------------------------------------------------------------
 
my_cpu : cpu09 port map (
clk => SysClk,
rst => cpu_reset,
rw => cpu_rw,
vma => cpu_vma,
address => cpu_addr(15 downto 0),
data_in => cpu_data_in,
data_out => cpu_data_out,
halt => cpu_halt,
hold => cpu_hold,
irq => cpu_irq,
nmi => cpu_nmi,
firq => cpu_firq,
test_alu => test_alu,
test_cc => test_cc
);
 
 
my_uart : miniUART port map (
SysClk => SysClk,
rst => cpu_reset,
cs => uart_cs,
rw => cpu_rw,
RxD => rxbit,
TxD => txbit,
CTS_n => cts_n,
RTS_n => rts_n,
Irq => uart_irq,
Addr => cpu_addr(0),
Datain => cpu_data_out,
DataOut => uart_data_out
);
 
--my_timer : timer port map (
-- clk => SysClk,
-- rst => cpu_reset,
-- cs => timer_cs,
-- rw => cpu_rw,
-- addr => cpu_addr(0),
-- data_in => cpu_data_out,
-- data_out => timer_data_out,
-- irq => timer_irq,
-- timer_in => CountL(5),
-- timer_out => timer_out
-- );
 
--my_ioport : ioport port map (
-- clk => SysClk,
-- rst => cpu_reset,
-- cs => ioport_cs,
-- rw => cpu_rw,
-- addr => cpu_addr(1 downto 0),
-- data_in => cpu_data_out,
-- data_out => ioport_data_out,
-- porta_io => porta,
-- portb_io => portb
-- );
 
my_rom : boot_rom port map (
addr => cpu_addr(10 downto 0),
data => rom_data_out
);
 
--my_rom : sbug_rom port map (
-- MEMclk => SysClk,
-- MEMaddr => cpu_addr(10 downto 0),
-- MEMrdata => rom_data_out
-- );
 
my_dat : dat_ram port map (
clk => SysClk,
rst => cpu_reset,
cs => dat_cs,
rw => cpu_rw,
addr_hi => cpu_addr(15 downto 12),
addr_lo => cpu_addr(3 downto 0),
data_in => cpu_data_out,
data_out => dat_addr(7 downto 0)
);
 
--my_ram : block_ram port map (
-- MEMclk => SysClk,
-- MEMcs => xram_cs,
-- MEMrw => cpu_rw,
-- MEMaddr => cpu_addr(10 downto 0),
-- MEMwdata => cpu_data_out,
-- MEMrdata => xram_data_out
-- );
 
-- clk_buffer : BUFG port map(
-- i => e_clk,
-- o => cpu_clk
-- );
----------------------------------------------------------------------
--
-- Process to decode memory map
--
----------------------------------------------------------------------
 
mem_decode: process( SysClk, Reset_n,
cpu_addr, cpu_rw, cpu_vma,
dat_cs, dat_addr,
-- map_cs, map_sw,
rom_data_out, ram_data_out,
-- xram_data_out,
cf_data_out,
-- timer_data_out, ioport_data_out,
uart_data_out )
begin
case cpu_addr(15 downto 11) is
--
-- SBUG Monitor ROM $F800 - $FFFF
--
when "11111" => -- $F800 - $FFFF
cpu_data_in <= rom_data_out; -- read ROM
dat_cs <= cpu_vma; -- write DAT
ram_cs <= '0';
uart_cs <= '0';
cf_cs <= '0';
-- timer_cs <= '0';
-- ioport_cs <= '0';
-- xram_cs <= '0';
-- map_cs <= '0';
 
--
-- Shadow RAM Monitor switch
--
-- when "11101" => -- $E800 - $EFFF
-- when "11111" => -- $F800 - $FFFF
-- if map_sw = '1' then
-- cpu_data_in <= rom_data_out; -- read ROM
-- dat_cs <= '0'; -- disable write to DAT
-- ram_cs <= cpu_vma; -- enable write to RAM
-- else
-- cpu_data_in <= ram_data_out; -- read RAM
-- dat_cs <= cpu_vma; -- enable write DAT
-- ram_cs <= cpu_vma and cpu_rw; -- disable write to RAM
-- end if;
-- uart_cs <= '0';
-- cf_cs <= '0';
-- timer_cs <= '0';
-- ioport_cs <= '0';
-- xram_cs <= cpu_vma;
-- map_cs <= '0';
 
--
-- Synchronous Block RAM $F000 - $F7FF
--
-- when "11110" => -- $F000 - $F7FF
-- cpu_data_in <= xram_data_out;
-- dat_cs <= '0';
-- ram_cs <= '0';
-- uart_cs <= '0';
-- cf_cs <= '0';
-- timer_cs <= '0';
-- ioport_cs <= '0';
-- xram_cs <= cpu_vma;
-- map_cs <= '0';
 
--
-- IO Devices $E000 - $E7FF
--
when "11100" => -- $E000 - $E7FF
dat_cs <= '0';
ram_cs <= '0';
-- xram_cs <= '0';
case cpu_addr(7 downto 4) is
--
-- UART / ACIA $E000
--
when "0000" => -- $E000
cpu_data_in <= uart_data_out;
uart_cs <= cpu_vma;
cf_cs <= '0';
-- timer_cs <= '0';
-- ioport_cs <= '0';
-- map_cs <= '0';
--
-- Compact Flash $E010 - $E01F
--
when "0001" => -- $E010
cpu_data_in <= cf_data_out;
uart_cs <= '0';
cf_cs <= cpu_vma;
-- timer_cs <= '0';
-- ioport_cs <= '0';
-- map_cs <= '0';
--
-- Timer $E020 - $E02F
--
-- when "0010" => -- $E020
-- cpu_data_in <= timer_data_out;
-- uart_cs <= '0';
-- cf_cs <= '0';
-- timer_cs <= cpu_vma;
-- ioport_cs <= '0';
-- map_cs <= '0';
 
--
-- ROM Map switch $E030
--
-- when "0011" => -- $E030
-- cpu_data_in <= "00000000";
-- uart_cs <= '0';
-- cf_cs <= '0';
-- timer_cs <= '0';
-- ioport_cs <= '0';
-- map_cs <= cpu_vma;
 
--
-- I/O port $E040 - $E04F
--
-- when "0100" => -- $E040
-- cpu_data_in <= ioport_data_out;
-- uart_cs <= '0';
-- cf_cs <= '0';
-- timer_cs <= '0';
-- ioport_cs <= cpu_vma;
-- map_cs <= '0';
 
when others => -- $E040 to $E7FF
cpu_data_in <= "00000000";
uart_cs <= '0';
cf_cs <= '0';
-- timer_cs <= '0';
-- ioport_cs <= '0';
-- map_cs <= '0';
end case;
--
-- Everything else is RAM
--
when others =>
cpu_data_in <= ram_data_out;
ram_cs <= cpu_vma;
dat_cs <= '0';
uart_cs <= '0';
cf_cs <= '0';
-- timer_cs <= '0';
-- ioport_cs <= '0';
-- xram_cs <= '0';
-- map_cs <= '0';
end case;
end process;
 
--
-- B3-SRAM Control
-- Processes to read and write memory based on bus signals
--
ram_process: process( SysClk, Reset_n,
cpu_addr, cpu_rw, cpu_vma, cpu_data_out,
dat_addr,
ram_cs, ram_wrl, ram_wru, ram_data_out )
begin
ram_csn <= not( ram_cs and Reset_n );
ram_wrl <= (not dat_addr(5)) and (not cpu_rw) and SysClk;
ram_wrln <= not (ram_wrl);
ram_wru <= dat_addr(5) and (not cpu_rw) and SysClk;
ram_wrun <= not (ram_wru);
ram_addr(16 downto 12) <= dat_addr(4 downto 0);
ram_addr(11 downto 0) <= cpu_addr(11 downto 0);
 
if ram_wrl = '1' then
ram_data(7 downto 0) <= cpu_data_out;
else
ram_data(7 downto 0) <= "ZZZZZZZZ";
end if;
 
if ram_wru = '1' then
ram_data(15 downto 8) <= cpu_data_out;
else
ram_data(15 downto 8) <= "ZZZZZZZZ";
end if;
 
if dat_addr(5) = '1' then
ram_data_out <= ram_data(15 downto 8);
else
ram_data_out <= ram_data(7 downto 0);
end if;
end process;
 
--
-- Compact Flash Control
--
compact_flash: process( SysClk, Reset_n,
cpu_addr, cpu_rw, cpu_vma, cpu_data_out,
cf_cs, cf_rd, cf_wr, cf_data_out )
begin
cf_rst_n <= Reset_n;
cf_cs0_n <= not( cf_cs ) or cpu_addr(3);
cf_cs1_n <= not( cf_cs and cpu_addr(3));
cf_cs16_n <= '1';
cf_wr <= cf_cs and (not cpu_rw);
cf_rd <= cf_cs and cpu_rw;
cf_wr_n <= not cf_wr;
cf_rd_n <= not cf_rd;
cf_a <= cpu_addr(2 downto 0);
if cf_wr = '1' then
cf_d(7 downto 0) <= cpu_data_out;
else
cf_d(7 downto 0) <= "ZZZZZZZZ";
end if;
cf_data_out <= cf_d(7 downto 0);
cf_d(15 downto 8) <= "ZZZZZZZZ";
end process;
 
--
-- ROM Map switch
-- The Map switch output is initially set
-- On a Write to the Map Switch port, clear the Map Switch
-- and map the RAM in place of the boot ROM.
--
--map_proc : process( SysClk, Reset_n, map_cs, cpu_rw )
--begin
-- if SysClk'event and SysClk = '0' then
-- if Reset_n = '0' then
-- map_sw <= '1';
-- else
-- if (map_cs = '1') and (cpu_rw = '0') then
-- map_sw <= '0';
-- else
-- map_sw <= map_sw;
-- end if;
-- end if;
-- end if;
--end process;
 
--
-- Interrupts and other bus control signals
--
interrupts : process( Reset_n, uart_irq
-- ,timer_irq
)
begin
cpu_reset <= not Reset_n; -- CPU reset is active high
cpu_irq <= uart_irq;
-- cpu_nmi <= timer_irq;
cpu_nmi <= '0';
cpu_firq <= '0';
cpu_halt <= '0';
cpu_hold <= '0';
end process;
 
--
-- flash led to indicate code is working
--
increment: process (SysClk, CountL )
begin
if(SysClk'event and SysClk = '0') then
countL <= countL + 1;
end if;
LED <= countL(21);
end process;
end my_computer; --===================== End of architecture =======================--
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.