diff --git a/Arcade_MiST/IremM52 Hardware/TraverseUSA_MiST/TraverseUSA_MiST.qsf b/Arcade_MiST/IremM52 Hardware/TraverseUSA_MiST/TraverseUSA_MiST.qsf
index 66fc4b2b..c3fc9843 100644
--- a/Arcade_MiST/IremM52 Hardware/TraverseUSA_MiST/TraverseUSA_MiST.qsf
+++ b/Arcade_MiST/IremM52 Hardware/TraverseUSA_MiST/TraverseUSA_MiST.qsf
@@ -149,6 +149,7 @@ set_global_assignment -name GENERATE_RBF_FILE ON
set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "USE AS REGULAR IO"
set_global_assignment -name RESERVE_DATA0_AFTER_CONFIGURATION "USE AS REGULAR IO"
set_global_assignment -name RESERVE_DCLK_AFTER_CONFIGURATION "USE AS REGULAR IO"
+set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
set_global_assignment -name QIP_FILE rtl/pll_mist.qip
set_global_assignment -name SYSTEMVERILOG_FILE rtl/YM2149.sv
set_global_assignment -name VERILOG_FILE rtl/data_io.v
@@ -175,7 +176,5 @@ set_global_assignment -name VHDL_FILE rtl/moon_patrol_sound_board.vhd
set_global_assignment -name VHDL_FILE rtl/gen_ram.vhd
set_global_assignment -name VHDL_FILE rtl/dac.vhd
set_global_assignment -name VHDL_FILE rtl/cpu68.vhd
-set_global_assignment -name VHDL_FILE rtl/cpu09l_128.vhd
set_global_assignment -name VERILOG_FILE rtl/build_id.v
-set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip
-set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
\ No newline at end of file
+set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip
\ No newline at end of file
diff --git a/Arcade_MiST/IremM52 Hardware/TraverseUSA_MiST/rtl/YM2149_linmix_sep.vhd b/Arcade_MiST/IremM52 Hardware/TraverseUSA_MiST/rtl/YM2149_linmix_sep.vhd
deleted file mode 100644
index 6ed2498a..00000000
--- a/Arcade_MiST/IremM52 Hardware/TraverseUSA_MiST/rtl/YM2149_linmix_sep.vhd
+++ /dev/null
@@ -1,574 +0,0 @@
--- changes for seperate audio outputs and enable now enables cpu access as well
---
--- A simulation model of YM2149 (AY-3-8910 with bells on)
-
--- Copyright (c) MikeJ - Jan 2005
---
--- All rights reserved
---
--- Redistribution and use in source and synthezised forms, with or without
--- modification, are permitted provided that the following conditions are met:
---
--- Redistributions of source code must retain the above copyright notice,
--- this list of conditions and the following disclaimer.
---
--- Redistributions in synthesized form must reproduce the above copyright
--- notice, this list of conditions and the following disclaimer in the
--- documentation and/or other materials provided with the distribution.
---
--- Neither the name of the author nor the names of other contributors may
--- be used to endorse or promote products derived from this software without
--- specific prior written permission.
---
--- THIS CODE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
--- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
--- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
--- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
--- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
--- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
--- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
--- POSSIBILITY OF SUCH DAMAGE.
---
--- You are responsible for any legal issues arising from your use of this code.
---
--- The latest version of this file can be found at: www.fpgaarcade.com
---
--- Email support@fpgaarcade.com
---
--- Revision list
---
--- version 001 initial release
---
--- Clues from MAME sound driver and Kazuhiro TSUJIKAWA
---
--- These are the measured outputs from a real chip for a single Isolated channel into a 1K load (V)
--- vol 15 .. 0
--- 3.27 2.995 2.741 2.588 2.452 2.372 2.301 2.258 2.220 2.198 2.178 2.166 2.155 2.148 2.141 2.132
--- As the envelope volume is 5 bit, I have fitted a curve to the not quite log shape in order
--- to produced all the required values.
--- (The first part of the curve is a bit steeper and the last bit is more linear than expected)
---
--- NOTE, this component uses LINEAR mixing of the three analogue channels, and is only
--- accurate for designs where the outputs are buffered and not simply wired together.
--- The ouput level is more complex in that case and requires a larger table.
-
-library ieee;
- use ieee.std_logic_1164.all;
- use ieee.std_logic_arith.all;
- use ieee.std_logic_unsigned.all;
-
-entity YM2149 is
- port (
- -- data bus
- I_DA : in std_logic_vector(7 downto 0);
- O_DA : out std_logic_vector(7 downto 0);
- O_DA_OE_L : out std_logic;
- -- control
- I_A9_L : in std_logic;
- I_A8 : in std_logic;
- I_BDIR : in std_logic;
- I_BC2 : in std_logic;
- I_BC1 : in std_logic;
- I_SEL_L : in std_logic;
-
- O_AUDIO : out std_logic_vector(7 downto 0);
- O_CHAN : out std_logic_vector(1 downto 0);
- -- port a
- I_IOA : in std_logic_vector(7 downto 0);
- O_IOA : out std_logic_vector(7 downto 0);
- O_IOA_OE_L : out std_logic;
- -- port b
- I_IOB : in std_logic_vector(7 downto 0);
- O_IOB : out std_logic_vector(7 downto 0);
- O_IOB_OE_L : out std_logic;
-
- ENA : in std_logic; -- clock enable for higher speed operation
- RESET_L : in std_logic;
- CLK : in std_logic -- note 6 Mhz
- );
-end;
-
-architecture RTL of YM2149 is
- type array_16x8 is array (0 to 15) of std_logic_vector( 7 downto 0);
- type array_3x12 is array (1 to 3) of std_logic_vector(11 downto 0);
-
- signal cnt_div : std_logic_vector(3 downto 0) := (others => '0');
- signal cnt_div_t1 : std_logic_vector(3 downto 0);
- signal noise_div : std_logic := '0';
- signal ena_div : std_logic;
- signal ena_div_noise : std_logic;
- signal poly17 : std_logic_vector(16 downto 0) := (others => '0');
-
- -- registers
- signal addr : std_logic_vector(7 downto 0);
- signal busctrl_addr : std_logic;
- signal busctrl_we : std_logic;
- signal busctrl_re : std_logic;
-
- signal reg : array_16x8;
- signal env_reset : std_logic;
- signal ioa_inreg : std_logic_vector(7 downto 0);
- signal iob_inreg : std_logic_vector(7 downto 0);
-
- signal noise_gen_cnt : std_logic_vector(4 downto 0);
- signal noise_gen_op : std_logic;
- signal tone_gen_cnt : array_3x12 := (others => (others => '0'));
- signal tone_gen_op : std_logic_vector(3 downto 1) := "000";
-
- signal env_gen_cnt : std_logic_vector(15 downto 0);
- signal env_ena : std_logic;
- signal env_hold : std_logic;
- signal env_inc : std_logic;
- signal env_vol : std_logic_vector(4 downto 0);
-
- signal tone_ena_l : std_logic;
- signal tone_src : std_logic;
- signal noise_ena_l : std_logic;
- signal chan_vol : std_logic_vector(4 downto 0);
-
- signal dac_amp : std_logic_vector(7 downto 0);
-begin
- -- cpu i/f
- p_busdecode : process(I_BDIR, I_BC2, I_BC1, addr, I_A9_L, I_A8)
- variable cs : std_logic;
- variable sel : std_logic_vector(2 downto 0);
- begin
- -- BDIR BC2 BC1 MODE
- -- 0 0 0 inactive
- -- 0 0 1 address
- -- 0 1 0 inactive
- -- 0 1 1 read
- -- 1 0 0 address
- -- 1 0 1 inactive
- -- 1 1 0 write
- -- 1 1 1 read
- busctrl_addr <= '0';
- busctrl_we <= '0';
- busctrl_re <= '0';
-
- cs := '0';
- if (I_A9_L = '0') and (I_A8 = '1') and (addr(7 downto 4) = "0000") then
- cs := '1';
- end if;
-
- sel := (I_BDIR & I_BC2 & I_BC1);
- case sel is
- when "000" => null;
- when "001" => busctrl_addr <= '1';
- when "010" => null;
- when "011" => busctrl_re <= cs;
- when "100" => busctrl_addr <= '1';
- when "101" => null;
- when "110" => busctrl_we <= cs;
- when "111" => busctrl_addr <= '1';
- when others => null;
- end case;
- end process;
-
- p_oe : process(busctrl_re)
- begin
- -- if we are emulating a real chip, maybe clock this to fake up the tristate typ delay of 100ns
- O_DA_OE_L <= not (busctrl_re);
- end process;
-
- --
- -- CLOCKED
- --
- p_waddr : process(RESET_L, CLK)
- begin
- -- looks like registers are latches in real chip, but the address is caught at the end of the address state.
- if (RESET_L = '0') then
- addr <= (others => '0');
- elsif rising_edge(CLK) then
- if (ENA = '1') then
- if (busctrl_addr = '1') then
- addr <= I_DA;
- end if;
- end if;
- end if;
- end process;
-
- p_wdata : process(RESET_L, CLK)
- begin
- if (RESET_L = '0') then
- reg <= (others => (others => '0'));
- env_reset <= '1';
- elsif rising_edge(CLK) then
- if (ENA = '1') then
- env_reset <= '0';
- if (busctrl_we = '1') then
- case addr(3 downto 0) is
- when x"0" => reg(0) <= I_DA;
- when x"1" => reg(1) <= I_DA;
- when x"2" => reg(2) <= I_DA;
- when x"3" => reg(3) <= I_DA;
- when x"4" => reg(4) <= I_DA;
- when x"5" => reg(5) <= I_DA;
- when x"6" => reg(6) <= I_DA;
- when x"7" => reg(7) <= I_DA;
- when x"8" => reg(8) <= I_DA;
- when x"9" => reg(9) <= I_DA;
- when x"A" => reg(10) <= I_DA;
- when x"B" => reg(11) <= I_DA;
- when x"C" => reg(12) <= I_DA;
- when x"D" => reg(13) <= I_DA; env_reset <= '1';
- when x"E" => reg(14) <= I_DA;
- when x"F" => reg(15) <= I_DA;
- when others => null;
- end case;
- end if;
- end if;
- end if;
- end process;
-
- p_rdata : process(busctrl_re, addr, reg, ioa_inreg, iob_inreg)
- begin
- O_DA <= (others => '0'); -- 'X'
- if (busctrl_re = '1') then -- not necessary, but useful for putting 'X's in the simulator
- case addr(3 downto 0) is
- when x"0" => O_DA <= reg(0) ;
- when x"1" => O_DA <= "0000" & reg(1)(3 downto 0) ;
- when x"2" => O_DA <= reg(2) ;
- when x"3" => O_DA <= "0000" & reg(3)(3 downto 0) ;
- when x"4" => O_DA <= reg(4) ;
- when x"5" => O_DA <= "0000" & reg(5)(3 downto 0) ;
- when x"6" => O_DA <= "000" & reg(6)(4 downto 0) ;
- when x"7" => O_DA <= reg(7) ;
- when x"8" => O_DA <= "000" & reg(8)(4 downto 0) ;
- when x"9" => O_DA <= "000" & reg(9)(4 downto 0) ;
- when x"A" => O_DA <= "000" & reg(10)(4 downto 0) ;
- when x"B" => O_DA <= reg(11);
- when x"C" => O_DA <= reg(12);
- when x"D" => O_DA <= "0000" & reg(13)(3 downto 0);
- when x"E" => if (reg(7)(6) = '0') then -- input
- O_DA <= ioa_inreg;
- else
- O_DA <= reg(14); -- read output reg
- end if;
- when x"F" => if (Reg(7)(7) = '0') then
- O_DA <= iob_inreg;
- else
- O_DA <= reg(15);
- end if;
- when others => null;
- end case;
- end if;
- end process;
- --
- p_divider : process
- begin
- wait until rising_edge(CLK);
- -- / 8 when SEL is high and /16 when SEL is low
- if (ENA = '1') then
- ena_div <= '0';
- ena_div_noise <= '0';
- if (cnt_div = "0000") then
- cnt_div <= (not I_SEL_L) & "111";
- ena_div <= '1';
-
- noise_div <= not noise_div;
- if (noise_div = '1') then
- ena_div_noise <= '1';
- end if;
- else
- cnt_div <= cnt_div - "1";
- end if;
- end if;
- end process;
-
- p_noise_gen : process
- variable noise_gen_comp : std_logic_vector(4 downto 0);
- variable poly17_zero : std_logic;
- begin
- wait until rising_edge(CLK);
- if (reg(6)(4 downto 0) = "00000") then
- noise_gen_comp := "00000";
- else
- noise_gen_comp := (reg(6)(4 downto 0) - "1");
- end if;
-
- poly17_zero := '0';
- if (poly17 = "00000000000000000") then poly17_zero := '1'; end if;
-
- if (ENA = '1') then
- if (ena_div_noise = '1') then -- divider ena
-
- if (noise_gen_cnt >= noise_gen_comp) then
- noise_gen_cnt <= "00000";
- poly17 <= (poly17(0) xor poly17(2) xor poly17_zero) & poly17(16 downto 1);
- else
- noise_gen_cnt <= (noise_gen_cnt + "1");
- end if;
- end if;
- end if;
- end process;
- noise_gen_op <= poly17(0);
-
- p_tone_gens : process
- variable tone_gen_freq : array_3x12;
- variable tone_gen_comp : array_3x12;
- begin
- wait until rising_edge(CLK);
- -- looks like real chips count up - we need to get the Exact behaviour ..
- tone_gen_freq(1) := reg(1)(3 downto 0) & reg(0);
- tone_gen_freq(2) := reg(3)(3 downto 0) & reg(2);
- tone_gen_freq(3) := reg(5)(3 downto 0) & reg(4);
- -- period 0 = period 1
- for i in 1 to 3 loop
- if (tone_gen_freq(i) = x"000") then
- tone_gen_comp(i) := x"000";
- else
- tone_gen_comp(i) := (tone_gen_freq(i) - "1");
- end if;
- end loop;
-
- if (ENA = '1') then
- for i in 1 to 3 loop
- if (ena_div = '1') then -- divider ena
-
- if (tone_gen_cnt(i) >= tone_gen_comp(i)) then
- tone_gen_cnt(i) <= x"000";
- tone_gen_op(i) <= not tone_gen_op(i);
- else
- tone_gen_cnt(i) <= (tone_gen_cnt(i) + "1");
- end if;
- end if;
- end loop;
- end if;
- end process;
-
- p_envelope_freq : process
- variable env_gen_freq : std_logic_vector(15 downto 0);
- variable env_gen_comp : std_logic_vector(15 downto 0);
- begin
- wait until rising_edge(CLK);
- env_gen_freq := reg(12) & reg(11);
- -- envelope freqs 1 and 0 are the same.
- if (env_gen_freq = x"0000") then
- env_gen_comp := x"0000";
- else
- env_gen_comp := (env_gen_freq - "1");
- end if;
-
- if (ENA = '1') then
- env_ena <= '0';
- if (ena_div = '1') then -- divider ena
- if (env_gen_cnt >= env_gen_comp) then
- env_gen_cnt <= x"0000";
- env_ena <= '1';
- else
- env_gen_cnt <= (env_gen_cnt + "1");
- end if;
- end if;
- end if;
- end process;
-
- p_envelope_shape : process(env_reset, reg, CLK)
- variable is_bot : boolean;
- variable is_bot_p1 : boolean;
- variable is_top_m1 : boolean;
- variable is_top : boolean;
- begin
- -- envelope shapes
- -- C AtAlH
- -- 0 0 x x \___
- --
- -- 0 1 x x /___
- --
- -- 1 0 0 0 \\\\
- --
- -- 1 0 0 1 \___
- --
- -- 1 0 1 0 \/\/
- -- ___
- -- 1 0 1 1 \
- --
- -- 1 1 0 0 ////
- -- ___
- -- 1 1 0 1 /
- --
- -- 1 1 1 0 /\/\
- --
- -- 1 1 1 1 /___
- if (env_reset = '1') then
- -- load initial state
- if (reg(13)(2) = '0') then -- attack
- env_vol <= "11111";
- env_inc <= '0'; -- -1
- else
- env_vol <= "00000";
- env_inc <= '1'; -- +1
- end if;
- env_hold <= '0';
-
- elsif rising_edge(CLK) then
- is_bot := (env_vol = "00000");
- is_bot_p1 := (env_vol = "00001");
- is_top_m1 := (env_vol = "11110");
- is_top := (env_vol = "11111");
-
- if (ENA = '1') then
- if (env_ena = '1') then
- if (env_hold = '0') then
- if (env_inc = '1') then
- env_vol <= (env_vol + "00001");
- else
- env_vol <= (env_vol + "11111");
- end if;
- end if;
-
- -- envelope shape control.
- if (reg(13)(3) = '0') then
- if (env_inc = '0') then -- down
- if is_bot_p1 then env_hold <= '1'; end if;
- else
- if is_top then env_hold <= '1'; end if;
- end if;
- else
- if (reg(13)(0) = '1') then -- hold = 1
- if (env_inc = '0') then -- down
- if (reg(13)(1) = '1') then -- alt
- if is_bot then env_hold <= '1'; end if;
- else
- if is_bot_p1 then env_hold <= '1'; end if;
- end if;
- else
- if (reg(13)(1) = '1') then -- alt
- if is_top then env_hold <= '1'; end if;
- else
- if is_top_m1 then env_hold <= '1'; end if;
- end if;
- end if;
-
- elsif (reg(13)(1) = '1') then -- alternate
- if (env_inc = '0') then -- down
- if is_bot_p1 then env_hold <= '1'; end if;
- if is_bot then env_hold <= '0'; env_inc <= '1'; end if;
- else
- if is_top_m1 then env_hold <= '1'; end if;
- if is_top then env_hold <= '0'; env_inc <= '0'; end if;
- end if;
- end if;
-
- end if;
- end if;
- end if;
- end if;
- end process;
-
- p_chan_mixer : process(cnt_div, reg, tone_gen_op)
- begin
- tone_ena_l <= '1'; tone_src <= '1';
- noise_ena_l <= '1'; chan_vol <= "00000";
- case cnt_div(1 downto 0) is
- when "00" =>
- tone_ena_l <= reg(7)(0); tone_src <= tone_gen_op(1); chan_vol <= reg(8)(4 downto 0);
- noise_ena_l <= reg(7)(3);
- when "01" =>
- tone_ena_l <= reg(7)(1); tone_src <= tone_gen_op(2); chan_vol <= reg(9)(4 downto 0);
- noise_ena_l <= reg(7)(4);
- when "10" =>
- tone_ena_l <= reg(7)(2); tone_src <= tone_gen_op(3); chan_vol <= reg(10)(4 downto 0);
- noise_ena_l <= reg(7)(5);
- when "11" => null; -- tone gen outputs become valid on this clock
- when others => null;
- end case;
- end process;
-
- p_op_mixer : process
- variable chan_mixed : std_logic;
- variable chan_amp : std_logic_vector(4 downto 0);
- begin
- wait until rising_edge(CLK);
- if (ENA = '1') then
-
- chan_mixed := (tone_ena_l or tone_src) and (noise_ena_l or noise_gen_op);
-
- chan_amp := (others => '0');
- if (chan_mixed = '1') then
- if (chan_vol(4) = '0') then
- if (chan_vol(3 downto 0) = "0000") then -- nothing is easy ! make sure quiet is quiet
- chan_amp := "00000";
- else
- chan_amp := chan_vol(3 downto 0) & '1'; -- make sure level 31 (env) = level 15 (tone)
- end if;
- else
- chan_amp := env_vol(4 downto 0);
- end if;
- end if;
-
- dac_amp <= x"00";
- case chan_amp is
- when "11111" => dac_amp <= x"FF";
- when "11110" => dac_amp <= x"D9";
- when "11101" => dac_amp <= x"BA";
- when "11100" => dac_amp <= x"9F";
- when "11011" => dac_amp <= x"88";
- when "11010" => dac_amp <= x"74";
- when "11001" => dac_amp <= x"63";
- when "11000" => dac_amp <= x"54";
- when "10111" => dac_amp <= x"48";
- when "10110" => dac_amp <= x"3D";
- when "10101" => dac_amp <= x"34";
- when "10100" => dac_amp <= x"2C";
- when "10011" => dac_amp <= x"25";
- when "10010" => dac_amp <= x"1F";
- when "10001" => dac_amp <= x"1A";
- when "10000" => dac_amp <= x"16";
- when "01111" => dac_amp <= x"13";
- when "01110" => dac_amp <= x"10";
- when "01101" => dac_amp <= x"0D";
- when "01100" => dac_amp <= x"0B";
- when "01011" => dac_amp <= x"09";
- when "01010" => dac_amp <= x"08";
- when "01001" => dac_amp <= x"07";
- when "01000" => dac_amp <= x"06";
- when "00111" => dac_amp <= x"05";
- when "00110" => dac_amp <= x"04";
- when "00101" => dac_amp <= x"03";
- when "00100" => dac_amp <= x"03";
- when "00011" => dac_amp <= x"02";
- when "00010" => dac_amp <= x"02";
- when "00001" => dac_amp <= x"01";
- when "00000" => dac_amp <= x"00";
- when others => null;
- end case;
-
- cnt_div_t1 <= cnt_div;
- end if;
- end process;
-
- p_audio_output : process(RESET_L, CLK)
- begin
- if (RESET_L = '0') then
- O_AUDIO <= (others => '0');
- O_CHAN <= (others => '0');
- elsif rising_edge(CLK) then
-
- if (ENA = '1') then
- O_AUDIO <= dac_amp(7 downto 0);
- O_CHAN <= cnt_div_t1(1 downto 0);
- end if;
- end if;
- end process;
-
- p_io_ports : process(reg)
- begin
- O_IOA <= reg(14);
- O_IOA_OE_L <= not reg(7)(6);
- O_IOB <= reg(15);
- O_IOB_OE_L <= not reg(7)(7);
- end process;
-
- p_io_ports_inreg : process
- begin
- wait until rising_edge(CLK);
- if (ENA = '1') then -- resync
- ioa_inreg <= I_IOA;
- iob_inreg <= I_IOB;
- end if;
- end process;
-end architecture RTL;
diff --git a/Arcade_MiST/IremM52 Hardware/TraverseUSA_MiST/rtl/cpu09l_128.vhd b/Arcade_MiST/IremM52 Hardware/TraverseUSA_MiST/rtl/cpu09l_128.vhd
deleted file mode 100644
index 12039bde..00000000
--- a/Arcade_MiST/IremM52 Hardware/TraverseUSA_MiST/rtl/cpu09l_128.vhd
+++ /dev/null
@@ -1,5906 +0,0 @@
---===========================================================================--
--- --
--- Synthesizable 6809 instruction compatible VHDL CPU core --
--- --
---===========================================================================--
---
--- File name : cpu09l.vhd
---
--- Entity name : cpu09
---
--- Purpose : 6809 instruction compatible CPU core written in VHDL
--- with Last Instruction Cycle, bus available, bus status,
--- and instruction fetch signals.
--- Not cycle compatible with the original 6809 CPU
---
--- Dependencies : ieee.std_logic_1164
--- ieee.std_logic_unsigned
---
--- Author : John E. Kent
---
--- Email : dilbert57@opencores.org
---
--- Web : http://opencores.org/project,system09
---
--- Description : VMA (valid memory address) is hight whenever a valid memory
--- access is made by an instruction fetch, interrupt vector fetch
--- or a data read or write otherwise it is low indicating an idle
--- bus cycle.
--- IFETCH (instruction fetch output) is high whenever an
--- instruction byte is read i.e. the program counter is applied
--- to the address bus.
--- LIC (last instruction cycle output) is normally low
--- but goes high on the last cycle of an instruction.
--- BA (bus available output) is normally low but goes high while
--- waiting in a Sync instruction state or the CPU is halted
--- i.e. a DMA grant.
--- BS (bus status output) is normally low but goes high during an
--- interrupt or reset vector fetch or the processor is halted
--- i.e. a DMA grant.
---
--- Copyright (C) 2003 - 2010 John Kent
---
--- This program is free software: you can redistribute it and/or modify
--- it under the terms of the GNU General Public License as published by
--- the Free Software Foundation, either version 3 of the License, or
--- (at your option) any later version.
---
--- This program is distributed in the hope that it will be useful,
--- but WITHOUT ANY WARRANTY; without even the implied warranty of
--- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--- GNU General Public License for more details.
---
--- You should have received a copy of the GNU General Public License
--- along with this program. If not, see .
---
---===========================================================================--
--- --
--- Revision History --
--- --
---===========================================================================--
---
--- Version 0.1 - 26 June 2003 - John Kent
--- Added extra level in state stack
--- fixed some calls to the extended addressing state
---
--- Version 0.2 - 5 Sept 2003 - John Kent
--- Fixed 16 bit indexed offset (was doing read rather than fetch)
--- Added/Fixed STY and STS instructions.
--- ORCC_STATE ANDed CC state rather than ORed it - Now fixed
--- CMPX Loaded ACCA and ACCB - Now fixed
---
--- Version 1.0 - 6 Sep 2003 - John Kent
--- Initial release to Open Cores
--- reversed clock edge
---
--- Version 1.1 - 29 November 2003 John kent
--- ACCA and ACCB indexed offsets are 2's complement.
--- ALU Right Mux now sign extends ACCA & ACCB offsets
--- Absolute Indirect addressing performed a read on the
--- second byte of the address rather than a fetch
--- so it formed an incorrect address. Now fixed.
---
--- Version 1.2 - 29 November 2003 John Kent
--- LEAX and LEAY affect the Z bit only
--- LEAS and LEAU do not affect any condition codes
--- added an extra ALU control for LEA.
---
--- Version 1.3 - 12 December 2003 John Kent
--- CWAI did not work, was missed a PUSH_ST on calling
--- the ANDCC_STATE. Thanks go to Ghassan Kraidy for
--- finding this fault.
---
--- Version 1.4 - 12 December 2003 John Kent
--- Missing cc_ctrl assignment in otherwise case of
--- lea_state resulted in cc_ctrl being latched in
--- that state.
--- The otherwise statement should never be reached,
--- and has been fixed simply to resolve synthesis warnings.
---
--- Version 1.5 - 17 january 2004 John kent
--- The clear instruction used "alu_ld8" to control the ALU
--- rather than "alu_clr". This mean the Carry was not being
--- cleared correctly.
---
--- Version 1.6 - 24 January 2004 John Kent
--- Fixed problems in PSHU instruction
---
--- Version 1.7 - 25 January 2004 John Kent
--- removed redundant "alu_inx" and "alu_dex'
--- Removed "test_alu" and "test_cc"
--- STD instruction did not set condition codes
--- JMP direct was not decoded properly
--- CLR direct performed an unwanted read cycle
--- Bogus "latch_md" in Page2 indexed addressing
---
--- Version 1.8 - 27 January 2004 John Kent
--- CWAI in decode1_state should increment the PC.
--- ABX is supposed to be an unsigned addition.
--- Added extra ALU function
--- ASR8 slightly changed in the ALU.
---
--- Version 1.9 - 20 August 2005
--- LSR8 is now handled in ASR8 and ROR8 case in the ALU,
--- rather than LSR16. There was a problem with single
--- operand instructions using the MD register which is
--- sign extended on the first 8 bit fetch.
---
--- Version 1.10 - 13 September 2005
--- TFR & EXG instructions did not work for the Condition Code Register
--- An extra case has been added to the ALU for the alu_tfr control
--- to assign the left ALU input (alu_left) to the condition code
--- outputs (cc_out).
---
--- Version 1.11 - 16 September 2005
--- JSR ,X should not predecrement S before calculating the jump address.
--- The reason is that JSR [0,S] needs S to point to the top of the stack
--- to fetch a valid vector address. The solution is to have the addressing
--- mode microcode called before decrementing S and then decrementing S in
--- JSR_STATE. JSR_STATE in turn calls PUSH_RETURN_LO_STATE rather than
--- PUSH_RETURN_HI_STATE so that both the High & Low halves of the PC are
--- pushed on the stack. This adds one extra bus cycle, but resolves the
--- addressing conflict. I've also removed the pre-decement S in
--- JSR EXTENDED as it also calls JSR_STATE.
---
--- Version 1.12 - 6th June 2006
--- 6809 Programming reference manual says V is not affected by ASR, LSR and ROR
--- This is different to the 6800. CLR should reset the V bit.
---
--- Version 1.13 - 7th July 2006
--- Disable NMI on reset until S Stack pointer has been loaded.
--- Added nmi_enable signal in sp_reg process and nmi_handler process.
---
--- Version 1.14 - 11th July 2006
--- 1. Added new state to RTI called rti_entire_state.
--- This state tests the CC register after it has been loaded
--- from the stack. Previously the current CC was tested which
--- was incorrect. The Entire Flag should be set before the
--- interrupt stacks the CC.
--- 2. On bogus Interrupts, int_cc_state went to rti_state,
--- which was an enumerated state, but not defined anywhere.
--- rti_state has been changed to rti_cc_state so that bogus interrupt
--- will perform an RTI after entering that state.
--- 3. Sync should generate an interrupt if the interrupt masks
--- are cleared. If the interrupt masks are set, then an interrupt
--- will cause the the PC to advance to the next instruction.
--- Note that I don't wait for an interrupt to be asserted for
--- three clock cycles.
--- 4. Added new ALU control state "alu_mul". "alu_mul" is used in
--- the Multiply instruction replacing "alu_add16". This is similar
--- to "alu_add16" except it sets the Carry bit to B7 of the result
--- in ACCB, sets the Zero bit if the 16 bit result is zero, but
--- does not affect The Half carry (H), Negative (N) or Overflow (V)
--- flags. The logic was re-arranged so that it adds md or zero so
--- that the Carry condition code is set on zero multiplicands.
--- 5. DAA (Decimal Adjust Accumulator) should set the Negative (N)
--- and Zero Flags. It will also affect the Overflow (V) flag although
--- the operation is undefined. It's anyones guess what DAA does to V.
---
--- Version 1.15 - 25th Feb 2007 - John Kent
--- line 9672 changed "if Halt <= '1' then" to "if Halt = '1' then"
--- Changed sensitivity lists.
---
--- Version 1.16 - 5th February 2008 - John Kent
--- FIRQ interrupts should take priority over IRQ Interrupts.
--- This presumably means they should be tested for before IRQ
--- when they happen concurrently.
---
--- Version 1.17 - 18th February 2008 - John Kent
--- NMI in CWAI should mask IRQ and FIRQ interrupts
---
--- Version 1.18 - 21st February 2008 - John Kent
--- Removed default register settings in each case statement
--- and placed them at the beginning of the state sequencer.
--- Modified the SYNC instruction so that the interrupt vector(iv)
--- is not set unless an unmasked FIRQ or IRQ is received.
---
--- Version 1.19 - 25th February 2008 - John Kent
--- Enumerated separate states for FIRQ/FAST and NMIIRQ/ENTIRE
--- Enumerated separate states for MASKI and MASKIF states
--- Removed code on BSR/JSR in fetch cycle
---
--- Version 1.20 - 8th October 2011 - John Kent
--- added fetch output which should go high during the fetch cycle
---
--- Version 1.21 - 8th October 2011 - John Kent
--- added Last Instruction Cycle signal
--- replaced fetch with ifetch (instruction fetch) signal
--- added ba & bs (bus available & bus status) signals
---
--- Version 1.22 - 2011-10-29 John Kent
--- The halt state isn't correct.
--- The halt state is entered into from the fetch_state
--- It returned to the fetch state which may re-run an execute cycle
--- on the accumulator and it won't necessarily be the last instruction cycle
--- I've changed the halt state to return to the decode1_state
---
--- Version 1.23 - 2011-10-30 John Kent
--- sample halt in the change_state process if lic is high (last instruction cycle)
---
--- Version 1.24 - 2011-11-01 John Kent
--- Handle interrupts in change_state process
--- Sample interrupt inputs on last instruction cycle
--- Remove iv_ctrl and implement iv (interrupt vector) in change_state process.
--- Generate fic (first instruction cycle) from lic (last instruction cycle)
--- and use it to complete the dual operand execute cycle before servicing
--- halt or interrupts requests.
--- rename lic to lic_out on the entity declaration so that lic can be tested internally.
--- add int_firq1_state and int_nmirq1_state to allow for the dual operand execute cycle
--- integrated nmi_ctrl into change_state process
--- Reduces the microcode state stack to one entry (saved_state)
--- imm16_state jumps directly to the fetch_state
--- pull_return_lo states jumps directly to the fetch_state
--- duplicate andcc_state as cwai_state
--- rename exg1_state as exg2 state and duplicate tfr_state as exg1_state
---
--- Version 1.25 - 2011-11-27 John Kent
--- Changed the microcode for saving registers on an interrupt into a microcode subroutine.
--- Removed SWI servicing from the change state process and made SWI, SWI2 & SWI3
--- call the interrupt microcode subroutine.
--- Added additional states for nmi, and irq for interrupt servicing.
--- Added additional states for nmi/irq, firq, and swi interrupts to mask I & F flags.
---
--- Version 1.26 - 2013-03-18 John Kent
--- pre-initialized cond_true variable to true in state sequencer
--- re-arranged change_state process slightly
---
--- Version 1.27 - 2015-05-30 John Kent
--- Added test in state machine for masked IRQ and FIRQ in Sync_state.
---
--- Version 1.28 - 2015-05-30 John Kent.
--- Moved IRQ and FIRQ test from state machine to the state sequencer Sync_state.
---
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.std_logic_unsigned.all;
-
-entity cpu09 is
- port (
- clk : in std_logic; -- E clock input (falling edge)
- rst : in std_logic; -- reset input (active high)
- vma : out std_logic; -- valid memory address (active high)
- lic_out : out std_logic; -- last instruction cycle (active high)
- ifetch : out std_logic; -- instruction fetch cycle (active high)
- opfetch : out std_logic; -- opcode fetch (active high)
- ba : out std_logic; -- bus available (high on sync wait or DMA grant)
- bs : out std_logic; -- bus status (high on interrupt or reset vector fetch or DMA grant)
- addr : out std_logic_vector(15 downto 0); -- address bus output
- rw : out std_logic; -- read not write output
- data_out : out std_logic_vector(7 downto 0); -- data bus output
- data_in : in std_logic_vector(7 downto 0); -- data bus input
- irq : in std_logic; -- interrupt request input (active high)
- firq : in std_logic; -- fast interrupt request input (active high)
- nmi : in std_logic; -- non maskable interrupt request input (active high)
- halt : in std_logic; -- halt input (active high) grants DMA
- hold : in std_logic -- hold input (active high) extend bus cycle
- );
-end cpu09;
-
-architecture rtl of cpu09 is
-
- constant EBIT : integer := 7;
- constant FBIT : integer := 6;
- constant HBIT : integer := 5;
- constant IBIT : integer := 4;
- constant NBIT : integer := 3;
- constant ZBIT : integer := 2;
- constant VBIT : integer := 1;
- constant CBIT : integer := 0;
-
- --
- -- Interrupt vector modifiers
- --
- constant RST_VEC : std_logic_vector(2 downto 0) := "111";
- constant NMI_VEC : std_logic_vector(2 downto 0) := "110";
- constant SWI_VEC : std_logic_vector(2 downto 0) := "101";
- constant IRQ_VEC : std_logic_vector(2 downto 0) := "100";
- constant FIRQ_VEC : std_logic_vector(2 downto 0) := "011";
- constant SWI2_VEC : std_logic_vector(2 downto 0) := "010";
- constant SWI3_VEC : std_logic_vector(2 downto 0) := "001";
- constant RESV_VEC : std_logic_vector(2 downto 0) := "000";
-
- type state_type is (-- Start off in Reset
- reset_state,
- -- Fetch Interrupt Vectors (including reset)
- vect_lo_state, vect_hi_state, vect_idle_state,
- -- Fetch Instruction Cycle
- fetch_state,
- -- Decode Instruction Cycles
- decode1_state, decode2_state, decode3_state,
- -- Calculate Effective Address
- imm16_state,
- indexed_state, index8_state, index16_state, index16_2_state,
- pcrel8_state, pcrel16_state, pcrel16_2_state,
- indexaddr_state, indexaddr2_state,
- postincr1_state, postincr2_state,
- indirect_state, indirect2_state, indirect3_state,
- extended_state,
- -- single ops
- single_op_read_state,
- single_op_exec_state,
- single_op_write_state,
- -- Dual op states
- dual_op_read8_state, dual_op_read16_state, dual_op_read16_2_state,
- dual_op_write8_state, dual_op_write16_state,
- --
- sync_state, halt_state, cwai_state,
- --
- andcc_state, orcc_state,
- tfr_state,
- exg_state, exg1_state, exg2_state,
- lea_state,
- -- Multiplication
- mul_state, mulea_state, muld_state,
- mul0_state, mul1_state, mul2_state, mul3_state,
- mul4_state, mul5_state, mul6_state, mul7_state,
- -- Branches
- lbranch_state, sbranch_state,
- -- Jumps, Subroutine Calls and Returns
- jsr_state, jmp_state,
- push_return_hi_state, push_return_lo_state,
- pull_return_hi_state, pull_return_lo_state,
- -- Interrupt cycles
- int_nmi_state, int_nmi1_state,
- int_irq_state, int_irq1_state,
- int_firq_state, int_firq1_state,
- int_entire_state, int_fast_state,
- int_pcl_state, int_pch_state,
- int_upl_state, int_uph_state,
- int_iyl_state, int_iyh_state,
- int_ixl_state, int_ixh_state,
- int_dp_state,
- int_accb_state, int_acca_state,
- int_cc_state,
- int_cwai_state,
- int_nmimask_state, int_firqmask_state, int_swimask_state, int_irqmask_state,
- -- Return From Interrupt
- rti_cc_state, rti_entire_state,
- rti_acca_state, rti_accb_state,
- rti_dp_state,
- rti_ixl_state, rti_ixh_state,
- rti_iyl_state, rti_iyh_state,
- rti_upl_state, rti_uph_state,
- rti_pcl_state, rti_pch_state,
- -- Push Registers using SP
- pshs_state,
- pshs_pcl_state, pshs_pch_state,
- pshs_upl_state, pshs_uph_state,
- pshs_iyl_state, pshs_iyh_state,
- pshs_ixl_state, pshs_ixh_state,
- pshs_dp_state,
- pshs_acca_state, pshs_accb_state,
- pshs_cc_state,
- -- Pull Registers using SP
- puls_state,
- puls_cc_state,
- puls_acca_state, puls_accb_state,
- puls_dp_state,
- puls_ixl_state, puls_ixh_state,
- puls_iyl_state, puls_iyh_state,
- puls_upl_state, puls_uph_state,
- puls_pcl_state, puls_pch_state,
- -- Push Registers using UP
- pshu_state,
- pshu_pcl_state, pshu_pch_state,
- pshu_spl_state, pshu_sph_state,
- pshu_iyl_state, pshu_iyh_state,
- pshu_ixl_state, pshu_ixh_state,
- pshu_dp_state,
- pshu_acca_state, pshu_accb_state,
- pshu_cc_state,
- -- Pull Registers using UP
- pulu_state,
- pulu_cc_state,
- pulu_acca_state, pulu_accb_state,
- pulu_dp_state,
- pulu_ixl_state, pulu_ixh_state,
- pulu_iyl_state, pulu_iyh_state,
- pulu_spl_state, pulu_sph_state,
- pulu_pcl_state, pulu_pch_state );
-
- type st_type is (reset_st, push_st, idle_st );
- type iv_type is (latch_iv, swi3_iv, swi2_iv, firq_iv, irq_iv, swi_iv, nmi_iv, reset_iv);
- type addr_type is (idle_ad, fetch_ad, read_ad, write_ad, pushu_ad, pullu_ad, pushs_ad, pulls_ad, int_hi_ad, int_lo_ad );
- type dout_type is (cc_dout, acca_dout, accb_dout, dp_dout,
- ix_lo_dout, ix_hi_dout, iy_lo_dout, iy_hi_dout,
- up_lo_dout, up_hi_dout, sp_lo_dout, sp_hi_dout,
- pc_lo_dout, pc_hi_dout, md_lo_dout, md_hi_dout );
- type op_type is (reset_op, fetch_op, latch_op );
- type pre_type is (reset_pre, fetch_pre, latch_pre );
- type cc_type is (reset_cc, load_cc, pull_cc, latch_cc );
- type acca_type is (reset_acca, load_acca, load_hi_acca, pull_acca, latch_acca );
- type accb_type is (reset_accb, load_accb, pull_accb, latch_accb );
- type dp_type is (reset_dp, load_dp, pull_dp, latch_dp );
- type ix_type is (reset_ix, load_ix, pull_lo_ix, pull_hi_ix, latch_ix );
- type iy_type is (reset_iy, load_iy, pull_lo_iy, pull_hi_iy, latch_iy );
- type sp_type is (reset_sp, latch_sp, load_sp, pull_hi_sp, pull_lo_sp );
- type up_type is (reset_up, latch_up, load_up, pull_hi_up, pull_lo_up );
- type pc_type is (reset_pc, latch_pc, load_pc, pull_lo_pc, pull_hi_pc, incr_pc );
- type md_type is (reset_md, latch_md, load_md, fetch_first_md, fetch_next_md, shiftl_md );
- type ea_type is (reset_ea, latch_ea, load_ea, fetch_first_ea, fetch_next_ea );
- type left_type is (cc_left, acca_left, accb_left, dp_left,
- ix_left, iy_left, up_left, sp_left,
- accd_left, md_left, pc_left, ea_left );
- type right_type is (ea_right, zero_right, one_right, two_right,
- acca_right, accb_right, accd_right,
- md_right, md_sign5_right, md_sign8_right );
- type alu_type is (alu_add8, alu_sub8, alu_add16, alu_sub16, alu_adc, alu_sbc,
- alu_and, alu_ora, alu_eor,
- alu_tst, alu_inc, alu_dec, alu_clr, alu_neg, alu_com,
- alu_lsr16, alu_lsl16,
- alu_ror8, alu_rol8, alu_mul,
- alu_asr8, alu_asl8, alu_lsr8,
- alu_andcc, alu_orcc, alu_sex, alu_tfr, alu_abx,
- alu_seif, alu_sei, alu_see, alu_cle,
- alu_ld8, alu_st8, alu_ld16, alu_st16, alu_lea, alu_nop, alu_daa );
-
- signal op_code: std_logic_vector(7 downto 0);
- signal pre_code: std_logic_vector(7 downto 0);
- signal acca: std_logic_vector(7 downto 0);
- signal accb: std_logic_vector(7 downto 0);
- signal cc: std_logic_vector(7 downto 0);
- signal cc_out: std_logic_vector(7 downto 0);
- signal dp: std_logic_vector(7 downto 0);
- signal xreg: std_logic_vector(15 downto 0);
- signal yreg: std_logic_vector(15 downto 0);
- signal sp: std_logic_vector(15 downto 0);
- signal up: std_logic_vector(15 downto 0);
- signal ea: std_logic_vector(15 downto 0);
- signal pc: std_logic_vector(15 downto 0);
- signal md: std_logic_vector(15 downto 0);
- signal left: std_logic_vector(15 downto 0);
- signal right: std_logic_vector(15 downto 0);
- signal out_alu: std_logic_vector(15 downto 0);
- signal iv: std_logic_vector(2 downto 0);
- signal nmi_req: std_logic;
- signal nmi_ack: std_logic;
- signal nmi_enable: std_logic;
- signal fic: std_logic; -- first instruction cycle
- signal lic: std_logic; -- last instruction cycle
-
- signal state: state_type;
- signal next_state: state_type;
- signal return_state: state_type;
- signal saved_state: state_type;
- signal st_ctrl: st_type;
- signal iv_ctrl: iv_type;
- signal pc_ctrl: pc_type;
- signal ea_ctrl: ea_type;
- signal op_ctrl: op_type;
- signal pre_ctrl: pre_type;
- signal md_ctrl: md_type;
- signal acca_ctrl: acca_type;
- signal accb_ctrl: accb_type;
- signal ix_ctrl: ix_type;
- signal iy_ctrl: iy_type;
- signal cc_ctrl: cc_type;
- signal dp_ctrl: dp_type;
- signal sp_ctrl: sp_type;
- signal up_ctrl: up_type;
- signal left_ctrl: left_type;
- signal right_ctrl: right_type;
- signal alu_ctrl: alu_type;
- signal addr_ctrl: addr_type;
- signal dout_ctrl: dout_type;
-
-
-begin
-
-----------------------------------
---
--- State machine stack
---
-----------------------------------
---state_stack_proc: process( clk, hold, state_stack, st_ctrl,
--- return_state, fetch_state )
-state_stack_proc: process( clk, st_ctrl, return_state )
-begin
- if clk'event and clk = '0' then
- if hold = '0' then
- case st_ctrl is
- when reset_st =>
- saved_state <= fetch_state;
- when push_st =>
- saved_state <= return_state;
- when others =>
- null;
- end case;
- end if;
- end if;
-end process;
-
-----------------------------------
---
--- Interrupt Vector control
---
-----------------------------------
---
-int_vec_proc: process( clk, iv_ctrl )
-begin
- if clk'event and clk = '0' then
- if hold = '0' then
- case iv_ctrl is
- when reset_iv =>
- iv <= RST_VEC;
- when nmi_iv =>
- iv <= NMI_VEC;
- when swi_iv =>
- iv <= SWI_VEC;
- when irq_iv =>
- iv <= IRQ_VEC;
- when firq_iv =>
- iv <= FIRQ_VEC;
- when swi2_iv =>
- iv <= SWI2_VEC;
- when swi3_iv =>
- iv <= SWI3_VEC;
- when others =>
- null;
- end case;
- end if; -- hold
- end if; -- clk
-end process;
-
-----------------------------------
---
--- Program Counter Control
---
-----------------------------------
-
---pc_reg: process( clk, pc_ctrl, hold, pc, out_alu, data_in )
-pc_reg: process( clk )
-begin
- if clk'event and clk = '0' then
- if hold = '0' then
- case pc_ctrl is
- when reset_pc =>
- pc <= (others=>'0');
- when load_pc =>
- pc <= out_alu(15 downto 0);
- when pull_lo_pc =>
- pc(7 downto 0) <= data_in;
- when pull_hi_pc =>
- pc(15 downto 8) <= data_in;
- when incr_pc =>
- pc <= pc + 1;
- when others =>
- null;
- end case;
- end if;
- end if;
-end process;
-
-----------------------------------
---
--- Effective Address Control
---
-----------------------------------
-
---ea_reg: process( clk, ea_ctrl, hold, ea, out_alu, data_in, dp )
-ea_reg: process( clk )
-begin
-
- if clk'event and clk = '0' then
- if hold= '0' then
- case ea_ctrl is
- when reset_ea =>
- ea <= (others=>'0');
- when fetch_first_ea =>
- ea(7 downto 0) <= data_in;
- ea(15 downto 8) <= dp;
- when fetch_next_ea =>
- ea(15 downto 8) <= ea(7 downto 0);
- ea(7 downto 0) <= data_in;
- when load_ea =>
- ea <= out_alu(15 downto 0);
- when others =>
- null;
- end case;
- end if;
- end if;
-end process;
-
---------------------------------
---
--- Accumulator A
---
---------------------------------
---acca_reg : process( clk, acca_ctrl, hold, out_alu, acca, data_in )
-acca_reg : process( clk )
-begin
- if clk'event and clk = '0' then
- if hold = '0' then
- case acca_ctrl is
- when reset_acca =>
- acca <= (others=>'0');
- 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 =>
- null;
- end case;
- end if;
- end if;
-end process;
-
---------------------------------
---
--- Accumulator B
---
---------------------------------
---accb_reg : process( clk, accb_ctrl, hold, out_alu, accb, data_in )
-accb_reg : process( clk )
-begin
- if clk'event and clk = '0' then
- if hold = '0' then
- case accb_ctrl is
- when reset_accb =>
- accb <= (others=>'0');
- when load_accb =>
- accb <= out_alu(7 downto 0);
- when pull_accb =>
- accb <= data_in;
- when others =>
- null;
- end case;
- end if;
- end if;
-end process;
-
---------------------------------
---
--- X Index register
---
---------------------------------
---ix_reg : process( clk, ix_ctrl, hold, out_alu, xreg, data_in )
-ix_reg : process( clk )
-begin
- if clk'event and clk = '0' then
- if hold = '0' then
- case ix_ctrl is
- when reset_ix =>
- xreg <= (others=>'0');
- 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 =>
- null;
- end case;
- end if;
- end if;
-end process;
-
---------------------------------
---
--- Y Index register
---
---------------------------------
---iy_reg : process( clk, iy_ctrl, hold, out_alu, yreg, data_in )
-iy_reg : process( clk )
-begin
- if clk'event and clk = '0' then
- if hold = '0' then
- case iy_ctrl is
- when reset_iy =>
- yreg <= (others=>'0');
- when load_iy =>
- yreg <= out_alu(15 downto 0);
- when pull_hi_iy =>
- yreg(15 downto 8) <= data_in;
- when pull_lo_iy =>
- yreg(7 downto 0) <= data_in;
- when others =>
- null;
- end case;
- end if;
- end if;
-end process;
-
---------------------------------
---
--- S stack pointer
---
---------------------------------
---sp_reg : process( clk, sp_ctrl, hold, sp, out_alu, data_in, nmi_enable )
-sp_reg : process( clk )
-begin
- if clk'event and clk = '0' then
- if hold = '0' then
- case sp_ctrl is
- when reset_sp =>
- sp <= (others=>'0');
- nmi_enable <= '0';
- when load_sp =>
- sp <= out_alu(15 downto 0);
- nmi_enable <= '1';
- when pull_hi_sp =>
- sp(15 downto 8) <= data_in;
- when pull_lo_sp =>
- sp(7 downto 0) <= data_in;
- nmi_enable <= '1';
- when others =>
- null;
- end case;
- end if;
- end if;
-end process;
-
---------------------------------
---
--- U stack pointer
---
---------------------------------
---up_reg : process( clk, up_ctrl, hold, up, out_alu, data_in )
-up_reg : process( clk )
-begin
- if clk'event and clk = '0' then
- if hold = '0' then
- case up_ctrl is
- when reset_up =>
- up <= (others=>'0');
- when load_up =>
- up <= out_alu(15 downto 0);
- when pull_hi_up =>
- up(15 downto 8) <= data_in;
- when pull_lo_up =>
- up(7 downto 0) <= data_in;
- when others =>
- null;
- end case;
- end if;
- end if;
-end process;
-
---------------------------------
---
--- Memory Data
---
---------------------------------
---md_reg : process( clk, md_ctrl, hold, out_alu, data_in, md )
-md_reg : process( clk )
-begin
- if clk'event and clk = '0' then
- if hold = '0' then
- case md_ctrl is
- when reset_md =>
- md <= (others=>'0');
- when load_md =>
- md <= out_alu(15 downto 0);
- when fetch_first_md => -- sign extend md for branches
- md(15 downto 8) <= data_in(7) & data_in(7) & data_in(7) & data_in(7) &
- data_in(7) & data_in(7) & data_in(7) & data_in(7) ;
- md(7 downto 0) <= data_in;
- when fetch_next_md =>
- md(15 downto 8) <= md(7 downto 0);
- md(7 downto 0) <= data_in;
- when shiftl_md =>
- md(15 downto 1) <= md(14 downto 0);
- md(0) <= '0';
- when others =>
- null;
- end case;
- end if;
- end if;
-end process;
-
-
-----------------------------------
---
--- Condition Codes
---
-----------------------------------
-
---cc_reg: process( clk, cc_ctrl, hold, cc_out, cc, data_in )
-cc_reg: process( clk )
-begin
- if clk'event and clk = '0' then
- if hold = '0' then
- case cc_ctrl is
- when reset_cc =>
- cc <= "11010000"; -- set EBIT, FBIT & IBIT
- when load_cc =>
- cc <= cc_out;
- when pull_cc =>
- cc <= data_in;
- when others =>
- null;
- end case;
- end if;
- end if;
-end process;
-
-----------------------------------
---
--- Direct Page register
---
-----------------------------------
-
---dp_reg: process( clk, dp_ctrl, hold, out_alu, dp, data_in )
-dp_reg: process( clk )
-begin
- if clk'event and clk = '0' then
- if hold = '0' then
- case dp_ctrl is
- when reset_dp =>
- dp <= (others=>'0');
- when load_dp =>
- dp <= out_alu(7 downto 0);
- when pull_dp =>
- dp <= data_in;
- when others =>
- null;
- end case;
- end if;
- end if;
-end process;
-
-
-----------------------------------
---
--- op code register
---
-----------------------------------
-
---op_reg: process( clk, op_ctrl, hold, op_code, data_in )
-op_reg: process( clk )
-begin
- if clk'event and clk = '0' then
- if hold = '0' then
- case op_ctrl is
- when reset_op =>
- op_code <= "00010010";
- when fetch_op =>
- op_code <= data_in;
- when others =>
- null;
- end case;
- end if;
- end if;
-end process;
-
-
-----------------------------------
---
--- pre byte op code register
---
-----------------------------------
-
---pre_reg: process( clk, pre_ctrl, hold, pre_code, data_in )
-pre_reg: process( clk )
-begin
- if clk'event and clk = '0' then
- if hold = '0' then
- case pre_ctrl is
- when reset_pre =>
- pre_code <= (others=>'0');
- when fetch_pre =>
- pre_code <= data_in;
- when others =>
- null;
- end case;
- end if;
- end if;
-end process;
-
---------------------------------
---
--- state machine
---
---------------------------------
-
---change_state: process( clk, rst, state, hold, next_state )
-change_state: process( clk )
-begin
- if clk'event and clk = '0' then
- if rst = '1' then
- fic <= '0';
- nmi_ack <= '0';
- state <= reset_state;
- elsif hold = '0' then
- fic <= lic;
- --
- -- nmi request is not cleared until nmi input goes low
- --
- if (nmi_req = '0') and (nmi_ack='1') then
- nmi_ack <= '0';
- end if;
-
- if (nmi_req = '1') and (nmi_ack = '0') and (state = int_nmimask_state) then
- nmi_ack <= '1';
- end if;
-
- if lic = '1' then
- if halt = '1' then
- state <= halt_state;
-
- -- service non maskable interrupts
- elsif (nmi_req = '1') and (nmi_ack = '0') then
- state <= int_nmi_state;
- --
- -- FIRQ & IRQ are level sensitive
- --
- elsif (firq = '1') and (cc(FBIT) = '0') then
- state <= int_firq_state;
-
- elsif (irq = '1') and (cc(IBIT) = '0') then
- state <= int_irq_state;
- --
- -- Version 1.27 2015-05-30
- -- Exit sync_state on masked interrupt.
- --
- -- Version 1.28 2015-05-30
- -- Move this code to the state sequencer
- -- near line 5566.
- --
- -- elsif (state = sync_state) and ((firq = '1') or (irq = '1'))then
- -- state <= fetch_state;
- --
- else
- state <= next_state;
- end if; -- halt, nmi, firq, irq
- else
- state <= next_state;
- end if; -- lic
- end if; -- reset/hold
- end if; -- clk
-end process;
-
-------------------------------------
---
--- Detect Edge of NMI interrupt
---
-------------------------------------
-
---nmi_handler : process( clk, rst, nmi, nmi_ack, nmi_req, nmi_enable )
-nmi_handler : process( rst, clk )
-begin
- if rst='1' then
- nmi_req <= '0';
- elsif clk'event and clk='0' then
- if (nmi='1') and (nmi_ack='0') and (nmi_enable='1') then
- nmi_req <= '1';
- else
- if (nmi='0') and (nmi_ack='1') then
- nmi_req <= '0';
- end if;
- end if;
- end if;
-end process;
-
-
-----------------------------------
---
--- Address output multiplexer
---
-----------------------------------
-
-addr_mux: process( addr_ctrl, pc, ea, up, sp, iv )
-begin
- ifetch <= '0';
- vma <= '1';
- case addr_ctrl is
- when fetch_ad =>
- addr <= pc;
- rw <= '1';
- ifetch <= '1';
- when read_ad =>
- addr <= ea;
- rw <= '1';
- when write_ad =>
- addr <= ea;
- rw <= '0';
- when pushs_ad =>
- addr <= sp;
- rw <= '0';
- when pulls_ad =>
- addr <= sp;
- rw <= '1';
- when pushu_ad =>
- addr <= up;
- rw <= '0';
- when pullu_ad =>
- addr <= up;
- rw <= '1';
- when int_hi_ad =>
- addr <= "111111111111" & iv & "0";
- rw <= '1';
- when int_lo_ad =>
- addr <= "111111111111" & iv & "1";
- rw <= '1';
- when others =>
- addr <= "1111111111111111";
- rw <= '1';
- vma <= '0';
- end case;
-end process;
-
---------------------------------
---
--- Data Bus output
---
---------------------------------
-dout_mux : process( dout_ctrl, md, acca, accb, dp, xreg, yreg, sp, up, pc, cc )
-begin
- case dout_ctrl is
- when cc_dout => -- condition code register
- data_out <= cc;
- when acca_dout => -- accumulator a
- data_out <= acca;
- when accb_dout => -- accumulator b
- data_out <= accb;
- when dp_dout => -- direct page register
- data_out <= dp;
- when ix_lo_dout => -- X index reg
- data_out <= xreg(7 downto 0);
- when ix_hi_dout => -- X index reg
- data_out <= xreg(15 downto 8);
- when iy_lo_dout => -- Y index reg
- data_out <= yreg(7 downto 0);
- when iy_hi_dout => -- Y index reg
- data_out <= yreg(15 downto 8);
- when up_lo_dout => -- U stack pointer
- data_out <= up(7 downto 0);
- when up_hi_dout => -- U stack pointer
- data_out <= up(15 downto 8);
- when sp_lo_dout => -- S stack pointer
- data_out <= sp(7 downto 0);
- when sp_hi_dout => -- S stack pointer
- data_out <= sp(15 downto 8);
- when md_lo_dout => -- alu output
- data_out <= md(7 downto 0);
- when md_hi_dout => -- alu output
- data_out <= md(15 downto 8);
- 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);
- end case;
-end process;
-
-----------------------------------
---
--- Left Mux
---
-----------------------------------
-
-left_mux: process( left_ctrl, acca, accb, cc, dp, xreg, yreg, up, sp, pc, ea, md )
-begin
- case left_ctrl is
- when cc_left =>
- left(15 downto 8) <= "00000000";
- left(7 downto 0) <= cc;
- when acca_left =>
- left(15 downto 8) <= "00000000";
- left(7 downto 0) <= acca;
- when accb_left =>
- left(15 downto 8) <= "00000000";
- left(7 downto 0) <= accb;
- when dp_left =>
- left(15 downto 8) <= "00000000";
- left(7 downto 0) <= dp;
- when accd_left =>
- left(15 downto 8) <= acca;
- left(7 downto 0) <= accb;
- when md_left =>
- left <= md;
- when ix_left =>
- left <= xreg;
- when iy_left =>
- left <= yreg;
- when sp_left =>
- left <= sp;
- when up_left =>
- left <= up;
- when pc_left =>
- left <= pc;
- when others =>
--- when ea_left =>
- left <= ea;
- end case;
-end process;
-
-----------------------------------
---
--- Right Mux
---
-----------------------------------
-
-right_mux: process( right_ctrl, md, acca, accb, ea )
-begin
- case right_ctrl is
- when ea_right =>
- right <= ea;
- when zero_right =>
- right <= "0000000000000000";
- when one_right =>
- right <= "0000000000000001";
- when two_right =>
- right <= "0000000000000010";
- when acca_right =>
- if acca(7) = '0' then
- right <= "00000000" & acca(7 downto 0);
- else
- right <= "11111111" & acca(7 downto 0);
- end if;
- when accb_right =>
- if accb(7) = '0' then
- right <= "00000000" & accb(7 downto 0);
- else
- right <= "11111111" & accb(7 downto 0);
- end if;
- when accd_right =>
- right <= acca & accb;
- when md_sign5_right =>
- if md(4) = '0' then
- right <= "00000000000" & md(4 downto 0);
- else
- right <= "11111111111" & md(4 downto 0);
- end if;
- when md_sign8_right =>
- if md(7) = '0' then
- right <= "00000000" & md(7 downto 0);
- else
- right <= "11111111" & md(7 downto 0);
- end if;
- when others =>
--- when md_right =>
- right <= md;
- end case;
-end process;
-
-----------------------------------
---
--- Arithmetic Logic Unit
---
-----------------------------------
-
-alu: process( alu_ctrl, cc, left, right, out_alu, cc_out )
-variable valid_lo, valid_hi : boolean;
-variable carry_in : std_logic;
-variable daa_reg : std_logic_vector(7 downto 0);
-begin
-
- case alu_ctrl is
- when alu_adc | alu_sbc |
- alu_rol8 | alu_ror8 =>
- carry_in := cc(CBIT);
- when alu_asr8 =>
- carry_in := left(7);
- when others =>
- carry_in := '0';
- end case;
-
- valid_lo := left(3 downto 0) <= 9;
- valid_hi := left(7 downto 4) <= 9;
-
- --
- -- CBIT HBIT VHI VLO DAA
- -- 0 0 0 0 66 (!VHI : hi_nybble>8)
- -- 0 0 0 1 60
- -- 0 0 1 1 00
- -- 0 0 1 0 06 ( VHI : hi_nybble<=8)
- --
- -- 0 1 1 0 06
- -- 0 1 1 1 06
- -- 0 1 0 1 66
- -- 0 1 0 0 66
- --
- -- 1 1 0 0 66
- -- 1 1 0 1 66
- -- 1 1 1 1 66
- -- 1 1 1 0 66
- --
- -- 1 0 1 0 66
- -- 1 0 1 1 60
- -- 1 0 0 1 60
- -- 1 0 0 0 66
- --
- -- 66 = (!VHI & !VLO) + (CBIT & HBIT) + (HBIT & !VHI) + (CBIT & !VLO)
- -- = (CBIT & (HBIT + !VLO)) + (!VHI & (HBIT + !VLO))
- -- = (!VLO & (CBIT + !VHI)) + (HBIT & (CBIT + !VHI))
- -- 60 = (CBIT & !HBIT & VLO) + (!HBIT & !VHI & VLO)
- -- = (!HBIT & VLO & (CBIT + !VHI))
- -- 06 = (!CBIT & VHI & (!VLO + VHI)
- -- 00 = (!CBIT & !HBIT & VHI & VLO)
- --
- if (cc(CBIT) = '0') then
- -- CBIT=0
- if( cc(HBIT) = '0' ) then
- -- HBIT=0
- if valid_lo then
- -- lo <= 9 (no overflow in low nybble)
- if valid_hi then
- -- hi <= 9 (no overflow in either low or high nybble)
- daa_reg := "00000000";
- else
- -- hi > 9 (overflow in high nybble only)
- daa_reg := "01100000";
- end if;
- else
- -- lo > 9 (overflow in low nybble)
- --
- -- since there is already an overflow in the low nybble
- -- you need to make room in the high nybble for the low nybble carry
- -- so compare the high nybble with 8 rather than 9
- -- if the high nybble is 9 there will be an overflow on the high nybble
- -- after the decimal adjust which means it will roll over to an invalid BCD digit
- --
- if( left(7 downto 4) <= 8 ) then
- -- hi <= 8 (overflow in low nybble only)
- daa_reg := "00000110";
- else
- -- hi > 8 (overflow in low and high nybble)
- daa_reg := "01100110";
- end if;
- end if;
- else
- -- HBIT=1 (overflow in low nybble)
- if valid_hi then
- -- hi <= 9 (overflow in low nybble only)
- daa_reg := "00000110";
- else
- -- hi > 9 (overflow in low and high nybble)
- daa_reg := "01100110";
- end if;
- end if;
- else
- -- CBIT=1 (carry => overflow in high nybble)
- if ( cc(HBIT) = '0' )then
- -- HBIT=0 (half carry clear => may or may not be an overflow in the low nybble)
- if valid_lo then
- -- lo <=9 (overflow in high nybble only)
- daa_reg := "01100000";
- else
- -- lo >9 (overflow in low and high nybble)
- daa_reg := "01100110";
- end if;
- else
- -- HBIT=1 (overflow in low and high nybble)
- daa_reg := "01100110";
- end if;
- end if;
-
- case alu_ctrl is
- when alu_add8 | alu_inc |
- alu_add16 | alu_adc | alu_mul =>
- out_alu <= left + right + ("000000000000000" & carry_in);
- when alu_sub8 | alu_dec |
- alu_sub16 | alu_sbc =>
- out_alu <= left - right - ("000000000000000" & carry_in);
- when alu_abx =>
- out_alu <= left + ("00000000" & right(7 downto 0)) ;
- 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 =>
- out_alu <= carry_in & left(15 downto 1); -- lsr16
- when alu_lsr8 | alu_asr8 | alu_ror8 =>
- out_alu <= "00000000" & carry_in & left(7 downto 1); -- ror8/asr8/lsr8
- when alu_neg =>
- out_alu <= right - left; -- neg (right=0)
- when alu_com =>
- out_alu <= not left;
- when alu_clr | alu_ld8 | alu_ld16 | alu_lea =>
- out_alu <= right; -- clr, ld
- when alu_st8 | alu_st16 | alu_andcc | alu_orcc | alu_tfr =>
- out_alu <= left;
- when alu_daa =>
- out_alu <= left + ("00000000" & daa_reg);
- when alu_sex =>
- if left(7) = '0' then
- out_alu <= "00000000" & left(7 downto 0);
- else
- out_alu <= "11111111" & left(7 downto 0);
- end if;
- when others =>
- out_alu <= left; -- nop
- 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_mul =>
- cc_out(CBIT) <= out_alu(7);
- when alu_daa =>
- if ( daa_reg(7 downto 4) = "0110" ) then
- cc_out(CBIT) <= '1';
- else
- cc_out(CBIT) <= '0';
- end if;
- when alu_andcc =>
- cc_out(CBIT) <= left(CBIT) and cc(CBIT);
- when alu_orcc =>
- cc_out(CBIT) <= left(CBIT) or cc(CBIT);
- when alu_tfr =>
- cc_out(CBIT) <= left(CBIT);
- when others =>
- cc_out(CBIT) <= cc(CBIT);
- end case;
- --
- -- Zero flag
- --
- case alu_ctrl is
- when alu_add8 | alu_sub8 |
- alu_adc | alu_sbc |
- alu_and | alu_ora | alu_eor |
- alu_inc | alu_dec |
- alu_neg | alu_com | alu_clr |
- alu_rol8 | alu_ror8 | alu_asr8 | alu_asl8 | alu_lsr8 |
- alu_ld8 | alu_st8 | alu_sex | alu_daa =>
- 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_mul |
- alu_lsl16 | alu_lsr16 |
- alu_ld16 | alu_st16 | alu_lea =>
- cc_out(ZBIT) <= not( out_alu(15) or out_alu(14) or out_alu(13) or out_alu(12) or
- out_alu(11) or out_alu(10) or out_alu(9) or out_alu(8) or
- out_alu(7) or out_alu(6) or out_alu(5) or out_alu(4) or
- out_alu(3) or out_alu(2) or out_alu(1) or out_alu(0) );
- when alu_andcc =>
- cc_out(ZBIT) <= left(ZBIT) and cc(ZBIT);
- when alu_orcc =>
- cc_out(ZBIT) <= left(ZBIT) or cc(ZBIT);
- when alu_tfr =>
- cc_out(ZBIT) <= left(ZBIT);
- when others =>
- cc_out(ZBIT) <= cc(ZBIT);
- end case;
-
- --
- -- negative flag
- --
- case alu_ctrl is
- when alu_add8 | alu_sub8 |
- alu_adc | alu_sbc |
- alu_and | alu_ora | alu_eor |
- alu_rol8 | alu_ror8 | alu_asr8 | alu_asl8 | alu_lsr8 |
- alu_inc | alu_dec | alu_neg | alu_com | alu_clr |
- alu_ld8 | alu_st8 | alu_sex | alu_daa =>
- cc_out(NBIT) <= out_alu(7);
- when alu_add16 | alu_sub16 |
- alu_lsl16 | alu_lsr16 |
- alu_ld16 | alu_st16 =>
- cc_out(NBIT) <= out_alu(15);
- when alu_andcc =>
- cc_out(NBIT) <= left(NBIT) and cc(NBIT);
- when alu_orcc =>
- cc_out(NBIT) <= left(NBIT) or cc(NBIT);
- when alu_tfr =>
- cc_out(NBIT) <= left(NBIT);
- when others =>
- cc_out(NBIT) <= cc(NBIT);
- end case;
-
- --
- -- Interrupt mask flag
- --
- case alu_ctrl is
- when alu_andcc =>
- cc_out(IBIT) <= left(IBIT) and cc(IBIT);
- when alu_orcc =>
- cc_out(IBIT) <= left(IBIT) or cc(IBIT);
- when alu_tfr =>
- cc_out(IBIT) <= left(IBIT);
- when alu_seif | alu_sei =>
- cc_out(IBIT) <= '1';
- when others =>
- cc_out(IBIT) <= cc(IBIT); -- interrupt mask
- end case;
-
- --
- -- Half Carry flag
- --
- case alu_ctrl is
- when alu_add8 | alu_adc =>
- cc_out(HBIT) <= (left(3) and right(3)) or
- (right(3) and not out_alu(3)) or
- (left(3) and not out_alu(3));
- when alu_andcc =>
- cc_out(HBIT) <= left(HBIT) and cc(HBIT);
- when alu_orcc =>
- cc_out(HBIT) <= left(HBIT) or cc(HBIT);
- when alu_tfr =>
- cc_out(HBIT) <= left(HBIT);
- when others =>
- cc_out(HBIT) <= cc(HBIT);
- end case;
-
- --
- -- Overflow flag
- --
- case alu_ctrl is
- when alu_add8 | alu_adc =>
- cc_out(VBIT) <= (left(7) and right(7) and (not out_alu(7))) or
- ((not left(7)) and (not right(7)) and out_alu(7));
- when alu_sub8 | alu_sbc =>
- cc_out(VBIT) <= (left(7) and (not right(7)) and (not out_alu(7))) or
- ((not left(7)) and right(7) and out_alu(7));
- when alu_add16 =>
- cc_out(VBIT) <= (left(15) and right(15) and (not out_alu(15))) or
- ((not left(15)) and (not right(15)) and out_alu(15));
- when alu_sub16 =>
- cc_out(VBIT) <= (left(15) and (not right(15)) and (not out_alu(15))) or
- ((not left(15)) and right(15) and out_alu(15));
- when alu_inc =>
- cc_out(VBIT) <= ((not left(7)) and left(6) and left(5) and left(4) and
- left(3) and left(2) and left(1) and left(0));
- when alu_dec | alu_neg =>
- cc_out(VBIT) <= (left(7) and (not left(6)) and (not left(5)) and (not left(4)) and
- (not left(3)) and (not left(2)) and (not left(1)) and (not left(0)));
--- 6809 Programming reference manual says
--- V not affected by ASR, LSR and ROR
--- This is different to the 6800
--- John Kent 6th June 2006
--- 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);
---
--- 11th July 2006 - John Kent
--- What DAA does with V is anyones guess
--- It is undefined in the 6809 programming manual
---
- when alu_daa =>
- cc_out(VBIT) <= left(7) xor out_alu(7) xor cc(CBIT);
--- CLR resets V Bit
--- John Kent 6th June 2006
- when alu_and | alu_ora | alu_eor | alu_com | alu_clr |
- alu_st8 | alu_st16 | alu_ld8 | alu_ld16 | alu_sex =>
- cc_out(VBIT) <= '0';
- when alu_andcc =>
- cc_out(VBIT) <= left(VBIT) and cc(VBIT);
- when alu_orcc =>
- cc_out(VBIT) <= left(VBIT) or cc(VBIT);
- when alu_tfr =>
- cc_out(VBIT) <= left(VBIT);
- when others =>
- cc_out(VBIT) <= cc(VBIT);
- end case;
-
- case alu_ctrl is
- when alu_andcc =>
- cc_out(FBIT) <= left(FBIT) and cc(FBIT);
- when alu_orcc =>
- cc_out(FBIT) <= left(FBIT) or cc(FBIT);
- when alu_tfr =>
- cc_out(FBIT) <= left(FBIT);
- when alu_seif =>
- cc_out(FBIT) <= '1';
- when others =>
- cc_out(FBIT) <= cc(FBIT);
- end case;
-
- case alu_ctrl is
- when alu_andcc =>
- cc_out(EBIT) <= left(EBIT) and cc(EBIT);
- when alu_orcc =>
- cc_out(EBIT) <= left(EBIT) or cc(EBIT);
- when alu_tfr =>
- cc_out(EBIT) <= left(EBIT);
- when alu_see =>
- cc_out(EBIT) <= '1';
- when alu_cle =>
- cc_out(EBIT) <= '0';
- when others =>
- cc_out(EBIT) <= cc(EBIT);
- end case;
-end process;
-
-------------------------------------
---
--- state sequencer
---
-------------------------------------
-process( state, saved_state,
- op_code, pre_code,
- cc, ea, md, iv, fic, halt,
- nmi_req, firq, irq, lic )
-variable cond_true : boolean; -- variable used to evaluate coditional branches
-begin
- cond_true := (1=1);
- ba <= '0';
- bs <= '0';
- lic <= '0';
- opfetch <= '0';
- iv_ctrl <= latch_iv;
- -- Registers preserved
- cc_ctrl <= latch_cc;
- acca_ctrl <= latch_acca;
- accb_ctrl <= latch_accb;
- dp_ctrl <= latch_dp;
- ix_ctrl <= latch_ix;
- iy_ctrl <= latch_iy;
- up_ctrl <= latch_up;
- sp_ctrl <= latch_sp;
- pc_ctrl <= latch_pc;
- md_ctrl <= latch_md;
- ea_ctrl <= latch_ea;
- op_ctrl <= latch_op;
- pre_ctrl <= latch_pre;
- -- ALU Idle
- left_ctrl <= pc_left;
- right_ctrl <= zero_right;
- alu_ctrl <= alu_nop;
- -- Bus idle
- addr_ctrl <= idle_ad;
- dout_ctrl <= cc_dout;
- -- Next State Fetch
- st_ctrl <= idle_st;
- return_state <= fetch_state;
- next_state <= fetch_state;
-
- case state is
- when reset_state => -- released from reset
- -- reset the registers
- iv_ctrl <= reset_iv;
- op_ctrl <= reset_op;
- pre_ctrl <= reset_pre;
- cc_ctrl <= reset_cc;
- acca_ctrl <= reset_acca;
- accb_ctrl <= reset_accb;
- dp_ctrl <= reset_dp;
- ix_ctrl <= reset_ix;
- iy_ctrl <= reset_iy;
- up_ctrl <= reset_up;
- sp_ctrl <= reset_sp;
- pc_ctrl <= reset_pc;
- ea_ctrl <= reset_ea;
- md_ctrl <= reset_md;
- st_ctrl <= reset_st;
- next_state <= vect_hi_state;
-
- --
- -- Jump via interrupt vector
- -- iv holds interrupt type
- -- fetch PC hi from vector location
- --
- when vect_hi_state =>
- -- fetch pc low interrupt vector
- pc_ctrl <= pull_hi_pc;
- addr_ctrl <= int_hi_ad;
- bs <= '1';
- next_state <= vect_lo_state;
-
- --
- -- jump via interrupt vector
- -- iv holds vector type
- -- fetch PC lo from vector location
- --
- when vect_lo_state =>
- -- fetch the vector low byte
- pc_ctrl <= pull_lo_pc;
- addr_ctrl <= int_lo_ad;
- bs <= '1';
- next_state <= fetch_state;
-
- when vect_idle_state =>
- --
- -- Last Instruction Cycle for SWI, SWI2 & SWI3
- --
- if op_code = "00111111" then
- lic <= '1';
- end if;
- next_state <= fetch_state;
-
- --
- -- Here to fetch an instruction
- -- PC points to opcode
- --
- when fetch_state =>
- -- fetch the op code
- opfetch <= '1';
- op_ctrl <= fetch_op;
- pre_ctrl <= fetch_pre;
- ea_ctrl <= reset_ea;
- -- Fetch op code
- addr_ctrl <= fetch_ad;
- -- Advance the PC to fetch next instruction byte
- pc_ctrl <= incr_pc;
- next_state <= decode1_state;
-
- --
- -- Here to decode instruction
- -- and fetch next byte of intruction
- -- whether it be necessary or not
- --
- when decode1_state =>
- -- fetch first byte of address or immediate data
- ea_ctrl <= fetch_first_ea;
- md_ctrl <= fetch_first_md;
- addr_ctrl <= fetch_ad;
- case op_code(7 downto 4) is
- --
- -- direct single op (2 bytes)
- -- 6809 => 6 cycles
- -- cpu09 => 5 cycles
- -- 1 op=(pc) / pc=pc+1
- -- 2 ea_hi=dp / ea_lo=(pc) / pc=pc+1
- -- 3 md_lo=(ea) / pc=pc
- -- 4 alu_left=md / md=alu_out / pc=pc
- -- 5 (ea)=md_lo / pc=pc
- --
- -- Exception is JMP
- -- 6809 => 3 cycles
- -- cpu09 => 3 cycles
- -- 1 op=(pc) / pc=pc+1
- -- 2 ea_hi=dp / ea_lo=(pc) / pc=pc+1
- -- 3 pc=ea
- --
- when "0000" =>
- -- advance the PC
- pc_ctrl <= incr_pc;
-
- case op_code(3 downto 0) is
- when "1110" => -- jmp
- next_state <= jmp_state;
-
- when "1111" => -- clr
- next_state <= single_op_exec_state;
-
- when others =>
- next_state <= single_op_read_state;
-
- end case;
-
- -- acca / accb inherent instructions
- when "0001" =>
- case op_code(3 downto 0) is
- --
- -- Page2 pre byte
- -- pre=(pc) / pc=pc+1
- -- op=(pc) / pc=pc+1
- --
- when "0000" => -- page2
- opfetch <= '1';
- op_ctrl <= fetch_op;
- -- advance pc
- pc_ctrl <= incr_pc;
- next_state <= decode2_state;
-
- --
- -- Page3 pre byte
- -- pre=(pc) / pc=pc+1
- -- op=(pc) / pc=pc+1
- --
- when "0001" => -- page3
- opfetch <= '1';
- op_ctrl <= fetch_op;
- -- advance pc
- pc_ctrl <= incr_pc;
- next_state <= decode3_state;
-
- --
- -- nop - No operation ( 1 byte )
- -- 6809 => 2 cycles
- -- cpu09 => 2 cycles
- -- 1 op=(pc) / pc=pc+1
- -- 2 decode
- --
- when "0010" => -- nop
- lic <= '1';
- next_state <= fetch_state;
-
- --
- -- sync - halt execution until an interrupt is received
- -- interrupt may be NMI, IRQ or FIRQ
- -- program execution continues if the
- -- interrupt is asserted for 3 clock cycles
- -- note that registers are not pushed onto the stack
- -- CPU09 => Interrupts need only be asserted for one clock cycle
- --
- when "0011" => -- sync
- next_state <= sync_state;
-
- --
- -- lbra -- long branch (3 bytes)
- -- 6809 => 5 cycles
- -- cpu09 => 4 cycles
- -- 1 op=(pc) / pc=pc+1
- -- 2 md_hi=sign(pc) / md_lo=(pc) / pc=pc+1
- -- 3 md_hi=md_lo / md_lo=(pc) / pc=pc+1
- -- 4 pc=pc+md
- --
- when "0110" =>
- -- increment the pc
- pc_ctrl <= incr_pc;
- next_state <= lbranch_state;
-
- --
- -- lbsr - long branch to subroutine (3 bytes)
- -- 6809 => 9 cycles
- -- cpu09 => 6 cycles
- -- 1 op=(pc) /pc=pc+1
- -- 2 md_hi=sign(pc) / md_lo=(pc) / pc=pc+1 / sp=sp-1
- -- 3 md_hi=md_lo / md_lo=(pc) / pc=pc+1
- -- 4 (sp)= pc_lo / sp=sp-1 / pc=pc
- -- 5 (sp)=pc_hi / pc=pc
- -- 6 pc=pc+md
- --
- when "0111" =>
- -- pre decrement sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- sp_ctrl <= load_sp;
- -- increment the pc
- pc_ctrl <= incr_pc;
- next_state <= lbranch_state;
-
- --
- -- Decimal Adjust Accumulator
- --
- when "1001" => -- daa
- left_ctrl <= acca_left;
- right_ctrl <= accb_right;
- alu_ctrl <= alu_daa;
- cc_ctrl <= load_cc;
- acca_ctrl <= load_acca;
- lic <= '1';
- next_state <= fetch_state;
-
- --
- -- OR Condition Codes
- --
- when "1010" => -- orcc
- -- increment the pc
- pc_ctrl <= incr_pc;
- next_state <= orcc_state;
-
- --
- -- AND Condition Codes
- --
- when "1100" => -- andcc
- -- increment the pc
- pc_ctrl <= incr_pc;
- next_state <= andcc_state;
-
- --
- -- Sign Extend
- --
- when "1101" => -- sex
- left_ctrl <= accb_left;
- right_ctrl <= zero_right;
- alu_ctrl <= alu_sex;
- cc_ctrl <= load_cc;
- acca_ctrl <= load_hi_acca;
- lic <= '1';
- next_state <= fetch_state;
-
- --
- -- Exchange Registers
- --
- when "1110" => -- exg
- -- increment the pc
- pc_ctrl <= incr_pc;
- next_state <= exg_state;
-
- --
- -- Transfer Registers
- --
- when "1111" => -- tfr
- -- increment the pc
- pc_ctrl <= incr_pc;
- next_state <= tfr_state;
-
- when others =>
- -- increment the pc
- pc_ctrl <= incr_pc;
- lic <= '1';
- next_state <= fetch_state;
- end case;
-
- --
- -- Short branch conditional
- -- 6809 => always 3 cycles
- -- cpu09 => always = 3 cycles
- -- 1 op=(pc) / pc=pc+1
- -- 2 md_hi=sign(pc) / md_lo=(pc) / pc=pc+1 / test cc
- -- 3 if cc tru pc=pc+md else pc=pc
- --
- when "0010" => -- branch conditional
- -- increment the pc
- pc_ctrl <= incr_pc;
- next_state <= sbranch_state;
-
- --
- -- Single byte stack operators
- -- Do not advance PC
- --
- when "0011" =>
- --
- -- lea - load effective address (2+ bytes)
- -- 6809 => 4 cycles + addressing mode
- -- cpu09 => 4 cycles + addressing mode
- -- 1 op=(pc) / pc=pc+1
- -- 2 md_lo=(pc) / pc=pc+1
- -- 3 calculate ea
- -- 4 ix/iy/sp/up = ea
- --
- case op_code(3 downto 0) is
- when "0000" | -- leax
- "0001" | -- leay
- "0010" | -- leas
- "0011" => -- leau
- -- advance PC
- pc_ctrl <= incr_pc;
- st_ctrl <= push_st;
- return_state <= lea_state;
- next_state <= indexed_state;
-
- --
- -- pshs - push registers onto sp stack
- -- 6809 => 5 cycles + registers
- -- cpu09 => 3 cycles + registers
- -- 1 op=(pc) / pc=pc+1
- -- 2 ea_lo=(pc) / pc=pc+1
- -- 3 if ea(7 downto 0) != "00000000" then sp=sp-1
- -- 4 if ea(7) = 1 (sp)=pcl, sp=sp-1
- -- 5 if ea(7) = 1 (sp)=pch
- -- if ea(6 downto 0) != "0000000" then sp=sp-1
- -- 6 if ea(6) = 1 (sp)=upl, sp=sp-1
- -- 7 if ea(6) = 1 (sp)=uph
- -- if ea(5 downto 0) != "000000" then sp=sp-1
- -- 8 if ea(5) = 1 (sp)=iyl, sp=sp-1
- -- 9 if ea(5) = 1 (sp)=iyh
- -- if ea(4 downto 0) != "00000" then sp=sp-1
- -- 10 if ea(4) = 1 (sp)=ixl, sp=sp-1
- -- 11 if ea(4) = 1 (sp)=ixh
- -- if ea(3 downto 0) != "0000" then sp=sp-1
- -- 12 if ea(3) = 1 (sp)=dp
- -- if ea(2 downto 0) != "000" then sp=sp-1
- -- 13 if ea(2) = 1 (sp)=accb
- -- if ea(1 downto 0) != "00" then sp=sp-1
- -- 14 if ea(1) = 1 (sp)=acca
- -- if ea(0 downto 0) != "0" then sp=sp-1
- -- 15 if ea(0) = 1 (sp)=cc
- --
- when "0100" => -- pshs
- -- advance PC
- pc_ctrl <= incr_pc;
- next_state <= pshs_state;
-
- --
- -- puls - pull registers of sp stack
- -- 6809 => 5 cycles + registers
- -- cpu09 => 3 cycles + registers
- --
- when "0101" => -- puls
- -- advance PC
- pc_ctrl <= incr_pc;
- next_state <= puls_state;
-
- --
- -- pshu - push registers onto up stack
- -- 6809 => 5 cycles + registers
- -- cpu09 => 3 cycles + registers
- --
- when "0110" => -- pshu
- -- advance PC
- pc_ctrl <= incr_pc;
- next_state <= pshu_state;
-
- --
- -- pulu - pull registers of up stack
- -- 6809 => 5 cycles + registers
- -- cpu09 => 3 cycles + registers
- --
- when "0111" => -- pulu
- -- advance PC
- pc_ctrl <= incr_pc;
- next_state <= pulu_state;
-
- --
- -- rts - return from subroutine
- -- 6809 => 5 cycles
- -- cpu09 => 4 cycles
- -- 1 op=(pc) / pc=pc+1
- -- 2 decode op
- -- 3 pc_hi = (sp) / sp=sp+1
- -- 4 pc_lo = (sp) / sp=sp+1
- --
- when "1001" =>
- next_state <= pull_return_hi_state;
-
- --
- -- ADD accb to index register
- -- *** Note: this is an unsigned addition.
- -- does not affect any condition codes
- -- 6809 => 3 cycles
- -- cpu09 => 2 cycles
- -- 1 op=(pc) / pc=pc+1
- -- 2 alu_left=ix / alu_right=accb / ix=alu_out / pc=pc
- --
- when "1010" => -- abx
- lic <= '1';
- left_ctrl <= ix_left;
- right_ctrl <= accb_right;
- alu_ctrl <= alu_abx;
- ix_ctrl <= load_ix;
- next_state <= fetch_state;
-
- --
- -- Return From Interrupt
- --
- when "1011" => -- rti
- next_state <= rti_cc_state;
-
- --
- -- CWAI
- --
- when "1100" => -- cwai #$
- -- pre decrement sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- sp_ctrl <= load_sp;
- -- increment pc
- pc_ctrl <= incr_pc;
- next_state <= cwai_state;
-
- --
- -- MUL Multiply
- --
- when "1101" => -- mul
- next_state <= mul_state;
-
- --
- -- SWI Software Interrupt
- --
- when "1111" => -- swi
- -- predecrement SP
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- sp_ctrl <= load_sp;
- iv_ctrl <= swi_iv;
- st_ctrl <= push_st;
- return_state <= int_swimask_state;
- next_state <= int_entire_state;
-
- when others =>
- lic <= '1';
- next_state <= fetch_state;
-
- end case;
- --
- -- Accumulator A Single operand
- -- source = acca, dest = acca
- -- Do not advance PC
- -- Typically 2 cycles 1 bytes
- -- 1 opcode fetch
- -- 2 post byte fetch / instruction decode
- -- Note that there is no post byte
- -- so do not advance PC in decode cycle
- -- Re-run opcode fetch cycle after decode
- --
- when "0100" => -- acca single op
- left_ctrl <= acca_left;
- case op_code(3 downto 0) is
-
- when "0000" => -- neg
- right_ctrl <= zero_right;
- alu_ctrl <= alu_neg;
- acca_ctrl <= load_acca;
- cc_ctrl <= load_cc;
-
- when "0011" => -- com
- right_ctrl <= zero_right;
- alu_ctrl <= alu_com;
- acca_ctrl <= load_acca;
- cc_ctrl <= load_cc;
-
- when "0100" => -- lsr
- right_ctrl <= zero_right;
- alu_ctrl <= alu_lsr8;
- acca_ctrl <= load_acca;
- cc_ctrl <= load_cc;
-
- when "0110" => -- ror
- right_ctrl <= zero_right;
- alu_ctrl <= alu_ror8;
- acca_ctrl <= load_acca;
- cc_ctrl <= load_cc;
-
- when "0111" => -- asr
- right_ctrl <= zero_right;
- alu_ctrl <= alu_asr8;
- acca_ctrl <= load_acca;
- cc_ctrl <= load_cc;
-
- when "1000" => -- asl
- right_ctrl <= zero_right;
- alu_ctrl <= alu_asl8;
- acca_ctrl <= load_acca;
- cc_ctrl <= load_cc;
-
- when "1001" => -- rol
- right_ctrl <= zero_right;
- alu_ctrl <= alu_rol8;
- acca_ctrl <= load_acca;
- cc_ctrl <= load_cc;
-
- when "1010" => -- dec
- right_ctrl <= one_right;
- alu_ctrl <= alu_dec;
- acca_ctrl <= load_acca;
- cc_ctrl <= load_cc;
-
- when "1011" => -- undefined
- right_ctrl <= zero_right;
- alu_ctrl <= alu_nop;
- acca_ctrl <= latch_acca;
- cc_ctrl <= latch_cc;
-
- when "1100" => -- inc
- right_ctrl <= one_right;
- alu_ctrl <= alu_inc;
- acca_ctrl <= load_acca;
- cc_ctrl <= load_cc;
-
- when "1101" => -- tst
- right_ctrl <= zero_right;
- alu_ctrl <= alu_st8;
- acca_ctrl <= latch_acca;
- cc_ctrl <= load_cc;
-
- when "1110" => -- jmp (not defined)
- 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;
- lic <= '1';
- next_state <= fetch_state;
-
- --
- -- Single Operand accb
- -- source = accb, dest = accb
- -- Typically 2 cycles 1 bytes
- -- 1 opcode fetch
- -- 2 post byte fetch / instruction decode
- -- Note that there is no post byte
- -- so do not advance PC in decode cycle
- -- Re-run opcode fetch cycle after decode
- --
- when "0101" =>
- left_ctrl <= accb_left;
- case op_code(3 downto 0) is
- when "0000" => -- neg
- right_ctrl <= zero_right;
- alu_ctrl <= alu_neg;
- accb_ctrl <= load_accb;
- cc_ctrl <= load_cc;
-
- when "0011" => -- com
- right_ctrl <= zero_right;
- alu_ctrl <= alu_com;
- accb_ctrl <= load_accb;
- cc_ctrl <= load_cc;
-
- when "0100" => -- lsr
- right_ctrl <= zero_right;
- alu_ctrl <= alu_lsr8;
- accb_ctrl <= load_accb;
- cc_ctrl <= load_cc;
-
- when "0110" => -- ror
- right_ctrl <= zero_right;
- alu_ctrl <= alu_ror8;
- accb_ctrl <= load_accb;
- cc_ctrl <= load_cc;
-
- when "0111" => -- asr
- right_ctrl <= zero_right;
- alu_ctrl <= alu_asr8;
- accb_ctrl <= load_accb;
- cc_ctrl <= load_cc;
-
- when "1000" => -- asl
- right_ctrl <= zero_right;
- alu_ctrl <= alu_asl8;
- accb_ctrl <= load_accb;
- cc_ctrl <= load_cc;
-
- when "1001" => -- rol
- right_ctrl <= zero_right;
- alu_ctrl <= alu_rol8;
- accb_ctrl <= load_accb;
- cc_ctrl <= load_cc;
-
- when "1010" => -- dec
- right_ctrl <= one_right;
- alu_ctrl <= alu_dec;
- accb_ctrl <= load_accb;
- cc_ctrl <= load_cc;
-
- when "1011" => -- undefined
- right_ctrl <= zero_right;
- alu_ctrl <= alu_nop;
- accb_ctrl <= latch_accb;
- cc_ctrl <= latch_cc;
-
- when "1100" => -- inc
- right_ctrl <= one_right;
- alu_ctrl <= alu_inc;
- accb_ctrl <= load_accb;
- cc_ctrl <= load_cc;
-
- when "1101" => -- tst
- right_ctrl <= zero_right;
- alu_ctrl <= alu_st8;
- accb_ctrl <= latch_accb;
- cc_ctrl <= load_cc;
-
- when "1110" => -- jmp (undefined)
- 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;
- lic <= '1';
- next_state <= fetch_state;
-
- --
- -- Single operand indexed
- -- Two byte instruction so advance PC
- -- EA should hold index offset
- --
- when "0110" => -- indexed single op
- -- increment the pc
- pc_ctrl <= incr_pc;
- st_ctrl <= push_st;
-
- case op_code(3 downto 0) is
- when "1110" => -- jmp
- return_state <= jmp_state;
-
- when "1111" => -- clr
- return_state <= single_op_exec_state;
-
- when others =>
- return_state <= single_op_read_state;
-
- end case;
- 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
- -- increment PC
- pc_ctrl <= incr_pc;
- st_ctrl <= push_st;
-
- case op_code(3 downto 0) is
- when "1110" => -- jmp
- return_state <= jmp_state;
-
- when "1111" => -- clr
- return_state <= single_op_exec_state;
-
- when others =>
- return_state <= single_op_read_state;
-
- end case;
- next_state <= extended_state;
-
- when "1000" => -- acca immediate
- -- increment the pc
- pc_ctrl <= incr_pc;
-
- case op_code(3 downto 0) is
- when "0011" | -- subd #
- "1100" | -- cmpx #
- "1110" => -- ldx #
- next_state <= imm16_state;
-
- --
- -- bsr offset - Branch to subroutine (2 bytes)
- -- 6809 => 7 cycles
- -- cpu09 => 5 cycles
- -- 1 op=(pc) / pc=pc+1
- -- 2 md_hi=sign(pc) / md_lo=(pc) / sp=sp-1 / pc=pc+1
- -- 3 (sp)=pc_lo / sp=sp-1
- -- 4 (sp)=pc_hi
- -- 5 pc=pc+md
- --
- when "1101" => -- bsr
- -- pre decrement SP
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- sp_ctrl <= load_sp;
- --
- st_ctrl <= push_st;
- return_state <= sbranch_state;
- next_state <= push_return_lo_state;
-
- when others =>
- lic <= '1';
- next_state <= fetch_state;
-
- end case;
-
- when "1001" => -- acca direct
- -- increment the pc
- pc_ctrl <= incr_pc;
- case op_code(3 downto 0) is
- when "0011" | -- subd
- "1100" | -- cmpx
- "1110" => -- ldx
- next_state <= dual_op_read16_state;
-
- when "0111" => -- sta direct
- next_state <= dual_op_write8_state;
-
- --
- -- jsr direct - Jump to subroutine in direct page (2 bytes)
- -- 6809 => 7 cycles
- -- cpu09 => 5 cycles
- -- 1 op=(pc) / pc=pc+1
- -- 2 ea_hi=0 / ea_lo=(pc) / sp=sp-1 / pc=pc+1
- -- 3 (sp)=pc_lo / sp=sp-1
- -- 4 (sp)=pc_hi
- -- 5 pc=ea
- --
- when "1101" => -- jsr direct
- -- pre decrement sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- sp_ctrl <= load_sp;
- --
- st_ctrl <= push_st;
- return_state <= jmp_state;
- next_state <= push_return_lo_state;
-
-
- when "1111" => -- stx direct
- -- idle ALU
- left_ctrl <= ix_left;
- right_ctrl <= zero_right;
- alu_ctrl <= alu_nop;
- cc_ctrl <= latch_cc;
- sp_ctrl <= latch_sp;
- next_state <= dual_op_write16_state;
-
- when others =>
- next_state <= dual_op_read8_state;
-
- end case;
-
- when "1010" => -- acca indexed
- -- increment the pc
- pc_ctrl <= incr_pc;
- case op_code(3 downto 0) is
- when "0011" | -- subd
- "1100" | -- cmpx
- "1110" => -- ldx
- st_ctrl <= push_st;
- return_state <= dual_op_read16_state;
- next_state <= indexed_state;
-
- when "0111" => -- staa ,x
- st_ctrl <= push_st;
- return_state <= dual_op_write8_state;
- next_state <= indexed_state;
-
- when "1101" => -- jsr ,x
- -- DO NOT pre decrement SP
- st_ctrl <= push_st;
- return_state <= jsr_state;
- next_state <= indexed_state;
-
- when "1111" => -- stx ,x
- st_ctrl <= push_st;
- return_state <= dual_op_write16_state;
- next_state <= indexed_state;
-
- when others =>
- st_ctrl <= push_st;
- return_state <= dual_op_read8_state;
- next_state <= indexed_state;
-
- end case;
-
- when "1011" => -- acca extended
- -- increment the pc
- pc_ctrl <= incr_pc;
- case op_code(3 downto 0) is
- when "0011" | -- subd
- "1100" | -- cmpx
- "1110" => -- ldx
- st_ctrl <= push_st;
- return_state <= dual_op_read16_state;
- next_state <= extended_state;
-
- when "0111" => -- staa >
- st_ctrl <= push_st;
- return_state <= dual_op_write8_state;
- next_state <= extended_state;
-
- when "1101" => -- jsr >extended
- -- DO NOT pre decrement sp
- st_ctrl <= push_st;
- return_state <= jsr_state;
- next_state <= extended_state;
-
- when "1111" => -- stx >
- st_ctrl <= push_st;
- return_state <= dual_op_write16_state;
- next_state <= extended_state;
-
- when others =>
- st_ctrl <= push_st;
- return_state <= dual_op_read8_state;
- next_state <= extended_state;
-
- end case;
-
- when "1100" => -- accb immediate
- -- increment the pc
- pc_ctrl <= incr_pc;
- case op_code(3 downto 0) is
- when "0011" | -- addd #
- "1100" | -- ldd #
- "1110" => -- ldu #
- next_state <= imm16_state;
-
- when others =>
- lic <= '1';
- next_state <= fetch_state;
-
- end case;
-
- when "1101" => -- accb direct
- -- increment the pc
- pc_ctrl <= incr_pc;
- case op_code(3 downto 0) is
- when "0011" | -- addd
- "1100" | -- ldd
- "1110" => -- ldu
- next_state <= dual_op_read16_state;
-
- when "0111" => -- stab direct
- next_state <= dual_op_write8_state;
-
- when "1101" => -- std direct
- next_state <= dual_op_write16_state;
-
- when "1111" => -- stu direct
- next_state <= dual_op_write16_state;
-
- when others =>
- next_state <= dual_op_read8_state;
-
- end case;
-
- when "1110" => -- accb indexed
- -- increment the pc
- pc_ctrl <= incr_pc;
- case op_code(3 downto 0) is
- when "0011" | -- addd
- "1100" | -- ldd
- "1110" => -- ldu
- st_ctrl <= push_st;
- return_state <= dual_op_read16_state;
- next_state <= indexed_state;
-
- when "0111" => -- stab indexed
- st_ctrl <= push_st;
- return_state <= dual_op_write8_state;
- next_state <= indexed_state;
-
- when "1101" => -- std indexed
- st_ctrl <= push_st;
- return_state <= dual_op_write16_state;
- next_state <= indexed_state;
-
- when "1111" => -- stu indexed
- st_ctrl <= push_st;
- return_state <= dual_op_write16_state;
- next_state <= indexed_state;
-
- when others =>
- st_ctrl <= push_st;
- return_state <= dual_op_read8_state;
- next_state <= indexed_state;
-
- end case;
-
- when "1111" => -- accb extended
- -- increment the pc
- pc_ctrl <= incr_pc;
- case op_code(3 downto 0) is
- when "0011" | -- addd
- "1100" | -- ldd
- "1110" => -- ldu
- st_ctrl <= push_st;
- return_state <= dual_op_read16_state;
- next_state <= extended_state;
-
- when "0111" => -- stab extended
- st_ctrl <= push_st;
- return_state <= dual_op_write8_state;
- next_state <= extended_state;
-
- when "1101" => -- std extended
- st_ctrl <= push_st;
- return_state <= dual_op_write16_state;
- next_state <= extended_state;
-
- when "1111" => -- stu extended
- st_ctrl <= push_st;
- return_state <= dual_op_write16_state;
- next_state <= extended_state;
-
- when others =>
- st_ctrl <= push_st;
- return_state <= dual_op_read8_state;
- next_state <= extended_state;
- end case;
- --
- -- not sure why I need this
- --
- when others =>
- lic <= '1';
- next_state <= fetch_state;
- end case;
-
- --
- -- Here to decode prefix 2 instruction
- -- and fetch next byte of intruction
- -- whether it be necessary or not
- --
- when decode2_state =>
- -- fetch first byte of address or immediate data
- ea_ctrl <= fetch_first_ea;
- md_ctrl <= fetch_first_md;
- addr_ctrl <= fetch_ad;
- case op_code(7 downto 4) is
- --
- -- lbcc -- long branch conditional
- -- 6809 => branch 6 cycles, no branch 5 cycles
- -- cpu09 => always 5 cycles
- -- 1 pre=(pc) / pc=pc+1
- -- 2 op=(pc) / pc=pc+1
- -- 3 md_hi=sign(pc) / md_lo=(pc) / pc=pc+1
- -- 4 md_hi=md_lo / md_lo=(pc) / pc=pc+1
- -- 5 if cond pc=pc+md else pc=pc
- --
- when "0010" =>
- -- increment the pc
- pc_ctrl <= incr_pc;
- next_state <= lbranch_state;
-
- --
- -- Single byte stack operators
- -- Do not advance PC
- --
- when "0011" =>
- case op_code(3 downto 0) is
- when "1111" => -- swi 2
- -- predecrement sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- sp_ctrl <= load_sp;
- iv_ctrl <= swi2_iv;
- st_ctrl <= push_st;
- return_state <= vect_hi_state;
- next_state <= int_entire_state;
-
- when others =>
- lic <= '1';
- next_state <= fetch_state;
- end case;
-
- when "1000" => -- acca immediate
- -- increment the pc
- pc_ctrl <= incr_pc;
- case op_code(3 downto 0) is
- when "0011" | -- cmpd #
- "1100" | -- cmpy #
- "1110" => -- ldy #
- next_state <= imm16_state;
-
- when others =>
- lic <= '1';
- next_state <= fetch_state;
-
- end case;
-
- when "1001" => -- acca direct
- -- increment the pc
- pc_ctrl <= incr_pc;
- case op_code(3 downto 0) is
- when "0011" | -- cmpd <
- "1100" | -- cmpy <
- "1110" => -- ldy <
- next_state <= dual_op_read16_state;
-
- when "1111" => -- sty <
- next_state <= dual_op_write16_state;
-
- when others =>
- lic <= '1';
- next_state <= fetch_state;
-
- end case;
-
- when "1010" => -- acca indexed
- -- increment the pc
- pc_ctrl <= incr_pc;
- case op_code(3 downto 0) is
- when "0011" | -- cmpd ,ind
- "1100" | -- cmpy ,ind
- "1110" => -- ldy ,ind
- st_ctrl <= push_st;
- return_state <= dual_op_read16_state;
- next_state <= indexed_state;
-
- when "1111" => -- sty ,ind
- st_ctrl <= push_st;
- return_state <= dual_op_write16_state;
- next_state <= indexed_state;
-
- when others =>
- lic <= '1';
- next_state <= fetch_state;
- end case;
-
- when "1011" => -- acca extended
- -- increment the pc
- pc_ctrl <= incr_pc;
- case op_code(3 downto 0) is
- when "0011" | -- cmpd <
- "1100" | -- cmpy <
- "1110" => -- ldy <
- st_ctrl <= push_st;
- return_state <= dual_op_read16_state;
- next_state <= extended_state;
-
- when "1111" => -- sty >
- st_ctrl <= push_st;
- return_state <= dual_op_write16_state;
- next_state <= extended_state;
-
- when others =>
- lic <= '1';
- next_state <= fetch_state;
-
- end case;
-
- when "1100" => -- accb immediate
- -- increment the pc
- pc_ctrl <= incr_pc;
- case op_code(3 downto 0) is
- when "0011" | -- undef #
- "1100" | -- undef #
- "1110" => -- lds #
- next_state <= imm16_state;
-
- when others =>
- next_state <= fetch_state;
-
- end case;
-
- when "1101" => -- accb direct
- -- increment the pc
- pc_ctrl <= incr_pc;
- case op_code(3 downto 0) is
- when "0011" | -- undef <
- "1100" | -- undef <
- "1110" => -- lds <
- next_state <= dual_op_read16_state;
-
- when "1111" => -- sts <
- next_state <= dual_op_write16_state;
-
- when others =>
- lic <= '1';
- next_state <= fetch_state;
-
- end case;
-
- when "1110" => -- accb indexed
- -- increment the pc
- pc_ctrl <= incr_pc;
- case op_code(3 downto 0) is
- when "0011" | -- undef ,ind
- "1100" | -- undef ,ind
- "1110" => -- lds ,ind
- st_ctrl <= push_st;
- return_state <= dual_op_read16_state;
- next_state <= indexed_state;
-
- when "1111" => -- sts ,ind
- st_ctrl <= push_st;
- return_state <= dual_op_write16_state;
- next_state <= indexed_state;
-
- when others =>
- lic <= '1';
- next_state <= fetch_state;
-
- end case;
-
- when "1111" => -- accb extended
- -- increment the pc
- pc_ctrl <= incr_pc;
- case op_code(3 downto 0) is
- when "0011" | -- undef >
- "1100" | -- undef >
- "1110" => -- lds >
- st_ctrl <= push_st;
- return_state <= dual_op_read16_state;
- next_state <= extended_state;
-
- when "1111" => -- sts >
- st_ctrl <= push_st;
- return_state <= dual_op_write16_state;
- next_state <= extended_state;
-
- when others =>
- lic <= '1';
- next_state <= fetch_state;
- end case;
-
- when others =>
- lic <= '1';
- next_state <= fetch_state;
- end case;
- --
- -- Here to decode instruction
- -- and fetch next byte of intruction
- -- whether it be necessary or not
- --
- when decode3_state =>
- ea_ctrl <= fetch_first_ea;
- md_ctrl <= fetch_first_md;
- addr_ctrl <= fetch_ad;
- dout_ctrl <= md_lo_dout;
- case op_code(7 downto 4) is
- --
- -- Single byte stack operators
- -- Do not advance PC
- --
- when "0011" =>
- case op_code(3 downto 0) is
- when "1111" => -- swi3
- -- predecrement sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- sp_ctrl <= load_sp;
- iv_ctrl <= swi3_iv;
- st_ctrl <= push_st;
- return_state <= vect_hi_state;
- next_state <= int_entire_state;
- when others =>
- lic <= '1';
- next_state <= fetch_state;
- end case;
-
- when "1000" => -- acca immediate
- -- increment the pc
- pc_ctrl <= incr_pc;
- case op_code(3 downto 0) is
- when "0011" | -- cmpu #
- "1100" | -- cmps #
- "1110" => -- undef #
- next_state <= imm16_state;
- when others =>
- lic <= '1';
- next_state <= fetch_state;
- end case;
-
- when "1001" => -- acca direct
- -- increment the pc
- pc_ctrl <= incr_pc;
- case op_code(3 downto 0) is
- when "0011" | -- cmpu <
- "1100" | -- cmps <
- "1110" => -- undef <
- next_state <= dual_op_read16_state;
-
- when others =>
- lic <= '1';
- next_state <= fetch_state;
-
- end case;
-
- when "1010" => -- acca indexed
- -- increment the pc
- pc_ctrl <= incr_pc;
- case op_code(3 downto 0) is
- when "0011" | -- cmpu ,X
- "1100" | -- cmps ,X
- "1110" => -- undef ,X
- st_ctrl <= push_st;
- return_state <= dual_op_read16_state;
- next_state <= indexed_state;
-
- when others =>
- lic <= '1';
- next_state <= fetch_state;
-
- end case;
-
- when "1011" => -- acca extended
- -- increment the pc
- pc_ctrl <= incr_pc;
- case op_code(3 downto 0) is
- when "0011" | -- cmpu >
- "1100" | -- cmps >
- "1110" => -- undef >
- st_ctrl <= push_st;
- return_state <= dual_op_read16_state;
- next_state <= extended_state;
- when others =>
- lic <= '1';
- next_state <= fetch_state;
- end case;
-
- when others =>
- lic <= '1';
- next_state <= fetch_state;
- end case;
-
- --
- -- here if ea holds low byte
- -- Direct
- -- Extended
- -- Indexed
- -- read memory location
- --
- when single_op_read_state =>
- -- read memory into md
- md_ctrl <= fetch_first_md;
- addr_ctrl <= read_ad;
- dout_ctrl <= md_lo_dout;
- next_state <= single_op_exec_state;
-
- when single_op_exec_state =>
- case op_code(3 downto 0) is
- when "0000" => -- neg
- left_ctrl <= md_left;
- right_ctrl <= zero_right;
- alu_ctrl <= alu_neg;
- cc_ctrl <= load_cc;
- md_ctrl <= load_md;
- next_state <= single_op_write_state;
- when "0011" => -- com
- left_ctrl <= md_left;
- right_ctrl <= zero_right;
- alu_ctrl <= alu_com;
- cc_ctrl <= load_cc;
- md_ctrl <= load_md;
- next_state <= single_op_write_state;
- when "0100" => -- lsr
- left_ctrl <= md_left;
- right_ctrl <= zero_right;
- alu_ctrl <= alu_lsr8;
- cc_ctrl <= load_cc;
- md_ctrl <= load_md;
- next_state <= single_op_write_state;
- when "0110" => -- ror
- left_ctrl <= md_left;
- right_ctrl <= zero_right;
- alu_ctrl <= alu_ror8;
- cc_ctrl <= load_cc;
- md_ctrl <= load_md;
- next_state <= single_op_write_state;
- when "0111" => -- asr
- left_ctrl <= md_left;
- right_ctrl <= zero_right;
- alu_ctrl <= alu_asr8;
- cc_ctrl <= load_cc;
- md_ctrl <= load_md;
- next_state <= single_op_write_state;
- when "1000" => -- asl
- left_ctrl <= md_left;
- right_ctrl <= zero_right;
- alu_ctrl <= alu_asl8;
- cc_ctrl <= load_cc;
- md_ctrl <= load_md;
- next_state <= single_op_write_state;
- when "1001" => -- rol
- left_ctrl <= md_left;
- right_ctrl <= zero_right;
- alu_ctrl <= alu_rol8;
- cc_ctrl <= load_cc;
- md_ctrl <= load_md;
- next_state <= single_op_write_state;
- when "1010" => -- dec
- left_ctrl <= md_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_dec;
- cc_ctrl <= load_cc;
- md_ctrl <= load_md;
- next_state <= single_op_write_state;
- when "1011" => -- undefined
- lic <= '1';
- next_state <= fetch_state;
- when "1100" => -- inc
- left_ctrl <= md_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_inc;
- cc_ctrl <= load_cc;
- md_ctrl <= load_md;
- next_state <= single_op_write_state;
- when "1101" => -- tst
- left_ctrl <= md_left;
- right_ctrl <= zero_right;
- alu_ctrl <= alu_st8;
- cc_ctrl <= load_cc;
- lic <= '1';
- next_state <= fetch_state;
- when "1110" => -- jmp
- left_ctrl <= md_left;
- right_ctrl <= zero_right;
- alu_ctrl <= alu_ld16;
- pc_ctrl <= load_pc;
- lic <= '1';
- next_state <= fetch_state;
- when "1111" => -- clr
- left_ctrl <= md_left;
- right_ctrl <= zero_right;
- alu_ctrl <= alu_clr;
- cc_ctrl <= load_cc;
- md_ctrl <= load_md;
- next_state <= single_op_write_state;
- when others =>
- lic <= '1';
- next_state <= fetch_state;
- end case;
- --
- -- single operand 8 bit write
- -- Write low 8 bits of ALU output
- -- EA holds address
- -- MD holds data
- --
- when single_op_write_state =>
- -- write ALU low byte output
- addr_ctrl <= write_ad;
- dout_ctrl <= md_lo_dout;
- lic <= '1';
- next_state <= fetch_state;
-
- --
- -- here if ea holds address of low byte
- -- read memory location
- --
- when dual_op_read8_state =>
- -- read first data byte from ea
- md_ctrl <= fetch_first_md;
- addr_ctrl <= read_ad;
- lic <= '1';
- next_state <= fetch_state;
-
- --
- -- Here to read a 16 bit value into MD
- -- pointed to by the EA register
- -- The first byte is read
- -- and the EA is incremented
- --
- when dual_op_read16_state =>
- -- increment the effective address
- left_ctrl <= ea_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- ea_ctrl <= load_ea;
- -- read the high byte of the 16 bit data
- md_ctrl <= fetch_first_md;
- addr_ctrl <= read_ad;
- next_state <= dual_op_read16_2_state;
-
- --
- -- here to read the second byte
- -- pointed to by EA into MD
- --
- when dual_op_read16_2_state =>
- -- read the low byte of the 16 bit data
- md_ctrl <= fetch_next_md;
- addr_ctrl <= read_ad;
- lic <= '1';
- next_state <= fetch_state;
-
- --
- -- 16 bit Write state
- -- EA hold address of memory to write to
- -- Advance the effective address in ALU
- -- decode op_code to determine which
- -- register to write
- --
- when dual_op_write16_state =>
- -- increment the effective address
- left_ctrl <= ea_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- ea_ctrl <= load_ea;
- -- write the ALU hi byte at ea
- addr_ctrl <= write_ad;
- if op_code(6) = '0' then
- case op_code(3 downto 0) is
- when "1111" => -- stx / sty
- case pre_code is
- when "00010000" => -- page 2 -- sty
- dout_ctrl <= iy_hi_dout;
- when others => -- page 1 -- stx
- dout_ctrl <= ix_hi_dout;
- end case;
- when others =>
- dout_ctrl <= md_hi_dout;
- end case;
- else
- case op_code(3 downto 0) is
- when "1101" => -- std
- dout_ctrl <= acca_dout; -- acca is high byte of ACCD
- when "1111" => -- stu / sts
- case pre_code is
- when "00010000" => -- page 2 -- sts
- dout_ctrl <= sp_hi_dout;
- when others => -- page 1 -- stu
- dout_ctrl <= up_hi_dout;
- end case;
- when others =>
- dout_ctrl <= md_hi_dout;
- end case;
- end if;
- next_state <= dual_op_write8_state;
-
- --
- -- Dual operand 8 bit write
- -- Write 8 bit accumulator
- -- or low byte of 16 bit register
- -- EA holds address
- -- decode opcode to determine
- -- which register to apply to the bus
- -- Also set the condition codes here
- --
- when dual_op_write8_state =>
- if op_code(6) = '0' then
- case op_code(3 downto 0) is
- when "0111" => -- sta
- dout_ctrl <= acca_dout;
- when "1111" => -- stx / sty
- case pre_code is
- when "00010000" => -- page 2 -- sty
- dout_ctrl <= iy_lo_dout;
- when others => -- page 1 -- stx
- dout_ctrl <= ix_lo_dout;
- end case;
- when others =>
- dout_ctrl <= md_lo_dout;
- end case;
- else
- case op_code(3 downto 0) is
- when "0111" => -- stb
- dout_ctrl <= accb_dout;
- when "1101" => -- std
- dout_ctrl <= accb_dout; -- accb is low byte of accd
- when "1111" => -- stu / sts
- case pre_code is
- when "00010000" => -- page 2 -- sts
- dout_ctrl <= sp_lo_dout;
- when others => -- page 1 -- stu
- dout_ctrl <= up_lo_dout;
- end case;
- when others =>
- dout_ctrl <= md_lo_dout;
- end case;
- end if;
- -- write ALU low byte output
- addr_ctrl <= write_ad;
- lic <= '1';
- next_state <= fetch_state;
-
- --
- -- 16 bit immediate addressing mode
- --
- when imm16_state =>
- -- increment pc
- pc_ctrl <= incr_pc;
- -- fetch next immediate byte
- md_ctrl <= fetch_next_md;
- addr_ctrl <= fetch_ad;
- lic <= '1';
- next_state <= fetch_state;
-
- --
- -- md & ea holds 8 bit index offset
- -- calculate the effective memory address
- -- using the alu
- --
- when indexed_state =>
- --
- -- decode indexing mode
- --
- if md(7) = '0' then
- case md(6 downto 5) is
- when "00" =>
- left_ctrl <= ix_left;
- when "01" =>
- left_ctrl <= iy_left;
- when "10" =>
- left_ctrl <= up_left;
- when others =>
- -- when "11" =>
- left_ctrl <= sp_left;
- end case;
- right_ctrl <= md_sign5_right;
- alu_ctrl <= alu_add16;
- ea_ctrl <= load_ea;
- next_state <= saved_state;
-
- else
- case md(3 downto 0) is
- when "0000" => -- ,R+
- case md(6 downto 5) is
- when "00" =>
- left_ctrl <= ix_left;
- when "01" =>
- left_ctrl <= iy_left;
- when "10" =>
- left_ctrl <= up_left;
- when others =>
- left_ctrl <= sp_left;
- end case;
- --
- right_ctrl <= zero_right;
- alu_ctrl <= alu_add16;
- ea_ctrl <= load_ea;
- next_state <= postincr1_state;
-
- when "0001" => -- ,R++
- case md(6 downto 5) is
- when "00" =>
- left_ctrl <= ix_left;
- when "01" =>
- left_ctrl <= iy_left;
- when "10" =>
- left_ctrl <= up_left;
- when others =>
- -- when "11" =>
- left_ctrl <= sp_left;
- end case;
- right_ctrl <= zero_right;
- alu_ctrl <= alu_add16;
- ea_ctrl <= load_ea;
- next_state <= postincr2_state;
-
- when "0010" => -- ,-R
- case md(6 downto 5) is
- when "00" =>
- left_ctrl <= ix_left;
- ix_ctrl <= load_ix;
- when "01" =>
- left_ctrl <= iy_left;
- iy_ctrl <= load_iy;
- when "10" =>
- left_ctrl <= up_left;
- up_ctrl <= load_up;
- when others =>
- -- when "11" =>
- left_ctrl <= sp_left;
- sp_ctrl <= load_sp;
- end case;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- ea_ctrl <= load_ea;
- next_state <= saved_state;
-
- when "0011" => -- ,--R
- case md(6 downto 5) is
- when "00" =>
- left_ctrl <= ix_left;
- ix_ctrl <= load_ix;
- when "01" =>
- left_ctrl <= iy_left;
- iy_ctrl <= load_iy;
- when "10" =>
- left_ctrl <= up_left;
- up_ctrl <= load_up;
- when others =>
- -- when "11" =>
- left_ctrl <= sp_left;
- sp_ctrl <= load_sp;
- end case;
- right_ctrl <= two_right;
- alu_ctrl <= alu_sub16;
- ea_ctrl <= load_ea;
- if md(4) = '0' then
- next_state <= saved_state;
- else
- next_state <= indirect_state;
- end if;
-
- when "0100" => -- ,R (zero offset)
- case md(6 downto 5) is
- when "00" =>
- left_ctrl <= ix_left;
- when "01" =>
- left_ctrl <= iy_left;
- when "10" =>
- left_ctrl <= up_left;
- when others =>
- -- when "11" =>
- left_ctrl <= sp_left;
- end case;
- right_ctrl <= zero_right;
- alu_ctrl <= alu_add16;
- ea_ctrl <= load_ea;
- if md(4) = '0' then
- next_state <= saved_state;
- else
- next_state <= indirect_state;
- end if;
-
- when "0101" => -- ACCB,R
- case md(6 downto 5) is
- when "00" =>
- left_ctrl <= ix_left;
- when "01" =>
- left_ctrl <= iy_left;
- when "10" =>
- left_ctrl <= up_left;
- when others =>
- -- when "11" =>
- left_ctrl <= sp_left;
- end case;
- right_ctrl <= accb_right;
- alu_ctrl <= alu_add16;
- ea_ctrl <= load_ea;
- if md(4) = '0' then
- next_state <= saved_state;
- else
- next_state <= indirect_state;
- end if;
-
- when "0110" => -- ACCA,R
- case md(6 downto 5) is
- when "00" =>
- left_ctrl <= ix_left;
- when "01" =>
- left_ctrl <= iy_left;
- when "10" =>
- left_ctrl <= up_left;
- when others =>
- -- when "11" =>
- left_ctrl <= sp_left;
- end case;
- right_ctrl <= acca_right;
- alu_ctrl <= alu_add16;
- ea_ctrl <= load_ea;
- if md(4) = '0' then
- next_state <= saved_state;
- else
- next_state <= indirect_state;
- end if;
-
- when "0111" => -- undefined
- case md(6 downto 5) is
- when "00" =>
- left_ctrl <= ix_left;
- when "01" =>
- left_ctrl <= iy_left;
- when "10" =>
- left_ctrl <= up_left;
- when others =>
- -- when "11" =>
- left_ctrl <= sp_left;
- end case;
- right_ctrl <= zero_right;
- alu_ctrl <= alu_add16;
- ea_ctrl <= load_ea;
- if md(4) = '0' then
- next_state <= saved_state;
- else
- next_state <= indirect_state;
- end if;
-
- when "1000" => -- offset8,R
- md_ctrl <= fetch_first_md; -- pick up 8 bit offset
- addr_ctrl <= fetch_ad;
- pc_ctrl <= incr_pc;
- next_state <= index8_state;
-
- when "1001" => -- offset16,R
- md_ctrl <= fetch_first_md; -- pick up first byte of 16 bit offset
- addr_ctrl <= fetch_ad;
- pc_ctrl <= incr_pc;
- next_state <= index16_state;
-
- when "1010" => -- undefined
- case md(6 downto 5) is
- when "00" =>
- left_ctrl <= ix_left;
- when "01" =>
- left_ctrl <= iy_left;
- when "10" =>
- left_ctrl <= up_left;
- when others =>
- -- when "11" =>
- left_ctrl <= sp_left;
- end case;
- right_ctrl <= zero_right;
- alu_ctrl <= alu_add16;
- ea_ctrl <= load_ea;
- --
- if md(4) = '0' then
- next_state <= saved_state;
- else
- next_state <= indirect_state;
- end if;
-
- when "1011" => -- ACCD,R
- case md(6 downto 5) is
- when "00" =>
- left_ctrl <= ix_left;
- when "01" =>
- left_ctrl <= iy_left;
- when "10" =>
- left_ctrl <= up_left;
- when others =>
- -- when "11" =>
- left_ctrl <= sp_left;
- end case;
- right_ctrl <= accd_right;
- alu_ctrl <= alu_add16;
- ea_ctrl <= load_ea;
- if md(4) = '0' then
- next_state <= saved_state;
- else
- next_state <= indirect_state;
- end if;
-
- when "1100" => -- offset8,PC
- -- fetch 8 bit offset
- md_ctrl <= fetch_first_md;
- addr_ctrl <= fetch_ad;
- pc_ctrl <= incr_pc;
- next_state <= pcrel8_state;
-
- when "1101" => -- offset16,PC
- -- fetch offset
- md_ctrl <= fetch_first_md;
- addr_ctrl <= fetch_ad;
- pc_ctrl <= incr_pc;
- next_state <= pcrel16_state;
-
- when "1110" => -- undefined
- case md(6 downto 5) is
- when "00" =>
- left_ctrl <= ix_left;
- when "01" =>
- left_ctrl <= iy_left;
- when "10" =>
- left_ctrl <= up_left;
- when others =>
- -- when "11" =>
- left_ctrl <= sp_left;
- end case;
- right_ctrl <= zero_right;
- alu_ctrl <= alu_add16;
- ea_ctrl <= load_ea;
- if md(4) = '0' then
- next_state <= saved_state;
- else
- next_state <= indirect_state;
- end if;
-
- when others =>
--- when "1111" => -- [,address]
- -- advance PC to pick up address
- md_ctrl <= fetch_first_md;
- addr_ctrl <= fetch_ad;
- pc_ctrl <= incr_pc;
- next_state <= indexaddr_state;
- end case;
- end if;
-
- -- load index register with ea plus one
- when postincr1_state =>
- left_ctrl <= ea_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- case md(6 downto 5) is
- when "00" =>
- ix_ctrl <= load_ix;
- when "01" =>
- iy_ctrl <= load_iy;
- when "10" =>
- up_ctrl <= load_up;
- when others =>
- -- when "11" =>
- sp_ctrl <= load_sp;
- end case;
- -- return to previous state
- if md(4) = '0' then
- next_state <= saved_state;
- else
- next_state <= indirect_state;
- end if;
-
- -- load index register with ea plus two
- when postincr2_state =>
- -- increment register by two (address)
- left_ctrl <= ea_left;
- right_ctrl <= two_right;
- alu_ctrl <= alu_add16;
- case md(6 downto 5) is
- when "00" =>
- ix_ctrl <= load_ix;
- when "01" =>
- iy_ctrl <= load_iy;
- when "10" =>
- up_ctrl <= load_up;
- when others =>
- -- when "11" =>
- sp_ctrl <= load_sp;
- end case;
- -- return to previous state
- if md(4) = '0' then
- next_state <= saved_state;
- else
- next_state <= indirect_state;
- end if;
- --
- -- ea = index register + md (8 bit signed offset)
- -- ea holds post byte
- --
- when index8_state =>
- case ea(6 downto 5) is
- when "00" =>
- left_ctrl <= ix_left;
- when "01" =>
- left_ctrl <= iy_left;
- when "10" =>
- left_ctrl <= up_left;
- when others =>
- -- when "11" =>
- left_ctrl <= sp_left;
- end case;
- -- ea = index reg + md
- right_ctrl <= md_sign8_right;
- alu_ctrl <= alu_add16;
- ea_ctrl <= load_ea;
- -- return to previous state
- if ea(4) = '0' then
- next_state <= saved_state;
- else
- next_state <= indirect_state;
- end if;
-
- -- fetch low byte of 16 bit indexed offset
- when index16_state =>
- -- advance pc
- pc_ctrl <= incr_pc;
- -- fetch low byte
- md_ctrl <= fetch_next_md;
- addr_ctrl <= fetch_ad;
- next_state <= index16_2_state;
-
- -- ea = index register + md (16 bit offset)
- -- ea holds post byte
- when index16_2_state =>
- case ea(6 downto 5) is
- when "00" =>
- left_ctrl <= ix_left;
- when "01" =>
- left_ctrl <= iy_left;
- when "10" =>
- left_ctrl <= up_left;
- when others =>
- -- when "11" =>
- left_ctrl <= sp_left;
- end case;
- -- ea = index reg + md
- right_ctrl <= md_right;
- alu_ctrl <= alu_add16;
- ea_ctrl <= load_ea;
- -- return to previous state
- if ea(4) = '0' then
- next_state <= saved_state;
- else
- next_state <= indirect_state;
- end if;
- --
- -- pc relative with 8 bit signed offest
- -- md holds signed offset
- --
- when pcrel8_state =>
- -- ea = pc + signed md
- left_ctrl <= pc_left;
- right_ctrl <= md_sign8_right;
- alu_ctrl <= alu_add16;
- ea_ctrl <= load_ea;
- -- return to previous state
- if ea(4) = '0' then
- next_state <= saved_state;
- else
- next_state <= indirect_state;
- end if;
-
- -- pc relative addressing with 16 bit offset
- -- pick up the low byte of the offset in md
- -- advance the pc
- when pcrel16_state =>
- -- advance pc
- pc_ctrl <= incr_pc;
- -- fetch low byte
- md_ctrl <= fetch_next_md;
- addr_ctrl <= fetch_ad;
- next_state <= pcrel16_2_state;
-
- -- pc relative with16 bit signed offest
- -- md holds signed offset
- when pcrel16_2_state =>
- -- ea = pc + md
- left_ctrl <= pc_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_add16;
- ea_ctrl <= load_ea;
- -- return to previous state
- if ea(4) = '0' then
- next_state <= saved_state;
- else
- next_state <= indirect_state;
- end if;
-
- -- indexed to address
- -- pick up the low byte of the address
- -- advance the pc
- when indexaddr_state =>
- -- advance pc
- pc_ctrl <= incr_pc;
- -- fetch low byte
- md_ctrl <= fetch_next_md;
- addr_ctrl <= fetch_ad;
- next_state <= indexaddr2_state;
-
- -- indexed to absolute address
- -- md holds address
- -- ea hold indexing mode byte
- when indexaddr2_state =>
- -- ea = md
- left_ctrl <= pc_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_ld16;
- ea_ctrl <= load_ea;
- -- return to previous state
- if ea(4) = '0' then
- next_state <= saved_state;
- else
- next_state <= indirect_state;
- end if;
-
- --
- -- load md with high byte of indirect address
- -- pointed to by ea
- -- increment ea
- --
- when indirect_state =>
- -- increment ea
- left_ctrl <= ea_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- ea_ctrl <= load_ea;
- -- fetch high byte
- md_ctrl <= fetch_first_md;
- addr_ctrl <= read_ad;
- next_state <= indirect2_state;
- --
- -- load md with low byte of indirect address
- -- pointed to by ea
- -- ea has previously been incremented
- --
- when indirect2_state =>
- -- fetch high byte
- md_ctrl <= fetch_next_md;
- addr_ctrl <= read_ad;
- dout_ctrl <= md_lo_dout;
- next_state <= indirect3_state;
- --
- -- complete idirect addressing
- -- by loading ea with md
- --
- when indirect3_state =>
- -- load ea with md
- left_ctrl <= ea_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_ld16;
- ea_ctrl <= load_ea;
- -- return to previous state
- next_state <= saved_state;
-
- --
- -- ea holds the low byte of the absolute address
- -- Move ea low byte into ea high byte
- -- load new ea low byte to for absolute 16 bit address
- -- advance the program counter
- --
- when extended_state => -- fetch ea low byte
- -- increment pc
- pc_ctrl <= incr_pc;
- -- fetch next effective address bytes
- ea_ctrl <= fetch_next_ea;
- addr_ctrl <= fetch_ad;
- -- return to previous state
- next_state <= saved_state;
-
- when lea_state => -- here on load effective address
- -- load index register with effective address
- left_ctrl <= pc_left;
- right_ctrl <= ea_right;
- alu_ctrl <= alu_lea;
- case op_code(3 downto 0) is
- when "0000" => -- leax
- cc_ctrl <= load_cc;
- ix_ctrl <= load_ix;
- when "0001" => -- leay
- cc_ctrl <= load_cc;
- iy_ctrl <= load_iy;
- when "0010" => -- leas
- sp_ctrl <= load_sp;
- when "0011" => -- leau
- up_ctrl <= load_up;
- when others =>
- null;
- end case;
- lic <= '1';
- next_state <= fetch_state;
-
- --
- -- jump to subroutine
- -- sp=sp-1
- -- call push_return_lo_state to save pc
- -- return to jmp_state
- --
- when jsr_state =>
- -- decrement sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- sp_ctrl <= load_sp;
- -- call push_return_state
- st_ctrl <= push_st;
- return_state <= jmp_state;
- next_state <= push_return_lo_state;
-
- --
- -- Load pc with ea
- -- (JMP)
- --
- when jmp_state =>
- -- load PC with effective address
- left_ctrl <= pc_left;
- right_ctrl <= ea_right;
- alu_ctrl <= alu_ld16;
- pc_ctrl <= load_pc;
- lic <= '1';
- next_state <= fetch_state;
-
- --
- -- long branch or branch to subroutine
- -- pick up next md byte
- -- md_hi = md_lo
- -- md_lo = (pc)
- -- pc=pc+1
- -- if a lbsr push return address
- -- continue to sbranch_state
- -- to evaluate conditional branches
- --
- when lbranch_state =>
- pc_ctrl <= incr_pc;
- -- fetch the next byte into md_lo
- md_ctrl <= fetch_next_md;
- addr_ctrl <= fetch_ad;
- -- if lbsr - push return address
- -- then continue on to short branch
- if op_code = "00010111" then
- st_ctrl <= push_st;
- return_state <= sbranch_state;
- next_state <= push_return_lo_state;
- else
- next_state <= sbranch_state;
- end if;
-
- --
- -- here to execute conditional branch
- -- short conditional branch md = signed 8 bit offset
- -- long branch md = 16 bit offset
- --
- when sbranch_state =>
- left_ctrl <= pc_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_add16;
- -- Test condition for branch
- if op_code(7 downto 4) = "0010" then -- conditional branch
- case op_code(3 downto 0) is
- when "0000" => -- bra
- cond_true := (1 = 1);
- when "0001" => -- brn
- cond_true := (1 = 0);
- when "0010" => -- bhi
- cond_true := ((cc(CBIT) or cc(ZBIT)) = '0');
- when "0011" => -- bls
- cond_true := ((cc(CBIT) or cc(ZBIT)) = '1');
- when "0100" => -- bcc/bhs
- cond_true := (cc(CBIT) = '0');
- when "0101" => -- bcs/blo
- cond_true := (cc(CBIT) = '1');
- when "0110" => -- bne
- cond_true := (cc(ZBIT) = '0');
- when "0111" => -- beq
- cond_true := (cc(ZBIT) = '1');
- when "1000" => -- bvc
- cond_true := (cc(VBIT) = '0');
- when "1001" => -- bvs
- cond_true := (cc(VBIT) = '1');
- when "1010" => -- bpl
- cond_true := (cc(NBIT) = '0');
- when "1011" => -- bmi
- cond_true := (cc(NBIT) = '1');
- when "1100" => -- bge
- cond_true := ((cc(NBIT) xor cc(VBIT)) = '0');
- when "1101" => -- blt
- cond_true := ((cc(NBIT) xor cc(VBIT)) = '1');
- when "1110" => -- bgt
- cond_true := ((cc(ZBIT) or (cc(NBIT) xor cc(VBIT))) = '0');
- when "1111" => -- ble
- cond_true := ((cc(ZBIT) or (cc(NBIT) xor cc(VBIT))) = '1');
- when others =>
- null;
- end case;
- end if;
- if cond_true then
- pc_ctrl <= load_pc;
- end if;
- lic <= '1';
- next_state <= fetch_state;
-
- --
- -- push return address onto the S stack
- --
- -- (sp) = pc_lo
- -- sp = sp - 1
- --
- when push_return_lo_state =>
- -- decrement the sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- sp_ctrl <= load_sp;
- -- write PC low
- addr_ctrl <= pushs_ad;
- dout_ctrl <= pc_lo_dout;
- next_state <= push_return_hi_state;
-
- --
- -- push program counter hi byte onto the stack
- -- (sp) = pc_hi
- -- sp = sp
- -- return to originating state
- --
- when push_return_hi_state =>
- -- write pc hi bytes
- addr_ctrl <= pushs_ad;
- dout_ctrl <= pc_hi_dout;
- next_state <= saved_state;
-
- --
- -- RTS pull return address from stack
- --
- when pull_return_hi_state =>
- -- increment the sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- sp_ctrl <= load_sp;
- -- read pc hi
- pc_ctrl <= pull_hi_pc;
- addr_ctrl <= pulls_ad;
- next_state <= pull_return_lo_state;
-
- when pull_return_lo_state =>
- -- increment the SP
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- sp_ctrl <= load_sp;
- -- read pc low
- pc_ctrl <= pull_lo_pc;
- addr_ctrl <= pulls_ad;
- dout_ctrl <= pc_lo_dout;
- --
- lic <= '1';
- next_state <= fetch_state;
-
- when andcc_state =>
- -- AND CC with md
- left_ctrl <= md_left;
- right_ctrl <= zero_right;
- alu_ctrl <= alu_andcc;
- cc_ctrl <= load_cc;
- --
- lic <= '1';
- next_state <= fetch_state;
-
- when orcc_state =>
- -- OR CC with md
- left_ctrl <= md_left;
- right_ctrl <= zero_right;
- alu_ctrl <= alu_orcc;
- cc_ctrl <= load_cc;
- --
- lic <= '1';
- next_state <= fetch_state;
-
- when tfr_state =>
- -- select source register
- case md(7 downto 4) is
- when "0000" =>
- left_ctrl <= accd_left;
- when "0001" =>
- left_ctrl <= ix_left;
- when "0010" =>
- left_ctrl <= iy_left;
- when "0011" =>
- left_ctrl <= up_left;
- when "0100" =>
- left_ctrl <= sp_left;
- when "0101" =>
- left_ctrl <= pc_left;
- when "1000" =>
- left_ctrl <= acca_left;
- when "1001" =>
- left_ctrl <= accb_left;
- when "1010" =>
- left_ctrl <= cc_left;
- when "1011" =>
- left_ctrl <= dp_left;
- when others =>
- left_ctrl <= md_left;
- end case;
- right_ctrl <= zero_right;
- alu_ctrl <= alu_tfr;
- -- select destination register
- case md(3 downto 0) is
- when "0000" => -- accd
- acca_ctrl <= load_hi_acca;
- accb_ctrl <= load_accb;
- when "0001" => -- ix
- ix_ctrl <= load_ix;
- when "0010" => -- iy
- iy_ctrl <= load_iy;
- when "0011" => -- up
- up_ctrl <= load_up;
- when "0100" => -- sp
- sp_ctrl <= load_sp;
- when "0101" => -- pc
- pc_ctrl <= load_pc;
- when "1000" => -- acca
- acca_ctrl <= load_acca;
- when "1001" => -- accb
- accb_ctrl <= load_accb;
- when "1010" => -- cc
- cc_ctrl <= load_cc;
- when "1011" => --dp
- dp_ctrl <= load_dp;
- when others =>
- null;
- end case;
- --
- lic <= '1';
- next_state <= fetch_state;
-
- when exg_state =>
- -- save destination register
- case md(3 downto 0) is
- when "0000" =>
- left_ctrl <= accd_left;
- when "0001" =>
- left_ctrl <= ix_left;
- when "0010" =>
- left_ctrl <= iy_left;
- when "0011" =>
- left_ctrl <= up_left;
- when "0100" =>
- left_ctrl <= sp_left;
- when "0101" =>
- left_ctrl <= pc_left;
- when "1000" =>
- left_ctrl <= acca_left;
- when "1001" =>
- left_ctrl <= accb_left;
- when "1010" =>
- left_ctrl <= cc_left;
- when "1011" =>
- left_ctrl <= dp_left;
- when others =>
- left_ctrl <= md_left;
- end case;
- right_ctrl <= zero_right;
- alu_ctrl <= alu_tfr;
- ea_ctrl <= load_ea;
- -- call tranfer microcode
- next_state <= exg1_state;
-
- when exg1_state =>
- -- select source register
- case md(7 downto 4) is
- when "0000" =>
- left_ctrl <= accd_left;
- when "0001" =>
- left_ctrl <= ix_left;
- when "0010" =>
- left_ctrl <= iy_left;
- when "0011" =>
- left_ctrl <= up_left;
- when "0100" =>
- left_ctrl <= sp_left;
- when "0101" =>
- left_ctrl <= pc_left;
- when "1000" =>
- left_ctrl <= acca_left;
- when "1001" =>
- left_ctrl <= accb_left;
- when "1010" =>
- left_ctrl <= cc_left;
- when "1011" =>
- left_ctrl <= dp_left;
- when others =>
- left_ctrl <= md_left;
- end case;
- right_ctrl <= zero_right;
- alu_ctrl <= alu_tfr;
- -- select destination register
- case md(3 downto 0) is
- when "0000" => -- accd
- acca_ctrl <= load_hi_acca;
- accb_ctrl <= load_accb;
- when "0001" => -- ix
- ix_ctrl <= load_ix;
- when "0010" => -- iy
- iy_ctrl <= load_iy;
- when "0011" => -- up
- up_ctrl <= load_up;
- when "0100" => -- sp
- sp_ctrl <= load_sp;
- when "0101" => -- pc
- pc_ctrl <= load_pc;
- when "1000" => -- acca
- acca_ctrl <= load_acca;
- when "1001" => -- accb
- accb_ctrl <= load_accb;
- when "1010" => -- cc
- cc_ctrl <= load_cc;
- when "1011" => --dp
- dp_ctrl <= load_dp;
- when others =>
- null;
- end case;
- next_state <= exg2_state;
-
- when exg2_state =>
- -- restore destination
- left_ctrl <= ea_left;
- right_ctrl <= zero_right;
- alu_ctrl <= alu_tfr;
- -- save as source register
- case md(7 downto 4) is
- when "0000" => -- accd
- acca_ctrl <= load_hi_acca;
- accb_ctrl <= load_accb;
- when "0001" => -- ix
- ix_ctrl <= load_ix;
- when "0010" => -- iy
- iy_ctrl <= load_iy;
- when "0011" => -- up
- up_ctrl <= load_up;
- when "0100" => -- sp
- sp_ctrl <= load_sp;
- when "0101" => -- pc
- pc_ctrl <= load_pc;
- when "1000" => -- acca
- acca_ctrl <= load_acca;
- when "1001" => -- accb
- accb_ctrl <= load_accb;
- when "1010" => -- cc
- cc_ctrl <= load_cc;
- when "1011" => --dp
- dp_ctrl <= load_dp;
- when others =>
- null;
- end case;
- lic <= '1';
- next_state <= fetch_state;
-
- when mul_state =>
- -- move acca to md
- left_ctrl <= acca_left;
- right_ctrl <= zero_right;
- alu_ctrl <= alu_st16;
- md_ctrl <= load_md;
- next_state <= mulea_state;
-
- when mulea_state =>
- -- move accb to ea
- left_ctrl <= accb_left;
- right_ctrl <= zero_right;
- alu_ctrl <= alu_st16;
- ea_ctrl <= load_ea;
- next_state <= muld_state;
-
- when muld_state =>
- -- clear accd
- left_ctrl <= acca_left;
- right_ctrl <= zero_right;
- alu_ctrl <= alu_ld8;
- acca_ctrl <= load_hi_acca;
- accb_ctrl <= load_accb;
- next_state <= mul0_state;
-
- when mul0_state =>
- -- if bit 0 of ea set, add accd to md
- left_ctrl <= accd_left;
- if ea(0) = '1' then
- right_ctrl <= md_right;
- else
- right_ctrl <= zero_right;
- end if;
- alu_ctrl <= alu_mul;
- cc_ctrl <= load_cc;
- acca_ctrl <= load_hi_acca;
- accb_ctrl <= load_accb;
- md_ctrl <= shiftl_md;
- next_state <= mul1_state;
-
- when mul1_state =>
- -- if bit 1 of ea set, add accd to md
- left_ctrl <= accd_left;
- if ea(1) = '1' then
- right_ctrl <= md_right;
- else
- right_ctrl <= zero_right;
- end if;
- alu_ctrl <= alu_mul;
- cc_ctrl <= load_cc;
- acca_ctrl <= load_hi_acca;
- accb_ctrl <= load_accb;
- md_ctrl <= shiftl_md;
- next_state <= mul2_state;
-
- when mul2_state =>
- -- if bit 2 of ea set, add accd to md
- left_ctrl <= accd_left;
- if ea(2) = '1' then
- right_ctrl <= md_right;
- else
- right_ctrl <= zero_right;
- end if;
- alu_ctrl <= alu_mul;
- cc_ctrl <= load_cc;
- acca_ctrl <= load_hi_acca;
- accb_ctrl <= load_accb;
- md_ctrl <= shiftl_md;
- next_state <= mul3_state;
-
- when mul3_state =>
- -- if bit 3 of ea set, add accd to md
- left_ctrl <= accd_left;
- if ea(3) = '1' then
- right_ctrl <= md_right;
- else
- right_ctrl <= zero_right;
- end if;
- alu_ctrl <= alu_mul;
- cc_ctrl <= load_cc;
- acca_ctrl <= load_hi_acca;
- accb_ctrl <= load_accb;
- md_ctrl <= shiftl_md;
- next_state <= mul4_state;
-
- when mul4_state =>
- -- if bit 4 of ea set, add accd to md
- left_ctrl <= accd_left;
- if ea(4) = '1' then
- right_ctrl <= md_right;
- else
- right_ctrl <= zero_right;
- end if;
- alu_ctrl <= alu_mul;
- cc_ctrl <= load_cc;
- acca_ctrl <= load_hi_acca;
- accb_ctrl <= load_accb;
- md_ctrl <= shiftl_md;
- next_state <= mul5_state;
-
- when mul5_state =>
- -- if bit 5 of ea set, add accd to md
- left_ctrl <= accd_left;
- if ea(5) = '1' then
- right_ctrl <= md_right;
- else
- right_ctrl <= zero_right;
- end if;
- alu_ctrl <= alu_mul;
- cc_ctrl <= load_cc;
- acca_ctrl <= load_hi_acca;
- accb_ctrl <= load_accb;
- md_ctrl <= shiftl_md;
- next_state <= mul6_state;
-
- when mul6_state =>
- -- if bit 6 of ea set, add accd to md
- left_ctrl <= accd_left;
- if ea(6) = '1' then
- right_ctrl <= md_right;
- else
- right_ctrl <= zero_right;
- end if;
- alu_ctrl <= alu_mul;
- cc_ctrl <= load_cc;
- acca_ctrl <= load_hi_acca;
- accb_ctrl <= load_accb;
- md_ctrl <= shiftl_md;
- next_state <= mul7_state;
-
- when mul7_state =>
- -- if bit 7 of ea set, add accd to md
- left_ctrl <= accd_left;
- if ea(7) = '1' then
- right_ctrl <= md_right;
- else
- right_ctrl <= zero_right;
- end if;
- alu_ctrl <= alu_mul;
- cc_ctrl <= load_cc;
- acca_ctrl <= load_hi_acca;
- accb_ctrl <= load_accb;
- md_ctrl <= shiftl_md;
- lic <= '1';
- next_state <= fetch_state;
-
- --
- -- Enter here on pushs
- -- ea holds post byte
- --
- when pshs_state =>
- -- decrement sp if any registers to be pushed
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- -- idle address
- addr_ctrl <= idle_ad;
- dout_ctrl <= cc_dout;
- if ea(7 downto 0) = "00000000" then
- sp_ctrl <= latch_sp;
- else
- sp_ctrl <= load_sp;
- end if;
- if ea(7) = '1' then
- next_state <= pshs_pcl_state;
- elsif ea(6) = '1' then
- next_state <= pshs_upl_state;
- elsif ea(5) = '1' then
- next_state <= pshs_iyl_state;
- elsif ea(4) = '1' then
- next_state <= pshs_ixl_state;
- elsif ea(3) = '1' then
- next_state <= pshs_dp_state;
- elsif ea(2) = '1' then
- next_state <= pshs_accb_state;
- elsif ea(1) = '1' then
- next_state <= pshs_acca_state;
- elsif ea(0) = '1' then
- next_state <= pshs_cc_state;
- else
- lic <= '1';
- next_state <= fetch_state;
- end if;
-
- when pshs_pcl_state =>
- -- decrement sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- sp_ctrl <= load_sp;
- -- write pc low
- addr_ctrl <= pushs_ad;
- dout_ctrl <= pc_lo_dout;
- next_state <= pshs_pch_state;
-
- when pshs_pch_state =>
- -- decrement sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- if ea(6 downto 0) = "0000000" then
- sp_ctrl <= latch_sp;
- else
- sp_ctrl <= load_sp;
- end if;
- -- write pc hi
- addr_ctrl <= pushs_ad;
- dout_ctrl <= pc_hi_dout;
- if ea(6) = '1' then
- next_state <= pshs_upl_state;
- elsif ea(5) = '1' then
- next_state <= pshs_iyl_state;
- elsif ea(4) = '1' then
- next_state <= pshs_ixl_state;
- elsif ea(3) = '1' then
- next_state <= pshs_dp_state;
- elsif ea(2) = '1' then
- next_state <= pshs_accb_state;
- elsif ea(1) = '1' then
- next_state <= pshs_acca_state;
- elsif ea(0) = '1' then
- next_state <= pshs_cc_state;
- else
- lic <= '1';
- next_state <= fetch_state;
- end if;
-
-
- when pshs_upl_state =>
- -- decrement sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- sp_ctrl <= load_sp;
- -- write pc low
- addr_ctrl <= pushs_ad;
- dout_ctrl <= up_lo_dout;
- next_state <= pshs_uph_state;
-
- when pshs_uph_state =>
- -- decrement sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- if ea(5 downto 0) = "000000" then
- sp_ctrl <= latch_sp;
- else
- sp_ctrl <= load_sp;
- end if;
- -- write pc hi
- addr_ctrl <= pushs_ad;
- dout_ctrl <= up_hi_dout;
- if ea(5) = '1' then
- next_state <= pshs_iyl_state;
- elsif ea(4) = '1' then
- next_state <= pshs_ixl_state;
- elsif ea(3) = '1' then
- next_state <= pshs_dp_state;
- elsif ea(2) = '1' then
- next_state <= pshs_accb_state;
- elsif ea(1) = '1' then
- next_state <= pshs_acca_state;
- elsif ea(0) = '1' then
- next_state <= pshs_cc_state;
- else
- lic <= '1';
- next_state <= fetch_state;
- end if;
-
- when pshs_iyl_state =>
- -- decrement sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- sp_ctrl <= load_sp;
- -- write iy low
- addr_ctrl <= pushs_ad;
- dout_ctrl <= iy_lo_dout;
- next_state <= pshs_iyh_state;
-
- when pshs_iyh_state =>
- -- decrement sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- if ea(4 downto 0) = "00000" then
- sp_ctrl <= latch_sp;
- else
- sp_ctrl <= load_sp;
- end if;
- -- write iy hi
- addr_ctrl <= pushs_ad;
- dout_ctrl <= iy_hi_dout;
- if ea(4) = '1' then
- next_state <= pshs_ixl_state;
- elsif ea(3) = '1' then
- next_state <= pshs_dp_state;
- elsif ea(2) = '1' then
- next_state <= pshs_accb_state;
- elsif ea(1) = '1' then
- next_state <= pshs_acca_state;
- elsif ea(0) = '1' then
- next_state <= pshs_cc_state;
- else
- lic <= '1';
- next_state <= fetch_state;
- end if;
-
- when pshs_ixl_state =>
- -- decrement sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- sp_ctrl <= load_sp;
- -- write ix low
- addr_ctrl <= pushs_ad;
- dout_ctrl <= ix_lo_dout;
- next_state <= pshs_ixh_state;
-
- when pshs_ixh_state =>
- -- decrement sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- if ea(3 downto 0) = "0000" then
- sp_ctrl <= latch_sp;
- else
- sp_ctrl <= load_sp;
- end if;
- -- write ix hi
- addr_ctrl <= pushs_ad;
- dout_ctrl <= ix_hi_dout;
- if ea(3) = '1' then
- next_state <= pshs_dp_state;
- elsif ea(2) = '1' then
- next_state <= pshs_accb_state;
- elsif ea(1) = '1' then
- next_state <= pshs_acca_state;
- elsif ea(0) = '1' then
- next_state <= pshs_cc_state;
- else
- lic <= '1';
- next_state <= fetch_state;
- end if;
-
- when pshs_dp_state =>
- -- decrement sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- if ea(2 downto 0) = "000" then
- sp_ctrl <= latch_sp;
- else
- sp_ctrl <= load_sp;
- end if;
- -- write dp
- addr_ctrl <= pushs_ad;
- dout_ctrl <= dp_dout;
- if ea(2) = '1' then
- next_state <= pshs_accb_state;
- elsif ea(1) = '1' then
- next_state <= pshs_acca_state;
- elsif ea(0) = '1' then
- next_state <= pshs_cc_state;
- else
- lic <= '1';
- next_state <= fetch_state;
- end if;
-
- when pshs_accb_state =>
- -- decrement sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- if ea(1 downto 0) = "00" then
- sp_ctrl <= latch_sp;
- else
- sp_ctrl <= load_sp;
- end if;
- -- write accb
- addr_ctrl <= pushs_ad;
- dout_ctrl <= accb_dout;
- if ea(1) = '1' then
- next_state <= pshs_acca_state;
- elsif ea(0) = '1' then
- next_state <= pshs_cc_state;
- else
- lic <= '1';
- next_state <= fetch_state;
- end if;
-
- when pshs_acca_state =>
- -- decrement sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- if ea(0) = '1' then
- sp_ctrl <= load_sp;
- else
- sp_ctrl <= latch_sp;
- end if;
- -- write acca
- addr_ctrl <= pushs_ad;
- dout_ctrl <= acca_dout;
- if ea(0) = '1' then
- next_state <= pshs_cc_state;
- else
- lic <= '1';
- next_state <= fetch_state;
- end if;
-
- when pshs_cc_state =>
- -- idle sp
- -- write cc
- addr_ctrl <= pushs_ad;
- dout_ctrl <= cc_dout;
- lic <= '1';
- next_state <= fetch_state;
-
- --
- -- enter here on PULS
- -- ea hold register mask
- --
- when puls_state =>
- if ea(0) = '1' then
- next_state <= puls_cc_state;
- elsif ea(1) = '1' then
- next_state <= puls_acca_state;
- elsif ea(2) = '1' then
- next_state <= puls_accb_state;
- elsif ea(3) = '1' then
- next_state <= puls_dp_state;
- elsif ea(4) = '1' then
- next_state <= puls_ixh_state;
- elsif ea(5) = '1' then
- next_state <= puls_iyh_state;
- elsif ea(6) = '1' then
- next_state <= puls_uph_state;
- elsif ea(7) = '1' then
- next_state <= puls_pch_state;
- else
- lic <= '1';
- next_state <= fetch_state;
- end if;
-
- when puls_cc_state =>
- -- increment sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- sp_ctrl <= load_sp;
- -- read cc
- cc_ctrl <= pull_cc;
- addr_ctrl <= pulls_ad;
- if ea(1) = '1' then
- next_state <= puls_acca_state;
- elsif ea(2) = '1' then
- next_state <= puls_accb_state;
- elsif ea(3) = '1' then
- next_state <= puls_dp_state;
- elsif ea(4) = '1' then
- next_state <= puls_ixh_state;
- elsif ea(5) = '1' then
- next_state <= puls_iyh_state;
- elsif ea(6) = '1' then
- next_state <= puls_uph_state;
- elsif ea(7) = '1' then
- next_state <= puls_pch_state;
- else
- lic <= '1';
- next_state <= fetch_state;
- end if;
-
- when puls_acca_state =>
- -- increment sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- sp_ctrl <= load_sp;
- -- read acca
- acca_ctrl <= pull_acca;
- addr_ctrl <= pulls_ad;
- if ea(2) = '1' then
- next_state <= puls_accb_state;
- elsif ea(3) = '1' then
- next_state <= puls_dp_state;
- elsif ea(4) = '1' then
- next_state <= puls_ixh_state;
- elsif ea(5) = '1' then
- next_state <= puls_iyh_state;
- elsif ea(6) = '1' then
- next_state <= puls_uph_state;
- elsif ea(7) = '1' then
- next_state <= puls_pch_state;
- else
- lic <= '1';
- next_state <= fetch_state;
- end if;
-
- when puls_accb_state =>
- -- increment sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- sp_ctrl <= load_sp;
- -- read accb
- accb_ctrl <= pull_accb;
- addr_ctrl <= pulls_ad;
- if ea(3) = '1' then
- next_state <= puls_dp_state;
- elsif ea(4) = '1' then
- next_state <= puls_ixh_state;
- elsif ea(5) = '1' then
- next_state <= puls_iyh_state;
- elsif ea(6) = '1' then
- next_state <= puls_uph_state;
- elsif ea(7) = '1' then
- next_state <= puls_pch_state;
- else
- lic <= '1';
- next_state <= fetch_state;
- end if;
-
- when puls_dp_state =>
- -- increment sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- sp_ctrl <= load_sp;
- -- read dp
- dp_ctrl <= pull_dp;
- addr_ctrl <= pulls_ad;
- if ea(4) = '1' then
- next_state <= puls_ixh_state;
- elsif ea(5) = '1' then
- next_state <= puls_iyh_state;
- elsif ea(6) = '1' then
- next_state <= puls_uph_state;
- elsif ea(7) = '1' then
- next_state <= puls_pch_state;
- else
- lic <= '1';
- next_state <= fetch_state;
- end if;
-
- when puls_ixh_state =>
- -- increment sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- sp_ctrl <= load_sp;
- -- pull ix hi
- ix_ctrl <= pull_hi_ix;
- addr_ctrl <= pulls_ad;
- next_state <= puls_ixl_state;
-
- when puls_ixl_state =>
- -- increment sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- sp_ctrl <= load_sp;
- -- read ix low
- ix_ctrl <= pull_lo_ix;
- addr_ctrl <= pulls_ad;
- if ea(5) = '1' then
- next_state <= puls_iyh_state;
- elsif ea(6) = '1' then
- next_state <= puls_uph_state;
- elsif ea(7) = '1' then
- next_state <= puls_pch_state;
- else
- lic <= '1';
- next_state <= fetch_state;
- end if;
-
- when puls_iyh_state =>
- -- increment sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- sp_ctrl <= load_sp;
- -- pull iy hi
- iy_ctrl <= pull_hi_iy;
- addr_ctrl <= pulls_ad;
- next_state <= puls_iyl_state;
-
- when puls_iyl_state =>
- -- increment sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- sp_ctrl <= load_sp;
- -- read iy low
- iy_ctrl <= pull_lo_iy;
- addr_ctrl <= pulls_ad;
- if ea(6) = '1' then
- next_state <= puls_uph_state;
- elsif ea(7) = '1' then
- next_state <= puls_pch_state;
- else
- lic <= '1';
- next_state <= fetch_state;
- end if;
-
- when puls_uph_state =>
- -- increment sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- sp_ctrl <= load_sp;
- -- pull up hi
- up_ctrl <= pull_hi_up;
- addr_ctrl <= pulls_ad;
- next_state <= puls_upl_state;
-
- when puls_upl_state =>
- -- increment sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- sp_ctrl <= load_sp;
- -- read up low
- up_ctrl <= pull_lo_up;
- addr_ctrl <= pulls_ad;
- if ea(7) = '1' then
- next_state <= puls_pch_state;
- else
- lic <= '1';
- next_state <= fetch_state;
- end if;
-
- when puls_pch_state =>
- -- increment sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- sp_ctrl <= load_sp;
- -- pull pc hi
- pc_ctrl <= pull_hi_pc;
- addr_ctrl <= pulls_ad;
- next_state <= puls_pcl_state;
-
- when puls_pcl_state =>
- -- increment sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- sp_ctrl <= load_sp;
- -- read pc low
- pc_ctrl <= pull_lo_pc;
- addr_ctrl <= pulls_ad;
- lic <= '1';
- next_state <= fetch_state;
-
- --
- -- Enter here on pshu
- -- ea holds post byte
- --
- when pshu_state =>
- -- decrement up if any registers to be pushed
- left_ctrl <= up_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- if ea(7 downto 0) = "00000000" then
- up_ctrl <= latch_up;
- else
- up_ctrl <= load_up;
- end if;
- -- write idle bus
- if ea(7) = '1' then
- next_state <= pshu_pcl_state;
- elsif ea(6) = '1' then
- next_state <= pshu_spl_state;
- elsif ea(5) = '1' then
- next_state <= pshu_iyl_state;
- elsif ea(4) = '1' then
- next_state <= pshu_ixl_state;
- elsif ea(3) = '1' then
- next_state <= pshu_dp_state;
- elsif ea(2) = '1' then
- next_state <= pshu_accb_state;
- elsif ea(1) = '1' then
- next_state <= pshu_acca_state;
- elsif ea(0) = '1' then
- next_state <= pshu_cc_state;
- else
- lic <= '1';
- next_state <= fetch_state;
- end if;
- --
- -- push PC onto U stack
- --
- when pshu_pcl_state =>
- -- decrement up
- left_ctrl <= up_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- up_ctrl <= load_up;
- -- write pc low
- addr_ctrl <= pushu_ad;
- dout_ctrl <= pc_lo_dout;
- next_state <= pshu_pch_state;
-
- when pshu_pch_state =>
- -- decrement up
- left_ctrl <= up_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- if ea(6 downto 0) = "0000000" then
- up_ctrl <= latch_up;
- else
- up_ctrl <= load_up;
- end if;
- -- write pc hi
- addr_ctrl <= pushu_ad;
- dout_ctrl <= pc_hi_dout;
- if ea(6) = '1' then
- next_state <= pshu_spl_state;
- elsif ea(5) = '1' then
- next_state <= pshu_iyl_state;
- elsif ea(4) = '1' then
- next_state <= pshu_ixl_state;
- elsif ea(3) = '1' then
- next_state <= pshu_dp_state;
- elsif ea(2) = '1' then
- next_state <= pshu_accb_state;
- elsif ea(1) = '1' then
- next_state <= pshu_acca_state;
- elsif ea(0) = '1' then
- next_state <= pshu_cc_state;
- else
- lic <= '1';
- next_state <= fetch_state;
- end if;
-
- when pshu_spl_state =>
- -- decrement up
- left_ctrl <= up_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- up_ctrl <= load_up;
- -- write sp low
- addr_ctrl <= pushu_ad;
- dout_ctrl <= sp_lo_dout;
- next_state <= pshu_sph_state;
-
- when pshu_sph_state =>
- -- decrement up
- left_ctrl <= up_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- if ea(5 downto 0) = "000000" then
- up_ctrl <= latch_up;
- else
- up_ctrl <= load_up;
- end if;
- -- write sp hi
- addr_ctrl <= pushu_ad;
- dout_ctrl <= sp_hi_dout;
- if ea(5) = '1' then
- next_state <= pshu_iyl_state;
- elsif ea(4) = '1' then
- next_state <= pshu_ixl_state;
- elsif ea(3) = '1' then
- next_state <= pshu_dp_state;
- elsif ea(2) = '1' then
- next_state <= pshu_accb_state;
- elsif ea(1) = '1' then
- next_state <= pshu_acca_state;
- elsif ea(0) = '1' then
- next_state <= pshu_cc_state;
- else
- lic <= '1';
- next_state <= fetch_state;
- end if;
-
- when pshu_iyl_state =>
- -- decrement up
- left_ctrl <= up_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- up_ctrl <= load_up;
- -- write iy low
- addr_ctrl <= pushu_ad;
- dout_ctrl <= iy_lo_dout;
- next_state <= pshu_iyh_state;
-
- when pshu_iyh_state =>
- -- decrement up
- left_ctrl <= up_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- if ea(4 downto 0) = "00000" then
- up_ctrl <= latch_up;
- else
- up_ctrl <= load_up;
- end if;
- -- write iy hi
- addr_ctrl <= pushu_ad;
- dout_ctrl <= iy_hi_dout;
- if ea(4) = '1' then
- next_state <= pshu_ixl_state;
- elsif ea(3) = '1' then
- next_state <= pshu_dp_state;
- elsif ea(2) = '1' then
- next_state <= pshu_accb_state;
- elsif ea(1) = '1' then
- next_state <= pshu_acca_state;
- elsif ea(0) = '1' then
- next_state <= pshu_cc_state;
- else
- lic <= '1';
- next_state <= fetch_state;
- end if;
-
- when pshu_ixl_state =>
- -- decrement up
- left_ctrl <= up_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- up_ctrl <= load_up;
- -- write ix low
- addr_ctrl <= pushu_ad;
- dout_ctrl <= ix_lo_dout;
- next_state <= pshu_ixh_state;
-
- when pshu_ixh_state =>
- -- decrement up
- left_ctrl <= up_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- if ea(3 downto 0) = "0000" then
- up_ctrl <= latch_up;
- else
- up_ctrl <= load_up;
- end if;
- -- write ix hi
- addr_ctrl <= pushu_ad;
- dout_ctrl <= ix_hi_dout;
- if ea(3) = '1' then
- next_state <= pshu_dp_state;
- elsif ea(2) = '1' then
- next_state <= pshu_accb_state;
- elsif ea(1) = '1' then
- next_state <= pshu_acca_state;
- elsif ea(0) = '1' then
- next_state <= pshu_cc_state;
- else
- lic <= '1';
- next_state <= fetch_state;
- end if;
-
- when pshu_dp_state =>
- -- decrement up
- left_ctrl <= up_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- if ea(2 downto 0) = "000" then
- up_ctrl <= latch_up;
- else
- up_ctrl <= load_up;
- end if;
- -- write dp
- addr_ctrl <= pushu_ad;
- dout_ctrl <= dp_dout;
- if ea(2) = '1' then
- next_state <= pshu_accb_state;
- elsif ea(1) = '1' then
- next_state <= pshu_acca_state;
- elsif ea(0) = '1' then
- next_state <= pshu_cc_state;
- else
- lic <= '1';
- next_state <= fetch_state;
- end if;
-
- when pshu_accb_state =>
- -- decrement up
- left_ctrl <= up_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- if ea(1 downto 0) = "00" then
- up_ctrl <= latch_up;
- else
- up_ctrl <= load_up;
- end if;
- -- write accb
- addr_ctrl <= pushu_ad;
- dout_ctrl <= accb_dout;
- if ea(1) = '1' then
- next_state <= pshu_acca_state;
- elsif ea(0) = '1' then
- next_state <= pshu_cc_state;
- else
- lic <= '1';
- next_state <= fetch_state;
- end if;
-
- when pshu_acca_state =>
- -- decrement up
- left_ctrl <= up_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- if ea(0) = '0' then
- up_ctrl <= latch_up;
- else
- up_ctrl <= load_up;
- end if;
- -- write acca
- addr_ctrl <= pushu_ad;
- dout_ctrl <= acca_dout;
- if ea(0) = '1' then
- next_state <= pshu_cc_state;
- else
- lic <= '1';
- next_state <= fetch_state;
- end if;
-
- when pshu_cc_state =>
- -- idle up
- -- write cc
- addr_ctrl <= pushu_ad;
- dout_ctrl <= cc_dout;
- lic <= '1';
- next_state <= fetch_state;
-
- --
- -- enter here on PULU
- -- ea hold register mask
- --
- when pulu_state =>
- -- idle UP
- -- idle bus
- if ea(0) = '1' then
- next_state <= pulu_cc_state;
- elsif ea(1) = '1' then
- next_state <= pulu_acca_state;
- elsif ea(2) = '1' then
- next_state <= pulu_accb_state;
- elsif ea(3) = '1' then
- next_state <= pulu_dp_state;
- elsif ea(4) = '1' then
- next_state <= pulu_ixh_state;
- elsif ea(5) = '1' then
- next_state <= pulu_iyh_state;
- elsif ea(6) = '1' then
- next_state <= pulu_sph_state;
- elsif ea(7) = '1' then
- next_state <= pulu_pch_state;
- else
- lic <= '1';
- next_state <= fetch_state;
- end if;
-
- when pulu_cc_state =>
- -- increment up
- left_ctrl <= up_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- up_ctrl <= load_up;
- -- read cc
- cc_ctrl <= pull_cc;
- addr_ctrl <= pullu_ad;
- if ea(1) = '1' then
- next_state <= pulu_acca_state;
- elsif ea(2) = '1' then
- next_state <= pulu_accb_state;
- elsif ea(3) = '1' then
- next_state <= pulu_dp_state;
- elsif ea(4) = '1' then
- next_state <= pulu_ixh_state;
- elsif ea(5) = '1' then
- next_state <= pulu_iyh_state;
- elsif ea(6) = '1' then
- next_state <= pulu_sph_state;
- elsif ea(7) = '1' then
- next_state <= pulu_pch_state;
- else
- lic <= '1';
- next_state <= fetch_state;
- end if;
-
- when pulu_acca_state =>
- -- increment up
- left_ctrl <= up_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- up_ctrl <= load_up;
- -- read acca
- acca_ctrl <= pull_acca;
- addr_ctrl <= pullu_ad;
- if ea(2) = '1' then
- next_state <= pulu_accb_state;
- elsif ea(3) = '1' then
- next_state <= pulu_dp_state;
- elsif ea(4) = '1' then
- next_state <= pulu_ixh_state;
- elsif ea(5) = '1' then
- next_state <= pulu_iyh_state;
- elsif ea(6) = '1' then
- next_state <= pulu_sph_state;
- elsif ea(7) = '1' then
- next_state <= pulu_pch_state;
- else
- lic <= '1';
- next_state <= fetch_state;
- end if;
-
- when pulu_accb_state =>
- -- increment up
- left_ctrl <= up_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- up_ctrl <= load_up;
- -- read accb
- accb_ctrl <= pull_accb;
- addr_ctrl <= pullu_ad;
- if ea(3) = '1' then
- next_state <= pulu_dp_state;
- elsif ea(4) = '1' then
- next_state <= pulu_ixh_state;
- elsif ea(5) = '1' then
- next_state <= pulu_iyh_state;
- elsif ea(6) = '1' then
- next_state <= pulu_sph_state;
- elsif ea(7) = '1' then
- next_state <= pulu_pch_state;
- else
- lic <= '1';
- next_state <= fetch_state;
- end if;
-
- when pulu_dp_state =>
- -- increment up
- left_ctrl <= up_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- up_ctrl <= load_up;
- -- read dp
- dp_ctrl <= pull_dp;
- addr_ctrl <= pullu_ad;
- if ea(4) = '1' then
- next_state <= pulu_ixh_state;
- elsif ea(5) = '1' then
- next_state <= pulu_iyh_state;
- elsif ea(6) = '1' then
- next_state <= pulu_sph_state;
- elsif ea(7) = '1' then
- next_state <= pulu_pch_state;
- else
- lic <= '1';
- next_state <= fetch_state;
- end if;
-
- when pulu_ixh_state =>
- -- increment up
- left_ctrl <= up_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- up_ctrl <= load_up;
- -- read ix hi
- ix_ctrl <= pull_hi_ix;
- addr_ctrl <= pullu_ad;
- next_state <= pulu_ixl_state;
-
- when pulu_ixl_state =>
- -- increment up
- left_ctrl <= up_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- up_ctrl <= load_up;
- -- read ix low
- ix_ctrl <= pull_lo_ix;
- addr_ctrl <= pullu_ad;
- if ea(5) = '1' then
- next_state <= pulu_iyh_state;
- elsif ea(6) = '1' then
- next_state <= pulu_sph_state;
- elsif ea(7) = '1' then
- next_state <= pulu_pch_state;
- else
- lic <= '1';
- next_state <= fetch_state;
- end if;
-
- when pulu_iyh_state =>
- -- increment up
- left_ctrl <= up_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- up_ctrl <= load_up;
- -- read iy hi
- iy_ctrl <= pull_hi_iy;
- addr_ctrl <= pullu_ad;
- next_state <= pulu_iyl_state;
-
- when pulu_iyl_state =>
- -- increment up
- left_ctrl <= up_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- up_ctrl <= load_up;
- -- read iy low
- iy_ctrl <= pull_lo_iy;
- addr_ctrl <= pullu_ad;
- if ea(6) = '1' then
- next_state <= pulu_sph_state;
- elsif ea(7) = '1' then
- next_state <= pulu_pch_state;
- else
- lic <= '1';
- next_state <= fetch_state;
- end if;
-
- when pulu_sph_state =>
- -- increment up
- left_ctrl <= up_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- up_ctrl <= load_up;
- -- read sp hi
- sp_ctrl <= pull_hi_sp;
- addr_ctrl <= pullu_ad;
- next_state <= pulu_spl_state;
-
- when pulu_spl_state =>
- -- increment up
- left_ctrl <= up_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- up_ctrl <= load_up;
- -- read sp low
- sp_ctrl <= pull_lo_sp;
- addr_ctrl <= pullu_ad;
- if ea(7) = '1' then
- next_state <= pulu_pch_state;
- else
- lic <= '1';
- next_state <= fetch_state;
- end if;
-
- when pulu_pch_state =>
- -- increment up
- left_ctrl <= up_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- up_ctrl <= load_up;
- -- pull pc hi
- pc_ctrl <= pull_hi_pc;
- addr_ctrl <= pullu_ad;
- next_state <= pulu_pcl_state;
-
- when pulu_pcl_state =>
- -- increment up
- left_ctrl <= up_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- up_ctrl <= load_up;
- -- read pc low
- pc_ctrl <= pull_lo_pc;
- addr_ctrl <= pullu_ad;
- lic <= '1';
- next_state <= fetch_state;
-
- --
- -- pop the Condition codes
- --
- when rti_cc_state =>
- -- increment sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- sp_ctrl <= load_sp;
- -- read cc
- cc_ctrl <= pull_cc;
- addr_ctrl <= pulls_ad;
- next_state <= rti_entire_state;
-
- --
- -- Added RTI cycle 11th July 2006 John Kent.
- -- test the "Entire" Flag
- -- that has just been popped off the stack
- --
- when rti_entire_state =>
- --
- -- The Entire flag must be recovered from the stack
- -- before testing.
- --
- if cc(EBIT) = '1' then
- next_state <= rti_acca_state;
- else
- next_state <= rti_pch_state;
- end if;
-
- when rti_acca_state =>
- -- increment sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- sp_ctrl <= load_sp;
- -- read acca
- acca_ctrl <= pull_acca;
- addr_ctrl <= pulls_ad;
- next_state <= rti_accb_state;
-
- when rti_accb_state =>
- -- increment sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- sp_ctrl <= load_sp;
- -- read accb
- accb_ctrl <= pull_accb;
- addr_ctrl <= pulls_ad;
- next_state <= rti_dp_state;
-
- when rti_dp_state =>
- -- increment sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- sp_ctrl <= load_sp;
- -- read dp
- dp_ctrl <= pull_dp;
- addr_ctrl <= pulls_ad;
- next_state <= rti_ixh_state;
-
- when rti_ixh_state =>
- -- increment sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- sp_ctrl <= load_sp;
- -- read ix hi
- ix_ctrl <= pull_hi_ix;
- addr_ctrl <= pulls_ad;
- next_state <= rti_ixl_state;
-
- when rti_ixl_state =>
- -- increment sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- sp_ctrl <= load_sp;
- -- read ix low
- ix_ctrl <= pull_lo_ix;
- addr_ctrl <= pulls_ad;
- next_state <= rti_iyh_state;
-
- when rti_iyh_state =>
- -- increment sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- sp_ctrl <= load_sp;
- -- read iy hi
- iy_ctrl <= pull_hi_iy;
- addr_ctrl <= pulls_ad;
- next_state <= rti_iyl_state;
-
- when rti_iyl_state =>
- -- increment sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- sp_ctrl <= load_sp;
- -- read iy low
- iy_ctrl <= pull_lo_iy;
- addr_ctrl <= pulls_ad;
- next_state <= rti_uph_state;
-
-
- when rti_uph_state =>
- -- increment sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- sp_ctrl <= load_sp;
- -- read up hi
- up_ctrl <= pull_hi_up;
- addr_ctrl <= pulls_ad;
- next_state <= rti_upl_state;
-
- when rti_upl_state =>
- -- increment sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- sp_ctrl <= load_sp;
- -- read up low
- up_ctrl <= pull_lo_up;
- addr_ctrl <= pulls_ad;
- next_state <= rti_pch_state;
-
- when rti_pch_state =>
- -- increment sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- sp_ctrl <= load_sp;
- -- pull pc hi
- pc_ctrl <= pull_hi_pc;
- addr_ctrl <= pulls_ad;
- next_state <= rti_pcl_state;
-
- when rti_pcl_state =>
- -- increment sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_add16;
- sp_ctrl <= load_sp;
- -- pull pc low
- pc_ctrl <= pull_lo_pc;
- addr_ctrl <= pulls_ad;
- lic <= '1';
- next_state <= fetch_state;
-
- --
- -- here on NMI interrupt
- -- Complete execute cycle of the last instruction.
- -- If it was a dual operand instruction
- --
- when int_nmi_state =>
- next_state <= int_nmi1_state;
-
- -- Idle bus cycle
- when int_nmi1_state =>
- -- pre decrement sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- sp_ctrl <= load_sp;
- iv_ctrl <= nmi_iv;
- st_ctrl <= push_st;
- return_state <= int_nmimask_state;
- next_state <= int_entire_state;
-
- --
- -- here on IRQ interrupt
- -- Complete execute cycle of the last instruction.
- -- If it was a dual operand instruction
- --
- when int_irq_state =>
- next_state <= int_irq1_state;
-
- -- pre decrement the sp
- -- Idle bus cycle
- when int_irq1_state =>
- -- pre decrement sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- sp_ctrl <= load_sp;
- iv_ctrl <= irq_iv;
- st_ctrl <= push_st;
- return_state <= int_irqmask_state;
- next_state <= int_entire_state;
-
- --
- -- here on FIRQ interrupt
- -- Complete execution cycle of the last instruction
- -- if it was a dual operand instruction
- --
- when int_firq_state =>
- next_state <= int_firq1_state;
-
- -- Idle bus cycle
- when int_firq1_state =>
- -- pre decrement sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- sp_ctrl <= load_sp;
- iv_ctrl <= firq_iv;
- st_ctrl <= push_st;
- return_state <= int_firqmask_state;
- next_state <= int_fast_state;
-
- --
- -- CWAI entry point
- -- stack pointer already pre-decremented
- -- mask condition codes
- --
- when cwai_state =>
- -- AND CC with md
- left_ctrl <= md_left;
- right_ctrl <= zero_right;
- alu_ctrl <= alu_andcc;
- cc_ctrl <= load_cc;
- st_ctrl <= push_st;
- return_state <= int_cwai_state;
- next_state <= int_entire_state;
-
- --
- -- wait here for an interrupt
- --
- when int_cwai_state =>
- if (nmi_req = '1') then
- iv_ctrl <= nmi_iv;
- next_state <= int_nmimask_state;
- --
- -- FIRQ & IRQ are level sensitive
- --
- elsif (firq = '1') and (cc(FBIT) = '0') then
- iv_ctrl <= firq_iv;
- next_state <= int_firqmask_state;
-
- elsif (irq = '1') and (cc(IBIT) = '0') then
- iv_ctrl <= irq_iv;
- next_state <= int_irqmask_state;
- else
- next_state <= int_cwai_state;
- end if;
-
- --
- -- State to mask I Flag and F Flag (NMI)
- --
- when int_nmimask_state =>
- alu_ctrl <= alu_seif;
- cc_ctrl <= load_cc;
- next_state <= vect_hi_state;
-
- --
- -- State to mask I Flag and F Flag (FIRQ)
- --
- when int_firqmask_state =>
- alu_ctrl <= alu_seif;
- cc_ctrl <= load_cc;
- next_state <= vect_hi_state;
-
-
- --
- -- State to mask I Flag and F Flag (SWI)
- --
- when int_swimask_state =>
- alu_ctrl <= alu_seif;
- cc_ctrl <= load_cc;
- next_state <= vect_hi_state;
-
- --
- -- State to mask I Flag only (IRQ)
- --
- when int_irqmask_state =>
- alu_ctrl <= alu_sei;
- cc_ctrl <= load_cc;
- next_state <= vect_hi_state;
-
- --
- -- set Entire Flag on SWI, SWI2, SWI3 and CWAI, IRQ and NMI
- -- before stacking all registers
- --
- when int_entire_state =>
- -- set entire flag
- alu_ctrl <= alu_see;
- cc_ctrl <= load_cc;
- next_state <= int_pcl_state;
-
- --
- -- clear Entire Flag on FIRQ
- -- before stacking all registers
- --
- when int_fast_state =>
- -- clear entire flag
- alu_ctrl <= alu_cle;
- cc_ctrl <= load_cc;
- next_state <= int_pcl_state;
-
- when int_pcl_state =>
- -- decrement sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- sp_ctrl <= load_sp;
- -- write pc low
- addr_ctrl <= pushs_ad;
- dout_ctrl <= pc_lo_dout;
- next_state <= int_pch_state;
-
- when int_pch_state =>
- -- decrement sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- sp_ctrl <= load_sp;
- -- write pc hi
- addr_ctrl <= pushs_ad;
- dout_ctrl <= pc_hi_dout;
- if cc(EBIT) = '1' then
- next_state <= int_upl_state;
- else
- next_state <= int_cc_state;
- end if;
-
- when int_upl_state =>
- -- decrement sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- sp_ctrl <= load_sp;
- -- write up low
- addr_ctrl <= pushs_ad;
- dout_ctrl <= up_lo_dout;
- next_state <= int_uph_state;
-
- when int_uph_state =>
- -- decrement sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- sp_ctrl <= load_sp;
- -- write ix hi
- addr_ctrl <= pushs_ad;
- dout_ctrl <= up_hi_dout;
- next_state <= int_iyl_state;
-
- when int_iyl_state =>
- -- decrement sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- sp_ctrl <= load_sp;
- -- write ix low
- addr_ctrl <= pushs_ad;
- dout_ctrl <= iy_lo_dout;
- next_state <= int_iyh_state;
-
- when int_iyh_state =>
- -- decrement sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- sp_ctrl <= load_sp;
- -- write ix hi
- addr_ctrl <= pushs_ad;
- dout_ctrl <= iy_hi_dout;
- next_state <= int_ixl_state;
-
- when int_ixl_state =>
- -- decrement sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- sp_ctrl <= load_sp;
- -- write ix low
- addr_ctrl <= pushs_ad;
- dout_ctrl <= ix_lo_dout;
- next_state <= int_ixh_state;
-
- when int_ixh_state =>
- -- decrement sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- sp_ctrl <= load_sp;
- -- write ix hi
- addr_ctrl <= pushs_ad;
- dout_ctrl <= ix_hi_dout;
- next_state <= int_dp_state;
-
- when int_dp_state =>
- -- decrement sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- sp_ctrl <= load_sp;
- -- write accb
- addr_ctrl <= pushs_ad;
- dout_ctrl <= dp_dout;
- next_state <= int_accb_state;
-
- when int_accb_state =>
- -- decrement sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- sp_ctrl <= load_sp;
- -- write accb
- addr_ctrl <= pushs_ad;
- dout_ctrl <= accb_dout;
- next_state <= int_acca_state;
-
- when int_acca_state =>
- -- decrement sp
- left_ctrl <= sp_left;
- right_ctrl <= one_right;
- alu_ctrl <= alu_sub16;
- sp_ctrl <= load_sp;
- -- write acca
- addr_ctrl <= pushs_ad;
- dout_ctrl <= acca_dout;
- next_state <= int_cc_state;
-
- when int_cc_state =>
- -- write cc
- addr_ctrl <= pushs_ad;
- dout_ctrl <= cc_dout;
- next_state <= saved_state;
-
- --
- -- According to the 6809 programming manual:
- -- If an interrupt is received and is masked
- -- or lasts for less than three cycles, the PC
- -- will advance to the next instruction.
- -- If an interrupt is unmasked and lasts
- -- for more than three cycles, an interrupt
- -- will be generated.
- -- Note that I don't wait 3 clock cycles.
- -- John Kent 11th July 2006
- --
- when sync_state =>
- lic <= '1';
- ba <= '1';
- --
- -- Version 1.28 2015-05-30
- -- Exit sync_state on interrupt.
- -- If the interrupts are active
- -- they will be caught in the state_machine process
- -- and the interrupt service routine microcode will be executed.
- -- Masked interrupts will exit the sync_state.
- -- Moved from the state_machine process to the state_sequencer process
- --
- if (firq = '1') or (irq = '1') then
- next_state <= fetch_state;
- else
- next_state <= sync_state;
- end if;
-
- when halt_state =>
- --
- -- 2011-10-30 John Kent
- -- ba & bs should be high
- ba <= '1';
- bs <= '1';
- if halt = '1' then
- next_state <= halt_state;
- else
- next_state <= fetch_state;
- end if;
-
- end case;
-
---
--- Ver 1.23 2011-10-30 John Kent
--- First instruction cycle might be
--- fetch_state
--- halt_state
--- int_nmirq_state
--- int_firq_state
---
- if fic = '1' then
- --
- case op_code(7 downto 6) is
- when "10" => -- acca
- case op_code(3 downto 0) is
- when "0000" => -- suba
- left_ctrl <= acca_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_sub8;
- cc_ctrl <= load_cc;
- acca_ctrl <= load_acca;
- when "0001" => -- cmpa
- left_ctrl <= acca_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_sub8;
- cc_ctrl <= load_cc;
- when "0010" => -- sbca
- left_ctrl <= acca_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_sbc;
- cc_ctrl <= load_cc;
- acca_ctrl <= load_acca;
- when "0011" =>
- case pre_code is
- when "00010000" => -- page 2 -- cmpd
- left_ctrl <= accd_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_sub16;
- cc_ctrl <= load_cc;
- when "00010001" => -- page 3 -- cmpu
- left_ctrl <= up_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_sub16;
- cc_ctrl <= load_cc;
- when others => -- page 1 -- subd
- left_ctrl <= accd_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_sub16;
- cc_ctrl <= load_cc;
- acca_ctrl <= load_hi_acca;
- accb_ctrl <= load_accb;
- end case;
- when "0100" => -- anda
- left_ctrl <= acca_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_and;
- cc_ctrl <= load_cc;
- acca_ctrl <= load_acca;
- when "0101" => -- bita
- left_ctrl <= acca_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_and;
- cc_ctrl <= load_cc;
- when "0110" => -- ldaa
- left_ctrl <= acca_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_ld8;
- cc_ctrl <= load_cc;
- acca_ctrl <= load_acca;
- when "0111" => -- staa
- left_ctrl <= acca_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_st8;
- cc_ctrl <= load_cc;
- when "1000" => -- eora
- left_ctrl <= acca_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_eor;
- cc_ctrl <= load_cc;
- acca_ctrl <= load_acca;
- when "1001" => -- adca
- left_ctrl <= acca_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_adc;
- cc_ctrl <= load_cc;
- acca_ctrl <= load_acca;
- when "1010" => -- oraa
- left_ctrl <= acca_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_ora;
- cc_ctrl <= load_cc;
- acca_ctrl <= load_acca;
- when "1011" => -- adda
- left_ctrl <= acca_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_add8;
- cc_ctrl <= load_cc;
- acca_ctrl <= load_acca;
- when "1100" =>
- case pre_code is
- when "00010000" => -- page 2 -- cmpy
- left_ctrl <= iy_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_sub16;
- cc_ctrl <= load_cc;
- when "00010001" => -- page 3 -- cmps
- left_ctrl <= sp_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_sub16;
- cc_ctrl <= load_cc;
- when others => -- page 1 -- cmpx
- left_ctrl <= ix_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_sub16;
- cc_ctrl <= load_cc;
- end case;
- when "1101" => -- bsr / jsr
- null;
- when "1110" => -- ldx
- case pre_code is
- when "00010000" => -- page 2 -- ldy
- left_ctrl <= iy_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_ld16;
- cc_ctrl <= load_cc;
- iy_ctrl <= load_iy;
- when others => -- page 1 -- ldx
- left_ctrl <= ix_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_ld16;
- cc_ctrl <= load_cc;
- ix_ctrl <= load_ix;
- end case;
- when "1111" => -- stx
- case pre_code is
- when "00010000" => -- page 2 -- sty
- left_ctrl <= iy_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_st16;
- cc_ctrl <= load_cc;
- when others => -- page 1 -- stx
- left_ctrl <= ix_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_st16;
- cc_ctrl <= load_cc;
- end case;
- when others =>
- null;
- end case;
- when "11" => -- accb dual op
- case op_code(3 downto 0) is
- when "0000" => -- subb
- left_ctrl <= accb_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_sub8;
- cc_ctrl <= load_cc;
- accb_ctrl <= load_accb;
- when "0001" => -- cmpb
- left_ctrl <= accb_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_sub8;
- cc_ctrl <= load_cc;
- when "0010" => -- sbcb
- left_ctrl <= accb_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_sbc;
- cc_ctrl <= load_cc;
- accb_ctrl <= load_accb;
- when "0011" => -- addd
- left_ctrl <= accd_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_add16;
- cc_ctrl <= load_cc;
- acca_ctrl <= load_hi_acca;
- accb_ctrl <= load_accb;
- when "0100" => -- andb
- left_ctrl <= accb_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_and;
- cc_ctrl <= load_cc;
- accb_ctrl <= load_accb;
- when "0101" => -- bitb
- left_ctrl <= accb_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_and;
- cc_ctrl <= load_cc;
- when "0110" => -- ldab
- left_ctrl <= accb_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_ld8;
- cc_ctrl <= load_cc;
- accb_ctrl <= load_accb;
- when "0111" => -- stab
- left_ctrl <= accb_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_st8;
- cc_ctrl <= load_cc;
- when "1000" => -- eorb
- left_ctrl <= accb_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_eor;
- cc_ctrl <= load_cc;
- accb_ctrl <= load_accb;
- when "1001" => -- adcb
- left_ctrl <= accb_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_adc;
- cc_ctrl <= load_cc;
- accb_ctrl <= load_accb;
- when "1010" => -- orab
- left_ctrl <= accb_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_ora;
- cc_ctrl <= load_cc;
- accb_ctrl <= load_accb;
- when "1011" => -- addb
- left_ctrl <= accb_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_add8;
- cc_ctrl <= load_cc;
- accb_ctrl <= load_accb;
- when "1100" => -- ldd
- left_ctrl <= accd_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_ld16;
- cc_ctrl <= load_cc;
- acca_ctrl <= load_hi_acca;
- accb_ctrl <= load_accb;
- when "1101" => -- std
- left_ctrl <= accd_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_st16;
- cc_ctrl <= load_cc;
- when "1110" => -- ldu
- case pre_code is
- when "00010000" => -- page 2 -- lds
- left_ctrl <= sp_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_ld16;
- cc_ctrl <= load_cc;
- sp_ctrl <= load_sp;
- when others => -- page 1 -- ldu
- left_ctrl <= up_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_ld16;
- cc_ctrl <= load_cc;
- up_ctrl <= load_up;
- end case;
- when "1111" =>
- case pre_code is
- when "00010000" => -- page 2 -- sts
- left_ctrl <= sp_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_st16;
- cc_ctrl <= load_cc;
- when others => -- page 1 -- stu
- left_ctrl <= up_left;
- right_ctrl <= md_right;
- alu_ctrl <= alu_st16;
- cc_ctrl <= load_cc;
- end case;
- when others =>
- null;
- end case;
- when others =>
- null;
- end case;
-
- end if; -- first instruction cycle (fic)
- lic_out <= lic;
-end process;
-
-end rtl;
-
diff --git a/Arcade_MiST/IremM52 Hardware/TraverseUSA_MiST/rtl/ym_2149_linmix.vhd b/Arcade_MiST/IremM52 Hardware/TraverseUSA_MiST/rtl/ym_2149_linmix.vhd
deleted file mode 100644
index b0573a80..00000000
--- a/Arcade_MiST/IremM52 Hardware/TraverseUSA_MiST/rtl/ym_2149_linmix.vhd
+++ /dev/null
@@ -1,645 +0,0 @@
---
--- A simulation model of YM2149 (AY-3-8910 with bells on)
-
--- Copyright (c) MikeJ - Jan 2005
---
--- All rights reserved
---
--- Redistribution and use in source and synthezised forms, with or without
--- modification, are permitted provided that the following conditions are met:
---
--- Redistributions of source code must retain the above copyright notice,
--- this list of conditions and the following disclaimer.
---
--- Redistributions in synthesized form must reproduce the above copyright
--- notice, this list of conditions and the following disclaimer in the
--- documentation and/or other materials provided with the distribution.
---
--- Neither the name of the author nor the names of other contributors may
--- be used to endorse or promote products derived from this software without
--- specific prior written permission.
---
--- THIS CODE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
--- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
--- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
--- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
--- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
--- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
--- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
--- POSSIBILITY OF SUCH DAMAGE.
---
--- You are responsible for any legal issues arising from your use of this code.
---
--- The latest version of this file can be found at: www.fpgaarcade.com
---
--- Email support@fpgaarcade.com
---
--- Revision list
---
--- version 001 initial release
---
--- Clues from MAME sound driver and Kazuhiro TSUJIKAWA
---
--- These are the measured outputs from a real chip for a single Isolated channel into a 1K load (V)
--- vol 15 .. 0
--- 3.27 2.995 2.741 2.588 2.452 2.372 2.301 2.258 2.220 2.198 2.178 2.166 2.155 2.148 2.141 2.132
--- As the envelope volume is 5 bit, I have fitted a curve to the not quite log shape in order
--- to produced all the required values.
--- (The first part of the curve is a bit steeper and the last bit is more linear than expected)
---
--- NOTE, this component uses LINEAR mixing of the three analogue channels, and is only
--- accurate for designs where the outputs are buffered and not simply wired together.
--- The ouput level is more complex in that case and requires a larger table.
-
-library ieee;
- use ieee.std_logic_1164.all;
- use ieee.std_logic_arith.all;
- use ieee.std_logic_unsigned.all;
-
-entity YM2149 is
- port (
- -- data bus
- I_DA : in std_logic_vector(7 downto 0);
- O_DA : out std_logic_vector(7 downto 0);
- O_DA_OE_L : out std_logic;
- -- control
- I_A9_L : in std_logic;
- I_A8 : in std_logic;
- I_BDIR : in std_logic;
- I_BC2 : in std_logic;
- I_BC1 : in std_logic;
- I_SEL_L : in std_logic;
-
- O_AUDIO : out std_logic_vector(7 downto 0);
- -- port a
- I_IOA : in std_logic_vector(7 downto 0);
- O_IOA : out std_logic_vector(7 downto 0);
- O_IOA_OE_L : out std_logic;
- -- port b
- I_IOB : in std_logic_vector(7 downto 0);
- O_IOB : out std_logic_vector(7 downto 0);
- O_IOB_OE_L : out std_logic;
-
- ENA : in std_logic; -- clock enable for higher speed operation
- RESET_L : in std_logic;
- CLK : in std_logic -- note 6 Mhz
- );
-end;
-
-architecture RTL of YM2149 is
- type array_16x8 is array (0 to 15) of std_logic_vector(7 downto 0);
- type array_3x12 is array (1 to 3) of std_logic_vector(11 downto 0);
-
- signal cnt_div : std_logic_vector(3 downto 0) := (others => '0');
- signal noise_div : std_logic := '0';
- signal ena_div : std_logic;
- signal ena_div_noise : std_logic;
- signal poly17 : std_logic_vector(16 downto 0) := (others => '0');
-
- -- registers
- signal addr : std_logic_vector(7 downto 0);
- signal busctrl_addr : std_logic;
- signal busctrl_we : std_logic;
- signal busctrl_re : std_logic;
-
- signal reg : array_16x8 ; --:= (
--- "00000000", -- R0 Period Tone A 8bits lsb
--- "00000100", -- R1 Period Tone A 4bits msb
--- "00000000", -- R2 Period Tone B 8bits lsb
--- "00000010", -- R3 Period Tone B 4bits msb
--- "00000000", -- R4 Period Tone C 8bits lsb
--- "00000001", -- R5 Period Tone C 4bits msb
--- "00001000", -- R6 Period Noise 5bits
--- "00111000", -- R7 Mixer Noise CBA 3bits, Tone CBA 3bits
--- "00000111", -- R8 Amplitude A Mode 1bit, Level 4bits
--- "00000111", -- R9 Amplitude B Mode 1bit, Level 4bits
--- "00000111", -- R10 Amplitude C Mode 1bit, Level 4bits
--- "00000000", -- R11 Period Enveloppe 8bits lsb
--- "00000000", -- R12 Period Enveloppe 8bits msb
--- "00000000", -- R13 Shape Enveloppe 4bits
--- "00000000", -- R14 Port A
--- "00000000" -- R15 Port B
--- );
-
- signal env_reset : std_logic;
- signal ioa_inreg : std_logic_vector(7 downto 0);
- signal iob_inreg : std_logic_vector(7 downto 0);
-
- signal noise_gen_cnt : std_logic_vector(4 downto 0);
- signal noise_gen_op : std_logic;
- signal tone_gen_cnt : array_3x12 := (others => (others => '0'));
- signal tone_gen_op : std_logic_vector(3 downto 1) := "000";
-
- signal env_gen_cnt : std_logic_vector(15 downto 0);
- signal env_ena : std_logic;
- signal env_hold : std_logic;
- signal env_inc : std_logic;
- signal env_vol : std_logic_vector(4 downto 0);
-
- signal tone_ena_l : std_logic;
- signal tone_src : std_logic;
- signal noise_ena_l : std_logic;
- signal chan_vol : std_logic_vector(4 downto 0);
-
- signal dac_amp : std_logic_vector(7 downto 0);
- signal audio_mix : std_logic_vector(9 downto 0);
- signal audio_final : std_logic_vector(9 downto 0);
-begin
- -- cpu i/f
- p_busdecode : process(I_BDIR, I_BC2, I_BC1, addr, I_A9_L, I_A8)
- variable cs : std_logic;
- variable sel : std_logic_vector(2 downto 0);
- begin
- -- BDIR BC2 BC1 MODE
- -- 0 0 0 inactive
- -- 0 0 1 address
- -- 0 1 0 inactive
- -- 0 1 1 read
- -- 1 0 0 address
- -- 1 0 1 inactive
- -- 1 1 0 write
- -- 1 1 1 read
- busctrl_addr <= '0';
- busctrl_we <= '0';
- busctrl_re <= '0';
-
- cs := '0';
- if (I_A9_L = '0') and (I_A8 = '1') and (addr(7 downto 4) = "0000") then
- cs := '1';
- end if;
-
- sel := (I_BDIR & I_BC2 & I_BC1);
- case sel is
- when "000" => null;
- when "001" => busctrl_addr <= '1';
- when "010" => null;
- when "011" => busctrl_re <= cs;
- when "100" => busctrl_addr <= '1';
- when "101" => null;
- when "110" => busctrl_we <= cs;
- when "111" => busctrl_addr <= '1';
- when others => null;
- end case;
- end process;
-
- p_oe : process(busctrl_re)
- begin
- -- if we are emulating a real chip, maybe clock this to fake up the tristate typ delay of 100ns
- O_DA_OE_L <= not (busctrl_re);
- end process;
-
- --
- -- CLOCKED
- --
- p_waddr : process
- begin
- ---- looks like registers are latches in real chip, but the address is caught at the end of the address state.
- wait until rising_edge(CLK);
-
- if (RESET_L = '0') then
- addr <= (others => '0');
- else
- if (busctrl_addr = '1') then
- addr <= I_DA;
- end if;
- end if;
- end process;
-
- p_wdata : process
- begin
- ---- looks like registers are latches in real chip, but the address is caught at the end of the address state.
- wait until rising_edge(CLK);
- env_reset <= '0';
-
- if (RESET_L = '0') then
- reg <= (others => (others => '0'));
- env_reset <= '1';
- else
- env_reset <= '0';
- if (busctrl_we = '1') then
- case addr(3 downto 0) is
- when x"0" => reg(0) <= I_DA;
- when x"1" => reg(1) <= I_DA;
- when x"2" => reg(2) <= I_DA;
- when x"3" => reg(3) <= I_DA;
- when x"4" => reg(4) <= I_DA;
- when x"5" => reg(5) <= I_DA;
- when x"6" => reg(6) <= I_DA;
- when x"7" => reg(7) <= I_DA;
- when x"8" => reg(8) <= I_DA;
- when x"9" => reg(9) <= I_DA;
- when x"A" => reg(10) <= I_DA;
- when x"B" => reg(11) <= I_DA;
- when x"C" => reg(12) <= I_DA;
- when x"D" => reg(13) <= I_DA; env_reset <= '1';
- when x"E" => reg(14) <= I_DA;
- when x"F" => reg(15) <= I_DA;
- when others => null;
- end case;
- end if;
- end if;
- end process;
-
- --
- -- LATCHED, useful when emulating a real chip in circuit. Nasty as gated clock.
- --
--- p_waddr : process(reset_l, busctrl_addr)
--- begin
--- -- looks like registers are latches in real chip, but the address is caught at the end of the address state.
--- if (RESET_L = '0') then
--- addr <= (others => '0');
--- elsif falling_edge(busctrl_addr) then -- yuk
--- addr <= I_DA;
--- end if;
--- end process;
---
--- p_wdata : process(reset_l, busctrl_we, addr)
--- begin
--- if (RESET_L = '0') then
--- reg <= (others => (others => '0'));
--- elsif falling_edge(busctrl_we) then
--- case addr(3 downto 0) is
--- when x"0" => reg(0) <= I_DA;
--- when x"1" => reg(1) <= I_DA;
--- when x"2" => reg(2) <= I_DA;
--- when x"3" => reg(3) <= I_DA;
--- when x"4" => reg(4) <= I_DA;
--- when x"5" => reg(5) <= I_DA;
--- when x"6" => reg(6) <= I_DA;
--- when x"7" => reg(7) <= I_DA;
--- when x"8" => reg(8) <= I_DA;
--- when x"9" => reg(9) <= I_DA;
--- when x"A" => reg(10) <= I_DA;
--- when x"B" => reg(11) <= I_DA;
--- when x"C" => reg(12) <= I_DA;
--- when x"D" => reg(13) <= I_DA;
--- when x"E" => reg(14) <= I_DA;
--- when x"F" => reg(15) <= I_DA;
--- when others => null;
--- end case;
--- end if;
---
--- env_reset <= '0';
--- if (busctrl_we = '1') and (addr(3 downto 0) = x"D") then
--- env_reset <= '1';
--- end if;
--- end process;
-
- --
- -- END LATCHED
- --
-
- p_rdata : process(busctrl_re, addr, reg)
- begin
- O_DA <= (others => '0'); -- 'X'
- if (busctrl_re = '1') then -- not necessary, but useful for putting 'X's in the simulator
- case addr(3 downto 0) is
- when x"0" => O_DA <= reg(0) ;
- when x"1" => O_DA <= "0000" & reg(1)(3 downto 0) ;
- when x"2" => O_DA <= reg(2) ;
- when x"3" => O_DA <= "0000" & reg(3)(3 downto 0) ;
- when x"4" => O_DA <= reg(4) ;
- when x"5" => O_DA <= "0000" & reg(5)(3 downto 0) ;
- when x"6" => O_DA <= "000" & reg(6)(4 downto 0) ;
- when x"7" => O_DA <= reg(7) ;
- when x"8" => O_DA <= "000" & reg(8)(4 downto 0) ;
- when x"9" => O_DA <= "000" & reg(9)(4 downto 0) ;
- when x"A" => O_DA <= "000" & reg(10)(4 downto 0) ;
- when x"B" => O_DA <= reg(11);
- when x"C" => O_DA <= reg(12);
- when x"D" => O_DA <= "0000" & reg(13)(3 downto 0);
- when x"E" => if (reg(7)(6) = '0') then -- input
- O_DA <= ioa_inreg;
- else
- O_DA <= reg(14); -- read output reg
- end if;
- when x"F" => if (Reg(7)(7) = '0') then
- O_DA <= iob_inreg;
- else
- O_DA <= reg(15);
- end if;
- when others => null;
- end case;
- end if;
- end process;
- --
- p_divider : process
- begin
- wait until rising_edge(CLK);
- -- / 8 when SEL is high and /16 when SEL is low
- if (ENA = '1') then
- ena_div <= '0';
- ena_div_noise <= '0';
- if (cnt_div = "0000") then
- cnt_div <= (not I_SEL_L) & "111";
- ena_div <= '1';
-
- noise_div <= not noise_div;
- if (noise_div = '1') then
- ena_div_noise <= '1';
- end if;
- else
- cnt_div <= cnt_div - "1";
- end if;
- end if;
- end process;
-
- p_noise_gen : process
- variable noise_gen_comp : std_logic_vector(4 downto 0);
- variable poly17_zero : std_logic;
- begin
- wait until rising_edge(CLK);
-
- if (reg(6)(4 downto 0) = "00000") then
- noise_gen_comp := "00000";
- else
- noise_gen_comp := (reg(6)(4 downto 0) - "1");
- end if;
-
- poly17_zero := '0';
- if (poly17 = "00000000000000000") then poly17_zero := '1'; end if;
-
- if (ENA = '1') then
-
- if (ena_div_noise = '1') then -- divider ena
-
- if (noise_gen_cnt >= noise_gen_comp) then
- noise_gen_cnt <= "00000";
- poly17 <= (poly17(0) xor poly17(2) xor poly17_zero) & poly17(16 downto 1);
- else
- noise_gen_cnt <= (noise_gen_cnt + "1");
- end if;
- end if;
- end if;
- end process;
- noise_gen_op <= poly17(0);
-
- p_tone_gens : process
- variable tone_gen_freq : array_3x12;
- variable tone_gen_comp : array_3x12;
- begin
- wait until rising_edge(CLK);
-
- -- looks like real chips count up - we need to get the Exact behaviour ..
- tone_gen_freq(1) := reg(1)(3 downto 0) & reg(0);
- tone_gen_freq(2) := reg(3)(3 downto 0) & reg(2);
- tone_gen_freq(3) := reg(5)(3 downto 0) & reg(4);
- -- period 0 = period 1
- for i in 1 to 3 loop
- if (tone_gen_freq(i) = x"000") then
- tone_gen_comp(i) := x"000";
- else
- tone_gen_comp(i) := (tone_gen_freq(i) - "1");
- end if;
- end loop;
-
- if (ENA = '1') then
- for i in 1 to 3 loop
- if (ena_div = '1') then -- divider ena
-
- if (tone_gen_cnt(i) >= tone_gen_comp(i)) then
- tone_gen_cnt(i) <= x"000";
- tone_gen_op(i) <= not tone_gen_op(i);
- else
- tone_gen_cnt(i) <= (tone_gen_cnt(i) + "1");
- end if;
- end if;
- end loop;
- end if;
- end process;
-
- p_envelope_freq : process
- variable env_gen_freq : std_logic_vector(15 downto 0);
- variable env_gen_comp : std_logic_vector(15 downto 0);
- begin
- wait until rising_edge(CLK);
- env_gen_freq := reg(12) & reg(11);
- -- envelope freqs 1 and 0 are the same.
- if (env_gen_freq = x"0000") then
- env_gen_comp := x"0000";
- else
- env_gen_comp := (env_gen_freq - "1");
- end if;
-
- if (ENA = '1') then
- env_ena <= '0';
- if (ena_div = '1') then -- divider ena
- if (env_gen_cnt >= env_gen_comp) then
- env_gen_cnt <= x"0000";
- env_ena <= '1';
- else
- env_gen_cnt <= (env_gen_cnt + "1");
- end if;
- end if;
- end if;
- end process;
-
- p_envelope_shape : process(env_reset, CLK)
- variable is_bot : boolean;
- variable is_bot_p1 : boolean;
- variable is_top_m1 : boolean;
- variable is_top : boolean;
- begin
- -- envelope shapes
- -- C AtAlH
- -- 0 0 x x \___
- --
- -- 0 1 x x /___
- --
- -- 1 0 0 0 \\\\
- --
- -- 1 0 0 1 \___
- --
- -- 1 0 1 0 \/\/
- -- ___
- -- 1 0 1 1 \
- --
- -- 1 1 0 0 ////
- -- ___
- -- 1 1 0 1 /
- --
- -- 1 1 1 0 /\/\
- --
- -- 1 1 1 1 /___
- if (env_reset = '1') then
- -- load initial state
- if (reg(13)(2) = '0') then -- attack
- env_vol <= "11111";
- env_inc <= '0'; -- -1
- else
- env_vol <= "00000";
- env_inc <= '1'; -- +1
- end if;
- env_hold <= '0';
-
- elsif rising_edge(CLK) then
- is_bot := (env_vol = "00000");
- is_bot_p1 := (env_vol = "00001");
- is_top_m1 := (env_vol = "11110");
- is_top := (env_vol = "11111");
-
- if (ENA = '1') then
- if (env_ena = '1') then
- if (env_hold = '0') then
- if (env_inc = '1') then
- env_vol <= (env_vol + "00001");
- else
- env_vol <= (env_vol + "11111");
- end if;
- end if;
-
- -- envelope shape control.
- if (reg(13)(3) = '0') then
- if (env_inc = '0') then -- down
- if is_bot_p1 then env_hold <= '1'; end if;
- else
- if is_top then env_hold <= '1'; end if;
- end if;
- else
- if (reg(13)(0) = '1') then -- hold = 1
- if (env_inc = '0') then -- down
- if (reg(13)(1) = '1') then -- alt
- if is_bot then env_hold <= '1'; end if;
- else
- if is_bot_p1 then env_hold <= '1'; end if;
- end if;
- else
- if (reg(13)(1) = '1') then -- alt
- if is_top then env_hold <= '1'; end if;
- else
- if is_top_m1 then env_hold <= '1'; end if;
- end if;
- end if;
-
- elsif (reg(13)(1) = '1') then -- alternate
- if (env_inc = '0') then -- down
- if is_bot_p1 then env_hold <= '1'; end if;
- if is_bot then env_hold <= '0'; env_inc <= '1'; end if;
- else
- if is_top_m1 then env_hold <= '1'; end if;
- if is_top then env_hold <= '0'; env_inc <= '0'; end if;
- end if;
- end if;
-
- end if;
- end if;
- end if;
- end if;
- end process;
-
- p_chan_mixer : process(cnt_div, reg, tone_gen_op)
- begin
- tone_ena_l <= '1'; tone_src <= '1';
- noise_ena_l <= '1'; chan_vol <= "00000";
- case cnt_div(1 downto 0) is
- when "00" =>
- tone_ena_l <= reg(7)(0); tone_src <= tone_gen_op(1); chan_vol <= reg(8)(4 downto 0);
- noise_ena_l <= reg(7)(3);
- when "01" =>
- tone_ena_l <= reg(7)(1); tone_src <= tone_gen_op(2); chan_vol <= reg(9)(4 downto 0);
- noise_ena_l <= reg(7)(4);
- when "10" =>
- tone_ena_l <= reg(7)(2); tone_src <= tone_gen_op(3); chan_vol <= reg(10)(4 downto 0);
- noise_ena_l <= reg(7)(5);
- when "11" => null; -- tone gen outputs become valid on this clock
- when others => null;
- end case;
- end process;
-
- p_op_mixer : process
- variable chan_mixed : std_logic;
- variable chan_amp : std_logic_vector(4 downto 0);
- begin
- wait until rising_edge(CLK);
- if (ENA = '1') then
-
- chan_mixed := (tone_ena_l or tone_src) and (noise_ena_l or noise_gen_op);
-
- chan_amp := (others => '0');
- if (chan_mixed = '1') then
- if (chan_vol(4) = '0') then
- if (chan_vol(3 downto 0) = "0000") then -- nothing is easy ! make sure quiet is quiet
- chan_amp := "00000";
- else
- chan_amp := chan_vol(3 downto 0) & '1'; -- make sure level 31 (env) = level 15 (tone)
- end if;
- else
- chan_amp := env_vol(4 downto 0);
- end if;
- end if;
-
- dac_amp <= x"00";
- case chan_amp is
- when "11111" => dac_amp <= x"FF";
- when "11110" => dac_amp <= x"D9";
- when "11101" => dac_amp <= x"BA";
- when "11100" => dac_amp <= x"9F";
- when "11011" => dac_amp <= x"88";
- when "11010" => dac_amp <= x"74";
- when "11001" => dac_amp <= x"63";
- when "11000" => dac_amp <= x"54";
- when "10111" => dac_amp <= x"48";
- when "10110" => dac_amp <= x"3D";
- when "10101" => dac_amp <= x"34";
- when "10100" => dac_amp <= x"2C";
- when "10011" => dac_amp <= x"25";
- when "10010" => dac_amp <= x"1F";
- when "10001" => dac_amp <= x"1A";
- when "10000" => dac_amp <= x"16";
- when "01111" => dac_amp <= x"13";
- when "01110" => dac_amp <= x"10";
- when "01101" => dac_amp <= x"0D";
- when "01100" => dac_amp <= x"0B";
- when "01011" => dac_amp <= x"09";
- when "01010" => dac_amp <= x"08";
- when "01001" => dac_amp <= x"07";
- when "01000" => dac_amp <= x"06";
- when "00111" => dac_amp <= x"05";
- when "00110" => dac_amp <= x"04";
- when "00101" => dac_amp <= x"03";
- when "00100" => dac_amp <= x"03";
- when "00011" => dac_amp <= x"02";
- when "00010" => dac_amp <= x"02";
- when "00001" => dac_amp <= x"01";
- when "00000" => dac_amp <= x"00";
- when others => null;
- end case;
-
- if (cnt_div(1 downto 0) = "10") then
- audio_mix <= (others => '0');
- audio_final <= audio_mix;
- else
- audio_mix <= audio_mix + ("00" & dac_amp);
- end if;
-
- if (RESET_L = '0') then
- O_AUDIO(7 downto 0) <= "00000000";
- else
- if (audio_final(9) = '0') then
- O_AUDIO(7 downto 0) <= audio_final(8 downto 1);
- else -- clip
- O_AUDIO(7 downto 0) <= x"FF";
- end if;
- end if;
- end if;
- end process;
-
- p_io_ports : process(reg)
- begin
- O_IOA <= reg(14);
-
- O_IOA_OE_L <= not reg(7)(6);
- O_IOB <= reg(15);
- O_IOB_OE_L <= not reg(7)(7);
- end process;
-
- p_io_ports_inreg : process
- begin
- wait until rising_edge(CLK);
- ioa_inreg <= I_IOA;
- iob_inreg <= I_IOB;
- end process;
-end architecture RTL;