--===========================================================================--
--
-- S Y N T H E Z I A B L E CPU68 C O R E
--
-- www.OpenCores.Org - December 2002
-- This core adheres to the GNU public license 
--
-- File name : cpu68.vhd
--
-- Purpose : Implements a 6800 compatible CPU core with some
-- additional instructions found in the 6801
-- 
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
--
-- Author : John E. Kent 
--
--===========================================================================----
--
-- Revision History:
--
-- Date: Revision Author
-- 22 Sep 2002 0.1 John Kent
--
-- 30 Oct 2002 0.2 John Kent
-- made NMI edge triggered
--
-- 30 Oct 2002 0.3 John Kent
-- more corrections to NMI
-- added wai_wait_state to prevent stack overflow on wai.
--
-- 1 Nov 2002 0.4 John Kent
-- removed WAI states and integrated WAI with the interrupt service routine
-- replace Data out (do) and Data in (di) register with a single Memory Data (md) reg.
-- Added Multiply instruction states.
-- run ALU and CC out of CPU module for timing measurements.
--
-- 3 Nov 2002 0.5 John Kent
-- Memory Data Register was not loaded on Store instructions
-- SEV and CLV were not defined in the ALU
-- Overflow Flag on NEG was incorrect
--
-- 16th Feb 2003 0.6 John Kent
-- Rearranged the execution cycle for dual operand instructions
-- so that occurs during the following fetch cycle.
-- This allows the reduction of one clock cycle from dual operand
-- instruction. Note that this also necessitated re-arranging the
-- program counter so that it is no longer incremented in the ALU.
-- The effective address has also been re-arranged to include a
-- separate added. The STD (store accd) now sets the condition codes.
--
-- 28th Jun 2003 0.7 John Kent
-- Added Hold and Halt signals. Hold is used to steal cycles from the
-- CPU or add wait states. Halt puts the CPU in the inactive state
-- and is only honoured in the fetch cycle. Both signals are active high.
--
-- 9th Jan 2004 0.8 John Kent
-- Clear instruction did an alu_ld8 rather than an alu_clr, so
-- the carry bit was not cleared correctly.
-- This error was picked up by Michael Hassenfratz.
--
-- 2019 Jared Boone
-- Stall1_State1 & Stall2|_State added for better cycle accuracy.
--
-- March 2020 Gyorgy Szombathelyi
-- Runned through VHDLFormatter
-- Set I bit at reset
-- Set I bit on NMI
-- Fixes many Irem sound board issues, where NMI is constantly
-- issued by the ADPCM chip, and interrupted by normal IRQ

library ieee;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;

entity cpu68 is
	port (
		clk : in std_logic;
		rst : in std_logic;
		rw : out std_logic;
		vma : out std_logic;
		address : out std_logic_vector(15 downto 0);
		data_in : in std_logic_vector(7 downto 0);
		data_out : out std_logic_vector(7 downto 0);
		hold : in std_logic;
		halt : in std_logic;
		irq : in std_logic;
		nmi : in std_logic;
		test_alu : out std_logic_vector(15 downto 0);
		test_cc : out std_logic_vector(7 downto 0)
	);
end;

architecture CPU_ARCH of cpu68 is

	constant SBIT : integer := 7;
	constant XBIT : integer := 6;
	constant HBIT : integer := 5;
	constant IBIT : integer := 4;
	constant NBIT : integer := 3;
	constant ZBIT : integer := 2;
	constant VBIT : integer := 1;
	constant CBIT : integer := 0;

	type state_type is (reset_state, fetch_state, decode_state, 
	extended_state, indexed_state, read8_state, read16_state, immediate16_state, 
	write8_state, write16_state, 
	execute_state, halt_state, error_state, 
	mul_state, mulea_state, muld_state, 
	mul0_state, mul1_state, mul2_state, mul3_state, 
	mul4_state, mul5_state, mul6_state, mul7_state, 
	jmp_state, jsr_state, jsr1_state, 
	branch_state, bsr_state, bsr1_state, 
	rts_hi_state, rts_lo_state, 
	int_pcl_state, int_pch_state, 
	int_ixl_state, int_ixh_state, 
	int_cc_state, int_acca_state, int_accb_state, 
	int_wai_state, int_mask_state, 
	rti_state, rti_cc_state, rti_acca_state, rti_accb_state, 
	rti_ixl_state, rti_ixh_state, 
	rti_pcl_state, rti_pch_state, 
	pula_state, psha_state, pulb_state, pshb_state, 
	pulx_lo_state, pulx_hi_state, pshx_lo_state, pshx_hi_state, 
	vect_lo_state, vect_hi_state, 
	stall1_state, stall2_state);
	type addr_type is (idle_ad, fetch_ad, read_ad, write_ad, push_ad, pull_ad, int_hi_ad, int_lo_ad);
	type dout_type is (md_lo_dout, md_hi_dout, acca_dout, accb_dout, ix_lo_dout, ix_hi_dout, cc_dout, pc_lo_dout, pc_hi_dout);
	type op_type is (reset_op, fetch_op, latch_op);
	type acca_type is (reset_acca, load_acca, load_hi_acca, pull_acca, latch_acca);
	type accb_type is (reset_accb, load_accb, pull_accb, latch_accb);
	type cc_type is (reset_cc, load_cc, pull_cc, latch_cc);
	type ix_type is (reset_ix, load_ix, pull_lo_ix, pull_hi_ix, latch_ix);
	type sp_type is (reset_sp, latch_sp, load_sp);
	type pc_type is (reset_pc, latch_pc, load_ea_pc, add_ea_pc, pull_lo_pc, pull_hi_pc, inc_pc);
	type md_type is (reset_md, latch_md, load_md, fetch_first_md, fetch_next_md, shiftl_md);
	type ea_type is (reset_ea, latch_ea, add_ix_ea, load_accb_ea, inc_ea, fetch_first_ea, fetch_next_ea);
	type iv_type is (reset_iv, latch_iv, swi_iv, nmi_iv, irq_iv);
	type nmi_type is (reset_nmi, set_nmi, latch_nmi);
	type left_type is (acca_left, accb_left, accd_left, md_left, ix_left, sp_left);
	type right_type is (md_right, zero_right, plus_one_right, accb_right);
	type alu_type is (alu_add8, alu_sub8, alu_add16, alu_sub16, alu_adc, alu_sbc, 
	alu_and, alu_ora, alu_eor, 
	alu_tst, alu_inc, alu_dec, alu_clr, alu_neg, alu_com, 
	alu_inx, alu_dex, alu_cpx, 
	alu_lsr16, alu_lsl16, 
	alu_ror8, alu_rol8, 
	alu_asr8, alu_asl8, alu_lsr8, 
	alu_sei, alu_cli, alu_sec, alu_clc, alu_sev, alu_clv, alu_tpa, alu_tap, 
	alu_ld8, alu_st8, alu_ld16, alu_st16, alu_nop, alu_daa);

	signal op_code : std_logic_vector(7 downto 0);
	signal acca : std_logic_vector(7 downto 0);
	signal accb : std_logic_vector(7 downto 0);
	signal cc : std_logic_vector(7 downto 0);
	signal cc_out : std_logic_vector(7 downto 0);
	signal xreg : std_logic_vector(15 downto 0);
	signal sp : std_logic_vector(15 downto 0);
	signal ea : std_logic_vector(15 downto 0);
	signal pc : std_logic_vector(15 downto 0);
	signal md : std_logic_vector(15 downto 0);
	signal left : std_logic_vector(15 downto 0);
	signal right : std_logic_vector(15 downto 0);
	signal out_alu : std_logic_vector(15 downto 0);
	signal iv : std_logic_vector(1 downto 0);
	signal nmi_req : std_logic;
	signal nmi_ack : std_logic;

	signal state : state_type;
	signal next_state : state_type;
	signal pc_ctrl : pc_type;
	signal ea_ctrl : ea_type;
	signal op_ctrl : op_type;
	signal md_ctrl : md_type;
	signal acca_ctrl : acca_type;
	signal accb_ctrl : accb_type;
	signal ix_ctrl : ix_type;
	signal cc_ctrl : cc_type;
	signal sp_ctrl : sp_type;
	signal iv_ctrl : iv_type;
	signal left_ctrl : left_type;
	signal right_ctrl : right_type;
	signal alu_ctrl : alu_type;
	signal addr_ctrl : addr_type;
	signal dout_ctrl : dout_type;
	signal nmi_ctrl : nmi_type;
begin
	----------------------------------
	--
	-- Address bus multiplexer
	--
	----------------------------------

	addr_mux : process (clk, addr_ctrl, pc, ea, sp, iv)
	begin
		case addr_ctrl is
			when idle_ad => 
				address <= "1111111111111111";
				vma <= '0';
				rw <= '1';
			when fetch_ad => 
				address <= pc;
				vma <= '1';
				rw <= '1';
			when read_ad => 
				address <= ea;
				vma <= '1';
				rw <= '1';
			when write_ad => 
				address <= ea;
				vma <= '1';
				rw <= '0';
			when push_ad => 
				address <= sp;
				vma <= '1';
				rw <= '0';
			when pull_ad => 
				address <= sp;
				vma <= '1';
				rw <= '1';
			when int_hi_ad => 
				address <= "1111111111111" & iv & "0";
				vma <= '1';
				rw <= '1';
			when int_lo_ad => 
				address <= "1111111111111" & iv & "1";
				vma <= '1';
				rw <= '1';
			when others => 
				address <= "1111111111111111";
				vma <= '0';
				rw <= '1';
		end case;
	end process;

	--------------------------------
	--
	-- Data Bus output
	--
	--------------------------------
	dout_mux : process (clk, dout_ctrl, md, acca, accb, xreg, pc, cc)
	begin
		case dout_ctrl is
			when md_hi_dout => -- alu output
				data_out <= md(15 downto 8);
			when md_lo_dout => 
				data_out <= md(7 downto 0);
			when acca_dout => -- accumulator a
				data_out <= acca;
			when accb_dout => -- accumulator b
				data_out <= accb;
			when ix_lo_dout => -- index reg
				data_out <= xreg(7 downto 0);
			when ix_hi_dout => -- index reg
				data_out <= xreg(15 downto 8);
			when cc_dout => -- condition codes
				data_out <= cc;
			when pc_lo_dout => -- low order pc
				data_out <= pc(7 downto 0);
			when pc_hi_dout => -- high order pc
				data_out <= pc(15 downto 8);
			when others => 
				data_out <= "00000000";
		end case;
	end process;
	----------------------------------
	--
	-- Program Counter Control
	--
	----------------------------------

	pc_mux : process (clk, pc_ctrl, pc, out_alu, data_in, ea, hold)
		variable tempof : std_logic_vector(15 downto 0);
		variable temppc : std_logic_vector(15 downto 0);
	begin
		case pc_ctrl is
			when add_ea_pc => 
				if ea(7) = '0' then
					tempof := "00000000" & ea(7 downto 0);
				else
					tempof := "11111111" & ea(7 downto 0);
				end if;
			when inc_pc => 
				tempof := "0000000000000001";
			when others => 
				tempof := "0000000000000000";
		end case;

		case pc_ctrl is
			when reset_pc => 
				temppc := "1111111111111110";
			when load_ea_pc => 
				temppc := ea;
			when pull_lo_pc => 
				temppc(7 downto 0) := data_in;
				temppc(15 downto 8) := pc(15 downto 8);
			when pull_hi_pc => 
				temppc(7 downto 0) := pc(7 downto 0);
				temppc(15 downto 8) := data_in;
			when others => 
				temppc := pc;
		end case;

		if clk'event and clk = '0' then
			if hold = '1' then
				pc <= pc;
			else
				pc <= temppc + tempof;
			end if;
		end if;
	end process;

	----------------------------------
	--
	-- Effective Address Control
	--
	----------------------------------

	ea_mux : process (clk, ea_ctrl, ea, out_alu, data_in, accb, xreg, hold)
		variable tempind : std_logic_vector(15 downto 0);
		variable tempea : std_logic_vector(15 downto 0);
	begin
		case ea_ctrl is
			when add_ix_ea => 
				tempind := "00000000" & ea(7 downto 0);
			when inc_ea => 
				tempind := "0000000000000001";
			when others => 
				tempind := "0000000000000000";
		end case;

		case ea_ctrl is
			when reset_ea => 
				tempea := "0000000000000000";
			when load_accb_ea => 
				tempea := "00000000" & accb(7 downto 0);
			when add_ix_ea => 
				tempea := xreg;
			when fetch_first_ea => 
				tempea(7 downto 0) := data_in;
				tempea(15 downto 8) := "00000000";
			when fetch_next_ea => 
				tempea(7 downto 0) := data_in;
				tempea(15 downto 8) := ea(7 downto 0);
			when others => 
				tempea := ea;
		end case;

		if clk'event and clk = '0' then
			if hold = '1' then
				ea <= ea;
			else
				ea <= tempea + tempind;
			end if;
		end if;
	end process;

	--------------------------------
	--
	-- Accumulator A
	--
	--------------------------------
	acca_mux : process (clk, acca_ctrl, out_alu, acca, data_in, hold)
	begin
		if clk'event and clk = '0' then
			if hold = '1' then
				acca <= acca;
			else
				case acca_ctrl is
					when reset_acca => 
						acca <= "00000000";
					when load_acca => 
						acca <= out_alu(7 downto 0);
					when load_hi_acca => 
						acca <= out_alu(15 downto 8);
					when pull_acca => 
						acca <= data_in;
					when others => 
						-- when latch_acca =>
						acca <= acca;
				end case;
			end if;
		end if;
	end process;

	--------------------------------
	--
	-- Accumulator B
	--
	--------------------------------
	accb_mux : process (clk, accb_ctrl, out_alu, accb, data_in, hold)
	begin
		if clk'event and clk = '0' then
			if hold = '1' then
				accb <= accb;
			else
				case accb_ctrl is
					when reset_accb => 
						accb <= "00000000";
					when load_accb => 
						accb <= out_alu(7 downto 0);
					when pull_accb => 
						accb <= data_in;
					when others => 
						-- when latch_accb =>
						accb <= accb;
				end case;
			end if;
		end if;
	end process;

	--------------------------------
	--
	-- X Index register
	--
	--------------------------------
	ix_mux : process (clk, ix_ctrl, out_alu, xreg, data_in, hold)
	begin
		if clk'event and clk = '0' then
			if hold = '1' then
				xreg <= xreg;
			else
				case ix_ctrl is
					when reset_ix => 
						xreg <= "0000000000000000";
					when load_ix => 
						xreg <= out_alu(15 downto 0);
					when pull_hi_ix => 
						xreg(15 downto 8) <= data_in;
					when pull_lo_ix => 
						xreg(7 downto 0) <= data_in;
					when others => 
						-- when latch_ix =>
						xreg <= xreg;
				end case;
			end if;
		end if;
	end process;

	--------------------------------
	--
	-- stack pointer
	--
	--------------------------------
	sp_mux : process (clk, sp_ctrl, out_alu, hold)
	begin
		if clk'event and clk = '0' then
			if hold = '1' then
				sp <= sp;
			else
				case sp_ctrl is
					when reset_sp => 
						sp <= "0000000000000000";
					when load_sp => 
						sp <= out_alu(15 downto 0);
					when others => 
						-- when latch_sp =>
						sp <= sp;
				end case;
			end if;
		end if;
	end process;

	--------------------------------
	--
	-- Memory Data
	--
	--------------------------------
	md_mux : process (clk, md_ctrl, out_alu, data_in, md, hold)
	begin
		if clk'event and clk = '0' then
			if hold = '1' then
				md <= md;
			else
				case md_ctrl is
					when reset_md => 
						md <= "0000000000000000";
					when load_md => 
						md <= out_alu(15 downto 0);
					when fetch_first_md => 
						md(15 downto 8) <= "00000000";
						md(7 downto 0) <= data_in;
					when fetch_next_md => 
						md(15 downto 8) <= md(7 downto 0);
						md(7 downto 0) <= data_in;
					when shiftl_md => 
						md(15 downto 1) <= md(14 downto 0);
						md(0) <= '0';
					when others => 
						-- when latch_md =>
						md <= md;
				end case;
			end if;
		end if;
	end process;
	----------------------------------
	--
	-- Condition Codes
	--
	----------------------------------

	cc_mux : process (clk, cc_ctrl, cc_out, cc, data_in, hold)
	begin
		if clk'event and clk = '0' then
			if hold = '1' then
				cc <= cc;
			else
				case cc_ctrl is
					when reset_cc => 
						cc <= "11010000";
					when load_cc => 
						cc <= cc_out;
					when pull_cc => 
						cc <= data_in;
					when others => 
						-- when latch_cc =>
						cc <= cc;
				end case;
			end if;
		end if;
	end process;

	----------------------------------
	--
	-- interrupt vector
	--
	----------------------------------

	iv_mux : process (clk, iv_ctrl, hold)
	begin
		if clk'event and clk = '0' then
			if hold = '1' then
				iv <= iv;
			else
				case iv_ctrl is
					when reset_iv => 
						iv <= "11";
					when nmi_iv => 
						iv <= "10";
					when swi_iv => 
						iv <= "01";
					when irq_iv => 
						iv <= "00";
					when others => 
						iv <= iv;
				end case;
			end if;
		end if;
	end process;

	----------------------------------
	--
	-- op code fetch
	--
	----------------------------------

	op_fetch : process (clk, data_in, op_ctrl, op_code, hold)
	begin
		if clk'event and clk = '0' then
			if hold = '1' then
				op_code <= op_code;
			else
				case op_ctrl is
					when reset_op => 
						op_code <= "00000001"; -- nop
					when fetch_op => 
						op_code <= data_in;
					when others => 
						-- when latch_op =>
						op_code <= op_code;
				end case;
			end if;
		end if;
	end process;

	----------------------------------
	--
	-- Left Mux
	--
	----------------------------------

	left_mux : process (left_ctrl, acca, accb, xreg, sp, pc, ea, md)
	begin
		case left_ctrl is
			when acca_left => 
				left(15 downto 8) <= "00000000";
				left(7 downto 0) <= acca;
			when accb_left => 
				left(15 downto 8) <= "00000000";
				left(7 downto 0) <= accb;
			when accd_left => 
				left(15 downto 8) <= acca;
				left(7 downto 0) <= accb;
			when ix_left => 
				left <= xreg;
			when sp_left => 
				left <= sp;
			when others => 
				-- when md_left =>
				left <= md;
		end case;
	end process;
	----------------------------------
	--
	-- Right Mux
	--
	----------------------------------

	right_mux : process (right_ctrl, data_in, md, accb, ea)
	begin
		case right_ctrl is
			when zero_right => 
				right <= "0000000000000000";
			when plus_one_right => 
				right <= "0000000000000001";
			when accb_right => 
				right <= "00000000" & accb;
			when others => 
				-- when md_right =>
				right <= md;
		end case;
	end process;

	----------------------------------
	--
	-- Arithmetic Logic Unit
	--
	----------------------------------

	mux_alu : process (alu_ctrl, cc, left, right, out_alu, cc_out)
		variable valid_lo, valid_hi : boolean;
		variable carry_in : std_logic;
		variable daa_reg : std_logic_vector(7 downto 0);
	begin
		case alu_ctrl is
			when alu_adc | alu_sbc | 
				alu_rol8 | alu_ror8 => 
				carry_in := cc(CBIT);
			when others => 
				carry_in := '0';
		end case;

		valid_lo := left(3 downto 0) <= 9;
		valid_hi := left(7 downto 4) <= 9;

		if (cc(CBIT) = '0') then
			if (cc(HBIT) = '1') then
				if valid_hi then
					daa_reg := "00000110";
				else
					daa_reg := "01100110";
				end if;
			else
				if valid_lo then
					if valid_hi then
						daa_reg := "00000000";
					else
						daa_reg := "01100000";
					end if;
				else
					if (left(7 downto 4) <= 8) then
						daa_reg := "00000110";
					else
						daa_reg := "01100110";
					end if;
				end if;
			end if;
		else
			if (cc(HBIT) = '1') then
				daa_reg := "01100110";
			else
				if valid_lo then
					daa_reg := "01100000";
				else
					daa_reg := "01100110";
				end if;
			end if;
		end if;

		case alu_ctrl is
			when alu_add8 | alu_inc | 
				alu_add16 | alu_inx | 
				alu_adc => 
				out_alu <= left + right + ("000000000000000" & carry_in);
			when alu_sub8 | alu_dec | 
				alu_sub16 | alu_dex | 
				alu_sbc | alu_cpx => 
				out_alu <= left - right - ("000000000000000" & carry_in);
			when alu_and => 
				out_alu <= left and right; -- and/bit
			when alu_ora => 
				out_alu <= left or right; -- or
			when alu_eor => 
				out_alu <= left xor right; -- eor/xor
			when alu_lsl16 | alu_asl8 | alu_rol8 => 
				out_alu <= left(14 downto 0) & carry_in; -- rol8/asl8/lsl16
			when alu_lsr16 | alu_lsr8 => 
				out_alu <= carry_in & left(15 downto 1); -- lsr
			when alu_ror8 => 
				out_alu <= "00000000" & carry_in & left(7 downto 1); -- ror
			when alu_asr8 => 
				out_alu <= "00000000" & left(7) & left(7 downto 1); -- asr
			when alu_neg => 
				out_alu <= right - left; -- neg (right=0)
			when alu_com => 
				out_alu <= not left;
			when alu_clr | alu_ld8 | alu_ld16 => 
				out_alu <= right; -- clr, ld
			when alu_st8 | alu_st16 => 
				out_alu <= left;
			when alu_daa => 
				out_alu <= left + ("00000000" & daa_reg);
			when alu_tpa => 
				out_alu <= "00000000" & cc;
			when others => 
				out_alu <= left; -- nop
		end case;

		--
		-- carry bit
		--
		case alu_ctrl is
			when alu_add8 | alu_adc => 
				cc_out(CBIT) <= (left(7) and right(7)) or
					(left(7) and not out_alu(7)) or
					(right(7) and not out_alu(7));
			when alu_sub8 | alu_sbc => 
				cc_out(CBIT) <= ((not left(7)) and right(7)) or
					((not left(7)) and out_alu(7)) or
					(right(7) and out_alu(7));
			when alu_add16 => 
				cc_out(CBIT) <= (left(15) and right(15)) or
					(left(15) and not out_alu(15)) or
					(right(15) and not out_alu(15));
			when alu_sub16 => 
				cc_out(CBIT) <= ((not left(15)) and right(15)) or
					((not left(15)) and out_alu(15)) or
					(right(15) and out_alu(15));
			when alu_ror8 | alu_lsr16 | alu_lsr8 | alu_asr8 => 
				cc_out(CBIT) <= left(0);
			when alu_rol8 | alu_asl8 => 
				cc_out(CBIT) <= left(7);
			when alu_lsl16 => 
				cc_out(CBIT) <= left(15);
			when alu_com => 
				cc_out(CBIT) <= '1';
			when alu_neg | alu_clr => 
				cc_out(CBIT) <= out_alu(7) or out_alu(6) or out_alu(5) or out_alu(4) or
					out_alu(3) or out_alu(2) or out_alu(1) or out_alu(0);
			when alu_daa => 
				if (daa_reg(7 downto 4) = "0110") then
					cc_out(CBIT) <= '1';
				else
					cc_out(CBIT) <= '0';
				end if;
			when alu_sec => 
				cc_out(CBIT) <= '1';
			when alu_clc => 
				cc_out(CBIT) <= '0';
			when alu_tap => 
				cc_out(CBIT) <= left(CBIT);
			when others => -- carry is not affected by cpx
				cc_out(CBIT) <= cc(CBIT);
		end case;
		--
		-- Zero flag
		--
		case alu_ctrl is
			when alu_add8 | alu_sub8 | 
				alu_adc | alu_sbc | 
				alu_and | alu_ora | alu_eor | 
				alu_inc | alu_dec | 
				alu_neg | alu_com | alu_clr | 
				alu_rol8 | alu_ror8 | alu_asr8 | alu_asl8 | alu_lsr8 | 
				alu_ld8 | alu_st8 => 
				cc_out(ZBIT) <= not(out_alu(7) or out_alu(6) or out_alu(5) or out_alu(4) or
					out_alu(3) or out_alu(2) or out_alu(1) or out_alu(0));
			when alu_add16 | alu_sub16 | 
				alu_lsl16 | alu_lsr16 | 
				alu_inx | alu_dex | 
				alu_ld16 | alu_st16 | alu_cpx => 
				cc_out(ZBIT) <= not(out_alu(15) or out_alu(14) or out_alu(13) or out_alu(12) or
					out_alu(11) or out_alu(10) or out_alu(9) or out_alu(8) or
					out_alu(7) or out_alu(6) or out_alu(5) or out_alu(4) or
					out_alu(3) or out_alu(2) or out_alu(1) or out_alu(0));
			when alu_tap => 
				cc_out(ZBIT) <= left(ZBIT);
			when others => 
				cc_out(ZBIT) <= cc(ZBIT);
		end case;

		--
		-- negative flag
		--
		case alu_ctrl is
			when alu_add8 | alu_sub8 | 
				alu_adc | alu_sbc | 
				alu_and | alu_ora | alu_eor | 
				alu_rol8 | alu_ror8 | alu_asr8 | alu_asl8 | alu_lsr8 | 
				alu_inc | alu_dec | alu_neg | alu_com | alu_clr | 
				alu_ld8 | alu_st8 => 
				cc_out(NBIT) <= out_alu(7);
			when alu_add16 | alu_sub16 | 
				alu_lsl16 | alu_lsr16 | 
				alu_ld16 | alu_st16 | alu_cpx => 
				cc_out(NBIT) <= out_alu(15);
			when alu_tap => 
				cc_out(NBIT) <= left(NBIT);
			when others => 
				cc_out(NBIT) <= cc(NBIT);
		end case;

		--
		-- Interrupt mask flag
		--
		case alu_ctrl is
			when alu_sei => 
				cc_out(IBIT) <= '1'; -- set interrupt mask
			when alu_cli => 
				cc_out(IBIT) <= '0'; -- clear interrupt mask
			when alu_tap => 
				cc_out(IBIT) <= left(IBIT);
			when others => 
				cc_out(IBIT) <= cc(IBIT); -- interrupt mask
		end case;

		--
		-- Half Carry flag
		--
		case alu_ctrl is
			when alu_add8 | alu_adc => 
				cc_out(HBIT) <= (left(3) and right(3)) or
					(right(3) and not out_alu(3)) or
					(left(3) and not out_alu(3));
			when alu_tap => 
				cc_out(HBIT) <= left(HBIT);
			when others => 
				cc_out(HBIT) <= cc(HBIT);
		end case;

		--
		-- Overflow flag
		--
		case alu_ctrl is
			when alu_add8 | alu_adc => 
				cc_out(VBIT) <= (left(7) and right(7) and (not out_alu(7))) or
					((not left(7)) and (not right(7)) and out_alu(7));
			when alu_sub8 | alu_sbc => 
				cc_out(VBIT) <= (left(7) and (not right(7)) and (not out_alu(7))) or
					((not left(7)) and right(7) and out_alu(7));
			when alu_add16 => 
				cc_out(VBIT) <= (left(15) and right(15) and (not out_alu(15))) or
					((not left(15)) and (not right(15)) and out_alu(15));
			when alu_sub16 | alu_cpx => 
				cc_out(VBIT) <= (left(15) and (not right(15)) and (not out_alu(15))) or
					((not left(15)) and right(15) and out_alu(15));
			when alu_inc => 
				cc_out(VBIT) <= ((not left(7)) and left(6) and left(5) and left(4) and
					left(3) and left(2) and left(1) and left(0));
			when alu_dec | alu_neg => 
				cc_out(VBIT) <= (left(7) and (not left(6)) and (not left(5)) and (not left(4)) and
					(not left(3)) and (not left(2)) and (not left(1)) and (not left(0)));
			when alu_asr8 => 
				cc_out(VBIT) <= left(0) xor left(7);
			when alu_lsr8 | alu_lsr16 => 
				cc_out(VBIT) <= left(0);
			when alu_ror8 => 
				cc_out(VBIT) <= left(0) xor cc(CBIT);
			when alu_lsl16 => 
				cc_out(VBIT) <= left(15) xor left(14);
			when alu_rol8 | alu_asl8 => 
				cc_out(VBIT) <= left(7) xor left(6);
			when alu_tap => 
				cc_out(VBIT) <= left(VBIT);
			when alu_and | alu_ora | alu_eor | alu_com | 
				alu_st8 | alu_st16 | alu_ld8 | alu_ld16 | 
				alu_clv => 
				cc_out(VBIT) <= '0';
			when alu_sev => 
				cc_out(VBIT) <= '1';
			when others => 
				cc_out(VBIT) <= cc(VBIT);
		end case;

		case alu_ctrl is
			when alu_tap => 
				cc_out(XBIT) <= cc(XBIT) and left(XBIT);
				cc_out(SBIT) <= left(SBIT);
			when others => 
				cc_out(XBIT) <= cc(XBIT) and left(XBIT);
				cc_out(SBIT) <= cc(SBIT);
		end case;

		test_alu <= out_alu;
		test_cc <= cc_out;
	end process;

	------------------------------------
	--
	-- Detect Edge of NMI interrupt
	--
	------------------------------------

	nmi_handler : process (clk, rst, nmi, nmi_ack)
	begin
		if clk'event and clk = '0' then
			if hold = '1' then
				nmi_req <= nmi_req;
			else
				if rst = '1' then
					nmi_req <= '0';
				else
					if (nmi = '1') and (nmi_ack = '0') then
						nmi_req <= '1';
					else
						if (nmi = '0') and (nmi_ack = '1') then
							nmi_req <= '0';
						else
							nmi_req <= nmi_req;
						end if;
					end if;
				end if;
			end if;
		end if;
	end process;

	------------------------------------
	--
	-- Nmi mux
	--
	------------------------------------

	nmi_mux : process (clk, nmi_ctrl, nmi_ack, hold)
	begin
		if clk'event and clk = '0' then
			if hold = '1' then
				nmi_ack <= nmi_ack;
			else
				case nmi_ctrl is
					when set_nmi => 
						nmi_ack <= '1';
					when reset_nmi => 
						nmi_ack <= '0';
					when others => 
						-- when latch_nmi =>
						nmi_ack <= nmi_ack;
				end case;
			end if;
		end if;
	end process;

	------------------------------------
	--
	-- state sequencer
	--
	------------------------------------
	process (state, op_code, cc, ea, irq, nmi_req, nmi_ack, hold, halt)
		begin
			case state is
				when reset_state => -- released from reset
					-- reset the registers
					op_ctrl <= reset_op;
					acca_ctrl <= reset_acca;
					accb_ctrl <= reset_accb;
					ix_ctrl <= reset_ix;
					sp_ctrl <= reset_sp;
					pc_ctrl <= reset_pc;
					ea_ctrl <= reset_ea;
					md_ctrl <= reset_md;
					iv_ctrl <= reset_iv;
					nmi_ctrl <= reset_nmi;
					-- idle the ALU
					left_ctrl <= acca_left;
					right_ctrl <= zero_right;
					alu_ctrl <= alu_nop;
					cc_ctrl <= reset_cc;
					-- idle the bus
					dout_ctrl <= md_lo_dout;
					addr_ctrl <= idle_ad;
					next_state <= vect_hi_state;

					--
					-- Jump via interrupt vector
					-- iv holds interrupt type
					-- fetch PC hi from vector location
					--
				when vect_hi_state => 
					-- default the registers
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					sp_ctrl <= latch_sp;
					md_ctrl <= latch_md;
					ea_ctrl <= latch_ea;
					iv_ctrl <= latch_iv;
					-- idle the ALU
					left_ctrl <= acca_left;
					right_ctrl <= zero_right;
					alu_ctrl <= alu_nop;
					cc_ctrl <= latch_cc;
					-- fetch pc low interrupt vector
					pc_ctrl <= pull_hi_pc;
					addr_ctrl <= int_hi_ad;
					dout_ctrl <= pc_hi_dout;
					next_state <= vect_lo_state;
					--
					-- jump via interrupt vector
					-- iv holds vector type
					-- fetch PC lo from vector location
					--
				when vect_lo_state => 
					-- default the registers
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					sp_ctrl <= latch_sp;
					md_ctrl <= latch_md;
					ea_ctrl <= latch_ea;
					iv_ctrl <= latch_iv;
					-- idle the ALU
					left_ctrl <= acca_left;
					right_ctrl <= zero_right;
					alu_ctrl <= alu_nop;
					cc_ctrl <= latch_cc;
					-- fetch the vector low byte
					pc_ctrl <= pull_lo_pc;
					addr_ctrl <= int_lo_ad;
					dout_ctrl <= pc_lo_dout;
					next_state <= fetch_state;

					--
					-- Here to fetch an instruction
					-- PC points to opcode
					-- Should service interrupt requests at this point
					-- either from the timer
					-- or from the external input.
					--
				when fetch_state => 
					case op_code(7 downto 4) is
						when "0000" | 
							"0001" | 
								"0010" | -- branch conditional
								"0011" | 
								"0100" | -- acca single op
								"0101" | -- accb single op
								"0110" | -- indexed single op
								"0111" => -- extended single op
								-- idle ALU
								left_ctrl <= acca_left;
								right_ctrl <= zero_right;
								alu_ctrl <= alu_nop;
								cc_ctrl <= latch_cc;
								acca_ctrl <= latch_acca;
								accb_ctrl <= latch_accb;
								ix_ctrl <= latch_ix;
								sp_ctrl <= latch_sp;

						when "1000" | -- acca immediate
							"1001" | -- acca direct
								"1010" | -- acca indexed
								"1011" => -- acca extended
								case op_code(3 downto 0) is
									when "0000" => -- suba
									left_ctrl <= acca_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_sub8;
									cc_ctrl <= load_cc;
									acca_ctrl <= load_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									when "0001" => -- cmpa
									left_ctrl <= acca_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_sub8;
									cc_ctrl <= load_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									when "0010" => -- sbca
									left_ctrl <= acca_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_sbc;
									cc_ctrl <= load_cc;
									acca_ctrl <= load_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									when "0011" => -- subd
									left_ctrl <= accd_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_sub16;
									cc_ctrl <= load_cc;
									acca_ctrl <= load_hi_acca;
									accb_ctrl <= load_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									when "0100" => -- anda
									left_ctrl <= acca_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_and;
									cc_ctrl <= load_cc;
									acca_ctrl <= load_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									when "0101" => -- bita
									left_ctrl <= acca_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_and;
									cc_ctrl <= load_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									when "0110" => -- ldaa
									left_ctrl <= acca_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_ld8;
									cc_ctrl <= load_cc;
									acca_ctrl <= load_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									when "0111" => -- staa
									left_ctrl <= acca_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_st8;
									cc_ctrl <= load_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									when "1000" => -- eora
									left_ctrl <= acca_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_eor;
									cc_ctrl <= load_cc;
									acca_ctrl <= load_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									when "1001" => -- adca
									left_ctrl <= acca_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_adc;
									cc_ctrl <= load_cc;
									acca_ctrl <= load_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									when "1010" => -- oraa
									left_ctrl <= acca_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_ora;
									cc_ctrl <= load_cc;
									acca_ctrl <= load_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									when "1011" => -- adda
									left_ctrl <= acca_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_add8;
									cc_ctrl <= load_cc;
									acca_ctrl <= load_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									when "1100" => -- cpx
									left_ctrl <= ix_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_cpx;
									cc_ctrl <= load_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									when "1101" => -- bsr / jsr
									left_ctrl <= acca_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_nop;
									cc_ctrl <= latch_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									when "1110" => -- lds
									left_ctrl <= sp_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_ld16;
									cc_ctrl <= load_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= load_sp;
									when "1111" => -- sts
									left_ctrl <= sp_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_st16;
									cc_ctrl <= load_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									when others => 
									left_ctrl <= acca_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_nop;
									cc_ctrl <= latch_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
						end case;
						when "1100" | -- accb immediate
							"1101" | -- accb direct
								"1110" | -- accb indexed
								"1111" => -- accb extended
								case op_code(3 downto 0) is
									when "0000" => -- subb
									left_ctrl <= accb_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_sub8;
									cc_ctrl <= load_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= load_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									when "0001" => -- cmpb
									left_ctrl <= accb_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_sub8;
									cc_ctrl <= load_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									when "0010" => -- sbcb
									left_ctrl <= accb_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_sbc;
									cc_ctrl <= load_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= load_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									when "0011" => -- addd
									left_ctrl <= accd_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_add16;
									cc_ctrl <= load_cc;
									acca_ctrl <= load_hi_acca;
									accb_ctrl <= load_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									when "0100" => -- andb
									left_ctrl <= accb_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_and;
									cc_ctrl <= load_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= load_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									when "0101" => -- bitb
									left_ctrl <= accb_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_and;
									cc_ctrl <= load_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									when "0110" => -- ldab
									left_ctrl <= accb_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_ld8;
									cc_ctrl <= load_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= load_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									when "0111" => -- stab
									left_ctrl <= accb_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_st8;
									cc_ctrl <= load_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									when "1000" => -- eorb
									left_ctrl <= accb_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_eor;
									cc_ctrl <= load_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= load_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									when "1001" => -- adcb
									left_ctrl <= accb_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_adc;
									cc_ctrl <= load_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= load_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									when "1010" => -- orab
									left_ctrl <= accb_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_ora;
									cc_ctrl <= load_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= load_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									when "1011" => -- addb
									left_ctrl <= accb_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_add8;
									cc_ctrl <= load_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= load_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									when "1100" => -- ldd
									left_ctrl <= accd_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_ld16;
									cc_ctrl <= load_cc;
									acca_ctrl <= load_hi_acca;
									accb_ctrl <= load_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									when "1101" => -- std
									left_ctrl <= accd_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_st16;
									cc_ctrl <= load_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									when "1110" => -- ldx
									left_ctrl <= ix_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_ld16;
									cc_ctrl <= load_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= load_ix;
									sp_ctrl <= latch_sp;
									when "1111" => -- stx
									left_ctrl <= ix_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_st16;
									cc_ctrl <= load_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									when others => 
									left_ctrl <= accb_left;
									right_ctrl <= md_right;
									alu_ctrl <= alu_nop;
									cc_ctrl <= latch_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
						end case;
						when others => 
							left_ctrl <= accd_left;
							right_ctrl <= md_right;
							alu_ctrl <= alu_nop;
							cc_ctrl <= latch_cc;
							acca_ctrl <= latch_acca;
							accb_ctrl <= latch_accb;
							ix_ctrl <= latch_ix;
							sp_ctrl <= latch_sp;
				end case;
				md_ctrl <= latch_md;
				-- fetch the op code
				op_ctrl <= fetch_op;
				ea_ctrl <= reset_ea;
				addr_ctrl <= fetch_ad;
				dout_ctrl <= md_lo_dout;
				iv_ctrl <= latch_iv;
				if halt = '1' then
					pc_ctrl <= latch_pc;
					nmi_ctrl <= latch_nmi;
					next_state <= halt_state;
					-- service non maskable interrupts
				elsif (nmi_req = '1') and (nmi_ack = '0') then
					pc_ctrl <= latch_pc;
					nmi_ctrl <= set_nmi;
					next_state <= int_pcl_state;
					-- service maskable interrupts
				else
					--
					-- nmi request is not cleared until nmi input goes low
					--
					if (nmi_req = '0') and (nmi_ack = '1') then
						nmi_ctrl <= reset_nmi;
					else
						nmi_ctrl <= latch_nmi;
					end if;
					--
					-- IRQ is level sensitive
					--
					if (irq = '1') and (cc(IBIT) = '0') then
						pc_ctrl <= latch_pc;
						next_state <= int_pcl_state;
					else
						-- Advance the PC to fetch next instruction byte
						pc_ctrl <= inc_pc;
						next_state <= decode_state;
					end if;
				end if;
				--
				-- Here to decode instruction
				-- and fetch next byte of intruction
				-- whether it be necessary or not
				--
				when decode_state => 
					-- fetch first byte of address or immediate data
					ea_ctrl <= fetch_first_ea;
					addr_ctrl <= fetch_ad;
					dout_ctrl <= md_lo_dout;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					iv_ctrl <= latch_iv;
					case op_code(7 downto 4) is
						when "0000" => 
							md_ctrl <= fetch_first_md;
							sp_ctrl <= latch_sp;
							pc_ctrl <= latch_pc;
							case op_code(3 downto 0) is
								when "0001" => -- nop
									left_ctrl <= accd_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_nop;
									cc_ctrl <= latch_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= latch_ix;
									next_state <= fetch_state;
								when "0100" => -- lsrd
									left_ctrl <= accd_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_lsr16;
									cc_ctrl <= load_cc;
									acca_ctrl <= load_hi_acca;
									accb_ctrl <= load_accb;
									ix_ctrl <= latch_ix;
									next_state <= fetch_state;
								when "0101" => -- lsld
									left_ctrl <= accd_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_lsl16;
									cc_ctrl <= load_cc;
									acca_ctrl <= load_hi_acca;
									accb_ctrl <= load_accb;
									ix_ctrl <= latch_ix;
									next_state <= fetch_state;
								when "0110" => -- tap
									left_ctrl <= acca_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_tap;
									cc_ctrl <= load_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= latch_ix;
									next_state <= fetch_state;
								when "0111" => -- tpa
									left_ctrl <= acca_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_tpa;
									cc_ctrl <= latch_cc;
									acca_ctrl <= load_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= latch_ix;
									next_state <= fetch_state;
								when "1000" => -- inx
									left_ctrl <= ix_left;
									right_ctrl <= plus_one_right;
									alu_ctrl <= alu_inx;
									cc_ctrl <= load_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= load_ix;
									next_state <= fetch_state;
								when "1001" => -- dex
									left_ctrl <= ix_left;
									right_ctrl <= plus_one_right;
									alu_ctrl <= alu_dex;
									cc_ctrl <= load_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= load_ix;
									next_state <= stall2_state;
								when "1010" => -- clv
									left_ctrl <= acca_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_clv;
									cc_ctrl <= load_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= latch_ix;
									next_state <= fetch_state;
								when "1011" => -- sev
									left_ctrl <= acca_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_sev;
									cc_ctrl <= load_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= latch_ix;
									next_state <= fetch_state;
								when "1100" => -- clc
									left_ctrl <= acca_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_clc;
									cc_ctrl <= load_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= latch_ix;
									next_state <= fetch_state;
								when "1101" => -- sec
									left_ctrl <= acca_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_sec;
									cc_ctrl <= load_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= latch_ix;
									next_state <= fetch_state;
								when "1110" => -- cli
									left_ctrl <= acca_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_cli;
									cc_ctrl <= load_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= latch_ix;
									next_state <= fetch_state;
								when "1111" => -- sei
									left_ctrl <= acca_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_sei;
									cc_ctrl <= load_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= latch_ix;
									next_state <= fetch_state;
								when others => 
									left_ctrl <= acca_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_nop;
									cc_ctrl <= latch_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= latch_accb;
									ix_ctrl <= latch_ix;
									next_state <= fetch_state;
						end case;
						-- acca / accb inherent instructions
						when "0001" => 
							md_ctrl <= fetch_first_md;
							ix_ctrl <= latch_ix;
							sp_ctrl <= latch_sp;
							pc_ctrl <= latch_pc;
							left_ctrl <= acca_left;
							right_ctrl <= accb_right;
							case op_code(3 downto 0) is
								when "0000" => -- sba
									alu_ctrl <= alu_sub8;
									cc_ctrl <= load_cc;
									acca_ctrl <= load_acca;
									accb_ctrl <= latch_accb;
								when "0001" => -- cba
									alu_ctrl <= alu_sub8;
									cc_ctrl <= load_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= latch_accb;
								when "0110" => -- tab
									alu_ctrl <= alu_st8;
									cc_ctrl <= load_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= load_accb;
								when "0111" => -- tba
									alu_ctrl <= alu_ld8;
									cc_ctrl <= load_cc;
									acca_ctrl <= load_acca;
									accb_ctrl <= latch_accb;
								when "1001" => -- daa
									alu_ctrl <= alu_daa;
									cc_ctrl <= load_cc;
									acca_ctrl <= load_acca;
									accb_ctrl <= latch_accb;
								when "1011" => -- aba
									alu_ctrl <= alu_add8;
									cc_ctrl <= load_cc;
									acca_ctrl <= load_acca;
									accb_ctrl <= latch_accb;
								when others => 
									alu_ctrl <= alu_nop;
									cc_ctrl <= latch_cc;
									acca_ctrl <= latch_acca;
									accb_ctrl <= latch_accb;
						end case;
						next_state <= fetch_state;
						when "0010" => -- branch conditional
							md_ctrl <= fetch_first_md;
							acca_ctrl <= latch_acca;
							accb_ctrl <= latch_accb;
							ix_ctrl <= latch_ix;
							sp_ctrl <= latch_sp;
							left_ctrl <= acca_left;
							right_ctrl <= zero_right;
							alu_ctrl <= alu_nop;
							cc_ctrl <= latch_cc;
							-- increment the pc
							pc_ctrl <= inc_pc;
							case op_code(3 downto 0) is
								when "0000" => -- bra
									next_state <= branch_state;
								when "0001" => -- brn
									next_state <= stall2_state;
								when "0010" => -- bhi
									if (cc(CBIT) or cc(ZBIT)) = '0' then
										next_state <= branch_state;
									else
										next_state <= stall2_state;
									end if;
								when "0011" => -- bls
									if (cc(CBIT) or cc(ZBIT)) = '1' then
										next_state <= branch_state;
									else
										next_state <= stall2_state;
									end if;
								when "0100" => -- bcc/bhs
									if cc(CBIT) = '0' then
										next_state <= branch_state;
									else
										next_state <= stall2_state;
									end if;
								when "0101" => -- bcs/blo
									if cc(CBIT) = '1' then
										next_state <= branch_state;
									else
										next_state <= stall2_state;
									end if;
								when "0110" => -- bne
									if cc(ZBIT) = '0' then
										next_state <= branch_state;
									else
										next_state <= stall2_state;
									end if;
								when "0111" => -- beq
									if cc(ZBIT) = '1' then
										next_state <= branch_state;
									else
										next_state <= stall2_state;
									end if;
								when "1000" => -- bvc
									if cc(VBIT) = '0' then
										next_state <= branch_state;
									else
										next_state <= stall2_state;
									end if;
								when "1001" => -- bvs
									if cc(VBIT) = '1' then
										next_state <= branch_state;
									else
										next_state <= stall2_state;
									end if;
								when "1010" => -- bpl
									if cc(NBIT) = '0' then
										next_state <= branch_state;
									else
										next_state <= stall2_state;
									end if;
								when "1011" => -- bmi
									if cc(NBIT) = '1' then
										next_state <= branch_state;
									else
										next_state <= stall2_state;
									end if;
								when "1100" => -- bge
									if (cc(NBIT) xor cc(VBIT)) = '0' then
										next_state <= branch_state;
									else
										next_state <= stall2_state;
									end if;
								when "1101" => -- blt
									if (cc(NBIT) xor cc(VBIT)) = '1' then
										next_state <= branch_state;
									else
										next_state <= stall2_state;
									end if;
								when "1110" => -- bgt
									if (cc(ZBIT) or (cc(NBIT) xor cc(VBIT))) = '0' then
										next_state <= branch_state;
									else
										next_state <= stall2_state;
									end if;
								when "1111" => -- ble
									if (cc(ZBIT) or (cc(NBIT) xor cc(VBIT))) = '1' then
										next_state <= branch_state;
									else
										next_state <= stall2_state;
									end if;
								when others => 
									next_state <= stall2_state;
						end case;
						--
						-- Single byte stack operators
						-- Do not advance PC
						--
						when "0011" => 
							md_ctrl <= fetch_first_md;
							acca_ctrl <= latch_acca;
							accb_ctrl <= latch_accb;
							pc_ctrl <= latch_pc;
							case op_code(3 downto 0) is
								when "0000" => -- tsx
									left_ctrl <= sp_left;
									right_ctrl <= plus_one_right;
									alu_ctrl <= alu_add16;
									cc_ctrl <= latch_cc;
									ix_ctrl <= load_ix;
									sp_ctrl <= latch_sp;
									next_state <= fetch_state;
								when "0001" => -- ins
									left_ctrl <= sp_left;
									right_ctrl <= plus_one_right;
									alu_ctrl <= alu_add16;
									cc_ctrl <= latch_cc;
									ix_ctrl <= latch_ix;
									sp_ctrl <= load_sp;
									next_state <= fetch_state;
								when "0010" => -- pula
									left_ctrl <= sp_left;
									right_ctrl <= plus_one_right;
									alu_ctrl <= alu_add16;
									cc_ctrl <= latch_cc;
									ix_ctrl <= latch_ix;
									sp_ctrl <= load_sp;
									next_state <= pula_state;
								when "0011" => -- pulb
									left_ctrl <= sp_left;
									right_ctrl <= plus_one_right;
									alu_ctrl <= alu_add16;
									cc_ctrl <= latch_cc;
									ix_ctrl <= latch_ix;
									sp_ctrl <= load_sp;
									next_state <= pulb_state;
								when "0100" => -- des
									-- decrement sp
									left_ctrl <= sp_left;
									right_ctrl <= plus_one_right;
									alu_ctrl <= alu_sub16;
									cc_ctrl <= latch_cc;
									ix_ctrl <= latch_ix;
									sp_ctrl <= load_sp;
									next_state <= fetch_state;
								when "0101" => -- txs
									left_ctrl <= ix_left;
									right_ctrl <= plus_one_right;
									alu_ctrl <= alu_sub16;
									cc_ctrl <= latch_cc;
									ix_ctrl <= latch_ix;
									sp_ctrl <= load_sp;
									next_state <= fetch_state;
								when "0110" => -- psha
									left_ctrl <= sp_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_nop;
									cc_ctrl <= latch_cc;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									next_state <= psha_state;
								when "0111" => -- pshb
									left_ctrl <= sp_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_nop;
									cc_ctrl <= latch_cc;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									next_state <= pshb_state;
								when "1000" => -- pulx
									left_ctrl <= sp_left;
									right_ctrl <= plus_one_right;
									alu_ctrl <= alu_add16;
									cc_ctrl <= latch_cc;
									ix_ctrl <= latch_ix;
									sp_ctrl <= load_sp;
									next_state <= pulx_hi_state;
								when "1001" => -- rts
									left_ctrl <= sp_left;
									right_ctrl <= plus_one_right;
									alu_ctrl <= alu_add16;
									cc_ctrl <= latch_cc;
									ix_ctrl <= latch_ix;
									sp_ctrl <= load_sp;
									next_state <= rts_hi_state;
								when "1010" => -- abx
									left_ctrl <= ix_left;
									right_ctrl <= accb_right;
									alu_ctrl <= alu_add16;
									cc_ctrl <= latch_cc;
									ix_ctrl <= load_ix;
									sp_ctrl <= latch_sp;
									next_state <= fetch_state;
								when "1011" => -- rti
									left_ctrl <= sp_left;
									right_ctrl <= plus_one_right;
									alu_ctrl <= alu_add16;
									cc_ctrl <= latch_cc;
									ix_ctrl <= latch_ix;
									sp_ctrl <= load_sp;
									next_state <= rti_cc_state;
								when "1100" => -- pshx
									left_ctrl <= sp_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_nop;
									cc_ctrl <= latch_cc;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									next_state <= pshx_lo_state;
								when "1101" => -- mul
									left_ctrl <= acca_left;
									right_ctrl <= accb_right;
									alu_ctrl <= alu_add16;
									cc_ctrl <= latch_cc;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									next_state <= mul_state;
								when "1110" => -- wai
									left_ctrl <= sp_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_nop;
									cc_ctrl <= latch_cc;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									next_state <= int_pcl_state;
								when "1111" => -- swi
									left_ctrl <= sp_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_nop;
									cc_ctrl <= latch_cc;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									next_state <= int_pcl_state;
								when others => 
									left_ctrl <= sp_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_nop;
									cc_ctrl <= latch_cc;
									ix_ctrl <= latch_ix;
									sp_ctrl <= latch_sp;
									next_state <= fetch_state;
						end case;
						--
						-- Accumulator A Single operand
						-- source = Acc A dest = Acc A
						-- Do not advance PC
						--
						when "0100" => -- acca single op
							md_ctrl <= fetch_first_md;
							accb_ctrl <= latch_accb;
							pc_ctrl <= latch_pc;
							ix_ctrl <= latch_ix;
							sp_ctrl <= latch_sp;
							left_ctrl <= acca_left;
							case op_code(3 downto 0) is
								when "0000" => -- neg
									right_ctrl <= zero_right;
									alu_ctrl <= alu_neg;
									acca_ctrl <= load_acca;
									cc_ctrl <= load_cc;
								when "0011" => -- com
									right_ctrl <= zero_right;
									alu_ctrl <= alu_com;
									acca_ctrl <= load_acca;
									cc_ctrl <= load_cc;
								when "0100" => -- lsr
									right_ctrl <= zero_right;
									alu_ctrl <= alu_lsr8;
									acca_ctrl <= load_acca;
									cc_ctrl <= load_cc;
								when "0110" => -- ror
									right_ctrl <= zero_right;
									alu_ctrl <= alu_ror8;
									acca_ctrl <= load_acca;
									cc_ctrl <= load_cc;
								when "0111" => -- asr
									right_ctrl <= zero_right;
									alu_ctrl <= alu_asr8;
									acca_ctrl <= load_acca;
									cc_ctrl <= load_cc;
								when "1000" => -- asl
									right_ctrl <= zero_right;
									alu_ctrl <= alu_asl8;
									acca_ctrl <= load_acca;
									cc_ctrl <= load_cc;
								when "1001" => -- rol
									right_ctrl <= zero_right;
									alu_ctrl <= alu_rol8;
									acca_ctrl <= load_acca;
									cc_ctrl <= load_cc;
								when "1010" => -- dec
									right_ctrl <= plus_one_right;
									alu_ctrl <= alu_dec;
									acca_ctrl <= load_acca;
									cc_ctrl <= load_cc;
								when "1011" => -- undefined
									right_ctrl <= zero_right;
									alu_ctrl <= alu_nop;
									acca_ctrl <= latch_acca;
									cc_ctrl <= latch_cc;
								when "1100" => -- inc
									right_ctrl <= plus_one_right;
									alu_ctrl <= alu_inc;
									acca_ctrl <= load_acca;
									cc_ctrl <= load_cc;
								when "1101" => -- tst
									right_ctrl <= zero_right;
									alu_ctrl <= alu_st8;
									acca_ctrl <= latch_acca;
									cc_ctrl <= load_cc;
								when "1110" => -- jmp
									right_ctrl <= zero_right;
									alu_ctrl <= alu_nop;
									acca_ctrl <= latch_acca;
									cc_ctrl <= latch_cc;
								when "1111" => -- clr
									right_ctrl <= zero_right;
									alu_ctrl <= alu_clr;
									acca_ctrl <= load_acca;
									cc_ctrl <= load_cc;
								when others => 
									right_ctrl <= zero_right;
									alu_ctrl <= alu_nop;
									acca_ctrl <= latch_acca;
									cc_ctrl <= latch_cc;
						end case;
						next_state <= fetch_state;
						--
						-- single operand acc b
						-- Do not advance PC
						--
						when "0101" => 
							md_ctrl <= fetch_first_md;
							acca_ctrl <= latch_acca;
							pc_ctrl <= latch_pc;
							ix_ctrl <= latch_ix;
							sp_ctrl <= latch_sp;
							left_ctrl <= accb_left;
							case op_code(3 downto 0) is
								when "0000" => -- neg
									right_ctrl <= zero_right;
									alu_ctrl <= alu_neg;
									accb_ctrl <= load_accb;
									cc_ctrl <= load_cc;
								when "0011" => -- com
									right_ctrl <= zero_right;
									alu_ctrl <= alu_com;
									accb_ctrl <= load_accb;
									cc_ctrl <= load_cc;
								when "0100" => -- lsr
									right_ctrl <= zero_right;
									alu_ctrl <= alu_lsr8;
									accb_ctrl <= load_accb;
									cc_ctrl <= load_cc;
								when "0110" => -- ror
									right_ctrl <= zero_right;
									alu_ctrl <= alu_ror8;
									accb_ctrl <= load_accb;
									cc_ctrl <= load_cc;
								when "0111" => -- asr
									right_ctrl <= zero_right;
									alu_ctrl <= alu_asr8;
									accb_ctrl <= load_accb;
									cc_ctrl <= load_cc;
								when "1000" => -- asl
									right_ctrl <= zero_right;
									alu_ctrl <= alu_asl8;
									accb_ctrl <= load_accb;
									cc_ctrl <= load_cc;
								when "1001" => -- rol
									right_ctrl <= zero_right;
									alu_ctrl <= alu_rol8;
									accb_ctrl <= load_accb;
									cc_ctrl <= load_cc;
								when "1010" => -- dec
									right_ctrl <= plus_one_right;
									alu_ctrl <= alu_dec;
									accb_ctrl <= load_accb;
									cc_ctrl <= load_cc;
								when "1011" => -- undefined
									right_ctrl <= zero_right;
									alu_ctrl <= alu_nop;
									accb_ctrl <= latch_accb;
									cc_ctrl <= latch_cc;
								when "1100" => -- inc
									right_ctrl <= plus_one_right;
									alu_ctrl <= alu_inc;
									accb_ctrl <= load_accb;
									cc_ctrl <= load_cc;
								when "1101" => -- tst
									right_ctrl <= zero_right;
									alu_ctrl <= alu_st8;
									accb_ctrl <= latch_accb;
									cc_ctrl <= load_cc;
								when "1110" => -- jmp
									right_ctrl <= zero_right;
									alu_ctrl <= alu_nop;
									accb_ctrl <= latch_accb;
									cc_ctrl <= latch_cc;
								when "1111" => -- clr
									right_ctrl <= zero_right;
									alu_ctrl <= alu_clr;
									accb_ctrl <= load_accb;
									cc_ctrl <= load_cc;
								when others => 
									right_ctrl <= zero_right;
									alu_ctrl <= alu_nop;
									accb_ctrl <= latch_accb;
									cc_ctrl <= latch_cc;
						end case;
						next_state <= fetch_state;
						--
						-- Single operand indexed
						-- Two byte instruction so advance PC
						-- EA should hold index offset
						--
						when "0110" => -- indexed single op
							md_ctrl <= fetch_first_md;
							acca_ctrl <= latch_acca;
							accb_ctrl <= latch_accb;
							ix_ctrl <= latch_ix;
							sp_ctrl <= latch_sp;
							-- increment the pc
							left_ctrl <= acca_left;
							right_ctrl <= zero_right;
							alu_ctrl <= alu_nop;
							cc_ctrl <= latch_cc;
							pc_ctrl <= inc_pc;
							next_state <= indexed_state;
							--
							-- Single operand extended addressing
							-- three byte instruction so advance the PC
							-- Low order EA holds high order address
							--
						when "0111" => -- extended single op
							md_ctrl <= fetch_first_md;
							acca_ctrl <= latch_acca;
							accb_ctrl <= latch_accb;
							ix_ctrl <= latch_ix;
							sp_ctrl <= latch_sp;
							-- increment the pc
							left_ctrl <= acca_left;
							right_ctrl <= zero_right;
							alu_ctrl <= alu_nop;
							cc_ctrl <= latch_cc;
							pc_ctrl <= inc_pc;
							next_state <= extended_state;

						when "1000" => -- acca immediate
							md_ctrl <= fetch_first_md;
							acca_ctrl <= latch_acca;
							accb_ctrl <= latch_accb;
							ix_ctrl <= latch_ix;
							sp_ctrl <= latch_sp;
							-- increment the pc
							left_ctrl <= acca_left;
							right_ctrl <= zero_right;
							alu_ctrl <= alu_nop;
							cc_ctrl <= latch_cc;
							pc_ctrl <= inc_pc;
							case op_code(3 downto 0) is
								when "0011" | -- subdd #
									"1100" | -- cpx #
										"1110" => -- lds #
										next_state <= immediate16_state;
								when "1101" => -- bsr
									next_state <= bsr_state;
								when others => 
									next_state <= fetch_state;
						end case;

						when "1001" => -- acca direct
							acca_ctrl <= latch_acca;
							accb_ctrl <= latch_accb;
							ix_ctrl <= latch_ix;
							sp_ctrl <= latch_sp;
							-- increment the pc
							pc_ctrl <= inc_pc;
							case op_code(3 downto 0) is
								when "0111" => -- staa direct
									left_ctrl <= acca_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_st8;
									cc_ctrl <= latch_cc;
									md_ctrl <= load_md;
									next_state <= write8_state;
								when "1111" => -- sts direct
									left_ctrl <= sp_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_st16;
									cc_ctrl <= latch_cc;
									md_ctrl <= load_md;
									next_state <= write16_state;
								when "1101" => -- jsr direct
									left_ctrl <= acca_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_nop;
									cc_ctrl <= latch_cc;
									md_ctrl <= fetch_first_md;
									next_state <= jsr_state;
								when others => 
									left_ctrl <= acca_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_nop;
									cc_ctrl <= latch_cc;
									md_ctrl <= fetch_first_md;
									next_state <= read8_state;
						end case;

						when "1010" => -- acca indexed
							md_ctrl <= fetch_first_md;
							acca_ctrl <= latch_acca;
							accb_ctrl <= latch_accb;
							ix_ctrl <= latch_ix;
							sp_ctrl <= latch_sp;
							-- increment the pc
							left_ctrl <= acca_left;
							right_ctrl <= zero_right;
							alu_ctrl <= alu_nop;
							cc_ctrl <= latch_cc;
							pc_ctrl <= inc_pc;
							next_state <= indexed_state;

						when "1011" => -- acca extended
							md_ctrl <= fetch_first_md;
							acca_ctrl <= latch_acca;
							accb_ctrl <= latch_accb;
							ix_ctrl <= latch_ix;
							sp_ctrl <= latch_sp;
							-- increment the pc
							left_ctrl <= acca_left;
							right_ctrl <= zero_right;
							alu_ctrl <= alu_nop;
							cc_ctrl <= latch_cc;
							pc_ctrl <= inc_pc;
							next_state <= extended_state;

						when "1100" => -- accb immediate
							md_ctrl <= fetch_first_md;
							acca_ctrl <= latch_acca;
							accb_ctrl <= latch_accb;
							ix_ctrl <= latch_ix;
							sp_ctrl <= latch_sp;
							-- increment the pc
							left_ctrl <= acca_left;
							right_ctrl <= zero_right;
							alu_ctrl <= alu_nop;
							cc_ctrl <= latch_cc;
							pc_ctrl <= inc_pc;
							case op_code(3 downto 0) is
								when "0011" | -- addd #
									"1100" | -- ldd #
										"1110" => -- ldx #
										next_state <= immediate16_state;
								when others => 
									next_state <= fetch_state;
						end case;

						when "1101" => -- accb direct
							acca_ctrl <= latch_acca;
							accb_ctrl <= latch_accb;
							ix_ctrl <= latch_ix;
							sp_ctrl <= latch_sp;
							-- increment the pc
							pc_ctrl <= inc_pc;
							case op_code(3 downto 0) is
								when "0111" => -- stab direct
									left_ctrl <= accb_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_st8;
									cc_ctrl <= latch_cc;
									md_ctrl <= load_md;
									next_state <= write8_state;
								when "1101" => -- std direct
									left_ctrl <= accd_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_st16;
									cc_ctrl <= latch_cc;
									md_ctrl <= load_md;
									next_state <= write16_state;
								when "1111" => -- stx direct
									left_ctrl <= ix_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_st16;
									cc_ctrl <= latch_cc;
									md_ctrl <= load_md;
									next_state <= write16_state;
								when others => 
									left_ctrl <= acca_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_nop;
									cc_ctrl <= latch_cc;
									md_ctrl <= fetch_first_md;
									next_state <= read8_state;
						end case;

						when "1110" => -- accb indexed
							md_ctrl <= fetch_first_md;
							acca_ctrl <= latch_acca;
							accb_ctrl <= latch_accb;
							ix_ctrl <= latch_ix;
							sp_ctrl <= latch_sp;
							-- increment the pc
							left_ctrl <= acca_left;
							right_ctrl <= zero_right;
							alu_ctrl <= alu_nop;
							cc_ctrl <= latch_cc;
							pc_ctrl <= inc_pc;
							next_state <= indexed_state;

						when "1111" => -- accb extended
							md_ctrl <= fetch_first_md;
							acca_ctrl <= latch_acca;
							accb_ctrl <= latch_accb;
							ix_ctrl <= latch_ix;
							sp_ctrl <= latch_sp;
							-- increment the pc
							left_ctrl <= acca_left;
							right_ctrl <= zero_right;
							alu_ctrl <= alu_nop;
							cc_ctrl <= latch_cc;
							pc_ctrl <= inc_pc;
							next_state <= extended_state;

						when others => 
							md_ctrl <= fetch_first_md;
							acca_ctrl <= latch_acca;
							accb_ctrl <= latch_accb;
							ix_ctrl <= latch_ix;
							sp_ctrl <= latch_sp;
							-- idle the pc
							left_ctrl <= acca_left;
							right_ctrl <= zero_right;
							alu_ctrl <= alu_nop;
							cc_ctrl <= latch_cc;
							pc_ctrl <= latch_pc;
							next_state <= fetch_state;
				end case;

				when immediate16_state => 
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					sp_ctrl <= latch_sp;
					op_ctrl <= latch_op;
					iv_ctrl <= latch_iv;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- increment pc
					left_ctrl <= acca_left;
					right_ctrl <= zero_right;
					alu_ctrl <= alu_nop;
					cc_ctrl <= latch_cc;
					pc_ctrl <= inc_pc;
					-- fetch next immediate byte
					md_ctrl <= fetch_next_md;
					addr_ctrl <= fetch_ad;
					dout_ctrl <= md_lo_dout;
					next_state <= fetch_state;
					--
					-- ea holds 8 bit index offet
					-- calculate the effective memory address
					-- using the alu
					--
				when indexed_state => 
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					sp_ctrl <= latch_sp;
					pc_ctrl <= latch_pc;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					-- calculate effective address from index reg
					-- index offest is not sign extended
					ea_ctrl <= add_ix_ea;
					-- idle the bus
					addr_ctrl <= idle_ad;
					dout_ctrl <= md_lo_dout;
					-- work out next state
					case op_code(7 downto 4) is
						when "0110" => -- single op indexed
							md_ctrl <= latch_md;
							left_ctrl <= acca_left;
							right_ctrl <= zero_right;
							alu_ctrl <= alu_nop;
							cc_ctrl <= latch_cc;
							case op_code(3 downto 0) is
								when "1011" => -- undefined
									next_state <= fetch_state;
								when "1110" => -- jmp
									next_state <= jmp_state;
								when others => 
									next_state <= read8_state;
						end case;
						when "1010" => -- acca indexed
							case op_code(3 downto 0) is
								when "0111" => -- staa
									left_ctrl <= acca_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_st8;
									cc_ctrl <= latch_cc;
									md_ctrl <= load_md;
									next_state <= write8_state;
								when "1101" => -- jsr
									left_ctrl <= acca_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_nop;
									cc_ctrl <= latch_cc;
									md_ctrl <= latch_md;
									next_state <= jsr_state;
								when "1111" => -- sts
									left_ctrl <= sp_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_st16;
									cc_ctrl <= latch_cc;
									md_ctrl <= load_md;
									next_state <= write16_state;
								when others => 
									left_ctrl <= acca_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_nop;
									cc_ctrl <= latch_cc;
									md_ctrl <= latch_md;
									next_state <= read8_state;
						end case;
						when "1110" => -- accb indexed
							case op_code(3 downto 0) is
								when "0111" => -- stab direct
									left_ctrl <= accb_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_st8;
									cc_ctrl <= latch_cc;
									md_ctrl <= load_md;
									next_state <= write8_state;
								when "1101" => -- std direct
									left_ctrl <= accd_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_st16;
									cc_ctrl <= latch_cc;
									md_ctrl <= load_md;
									next_state <= write16_state;
								when "1111" => -- stx direct
									left_ctrl <= ix_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_st16;
									cc_ctrl <= latch_cc;
									md_ctrl <= load_md;
									next_state <= write16_state;
								when others => 
									left_ctrl <= acca_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_nop;
									cc_ctrl <= latch_cc;
									md_ctrl <= latch_md;
									next_state <= read8_state;
						end case;
						when others => 
							md_ctrl <= latch_md;
							left_ctrl <= acca_left;
							right_ctrl <= zero_right;
							alu_ctrl <= alu_nop;
							cc_ctrl <= latch_cc;
							next_state <= fetch_state;
				end case;
				--
				-- ea holds the low byte of the absolute address
				-- Move ea low byte into ea high byte
				-- load new ea low byte to for absolute 16 bit address
				-- advance the program counter
				--
				when extended_state => -- fetch ea low byte
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					sp_ctrl <= latch_sp;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					-- increment pc
					pc_ctrl <= inc_pc;
					-- fetch next effective address bytes
					ea_ctrl <= fetch_next_ea;
					addr_ctrl <= fetch_ad;
					dout_ctrl <= md_lo_dout;
					-- work out the next state
					case op_code(7 downto 4) is
						when "0111" => -- single op extended
							md_ctrl <= latch_md;
							left_ctrl <= acca_left;
							right_ctrl <= zero_right;
							alu_ctrl <= alu_nop;
							cc_ctrl <= latch_cc;
							case op_code(3 downto 0) is
								when "1011" => -- undefined
									next_state <= fetch_state;
								when "1110" => -- jmp
									next_state <= jmp_state;
								when others => 
									next_state <= read8_state;
						end case;
						when "1011" => -- acca extended
							case op_code(3 downto 0) is
								when "0111" => -- staa
									left_ctrl <= acca_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_st8;
									cc_ctrl <= latch_cc;
									md_ctrl <= load_md;
									next_state <= write8_state;
								when "1101" => -- jsr
									left_ctrl <= acca_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_nop;
									cc_ctrl <= latch_cc;
									md_ctrl <= latch_md;
									next_state <= jsr_state;
								when "1111" => -- sts
									left_ctrl <= sp_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_st16;
									cc_ctrl <= latch_cc;
									md_ctrl <= load_md;
									next_state <= write16_state;
								when others => 
									left_ctrl <= acca_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_nop;
									cc_ctrl <= latch_cc;
									md_ctrl <= latch_md;
									next_state <= read8_state;
						end case;
						when "1111" => -- accb extended
							case op_code(3 downto 0) is
								when "0111" => -- stab
									left_ctrl <= accb_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_st8;
									cc_ctrl <= latch_cc;
									md_ctrl <= load_md;
									next_state <= write8_state;
								when "1101" => -- std
									left_ctrl <= accd_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_st16;
									cc_ctrl <= latch_cc;
									md_ctrl <= load_md;
									next_state <= write16_state;
								when "1111" => -- stx
									left_ctrl <= ix_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_st16;
									cc_ctrl <= latch_cc;
									md_ctrl <= load_md;
									next_state <= write16_state;
								when others => 
									left_ctrl <= acca_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_nop;
									cc_ctrl <= latch_cc;
									md_ctrl <= latch_md;
									next_state <= read8_state;
						end case;
						when others => 
							md_ctrl <= latch_md;
							left_ctrl <= acca_left;
							right_ctrl <= zero_right;
							alu_ctrl <= alu_nop;
							cc_ctrl <= latch_cc;
							next_state <= fetch_state;
				end case;
				--
				-- here if ea holds low byte (direct page)
				-- can enter here from extended addressing
				-- read memory location
				-- note that reads may be 8 or 16 bits
				--
				when read8_state => -- read data
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					sp_ctrl <= latch_sp;
					pc_ctrl <= latch_pc;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					--
					addr_ctrl <= read_ad;
					dout_ctrl <= md_lo_dout;
					case op_code(7 downto 4) is
						when "0110" | "0111" => -- single operand
							left_ctrl <= acca_left;
							right_ctrl <= zero_right;
							alu_ctrl <= alu_nop;
							cc_ctrl <= latch_cc;
							md_ctrl <= fetch_first_md;
							ea_ctrl <= latch_ea;
							next_state <= execute_state;

						when "1001" | "1010" | "1011" => -- acca
							case op_code(3 downto 0) is
								when "0011" | -- subd
									"1110" | -- lds
										"1100" => -- cpx
										left_ctrl <= acca_left;
										right_ctrl <= zero_right;
										alu_ctrl <= alu_nop;
										cc_ctrl <= latch_cc;
										md_ctrl <= fetch_first_md;
										-- increment the effective address in case of 16 bit load
										ea_ctrl <= inc_ea;
										next_state <= read16_state;
										-- when "0111" => -- staa
										-- left_ctrl <= acca_left;
										-- right_ctrl <= zero_right;
										-- alu_ctrl <= alu_st8;
										-- cc_ctrl <= latch_cc;
										-- md_ctrl <= load_md;
										-- ea_ctrl <= latch_ea;
										-- next_state <= write8_state;
										-- when "1101" => -- jsr
										-- left_ctrl <= acca_left;
										-- right_ctrl <= zero_right;
										-- alu_ctrl <= alu_nop;
										-- cc_ctrl <= latch_cc;
										-- md_ctrl <= latch_md;
										-- ea_ctrl <= latch_ea;
										-- next_state <= jsr_state;
										-- when "1111" => -- sts
										-- left_ctrl <= sp_left;
										-- right_ctrl <= zero_right;
										-- alu_ctrl <= alu_st16;
										-- cc_ctrl <= latch_cc;
										-- md_ctrl <= load_md;
										-- ea_ctrl <= latch_ea;
										-- next_state <= write16_state;
								when others => 
									left_ctrl <= acca_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_nop;
									cc_ctrl <= latch_cc;
									md_ctrl <= fetch_first_md;
									ea_ctrl <= latch_ea;
									next_state <= fetch_state;
						end case;

						when "1101" | "1110" | "1111" => -- accb
							case op_code(3 downto 0) is
								when "0011" | -- addd
									"1100" | -- ldd
										"1110" => -- ldx
										left_ctrl <= acca_left;
										right_ctrl <= zero_right;
										alu_ctrl <= alu_nop;
										cc_ctrl <= latch_cc;
										md_ctrl <= fetch_first_md;
										-- increment the effective address in case of 16 bit load
										ea_ctrl <= inc_ea;
										next_state <= read16_state;
										-- when "0111" => -- stab
										-- left_ctrl <= accb_left;
										-- right_ctrl <= zero_right;
										-- alu_ctrl <= alu_st8;
										-- cc_ctrl <= latch_cc;
										-- md_ctrl <= load_md;
										-- ea_ctrl <= latch_ea;
										-- next_state <= write8_state;
										-- when "1101" => -- std
										-- left_ctrl <= accd_left;
										-- right_ctrl <= zero_right;
										-- alu_ctrl <= alu_st16;
										-- cc_ctrl <= latch_cc;
										-- md_ctrl <= load_md;
										-- ea_ctrl <= latch_ea;
										-- next_state <= write16_state;
										-- when "1111" => -- stx
										-- left_ctrl <= ix_left;
										-- right_ctrl <= zero_right;
										-- alu_ctrl <= alu_st16;
										-- cc_ctrl <= latch_cc;
										-- md_ctrl <= load_md;
										-- ea_ctrl <= latch_ea;
										-- next_state <= write16_state;
								when others => 
									left_ctrl <= acca_left;
									right_ctrl <= zero_right;
									alu_ctrl <= alu_nop;
									cc_ctrl <= latch_cc;
									md_ctrl <= fetch_first_md;
									ea_ctrl <= latch_ea;
									next_state <= execute_state;
						end case;
						when others => 
							left_ctrl <= acca_left;
							right_ctrl <= zero_right;
							alu_ctrl <= alu_nop;
							cc_ctrl <= latch_cc;
							md_ctrl <= fetch_first_md;
							ea_ctrl <= latch_ea;
							next_state <= fetch_state;
				end case;

				when read16_state => -- read second data byte from ea
					-- default
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					sp_ctrl <= latch_sp;
					pc_ctrl <= latch_pc;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					left_ctrl <= acca_left;
					right_ctrl <= zero_right;
					alu_ctrl <= alu_nop;
					cc_ctrl <= latch_cc;
					-- idle the effective address
					ea_ctrl <= latch_ea;
					-- read the low byte of the 16 bit data
					md_ctrl <= fetch_next_md;
					addr_ctrl <= read_ad;
					dout_ctrl <= md_lo_dout;
					next_state <= fetch_state;
					--
					-- 16 bit Write state
					-- write high byte of ALU output.
					-- EA hold address of memory to write to
					-- Advance the effective address in ALU
					--
				when write16_state => 
					-- default
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					sp_ctrl <= latch_sp;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					-- increment the effective address
					left_ctrl <= acca_left;
					right_ctrl <= zero_right;
					alu_ctrl <= alu_nop;
					cc_ctrl <= latch_cc;
					ea_ctrl <= inc_ea;
					-- write the ALU hi byte to ea
					addr_ctrl <= write_ad;
					dout_ctrl <= md_hi_dout;
					next_state <= write8_state;
					--
					-- 8 bit write
					-- Write low 8 bits of ALU output
					--
				when write8_state => 
					-- default registers
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					sp_ctrl <= latch_sp;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- idle the ALU
					left_ctrl <= acca_left;
					right_ctrl <= zero_right;
					alu_ctrl <= alu_nop;
					cc_ctrl <= latch_cc;
					-- write ALU low byte output
					addr_ctrl <= write_ad;
					dout_ctrl <= md_lo_dout;
					next_state <= fetch_state;

				when jmp_state => 
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					sp_ctrl <= latch_sp;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- load PC with effective address
					left_ctrl <= acca_left;
					right_ctrl <= zero_right;
					alu_ctrl <= alu_nop;
					cc_ctrl <= latch_cc;
					pc_ctrl <= load_ea_pc;
					-- idle the bus
					addr_ctrl <= idle_ad;
					dout_ctrl <= md_lo_dout;
					next_state <= fetch_state;

				when jsr_state => -- JSR
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					sp_ctrl <= latch_sp;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- decrement sp
					left_ctrl <= sp_left;
					right_ctrl <= plus_one_right;
					alu_ctrl <= alu_sub16;
					cc_ctrl <= latch_cc;
					sp_ctrl <= load_sp;
					-- write pc low
					addr_ctrl <= push_ad;
					dout_ctrl <= pc_lo_dout;
					next_state <= jsr1_state;

				when jsr1_state => -- JSR
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- decrement sp
					left_ctrl <= sp_left;
					right_ctrl <= plus_one_right;
					alu_ctrl <= alu_sub16;
					cc_ctrl <= latch_cc;
					sp_ctrl <= load_sp;
					-- write pc hi
					addr_ctrl <= push_ad;
					dout_ctrl <= pc_hi_dout;
					next_state <= jmp_state;

				when branch_state => -- Bcc
					-- default registers
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					sp_ctrl <= latch_sp;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- calculate signed branch
					left_ctrl <= acca_left;
					right_ctrl <= zero_right;
					alu_ctrl <= alu_nop;
					cc_ctrl <= latch_cc;
					pc_ctrl <= add_ea_pc;
					-- idle the bus
					addr_ctrl <= idle_ad;
					dout_ctrl <= md_lo_dout;
					next_state <= stall1_state;

				when bsr_state => -- BSR
					-- default
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- decrement sp
					left_ctrl <= sp_left;
					right_ctrl <= plus_one_right;
					alu_ctrl <= alu_sub16;
					cc_ctrl <= latch_cc;
					sp_ctrl <= load_sp;
					-- write pc low
					addr_ctrl <= push_ad;
					dout_ctrl <= pc_lo_dout;
					next_state <= bsr1_state;

				when bsr1_state => -- BSR
					-- default registers
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- decrement sp
					left_ctrl <= sp_left;
					right_ctrl <= plus_one_right;
					alu_ctrl <= alu_sub16;
					cc_ctrl <= latch_cc;
					sp_ctrl <= load_sp;
					-- write pc hi
					addr_ctrl <= push_ad;
					dout_ctrl <= pc_hi_dout;
					next_state <= branch_state;

				when rts_hi_state => -- RTS
					-- default
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- increment the sp
					left_ctrl <= sp_left;
					right_ctrl <= plus_one_right;
					alu_ctrl <= alu_add16;
					cc_ctrl <= latch_cc;
					sp_ctrl <= load_sp;
					-- read pc hi
					pc_ctrl <= pull_hi_pc;
					addr_ctrl <= pull_ad;
					dout_ctrl <= pc_hi_dout;
					next_state <= rts_lo_state;

				when rts_lo_state => -- RTS1
					-- default
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					sp_ctrl <= latch_sp;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- idle the ALU
					left_ctrl <= acca_left;
					right_ctrl <= zero_right;
					alu_ctrl <= alu_nop;
					cc_ctrl <= latch_cc;
					-- read pc low
					pc_ctrl <= pull_lo_pc;
					addr_ctrl <= pull_ad;
					dout_ctrl <= pc_lo_dout;
					next_state <= fetch_state;

				when mul_state => 
					-- default
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					sp_ctrl <= latch_sp;
					pc_ctrl <= latch_pc;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- move acca to md
					left_ctrl <= acca_left;
					right_ctrl <= zero_right;
					alu_ctrl <= alu_st16;
					cc_ctrl <= latch_cc;
					md_ctrl <= load_md;
					-- idle bus
					addr_ctrl <= idle_ad;
					dout_ctrl <= md_lo_dout;
					next_state <= mulea_state;

				when mulea_state => 
					-- default
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					sp_ctrl <= latch_sp;
					pc_ctrl <= latch_pc;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					md_ctrl <= latch_md;
					-- idle ALU
					left_ctrl <= acca_left;
					right_ctrl <= zero_right;
					alu_ctrl <= alu_nop;
					cc_ctrl <= latch_cc;
					-- move accb to ea
					ea_ctrl <= load_accb_ea;
					-- idle bus
					addr_ctrl <= idle_ad;
					dout_ctrl <= md_lo_dout;
					next_state <= muld_state;

				when muld_state => 
					-- default
					ix_ctrl <= latch_ix;
					sp_ctrl <= latch_sp;
					pc_ctrl <= latch_pc;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					md_ctrl <= latch_md;
					-- clear accd
					left_ctrl <= acca_left;
					right_ctrl <= zero_right;
					alu_ctrl <= alu_ld8;
					cc_ctrl <= latch_cc;
					acca_ctrl <= load_hi_acca;
					accb_ctrl <= load_accb;
					-- idle bus
					addr_ctrl <= idle_ad;
					dout_ctrl <= md_lo_dout;
					next_state <= mul0_state;

				when mul0_state => 
					-- default
					ix_ctrl <= latch_ix;
					sp_ctrl <= latch_sp;
					pc_ctrl <= latch_pc;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- if bit 0 of ea set, add accd to md
					left_ctrl <= accd_left;
					right_ctrl <= md_right;
					alu_ctrl <= alu_add16;
					if ea(0) = '1' then
						cc_ctrl <= load_cc;
						acca_ctrl <= load_hi_acca;
						accb_ctrl <= load_accb;
					else
						cc_ctrl <= latch_cc;
						acca_ctrl <= latch_acca;
						accb_ctrl <= latch_accb;
					end if;
					md_ctrl <= shiftl_md;
					-- idle bus
					addr_ctrl <= idle_ad;
					dout_ctrl <= md_lo_dout;
					next_state <= mul1_state;

				when mul1_state => 
					-- default
					ix_ctrl <= latch_ix;
					sp_ctrl <= latch_sp;
					pc_ctrl <= latch_pc;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- if bit 1 of ea set, add accd to md
					left_ctrl <= accd_left;
					right_ctrl <= md_right;
					alu_ctrl <= alu_add16;
					if ea(1) = '1' then
						cc_ctrl <= load_cc;
						acca_ctrl <= load_hi_acca;
						accb_ctrl <= load_accb;
					else
						cc_ctrl <= latch_cc;
						acca_ctrl <= latch_acca;
						accb_ctrl <= latch_accb;
					end if;
					md_ctrl <= shiftl_md;
					-- idle bus
					addr_ctrl <= idle_ad;
					dout_ctrl <= md_lo_dout;
					next_state <= mul2_state;

				when mul2_state => 
					-- default
					ix_ctrl <= latch_ix;
					sp_ctrl <= latch_sp;
					pc_ctrl <= latch_pc;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- if bit 2 of ea set, add accd to md
					left_ctrl <= accd_left;
					right_ctrl <= md_right;
					alu_ctrl <= alu_add16;
					if ea(2) = '1' then
						cc_ctrl <= load_cc;
						acca_ctrl <= load_hi_acca;
						accb_ctrl <= load_accb;
					else
						cc_ctrl <= latch_cc;
						acca_ctrl <= latch_acca;
						accb_ctrl <= latch_accb;
					end if;
					md_ctrl <= shiftl_md;
					-- idle bus
					addr_ctrl <= idle_ad;
					dout_ctrl <= md_lo_dout;
					next_state <= mul3_state;

				when mul3_state => 
					-- default
					ix_ctrl <= latch_ix;
					sp_ctrl <= latch_sp;
					pc_ctrl <= latch_pc;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- if bit 3 of ea set, add accd to md
					left_ctrl <= accd_left;
					right_ctrl <= md_right;
					alu_ctrl <= alu_add16;
					if ea(3) = '1' then
						cc_ctrl <= load_cc;
						acca_ctrl <= load_hi_acca;
						accb_ctrl <= load_accb;
					else
						cc_ctrl <= latch_cc;
						acca_ctrl <= latch_acca;
						accb_ctrl <= latch_accb;
					end if;
					md_ctrl <= shiftl_md;
					-- idle bus
					addr_ctrl <= idle_ad;
					dout_ctrl <= md_lo_dout;
					next_state <= mul4_state;

				when mul4_state => 
					-- default
					ix_ctrl <= latch_ix;
					sp_ctrl <= latch_sp;
					pc_ctrl <= latch_pc;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- if bit 4 of ea set, add accd to md
					left_ctrl <= accd_left;
					right_ctrl <= md_right;
					alu_ctrl <= alu_add16;
					if ea(4) = '1' then
						cc_ctrl <= load_cc;
						acca_ctrl <= load_hi_acca;
						accb_ctrl <= load_accb;
					else
						cc_ctrl <= latch_cc;
						acca_ctrl <= latch_acca;
						accb_ctrl <= latch_accb;
					end if;
					md_ctrl <= shiftl_md;
					-- idle bus
					addr_ctrl <= idle_ad;
					dout_ctrl <= md_lo_dout;
					next_state <= mul5_state;

				when mul5_state => 
					-- default
					ix_ctrl <= latch_ix;
					sp_ctrl <= latch_sp;
					pc_ctrl <= latch_pc;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- if bit 5 of ea set, add accd to md
					left_ctrl <= accd_left;
					right_ctrl <= md_right;
					alu_ctrl <= alu_add16;
					if ea(5) = '1' then
						cc_ctrl <= load_cc;
						acca_ctrl <= load_hi_acca;
						accb_ctrl <= load_accb;
					else
						cc_ctrl <= latch_cc;
						acca_ctrl <= latch_acca;
						accb_ctrl <= latch_accb;
					end if;
					md_ctrl <= shiftl_md;
					-- idle bus
					addr_ctrl <= idle_ad;
					dout_ctrl <= md_lo_dout;
					next_state <= mul6_state;

				when mul6_state => 
					-- default
					ix_ctrl <= latch_ix;
					sp_ctrl <= latch_sp;
					pc_ctrl <= latch_pc;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- if bit 6 of ea set, add accd to md
					left_ctrl <= accd_left;
					right_ctrl <= md_right;
					alu_ctrl <= alu_add16;
					if ea(6) = '1' then
						cc_ctrl <= load_cc;
						acca_ctrl <= load_hi_acca;
						accb_ctrl <= load_accb;
					else
						cc_ctrl <= latch_cc;
						acca_ctrl <= latch_acca;
						accb_ctrl <= latch_accb;
					end if;
					md_ctrl <= shiftl_md;
					-- idle bus
					addr_ctrl <= idle_ad;
					dout_ctrl <= md_lo_dout;
					next_state <= mul7_state;

				when mul7_state => 
					-- default
					ix_ctrl <= latch_ix;
					sp_ctrl <= latch_sp;
					pc_ctrl <= latch_pc;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- if bit 7 of ea set, add accd to md
					left_ctrl <= accd_left;
					right_ctrl <= md_right;
					alu_ctrl <= alu_add16;
					if ea(7) = '1' then
						cc_ctrl <= load_cc;
						acca_ctrl <= load_hi_acca;
						accb_ctrl <= load_accb;
					else
						cc_ctrl <= latch_cc;
						acca_ctrl <= latch_acca;
						accb_ctrl <= latch_accb;
					end if;
					md_ctrl <= shiftl_md;
					-- idle bus
					addr_ctrl <= idle_ad;
					dout_ctrl <= md_lo_dout;
					next_state <= fetch_state;

				when execute_state => -- execute single operand instruction
					-- default
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					case op_code(7 downto 4) is
						when "0110" | -- indexed single op
							"0111" => -- extended single op
							acca_ctrl <= latch_acca;
							accb_ctrl <= latch_accb;
							ix_ctrl <= latch_ix;
							sp_ctrl <= latch_sp;
							pc_ctrl <= latch_pc;
							iv_ctrl <= latch_iv;
							ea_ctrl <= latch_ea;
							-- idle the bus
							addr_ctrl <= idle_ad;
							dout_ctrl <= md_lo_dout;
							left_ctrl <= md_left;
							case op_code(3 downto 0) is
								when "0000" => -- neg
									right_ctrl <= zero_right;
									alu_ctrl <= alu_neg;
									cc_ctrl <= load_cc;
									md_ctrl <= load_md;
									next_state <= write8_state;
								when "0011" => -- com
									right_ctrl <= zero_right;
									alu_ctrl <= alu_com;
									cc_ctrl <= load_cc;
									md_ctrl <= load_md;
									next_state <= write8_state;
								when "0100" => -- lsr
									right_ctrl <= zero_right;
									alu_ctrl <= alu_lsr8;
									cc_ctrl <= load_cc;
									md_ctrl <= load_md;
									next_state <= write8_state;
								when "0110" => -- ror
									right_ctrl <= zero_right;
									alu_ctrl <= alu_ror8;
									cc_ctrl <= load_cc;
									md_ctrl <= load_md;
									next_state <= write8_state;
								when "0111" => -- asr
									right_ctrl <= zero_right;
									alu_ctrl <= alu_asr8;
									cc_ctrl <= load_cc;
									md_ctrl <= load_md;
									next_state <= write8_state;
								when "1000" => -- asl
									right_ctrl <= zero_right;
									alu_ctrl <= alu_asl8;
									cc_ctrl <= load_cc;
									md_ctrl <= load_md;
									next_state <= write8_state;
								when "1001" => -- rol
									right_ctrl <= zero_right;
									alu_ctrl <= alu_rol8;
									cc_ctrl <= load_cc;
									md_ctrl <= load_md;
									next_state <= write8_state;
								when "1010" => -- dec
									right_ctrl <= plus_one_right;
									alu_ctrl <= alu_dec;
									cc_ctrl <= load_cc;
									md_ctrl <= load_md;
									next_state <= write8_state;
								when "1011" => -- undefined
									right_ctrl <= zero_right;
									alu_ctrl <= alu_nop;
									cc_ctrl <= latch_cc;
									md_ctrl <= latch_md;
									next_state <= fetch_state;
								when "1100" => -- inc
									right_ctrl <= plus_one_right;
									alu_ctrl <= alu_inc;
									cc_ctrl <= load_cc;
									md_ctrl <= load_md;
									next_state <= write8_state;
								when "1101" => -- tst
									right_ctrl <= zero_right;
									alu_ctrl <= alu_st8;
									cc_ctrl <= load_cc;
									md_ctrl <= latch_md;
									next_state <= fetch_state;
								when "1110" => -- jmp
									right_ctrl <= zero_right;
									alu_ctrl <= alu_nop;
									cc_ctrl <= latch_cc;
									md_ctrl <= latch_md;
									next_state <= fetch_state;
								when "1111" => -- clr
									right_ctrl <= zero_right;
									alu_ctrl <= alu_clr;
									cc_ctrl <= load_cc;
									md_ctrl <= load_md;
									next_state <= write8_state;
								when others => 
									right_ctrl <= zero_right;
									alu_ctrl <= alu_nop;
									cc_ctrl <= latch_cc;
									md_ctrl <= latch_md;
									next_state <= fetch_state;
						end case;

						when others => 
							left_ctrl <= accd_left;
							right_ctrl <= md_right;
							alu_ctrl <= alu_nop;
							cc_ctrl <= latch_cc;
							acca_ctrl <= latch_acca;
							accb_ctrl <= latch_accb;
							ix_ctrl <= latch_ix;
							sp_ctrl <= latch_sp;
							pc_ctrl <= latch_pc;
							md_ctrl <= latch_md;
							iv_ctrl <= latch_iv;
							ea_ctrl <= latch_ea;
							-- idle the bus
							addr_ctrl <= idle_ad;
							dout_ctrl <= md_lo_dout;
							next_state <= fetch_state;
				end case;

				when psha_state => 
					-- default registers
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- decrement sp
					left_ctrl <= sp_left;
					right_ctrl <= plus_one_right;
					alu_ctrl <= alu_sub16;
					cc_ctrl <= latch_cc;
					sp_ctrl <= load_sp;
					-- write acca
					addr_ctrl <= push_ad;
					dout_ctrl <= acca_dout;
					next_state <= fetch_state;

				when pula_state => 
					-- default registers
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- idle sp
					left_ctrl <= sp_left;
					right_ctrl <= zero_right;
					alu_ctrl <= alu_nop;
					cc_ctrl <= latch_cc;
					sp_ctrl <= latch_sp;
					-- read acca
					acca_ctrl <= pull_acca;
					addr_ctrl <= pull_ad;
					dout_ctrl <= acca_dout;
					next_state <= fetch_state;

				when pshb_state => 
					-- default registers
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- decrement sp
					left_ctrl <= sp_left;
					right_ctrl <= plus_one_right;
					alu_ctrl <= alu_sub16;
					cc_ctrl <= latch_cc;
					sp_ctrl <= load_sp;
					-- write accb
					addr_ctrl <= push_ad;
					dout_ctrl <= accb_dout;
					next_state <= fetch_state;

				when pulb_state => 
					-- default
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- idle sp
					left_ctrl <= sp_left;
					right_ctrl <= zero_right;
					alu_ctrl <= alu_nop;
					cc_ctrl <= latch_cc;
					sp_ctrl <= latch_sp;
					-- read accb
					accb_ctrl <= pull_accb;
					addr_ctrl <= pull_ad;
					dout_ctrl <= accb_dout;
					next_state <= fetch_state;

				when pshx_lo_state => 
					-- default
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					sp_ctrl <= latch_sp;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- decrement sp
					left_ctrl <= sp_left;
					right_ctrl <= plus_one_right;
					alu_ctrl <= alu_sub16;
					cc_ctrl <= latch_cc;
					sp_ctrl <= load_sp;
					-- write ix low
					addr_ctrl <= push_ad;
					dout_ctrl <= ix_lo_dout;
					next_state <= pshx_hi_state;

				when pshx_hi_state => 
					-- default registers
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- decrement sp
					left_ctrl <= sp_left;
					right_ctrl <= plus_one_right;
					alu_ctrl <= alu_sub16;
					cc_ctrl <= latch_cc;
					sp_ctrl <= load_sp;
					-- write ix hi
					addr_ctrl <= push_ad;
					dout_ctrl <= ix_hi_dout;
					next_state <= fetch_state;

				when pulx_hi_state => 
					-- default
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- increment sp
					left_ctrl <= sp_left;
					right_ctrl <= plus_one_right;
					alu_ctrl <= alu_add16;
					cc_ctrl <= latch_cc;
					sp_ctrl <= load_sp;
					-- pull ix hi
					ix_ctrl <= pull_hi_ix;
					addr_ctrl <= pull_ad;
					dout_ctrl <= ix_hi_dout;
					next_state <= pulx_lo_state;

				when pulx_lo_state => 
					-- default
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- idle sp
					left_ctrl <= sp_left;
					right_ctrl <= zero_right;
					alu_ctrl <= alu_nop;
					cc_ctrl <= latch_cc;
					sp_ctrl <= latch_sp;
					-- read ix low
					ix_ctrl <= pull_lo_ix;
					addr_ctrl <= pull_ad;
					dout_ctrl <= ix_lo_dout;
					next_state <= fetch_state;

					--
					-- return from interrupt
					-- enter here from bogus interrupts
					--
				when rti_state => 
					-- default registers
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- increment sp
					left_ctrl <= sp_left;
					right_ctrl <= plus_one_right;
					alu_ctrl <= alu_add16;
					sp_ctrl <= load_sp;
					-- idle address bus
					cc_ctrl <= latch_cc;
					addr_ctrl <= idle_ad;
					dout_ctrl <= cc_dout;
					next_state <= rti_cc_state;

				when rti_cc_state => 
					-- default registers
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- increment sp
					left_ctrl <= sp_left;
					right_ctrl <= plus_one_right;
					alu_ctrl <= alu_add16;
					sp_ctrl <= load_sp;
					-- read cc
					cc_ctrl <= pull_cc;
					addr_ctrl <= pull_ad;
					dout_ctrl <= cc_dout;
					next_state <= rti_accb_state;

				when rti_accb_state => 
					-- default registers
					acca_ctrl <= latch_acca;
					ix_ctrl <= latch_ix;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- increment sp
					left_ctrl <= sp_left;
					right_ctrl <= plus_one_right;
					alu_ctrl <= alu_add16;
					cc_ctrl <= latch_cc;
					sp_ctrl <= load_sp;
					-- read accb
					accb_ctrl <= pull_accb;
					addr_ctrl <= pull_ad;
					dout_ctrl <= accb_dout;
					next_state <= rti_acca_state;

				when rti_acca_state => 
					-- default registers
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- increment sp
					left_ctrl <= sp_left;
					right_ctrl <= plus_one_right;
					alu_ctrl <= alu_add16;
					cc_ctrl <= latch_cc;
					sp_ctrl <= load_sp;
					-- read acca
					acca_ctrl <= pull_acca;
					addr_ctrl <= pull_ad;
					dout_ctrl <= acca_dout;
					next_state <= rti_ixh_state;

				when rti_ixh_state => 
					-- default
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- increment sp
					left_ctrl <= sp_left;
					right_ctrl <= plus_one_right;
					alu_ctrl <= alu_add16;
					cc_ctrl <= latch_cc;
					sp_ctrl <= load_sp;
					-- read ix hi
					ix_ctrl <= pull_hi_ix;
					addr_ctrl <= pull_ad;
					dout_ctrl <= ix_hi_dout;
					next_state <= rti_ixl_state;

				when rti_ixl_state => 
					-- default
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- increment sp
					left_ctrl <= sp_left;
					right_ctrl <= plus_one_right;
					alu_ctrl <= alu_add16;
					cc_ctrl <= latch_cc;
					sp_ctrl <= load_sp;
					-- read ix low
					ix_ctrl <= pull_lo_ix;
					addr_ctrl <= pull_ad;
					dout_ctrl <= ix_lo_dout;
					next_state <= rti_pch_state;

				when rti_pch_state => 
					-- default
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- increment sp
					left_ctrl <= sp_left;
					right_ctrl <= plus_one_right;
					alu_ctrl <= alu_add16;
					cc_ctrl <= latch_cc;
					sp_ctrl <= load_sp;
					-- pull pc hi
					pc_ctrl <= pull_hi_pc;
					addr_ctrl <= pull_ad;
					dout_ctrl <= pc_hi_dout;
					next_state <= rti_pcl_state;

				when rti_pcl_state => 
					-- default
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- idle sp
					left_ctrl <= sp_left;
					right_ctrl <= zero_right;
					alu_ctrl <= alu_nop;
					cc_ctrl <= latch_cc;
					sp_ctrl <= latch_sp;
					-- pull pc low
					pc_ctrl <= pull_lo_pc;
					addr_ctrl <= pull_ad;
					dout_ctrl <= pc_lo_dout;
					next_state <= fetch_state;

					--
					-- here on interrupt
					-- iv register hold interrupt type
					--
				when int_pcl_state => 
					-- default
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- decrement sp
					left_ctrl <= sp_left;
					right_ctrl <= plus_one_right;
					alu_ctrl <= alu_sub16;
					cc_ctrl <= latch_cc;
					sp_ctrl <= load_sp;
					-- write pc low
					addr_ctrl <= push_ad;
					dout_ctrl <= pc_lo_dout;
					next_state <= int_pch_state;

				when int_pch_state => 
					-- default
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- decrement sp
					left_ctrl <= sp_left;
					right_ctrl <= plus_one_right;
					alu_ctrl <= alu_sub16;
					cc_ctrl <= latch_cc;
					sp_ctrl <= load_sp;
					-- write pc hi
					addr_ctrl <= push_ad;
					dout_ctrl <= pc_hi_dout;
					next_state <= int_ixl_state;

				when int_ixl_state => 
					-- default
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- decrement sp
					left_ctrl <= sp_left;
					right_ctrl <= plus_one_right;
					alu_ctrl <= alu_sub16;
					cc_ctrl <= latch_cc;
					sp_ctrl <= load_sp;
					-- write ix low
					addr_ctrl <= push_ad;
					dout_ctrl <= ix_lo_dout;
					next_state <= int_ixh_state;

				when int_ixh_state => 
					-- default
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- decrement sp
					left_ctrl <= sp_left;
					right_ctrl <= plus_one_right;
					alu_ctrl <= alu_sub16;
					cc_ctrl <= latch_cc;
					sp_ctrl <= load_sp;
					-- write ix hi
					addr_ctrl <= push_ad;
					dout_ctrl <= ix_hi_dout;
					next_state <= int_acca_state;

				when int_acca_state => 
					-- default
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- decrement sp
					left_ctrl <= sp_left;
					right_ctrl <= plus_one_right;
					alu_ctrl <= alu_sub16;
					cc_ctrl <= latch_cc;
					sp_ctrl <= load_sp;
					-- write acca
					addr_ctrl <= push_ad;
					dout_ctrl <= acca_dout;
					next_state <= int_accb_state;
				when int_accb_state => 
					-- default
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- decrement sp
					left_ctrl <= sp_left;
					right_ctrl <= plus_one_right;
					alu_ctrl <= alu_sub16;
					cc_ctrl <= latch_cc;
					sp_ctrl <= load_sp;
					-- write accb
					addr_ctrl <= push_ad;
					dout_ctrl <= accb_dout;
					next_state <= int_cc_state;

				when int_cc_state => 
					-- default
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- decrement sp
					left_ctrl <= sp_left;
					right_ctrl <= plus_one_right;
					alu_ctrl <= alu_sub16;
					cc_ctrl <= latch_cc;
					sp_ctrl <= load_sp;
					-- write cc
					addr_ctrl <= push_ad;
					dout_ctrl <= cc_dout;
					nmi_ctrl <= latch_nmi;
					--
					-- nmi is edge triggered
					-- nmi_req is cleared when nmi goes low.
					--
					if nmi_req = '1' then
						iv_ctrl <= nmi_iv;
						next_state <= int_mask_state;
					else
						--
						-- IRQ is level sensitive
						--
						if (irq = '1') and (cc(IBIT) = '0') then
							iv_ctrl <= irq_iv;
							next_state <= int_mask_state;
						else
							case op_code is
								when "00111110" => -- WAI (wait for interrupt)
									iv_ctrl <= latch_iv;
									next_state <= int_wai_state;
								when "00111111" => -- SWI (Software interrupt)
									iv_ctrl <= swi_iv;
									next_state <= vect_hi_state;
								when others => -- bogus interrupt (return)
									iv_ctrl <= latch_iv;
									next_state <= rti_state;
							end case;
						end if;
					end if;

				when int_wai_state => 
					-- default
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					op_ctrl <= latch_op;
					ea_ctrl <= latch_ea;
					-- enable interrupts
					left_ctrl <= sp_left;
					right_ctrl <= plus_one_right;
					alu_ctrl <= alu_cli;
					cc_ctrl <= load_cc;
					sp_ctrl <= latch_sp;
					-- idle bus
					addr_ctrl <= idle_ad;
					dout_ctrl <= cc_dout;
					if (nmi_req = '1') and (nmi_ack = '0') then
						iv_ctrl <= nmi_iv;
						nmi_ctrl <= set_nmi;
						next_state <= vect_hi_state;
					else
						--
						-- nmi request is not cleared until nmi input goes low
						--
						if (nmi_req = '0') and (nmi_ack = '1') then
							nmi_ctrl <= reset_nmi;
						else
							nmi_ctrl <= latch_nmi;
						end if;
						--
						-- IRQ is level sensitive
						--
						if (irq = '1') and (cc(IBIT) = '0') then
							iv_ctrl <= irq_iv;
							next_state <= int_mask_state;
						else
							iv_ctrl <= latch_iv;
							next_state <= int_wai_state;
						end if;
					end if;

				when int_mask_state => 
					-- default
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- Mask IRQ
					left_ctrl <= sp_left;
					right_ctrl <= zero_right;
					alu_ctrl <= alu_sei;
					cc_ctrl <= load_cc;
					sp_ctrl <= latch_sp;
					-- idle bus cycle
					addr_ctrl <= idle_ad;
					dout_ctrl <= md_lo_dout;
					next_state <= vect_hi_state;

				when halt_state => -- halt CPU.
					-- default
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					sp_ctrl <= latch_sp;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- do nothing in ALU
					left_ctrl <= acca_left;
					right_ctrl <= zero_right;
					alu_ctrl <= alu_nop;
					cc_ctrl <= latch_cc;
					-- idle bus cycle
					addr_ctrl <= idle_ad;
					dout_ctrl <= md_lo_dout;
					if halt = '1' then
						next_state <= halt_state;
					else
						next_state <= fetch_state;
					end if;

				when stall2_state => -- Do nothing for two cycles
					-- default
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					sp_ctrl <= latch_sp;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- do nothing in ALU
					left_ctrl <= acca_left;
					right_ctrl <= zero_right;
					alu_ctrl <= alu_nop;
					cc_ctrl <= latch_cc;
					-- idle bus cycle
					addr_ctrl <= idle_ad;
					dout_ctrl <= md_lo_dout;
					next_state <= stall1_state;

				when stall1_state => -- Do nothing for one cycle
					-- default
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					sp_ctrl <= latch_sp;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- do nothing in ALU
					left_ctrl <= acca_left;
					right_ctrl <= zero_right;
					alu_ctrl <= alu_nop;
					cc_ctrl <= latch_cc;
					-- idle bus cycle
					addr_ctrl <= idle_ad;
					dout_ctrl <= md_lo_dout;
					next_state <= fetch_state;

				when others => -- error state halt on undefine states
					-- default
					acca_ctrl <= latch_acca;
					accb_ctrl <= latch_accb;
					ix_ctrl <= latch_ix;
					sp_ctrl <= latch_sp;
					pc_ctrl <= latch_pc;
					md_ctrl <= latch_md;
					iv_ctrl <= latch_iv;
					op_ctrl <= latch_op;
					nmi_ctrl <= latch_nmi;
					ea_ctrl <= latch_ea;
					-- do nothing in ALU
					left_ctrl <= acca_left;
					right_ctrl <= zero_right;
					alu_ctrl <= alu_nop;
					cc_ctrl <= latch_cc;
					-- idle bus cycle
					addr_ctrl <= idle_ad;
					dout_ctrl <= md_lo_dout;
					next_state <= error_state;
			end case;
		end process;

		--------------------------------
		--
		-- state machine
		--
		--------------------------------

		change_state : process (clk, rst, state, hold)
		begin
			if clk'event and clk = '0' then
				if rst = '1' then
					state <= reset_state;
				elsif hold = '1' then
					state <= state;
				else
					state <= next_state;
				end if;
			end if;
		end process;
		-- output
 
end CPU_ARCH;
