Revision 1347
Added by markw almost 4 years ago
atari_chips/pokeyv2/pokey_mixer_mux.vhdl | ||
---|---|---|
---------------------------------------------------------------------------
|
||
-- (c) 2020 mark watson
|
||
-- I am happy for anyone to use this for non-commercial use.
|
||
-- If my vhdl files are used commercially or otherwise sold,
|
||
-- please contact me for explicit permission at scrameta (gmail).
|
||
-- This applies for source and binary form and derived works.
|
||
---------------------------------------------------------------------------
|
||
LIBRARY ieee;
|
||
USE ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
use IEEE.STD_LOGIC_MISC.all;
|
||
|
||
ENTITY pokey_mixer_mux IS
|
||
PORT
|
||
(
|
||
CLK : IN STD_LOGIC;
|
||
RESET_N : IN STD_LOGIC;
|
||
|
||
CHANNEL_0 : IN unsigned(5 downto 0);
|
||
CHANNEL_1 : IN unsigned(5 downto 0);
|
||
CHANNEL_2 : IN unsigned(5 downto 0);
|
||
CHANNEL_3 : IN unsigned(5 downto 0);
|
||
|
||
VOLUME_OUT_0 : OUT unsigned(15 downto 0);
|
||
VOLUME_OUT_1 : OUT unsigned(15 downto 0);
|
||
VOLUME_OUT_2 : OUT unsigned(15 downto 0);
|
||
VOLUME_OUT_3 : OUT unsigned(15 downto 0);
|
||
|
||
PROFILE_ADDR : OUT std_logic_vector(5 downto 0);
|
||
PROFILE_REQUEST : OUT std_logic;
|
||
PROFILE_READY : IN std_logic;
|
||
PROFILE_DATA : IN std_logic_vector(15 downto 0)
|
||
);
|
||
END pokey_mixer_mux;
|
||
|
||
ARCHITECTURE vhdl OF pokey_mixer_mux IS
|
||
signal CHANNEL_STATE_NEXT : STD_LOGIC_VECTOR(2 downto 0);
|
||
signal CHANNEL_STATE_REG : STD_LOGIC_VECTOR(2 downto 0);
|
||
constant CHANNEL_STATE_WAIT0 : STD_LOGIC_VECTOR(2 downto 0) := "000";
|
||
constant CHANNEL_STATE_WAIT1 : STD_LOGIC_VECTOR(2 downto 0) := "001";
|
||
constant CHANNEL_STATE_WAIT2 : STD_LOGIC_VECTOR(2 downto 0) := "010";
|
||
constant CHANNEL_STATE_WAIT3 : STD_LOGIC_VECTOR(2 downto 0) := "011";
|
||
constant CHANNEL_STATE_REQUEST0 : STD_LOGIC_VECTOR(2 downto 0) := "100";
|
||
constant CHANNEL_STATE_REQUEST1 : STD_LOGIC_VECTOR(2 downto 0) := "101";
|
||
constant CHANNEL_STATE_REQUEST2 : STD_LOGIC_VECTOR(2 downto 0) := "110";
|
||
constant CHANNEL_STATE_REQUEST3 : STD_LOGIC_VECTOR(2 downto 0) := "111";
|
||
|
||
signal CHANNEL_DIRTY_NEXT : STD_LOGIC_VECTOR(3 downto 0);
|
||
signal CHANNEL_DIRTY_REG : STD_LOGIC_VECTOR(3 downto 0);
|
||
signal CHANNEL_CHANGED : STD_LOGIC_VECTOR(3 downto 0);
|
||
|
||
signal CHANNEL_IN_0_NEXT : unsigned(5 downto 0);
|
||
signal CHANNEL_IN_0_REG : unsigned(5 downto 0);
|
||
signal CHANNEL_IN_1_NEXT : unsigned(5 downto 0);
|
||
signal CHANNEL_IN_1_REG : unsigned(5 downto 0);
|
||
signal CHANNEL_IN_2_NEXT : unsigned(5 downto 0);
|
||
signal CHANNEL_IN_2_REG : unsigned(5 downto 0);
|
||
signal CHANNEL_IN_3_NEXT : unsigned(5 downto 0);
|
||
signal CHANNEL_IN_3_REG : unsigned(5 downto 0);
|
||
|
||
signal VOLUME_OUT_0_NEXT : unsigned(15 downto 0);
|
||
signal VOLUME_OUT_0_REG : unsigned(15 downto 0);
|
||
signal VOLUME_OUT_1_NEXT : unsigned(15 downto 0);
|
||
signal VOLUME_OUT_1_REG : unsigned(15 downto 0);
|
||
signal VOLUME_OUT_2_NEXT : unsigned(15 downto 0);
|
||
signal VOLUME_OUT_2_REG : unsigned(15 downto 0);
|
||
signal VOLUME_OUT_3_NEXT : unsigned(15 downto 0);
|
||
signal VOLUME_OUT_3_REG : unsigned(15 downto 0);
|
||
|
||
signal CHANNEL_MUX : STD_LOGIC_VECTOR(1 downto 0);
|
||
signal CHANNEL_SUM_OUT : unsigned(5 downto 0);
|
||
BEGIN
|
||
|
||
process(clk,reset_n)
|
||
begin
|
||
if (reset_n='0') then
|
||
CHANNEL_STATE_REG <= CHANNEL_STATE_WAIT0;
|
||
CHANNEL_DIRTY_REG <= (others=>'1');
|
||
|
||
CHANNEL_IN_0_REG <= (others=>'0');
|
||
CHANNEL_IN_1_REG <= (others=>'0');
|
||
CHANNEL_IN_2_REG <= (others=>'0');
|
||
CHANNEL_IN_3_REG <= (others=>'0');
|
||
|
||
VOLUME_OUT_0_REG <= (others=>'0');
|
||
VOLUME_OUT_1_REG <= (others=>'0');
|
||
VOLUME_OUT_2_REG <= (others=>'0');
|
||
VOLUME_OUT_3_REG <= (others=>'0');
|
||
elsif (clk'event and clk='1') then
|
||
CHANNEL_STATE_REG <= CHANNEL_STATE_NEXT;
|
||
CHANNEL_DIRTY_REG <= CHANNEL_DIRTY_NEXT;
|
||
|
||
CHANNEL_IN_0_REG <= CHANNEL_IN_0_NEXT;
|
||
CHANNEL_IN_1_REG <= CHANNEL_IN_1_NEXT;
|
||
CHANNEL_IN_2_REG <= CHANNEL_IN_2_NEXT;
|
||
CHANNEL_IN_3_REG <= CHANNEL_IN_3_NEXT;
|
||
|
||
VOLUME_OUT_0_REG <= VOLUME_OUT_0_NEXT;
|
||
VOLUME_OUT_1_REG <= VOLUME_OUT_1_NEXT;
|
||
VOLUME_OUT_2_REG <= VOLUME_OUT_2_NEXT;
|
||
VOLUME_OUT_3_REG <= VOLUME_OUT_3_NEXT;
|
||
END IF;
|
||
END PROCESS;
|
||
|
||
-- takes a few cycles for each channel
|
||
process(
|
||
CHANNEL_IN_0_REG,CHANNEL_IN_1_REG,CHANNEL_IN_2_REG,CHANNEL_IN_3_REG,
|
||
CHANNEL_0,CHANNEL_1,CHANNEL_2,CHANNEL_3
|
||
)
|
||
begin
|
||
CHANNEL_IN_0_NEXT <= CHANNEL_0;
|
||
CHANNEL_IN_1_NEXT <= CHANNEL_1;
|
||
CHANNEL_IN_2_NEXT <= CHANNEL_2;
|
||
CHANNEL_IN_3_NEXT <= CHANNEL_3;
|
||
|
||
CHANNEL_CHANGED(0) <= '0';
|
||
if (CHANNEL_0 /= CHANNEL_IN_0_REG) then
|
||
CHANNEL_CHANGED(0) <= '1';
|
||
end if;
|
||
CHANNEL_CHANGED(1) <= '0';
|
||
if (CHANNEL_1 /= CHANNEL_IN_1_REG) then
|
||
CHANNEL_CHANGED(1) <= '1';
|
||
end if;
|
||
CHANNEL_CHANGED(2) <= '0';
|
||
if (CHANNEL_2 /= CHANNEL_IN_2_REG) then
|
||
CHANNEL_CHANGED(2) <= '1';
|
||
end if;
|
||
CHANNEL_CHANGED(3) <= '0';
|
||
if (CHANNEL_3 /= CHANNEL_IN_3_REG) then
|
||
CHANNEL_CHANGED(3) <= '1';
|
||
end if;
|
||
end process;
|
||
|
||
process(channel_state_reg,profile_ready,CHANNEL_DIRTY_REG,CHANNEL_CHANGED)
|
||
begin
|
||
CHANNEL_STATE_NEXT <= CHANNEL_STATE_REG;
|
||
CHANNEL_DIRTY_NEXT <= CHANNEL_DIRTY_REG or channel_changed;
|
||
|
||
CHANNEL_MUX <= (others=>'0');
|
||
PROFILE_REQUEST <= '0';
|
||
|
||
case CHANNEL_STATE_REG is
|
||
when CHANNEL_STATE_WAIT0 =>
|
||
if (CHANNEL_DIRTY_REG(0)='1') then
|
||
CHANNEL_STATE_NEXT <= CHANNEL_STATE_REQUEST0;
|
||
else
|
||
CHANNEL_STATE_NEXT <= CHANNEL_STATE_WAIT1;
|
||
end if;
|
||
when CHANNEL_STATE_WAIT1 =>
|
||
if (CHANNEL_DIRTY_REG(1)='1') then
|
||
CHANNEL_STATE_NEXT <= CHANNEL_STATE_REQUEST1;
|
||
else
|
||
CHANNEL_STATE_NEXT <= CHANNEL_STATE_WAIT2;
|
||
end if;
|
||
when CHANNEL_STATE_WAIT2 =>
|
||
if (CHANNEL_DIRTY_REG(2)='1') then
|
||
CHANNEL_STATE_NEXT <= CHANNEL_STATE_REQUEST2;
|
||
else
|
||
CHANNEL_STATE_NEXT <= CHANNEL_STATE_WAIT3;
|
||
end if;
|
||
when CHANNEL_STATE_WAIT3 =>
|
||
if (CHANNEL_DIRTY_REG(3)='1') then
|
||
CHANNEL_STATE_NEXT <= CHANNEL_STATE_REQUEST3;
|
||
else
|
||
CHANNEL_STATE_NEXT <= CHANNEL_STATE_WAIT0;
|
||
end if;
|
||
when CHANNEL_STATE_REQUEST0 =>
|
||
CHANNEL_MUX <= "00";
|
||
PROFILE_REQUEST <= '1';
|
||
CHANNEL_DIRTY_NEXT(0) <= not(profile_ready);
|
||
if (profile_ready='1') then
|
||
CHANNEL_STATE_NEXT <= CHANNEL_STATE_WAIT1;
|
||
end if;
|
||
when CHANNEL_STATE_REQUEST1 =>
|
||
CHANNEL_MUX <= "01";
|
||
PROFILE_REQUEST <= '1';
|
||
CHANNEL_DIRTY_NEXT(1) <= not(profile_ready);
|
||
if (profile_ready='1') then
|
||
CHANNEL_STATE_NEXT <= CHANNEL_STATE_WAIT2;
|
||
end if;
|
||
when CHANNEL_STATE_REQUEST2 =>
|
||
CHANNEL_MUX <= "10";
|
||
PROFILE_REQUEST <= '1';
|
||
CHANNEL_DIRTY_NEXT(2) <= not(profile_ready);
|
||
if (profile_ready='1') then
|
||
CHANNEL_STATE_NEXT <= CHANNEL_STATE_WAIT3;
|
||
end if;
|
||
when CHANNEL_STATE_REQUEST3 =>
|
||
CHANNEL_MUX <= "11";
|
||
PROFILE_REQUEST <= '1';
|
||
CHANNEL_DIRTY_NEXT(3) <= not(profile_ready);
|
||
if (profile_ready='1') then
|
||
CHANNEL_STATE_NEXT <= CHANNEL_STATE_WAIT0;
|
||
end if;
|
||
when OTHERS =>
|
||
CHANNEL_STATE_NEXT <= CHANNEL_STATE_WAIT0;
|
||
end case;
|
||
end process;
|
||
|
||
-- mux input
|
||
PROCESS(
|
||
CHANNEL_0,CHANNEL_1,CHANNEL_2,CHANNEL_3,
|
||
CHANNEL_MUX
|
||
)
|
||
variable channel_sum : unsigned(5 downto 0);
|
||
BEGIN
|
||
channel_sum := (OTHERS=>'0');
|
||
|
||
case channel_mux is
|
||
when "00" => -- 0
|
||
channel_sum := CHANNEL_0;
|
||
when "01" => -- 1
|
||
channel_sum := CHANNEL_1;
|
||
when "10" => -- 2
|
||
channel_sum := CHANNEL_2;
|
||
--when "0000001" => -- 3
|
||
when others =>
|
||
channel_sum := CHANNEL_3;
|
||
end case;
|
||
|
||
channel_sum_out <= channel_sum;
|
||
|
||
END PROCESS;
|
||
|
||
-- shared mixer
|
||
--shared_pokey_mixer : entity work.pokey_mixer
|
||
-- port map
|
||
-- (
|
||
-- sum => channel_sum_out,
|
||
--
|
||
-- saturate => saturate,
|
||
--
|
||
-- VOLUME_OUT_NEXT => VOLUME_OUT_NEXT
|
||
-- );
|
||
|
||
-- mux output
|
||
PROCESS(
|
||
PROFILE_DATA,
|
||
PROFILE_READY,
|
||
VOLUME_OUT_0_REG,
|
||
VOLUME_OUT_1_REG,
|
||
VOLUME_OUT_2_REG,
|
||
VOLUME_OUT_3_REG,
|
||
CHANNEL_MUX
|
||
)
|
||
BEGIN
|
||
VOLUME_OUT_0_NEXT <= VOLUME_OUT_0_REG;
|
||
VOLUME_OUT_1_NEXT <= VOLUME_OUT_1_REG;
|
||
VOLUME_OUT_2_NEXT <= VOLUME_OUT_2_REG;
|
||
VOLUME_OUT_3_NEXT <= VOLUME_OUT_3_REG;
|
||
|
||
if (profile_ready='1') then
|
||
case channel_mux is
|
||
when "00" => -- 0
|
||
VOLUME_OUT_0_NEXT <= unsigned(PROFILE_DATA);
|
||
when "01" => -- 1
|
||
VOLUME_OUT_1_NEXT <= unsigned(PROFILE_DATA);
|
||
when "10" => -- 2
|
||
VOLUME_OUT_2_NEXT <= unsigned(PROFILE_DATA);
|
||
when others=> -- 3
|
||
VOLUME_OUT_3_NEXT <= unsigned(PROFILE_DATA);
|
||
end case;
|
||
end if;
|
||
END PROCESS;
|
||
|
||
-- output
|
||
VOLUME_OUT_0 <= VOLUME_OUT_0_REG;
|
||
VOLUME_OUT_1 <= VOLUME_OUT_1_REG;
|
||
VOLUME_OUT_2 <= VOLUME_OUT_2_REG;
|
||
VOLUME_OUT_3 <= VOLUME_OUT_3_REG;
|
||
|
||
PROFILE_ADDR <= std_logic_vector(CHANNEL_SUM_OUT);
|
||
END vhdl;
|
||
|
atari_chips/pokeyv2/pokey_noise_filter.vhdl | ||
---|---|---|
---------------------------------------------------------------------------
|
||
-- (c) 2013 mark watson
|
||
-- I am happy for anyone to use this for non-commercial use.
|
||
-- If my vhdl files are used commercially or otherwise sold,
|
||
-- please contact me for explicit permission at scrameta (gmail).
|
||
-- This applies for source and binary form and derived works.
|
||
---------------------------------------------------------------------------
|
||
LIBRARY ieee;
|
||
USE ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
|
||
ENTITY pokey_noise_filter IS
|
||
PORT
|
||
(
|
||
CLK : IN STD_LOGIC;
|
||
RESET_N : IN STD_LOGIC;
|
||
|
||
NOISE_SELECT : IN STD_LOGIC_VECTOR(2 downto 0);
|
||
|
||
PULSE_IN : IN STD_LOGIC;
|
||
|
||
NOISE_4 : IN STD_LOGIC;
|
||
NOISE_5 : IN STD_LOGIC;
|
||
NOISE_LARGE : IN STD_LOGIC;
|
||
|
||
SYNC_RESET : IN STD_LOGIC;
|
||
|
||
PULSE_OUT : OUT STD_LOGIC
|
||
);
|
||
END pokey_noise_filter;
|
||
|
||
ARCHITECTURE vhdl OF pokey_noise_filter IS
|
||
-- signal pulse_noise_a : std_logic;
|
||
-- signal pulse_noise_b : std_logic;
|
||
|
||
signal audclk : std_logic;
|
||
signal out_next : std_logic;
|
||
signal out_reg : std_logic;
|
||
BEGIN
|
||
process(clk,reset_n)
|
||
begin
|
||
if (reset_n='0') then
|
||
out_reg <= '0';
|
||
elsif (clk'event and clk='1') then
|
||
out_reg <= out_next;
|
||
end if;
|
||
end process;
|
||
|
||
pulse_out <= out_reg;
|
||
|
||
process(pulse_in, noise_4, noise_5, noise_large, noise_select, audclk, out_reg, sync_reset)
|
||
begin
|
||
audclk <= pulse_in;
|
||
out_next <= out_reg;
|
||
|
||
if (NOISE_SELECT(2) = '0') then
|
||
audclk <= pulse_in and noise_5;
|
||
end if;
|
||
|
||
if (audclk = '1') then
|
||
if (NOISE_SELECT(0) = '1') then
|
||
-- toggle
|
||
out_next <= not(out_reg);
|
||
else
|
||
-- sample
|
||
if (NOISE_SELECT(1) = '1') then
|
||
out_next <= noise_4;
|
||
else
|
||
out_next <= noise_large;
|
||
end if;
|
||
end if;
|
||
end if;
|
||
|
||
if (sync_reset = '1') then
|
||
out_next <= '0';
|
||
end if;
|
||
|
||
end process;
|
||
end vhdl;
|
atari_chips/pokeyv2/pokey_poly_4.vhdl | ||
---|---|---|
---------------------------------------------------------------------------
|
||
-- (c) 2013 mark watson
|
||
-- I am happy for anyone to use this for non-commercial use.
|
||
-- If my vhdl files are used commercially or otherwise sold,
|
||
-- please contact me for explicit permission at scrameta (gmail).
|
||
-- This applies for source and binary form and derived works.
|
||
---------------------------------------------------------------------------
|
||
LIBRARY ieee;
|
||
USE ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
|
||
ENTITY pokey_poly_4 IS
|
||
PORT
|
||
(
|
||
CLK : IN STD_LOGIC;
|
||
RESET_N : IN STD_LOGIC;
|
||
ENABLE : IN STD_LOGIC;
|
||
INIT : IN STD_LOGIC;
|
||
|
||
BIT_OUT : OUT STD_LOGIC
|
||
);
|
||
END pokey_poly_4;
|
||
|
||
ARCHITECTURE vhdl OF pokey_poly_4 IS
|
||
signal shift_reg: std_logic_vector(3 downto 0);
|
||
signal shift_next: std_logic_vector(3 downto 0);
|
||
BEGIN
|
||
-- register
|
||
process(clk, reset_n)
|
||
begin
|
||
if (reset_n = '0') then
|
||
shift_reg <= "1010";
|
||
elsif (clk'event and clk='1') then
|
||
shift_reg <= shift_next;
|
||
end if;
|
||
end process;
|
||
|
||
-- next state
|
||
process(shift_reg,enable,init)
|
||
begin
|
||
shift_next <= shift_reg;
|
||
if (enable = '1') then
|
||
shift_next <= ((shift_reg(1) xnor shift_reg(0)) and not(init))&shift_reg(3 downto 1);
|
||
end if;
|
||
end process;
|
||
|
||
-- output
|
||
bit_out <= shift_reg(0);
|
||
|
||
END vhdl;
|
atari_chips/pokeyv2/pokey_keyboard_scanner.vhdl | ||
---|---|---|
---------------------------------------------------------------------------
|
||
-- (c) 2013 mark watson
|
||
-- I am happy for anyone to use this for non-commercial use.
|
||
-- If my vhdl files are used commercially or otherwise sold,
|
||
-- please contact me for explicit permission at scrameta (gmail).
|
||
-- This applies for source and binary form and derived works.
|
||
---------------------------------------------------------------------------
|
||
LIBRARY ieee;
|
||
USE ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
|
||
entity pokey_keyboard_scanner is
|
||
port
|
||
(
|
||
clk : in std_logic;
|
||
reset_n : in std_logic;
|
||
|
||
enable : in std_logic; -- typically hsync or equiv timing
|
||
keyboard_response : in std_logic_vector(1 downto 0);
|
||
debounce_disable : in std_logic;
|
||
scan_enable : in std_logic;
|
||
|
||
keyboard_scan : out std_logic_vector(5 downto 0);
|
||
|
||
key_held : out std_logic;
|
||
shift_held : out std_logic;
|
||
keycode : out std_logic_vector(7 downto 0);
|
||
other_key_irq : out std_logic;
|
||
break_irq : out std_logic
|
||
);
|
||
end pokey_keyboard_scanner;
|
||
|
||
architecture vhdl of pokey_keyboard_scanner is
|
||
signal bincnt_next : std_logic_vector(5 downto 0);
|
||
signal bincnt_reg : std_logic_vector(5 downto 0);
|
||
|
||
signal break_pressed_next : std_logic;
|
||
signal break_pressed_reg : std_logic;
|
||
|
||
signal shift_pressed_next : std_logic;
|
||
signal shift_pressed_reg : std_logic;
|
||
|
||
signal control_pressed_next : std_logic;
|
||
signal control_pressed_reg : std_logic;
|
||
|
||
signal compare_latch_next : std_logic_vector(5 downto 0);
|
||
signal compare_latch_reg : std_logic_vector(5 downto 0);
|
||
|
||
signal keycode_latch_next : std_logic_vector(7 downto 0);
|
||
signal keycode_latch_reg : std_logic_vector(7 downto 0);
|
||
|
||
signal irq_next : std_logic;
|
||
signal irq_reg : std_logic;
|
||
|
||
signal break_irq_next : std_logic;
|
||
signal break_irq_reg : std_logic;
|
||
|
||
signal key_held_next : std_logic;
|
||
signal key_held_reg : std_logic;
|
||
|
||
signal my_key : std_logic;
|
||
|
||
signal state_next : std_logic_vector(1 downto 0);
|
||
signal state_reg : std_logic_vector(1 downto 0);
|
||
constant state_wait_key : std_logic_vector(1 downto 0) := "00";
|
||
constant state_key_bounce : std_logic_vector(1 downto 0) := "01";
|
||
constant state_valid_key : std_logic_vector(1 downto 0) := "10";
|
||
constant state_key_debounce : std_logic_vector(1 downto 0) := "11";
|
||
begin
|
||
|
||
-- register
|
||
process(clk,reset_n)
|
||
begin
|
||
if (reset_n = '0') then
|
||
bincnt_reg <= (others=>'0');
|
||
break_pressed_reg <= '0';
|
||
shift_pressed_reg <= '0';
|
||
control_pressed_reg <= '0';
|
||
compare_latch_reg <= (others=>'0');
|
||
keycode_latch_reg <= (others=>'1');
|
||
key_held_reg <= '0';
|
||
state_reg <= state_wait_key;
|
||
irq_reg <= '0';
|
||
break_irq_reg <= '0';
|
||
elsif (clk'event and clk = '1') then
|
||
bincnt_reg <= bincnt_next;
|
||
state_reg <= state_next;
|
||
break_pressed_reg <= break_pressed_next;
|
||
shift_pressed_reg <= shift_pressed_next;
|
||
control_pressed_reg <= control_pressed_next;
|
||
compare_latch_reg <= compare_latch_next;
|
||
keycode_latch_reg <= keycode_latch_next;
|
||
key_held_reg <= key_held_next;
|
||
state_reg <= state_next;
|
||
irq_reg <= irq_next;
|
||
break_irq_reg <= break_irq_next;
|
||
end if;
|
||
end process;
|
||
|
||
process (enable, keyboard_response, scan_enable, key_held_reg, my_key, state_reg,bincnt_reg, compare_latch_reg, break_pressed_next, break_pressed_reg, shift_pressed_reg, break_irq_reg, control_pressed_reg, keycode_latch_reg, debounce_disable)
|
||
begin
|
||
bincnt_next <= bincnt_reg;
|
||
state_next <= state_reg;
|
||
compare_latch_next <= compare_latch_reg;
|
||
irq_next <= '0';
|
||
break_irq_next <= '0';
|
||
break_pressed_next <= break_pressed_reg;
|
||
shift_pressed_next <= shift_pressed_reg;
|
||
control_pressed_next <= control_pressed_reg;
|
||
keycode_latch_next <= keycode_latch_reg;
|
||
key_held_next <= key_held_reg;
|
||
|
||
my_key <= '0';
|
||
if (bincnt_reg = compare_latch_reg or debounce_disable='1') then
|
||
my_key <= '1';
|
||
end if;
|
||
|
||
if (enable = '1' and scan_enable='1') then
|
||
bincnt_next <= std_logic_vector(unsigned(bincnt_reg) + 1); -- check another key
|
||
|
||
key_held_next<= '0';
|
||
|
||
case state_reg is
|
||
when state_wait_key =>
|
||
if (keyboard_response(0) = '0') then -- detected key press
|
||
if (debounce_disable = '1') then
|
||
keycode_latch_next <= control_pressed_reg&shift_pressed_reg¬(bincnt_reg);
|
||
irq_next <= '1';
|
||
key_held_next<= '1';
|
||
else
|
||
state_next <= state_key_bounce;
|
||
compare_latch_next <= bincnt_reg;
|
||
end if;
|
||
end if;
|
||
|
||
when state_key_bounce =>
|
||
if (keyboard_response(0) = '0') then -- detected key press
|
||
if (my_key = '1') then -- same key
|
||
keycode_latch_next <= control_pressed_reg&shift_pressed_reg¬(compare_latch_reg);
|
||
irq_next <= '1';
|
||
key_held_next<= '1';
|
||
state_next <= state_valid_key;
|
||
else -- different key (multiple keys pressed)
|
||
state_next <= state_wait_key;
|
||
end if;
|
||
else -- key not pressed
|
||
if (my_key = '1') then -- same key, no longer pressed
|
||
state_next <= state_wait_key;
|
||
end if;
|
||
end if;
|
||
|
||
when state_valid_key =>
|
||
key_held_next<= '1';
|
||
if (my_key = '1') then -- only response to my key
|
||
if (keyboard_response(0) = '1') then -- no longer pressed
|
||
state_next <= state_key_debounce;
|
||
end if;
|
||
end if;
|
||
|
||
when state_key_debounce =>
|
||
key_held_next<= '1';
|
||
if (my_key = '1') then
|
||
if (keyboard_response(0) = '1') then -- no longer pressed
|
||
key_held_next<= '0';
|
||
state_next <= state_wait_key;
|
||
else
|
||
state_next <= state_valid_key;
|
||
end if;
|
||
end if;
|
||
|
||
when others=>
|
||
state_next <= state_wait_key;
|
||
end case;
|
||
|
||
if (bincnt_reg(3 downto 0) = "1111") then
|
||
case bincnt_reg(5 downto 4) is
|
||
when "00" =>
|
||
break_pressed_next <= not(keyboard_response(1)); --0x30
|
||
when "10" =>
|
||
shift_pressed_next <= not(keyboard_response(1)); --0x10
|
||
when "11" =>
|
||
control_pressed_next <= not(keyboard_response(1)); -- 0x00
|
||
when others =>
|
||
--
|
||
end case;
|
||
end if;
|
||
end if;
|
||
|
||
if (break_pressed_next='1' and break_pressed_reg='0') then
|
||
break_irq_next <= '1';
|
||
end if;
|
||
end process;
|
||
|
||
-- outputs
|
||
keyboard_scan <= bincnt_reg;
|
||
|
||
key_held <= key_held_reg;
|
||
shift_held <= shift_pressed_reg;
|
||
keycode <= keycode_latch_reg;
|
||
other_key_irq <= irq_reg;
|
||
break_irq <= break_irq_reg;
|
||
end vhdl;
|
atari_chips/pokeyv2/pokey_poly_17_9.vhdl | ||
---|---|---|
---------------------------------------------------------------------------
|
||
-- (c) 2013 mark watson
|
||
-- I am happy for anyone to use this for non-commercial use.
|
||
-- If my vhdl files are used commercially or otherwise sold,
|
||
-- please contact me for explicit permission at scrameta (gmail).
|
||
-- This applies for source and binary form and derived works.
|
||
---------------------------------------------------------------------------
|
||
LIBRARY ieee;
|
||
USE ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
|
||
ENTITY pokey_poly_17_9 IS
|
||
PORT
|
||
(
|
||
CLK : IN STD_LOGIC;
|
||
RESET_N : IN STD_LOGIC;
|
||
ENABLE : IN STD_LOGIC;
|
||
SELECT_9_17 : IN STD_LOGIC; -- 9 high, 17 low
|
||
INIT : IN STD_LOGIC;
|
||
|
||
BIT_OUT : OUT STD_LOGIC;
|
||
|
||
RAND_OUT : OUT std_logic_vector(7 downto 0)
|
||
);
|
||
END pokey_poly_17_9;
|
||
|
||
ARCHITECTURE vhdl OF pokey_poly_17_9 IS
|
||
signal shift_reg: std_logic_vector(16 downto 0);
|
||
signal shift_next: std_logic_vector(16 downto 0);
|
||
|
||
signal cycle_delay_reg : std_logic;
|
||
signal cycle_delay_next : std_logic;
|
||
|
||
signal select_9_17_del_reg : std_logic;
|
||
signal select_9_17_del_next : std_logic;
|
||
|
||
signal feedback : std_logic;
|
||
BEGIN
|
||
-- register
|
||
process(clk,reset_n)
|
||
begin
|
||
if (reset_n = '0') then
|
||
shift_reg <= "01010101010101010";
|
||
cycle_delay_reg <= '0';
|
||
select_9_17_del_reg <= '0';
|
||
elsif (clk'event and clk='1') then
|
||
shift_reg <= shift_next;
|
||
cycle_delay_reg <= cycle_delay_next;
|
||
select_9_17_del_reg <= select_9_17_del_next;
|
||
end if;
|
||
end process;
|
||
|
||
-- next state (as pokey decap)
|
||
feedback <= shift_reg(13) xnor shift_reg(8);
|
||
process(enable,shift_reg,feedback,select_9_17,select_9_17_del_reg,init,cycle_delay_reg)
|
||
begin
|
||
shift_next <= shift_reg;
|
||
cycle_delay_next <= cycle_delay_reg;
|
||
select_9_17_del_next <= select_9_17_del_reg;
|
||
|
||
if (enable = '1') then
|
||
select_9_17_del_next <= select_9_17;
|
||
shift_next(15 downto 8) <= shift_reg(16 downto 9);
|
||
shift_next(7) <= feedback;
|
||
shift_next(6 downto 0) <= shift_reg(7 downto 1);
|
||
|
||
shift_next(16) <= ((feedback and select_9_17_del_reg) or (shift_reg(0) and not(select_9_17))) and not(init);
|
||
|
||
cycle_delay_next <= shift_reg(9);
|
||
end if;
|
||
end process;
|
||
|
||
-- output
|
||
bit_out <= cycle_delay_reg; -- from pokey schematics
|
||
RAND_OUT(7 downto 0) <= not(shift_reg(15 downto 8));
|
||
|
||
END vhdl;
|
atari_chips/pokeyv2/pokey_mixer.vhdl | ||
---|---|---|
---------------------------------------------------------------------------
|
||
-- (c) 2013 mark watson
|
||
-- I am happy for anyone to use this for non-commercial use.
|
||
-- If my vhdl files are used commercially or otherwise sold,
|
||
-- please contact me for explicit permission at scrameta (gmail).
|
||
-- This applies for source and binary form and derived works.
|
||
---------------------------------------------------------------------------
|
||
LIBRARY ieee;
|
||
USE ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
use IEEE.STD_LOGIC_MISC.all;
|
||
|
||
ENTITY pokey_mixer IS
|
||
PORT
|
||
(
|
||
SUM : IN unsigned(5 downto 0);
|
||
|
||
SATURATE : IN std_logic; -- pokey style curve or linear
|
||
|
||
VOLUME_OUT_NEXT : OUT std_logic_vector(15 downto 0)
|
||
);
|
||
END pokey_mixer;
|
||
|
||
ARCHITECTURE vhdl OF pokey_mixer IS
|
||
|
||
function pokeyvolume(x: unsigned(5 downto 0)) return unsigned is
|
||
begin
|
||
case x is
|
||
when "000000" => return x"0022";
|
||
when "000001" => return x"0993";
|
||
when "000010" => return x"135E";
|
||
when "000011" => return x"1D9A";
|
||
when "000100" => return x"2842";
|
||
when "000101" => return x"3345";
|
||
when "000110" => return x"3E84";
|
||
when "000111" => return x"49E0";
|
||
when "001000" => return x"5538";
|
||
when "001001" => return x"606E";
|
||
when "001010" => return x"6B69";
|
||
when "001011" => return x"7612";
|
||
when "001100" => return x"805A";
|
||
when "001101" => return x"8A34";
|
||
when "001110" => return x"9399";
|
||
when "001111" => return x"9C84";
|
||
when "010000" => return x"A4F4";
|
||
when "010001" => return x"ACEA";
|
||
when "010010" => return x"B468";
|
||
when "010011" => return x"BB70";
|
||
when "010100" => return x"C207";
|
||
when "010101" => return x"C830";
|
||
when "010110" => return x"CDEE";
|
||
when "010111" => return x"D343";
|
||
when "011000" => return x"D833";
|
||
when "011001" => return x"DCC0";
|
||
when "011010" => return x"E0EB";
|
||
when "011011" => return x"E4B6";
|
||
when "011100" => return x"E824";
|
||
when "011101" => return x"EB36";
|
||
when "011110" => return x"EDEF";
|
||
when "011111" => return x"F053";
|
||
when "100000" => return x"F265";
|
||
when "100001" => return x"F42B";
|
||
when "100010" => return x"F5AB";
|
||
when "100011" => return x"F6E9";
|
||
when "100100" => return x"F7EF";
|
||
when "100101" => return x"F8C3";
|
||
when "100110" => return x"F96D";
|
||
when "100111" => return x"F9F4";
|
||
when "101000" => return x"FA61";
|
||
when "101001" => return x"FABB";
|
||
when "101010" => return x"FB07";
|
||
when "101011" => return x"FB4C";
|
||
when "101100" => return x"FB8D";
|
||
when "101101" => return x"FBCE";
|
||
when "101110" => return x"FC11";
|
||
when "101111" => return x"FC56";
|
||
when "110000" => return x"FC9F";
|
||
when "110001" => return x"FCEA";
|
||
when "110010" => return x"FD37";
|
||
when "110011" => return x"FD85";
|
||
when "110100" => return x"FDD5";
|
||
when "110101" => return x"FE28";
|
||
when "110110" => return x"FE82";
|
||
when "110111" => return x"FEE7";
|
||
when "111000" => return x"FF5D";
|
||
when "111001" => return x"FFEB";
|
||
when "111010" => return x"FFFF";
|
||
when "111011" => return x"FFFF";
|
||
when "111100" => return x"FFFF";
|
||
when others =>
|
||
return x"ffff";
|
||
end case;
|
||
end pokeyvolume;
|
||
BEGIN
|
||
-- next state
|
||
process (sum,saturate)
|
||
begin
|
||
-- saturation on
|
||
if (saturate='1') then
|
||
volume_out_next <= std_logic_vector(pokeyvolume(sum));
|
||
else
|
||
-- saturation off
|
||
volume_out_next <= (others=>'0');
|
||
volume_out_next(15 downto 6) <= std_logic_vector(unsigned(SUM&"0000")+unsigned("0000"&SUM));
|
||
end if;
|
||
end process;
|
||
|
||
END vhdl;
|
atari_chips/pokeyv2/pokey_poly_5.vhdl | ||
---|---|---|
---------------------------------------------------------------------------
|
||
-- (c) 2013 mark watson
|
||
-- I am happy for anyone to use this for non-commercial use.
|
||
-- If my vhdl files are used commercially or otherwise sold,
|
||
-- please contact me for explicit permission at scrameta (gmail).
|
||
-- This applies for source and binary form and derived works.
|
||
---------------------------------------------------------------------------
|
||
LIBRARY ieee;
|
||
USE ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
|
||
ENTITY pokey_poly_5 IS
|
||
PORT
|
||
(
|
||
CLK : IN STD_LOGIC;
|
||
RESET_N : IN STD_LOGIC;
|
||
ENABLE : IN STD_LOGIC;
|
||
INIT : IN STD_LOGIC;
|
||
|
||
BIT_OUT : OUT STD_LOGIC
|
||
);
|
||
END pokey_poly_5;
|
||
|
||
ARCHITECTURE vhdl OF pokey_poly_5 IS
|
||
signal shift_reg: std_logic_vector(4 downto 0);
|
||
signal shift_next: std_logic_vector(4 downto 0);
|
||
BEGIN
|
||
-- register
|
||
process(clk,reset_n)
|
||
begin
|
||
if (reset_n = '0') then
|
||
shift_reg <= "01010";
|
||
elsif (clk'event and clk='1') then
|
||
shift_reg <= shift_next;
|
||
end if;
|
||
end process;
|
||
|
||
-- next state
|
||
process(shift_reg,enable,init)
|
||
begin
|
||
shift_next <= shift_reg;
|
||
if (enable = '1') then
|
||
shift_next <= ((shift_reg(2) xnor shift_reg(0)) and not(init))&shift_reg(4 downto 1);
|
||
end if;
|
||
end process;
|
||
|
||
-- output
|
||
bit_out <= shift_reg(0);
|
||
|
||
END vhdl;
|
atari_chips/pokeyv2/pokey_countdown_timer.vhdl | ||
---|---|---|
---------------------------------------------------------------------------
|
||
-- (c) 2013 mark watson
|
||
-- I am happy for anyone to use this for non-commercial use.
|
||
-- If my vhdl files are used commercially or otherwise sold,
|
||
-- please contact me for explicit permission at scrameta (gmail).
|
||
-- This applies for source and binary form and derived works.
|
||
---------------------------------------------------------------------------
|
||
LIBRARY ieee;
|
||
USE ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
|
||
ENTITY pokey_countdown_timer IS
|
||
generic(UNDERFLOW_DELAY : natural := 3);
|
||
PORT
|
||
(
|
||
CLK : IN STD_LOGIC;
|
||
ENABLE : IN STD_LOGIC;
|
||
ENABLE_UNDERFLOW : IN STD_LOGIC;
|
||
RESET_N : IN STD_LOGIC;
|
||
|
||
WR_EN : IN STD_LOGIC;
|
||
DATA_IN : IN STD_LOGIC_VECTOR(7 downto 0);
|
||
|
||
DATA_OUT : OUT STD_LOGIC
|
||
);
|
||
END pokey_countdown_timer;
|
||
|
||
ARCHITECTURE vhdl OF pokey_countdown_timer IS
|
||
component delay_line IS
|
||
generic(COUNT : natural := 1);
|
||
PORT
|
||
(
|
||
CLK : IN STD_LOGIC;
|
||
SYNC_RESET : IN STD_LOGIC;
|
||
DATA_IN : IN STD_LOGIC;
|
||
|
||
ENABLE : IN STD_LOGIC;
|
||
RESET_N : IN STD_LOGIC;
|
||
|
||
DATA_OUT : OUT STD_LOGIC
|
||
);
|
||
END component;
|
||
|
||
function To_Std_Logic(L: BOOLEAN) return std_ulogic is
|
||
begin
|
||
if L then
|
||
return('1');
|
||
else
|
||
return('0');
|
||
end if;
|
||
end function To_Std_Logic;
|
||
|
||
signal count_reg : std_logic_vector(7 downto 0);
|
||
signal count_next: std_logic_vector(7 downto 0);
|
||
|
||
signal underflow : std_logic;
|
||
|
||
signal count_command : std_logic_vector(1 downto 0);
|
||
signal underflow_command: std_logic_vector(1 downto 0);
|
||
BEGIN
|
||
-- Instantiate delay (provides output)
|
||
underflow0_delay : delay_line
|
||
generic map (COUNT=>UNDERFLOW_DELAY)
|
||
port map(clk=>clk,sync_reset=>wr_en,data_in=>underflow,enable=>ENABLE_UNDERFLOW,reset_n=>reset_n,data_out=>data_out);
|
||
|
||
-- register
|
||
process(clk,reset_n)
|
||
begin
|
||
if (reset_N = '0') then
|
||
count_reg <= (others=>'0');
|
||
elsif (clk'event and clk='1') then
|
||
count_reg <= count_next;
|
||
end if;
|
||
end process;
|
||
|
||
-- count down on enable
|
||
process(count_reg,enable,wr_en,count_command,data_in)
|
||
begin
|
||
count_command <= enable&wr_en;
|
||
case count_command is
|
||
when "10" =>
|
||
count_next <= std_logic_vector(unsigned(count_reg) -1);
|
||
when "01"|"11" =>
|
||
count_next <= data_in;
|
||
when others =>
|
||
count_next <= count_reg;
|
||
end case;
|
||
end process;
|
||
|
||
-- underflow
|
||
process(count_reg,enable,underflow_command)
|
||
begin
|
||
underflow_command <= enable & To_Std_Logic(count_reg = X"00");
|
||
case underflow_command is
|
||
when "11" =>
|
||
underflow <= '1';
|
||
when others =>
|
||
underflow <= '0';
|
||
end case;
|
||
end process;
|
||
|
||
END vhdl;
|
atari_chips/pokeyv2/pokey.vhdl | ||
---|---|---|
---------------------------------------------------------------------------
|
||
-- (c) 2013 mark watson
|
||
-- I am happy for anyone to use this for non-commercial use.
|
||
-- If my vhdl files are used commercially or otherwise sold,
|
||
-- please contact me for explicit permission at scrameta (gmail).
|
||
-- This applies for source and binary form and derived works.
|
||
---------------------------------------------------------------------------
|
||
LIBRARY ieee;
|
||
USE ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
|
||
-- Problem - UART on the DE1 does not have all pins connected. Need to use...
|
||
|
||
ENTITY pokey IS
|
||
GENERIC
|
||
(
|
||
CUSTOM_KEYBOARD_SCAN : integer := 0 -- 0:drive from hsync-like, 1:otherwise custom increment signal, 2:remove!
|
||
);
|
||
PORT
|
||
(
|
||
CLK : IN STD_LOGIC;
|
||
ENABLE_179 :in std_logic;
|
||
ADDR : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
|
||
DATA_IN : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
|
||
WR_EN : IN STD_LOGIC;
|
||
|
||
RESET_N : IN STD_LOGIC;
|
||
|
||
-- keyboard interface
|
||
keyboard_scan_enable : in std_logic := '0';
|
||
keyboard_scan : out std_logic_vector(5 downto 0);
|
||
keyboard_scan_update : out std_logic;
|
||
keyboard_response : in std_logic_vector(1 downto 0);
|
||
|
||
-- pots - go high as capacitor charges
|
||
POT_IN : in std_logic_vector(7 downto 0);
|
||
|
||
-- sio interface
|
||
SIO_IN1 : IN std_logic;
|
||
|
||
DATA_OUT : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
|
||
|
||
CHANNEL_0_OUT : OUT STD_LOGIC_VECTOR(3 downto 0);
|
||
CHANNEL_1_OUT : OUT STD_LOGIC_VECTOR(3 downto 0);
|
||
CHANNEL_2_OUT : OUT STD_LOGIC_VECTOR(3 downto 0);
|
||
CHANNEL_3_OUT : OUT STD_LOGIC_VECTOR(3 downto 0);
|
||
|
||
IRQ_N_OUT : OUT std_logic;
|
||
|
||
SIO_OUT1 : OUT std_logic;
|
||
SIO_OUT2 : OUT std_logic;
|
||
SIO_OUT3 : OUT std_logic;
|
||
|
||
SIO_CLOCKIN_IN : IN std_logic := '1';
|
||
SIO_CLOCKIN_OUT : OUT std_logic;
|
||
SIO_CLOCKIN_OE : OUT std_logic;
|
||
SIO_CLOCKOUT : OUT std_logic;
|
||
|
||
POT_RESET : out std_logic
|
||
);
|
||
END pokey;
|
||
|
||
ARCHITECTURE vhdl OF pokey IS
|
||
component synchronizer IS
|
||
PORT
|
||
(
|
||
CLK : IN STD_LOGIC;
|
||
RAW : IN STD_LOGIC;
|
||
SYNC : OUT STD_LOGIC
|
||
);
|
||
END component;
|
||
|
||
component syncreset_enable_divider IS
|
||
generic(COUNT : natural := 1; RESETCOUNT : natural := 0);
|
||
PORT
|
||
(
|
||
CLK : IN STD_LOGIC;
|
||
syncreset : in std_logic;
|
||
reset_n : in std_logic;
|
||
ENABLE_IN : IN STD_LOGIC;
|
||
|
||
ENABLE_OUT : OUT STD_LOGIC
|
||
);
|
||
END component;
|
||
|
||
component pokey_poly_17_9 IS
|
||
PORT
|
||
(
|
||
CLK : IN STD_LOGIC;
|
||
RESET_N : IN STD_LOGIC;
|
||
ENABLE : IN STD_LOGIC;
|
||
SELECT_9_17 : IN STD_LOGIC; -- 9 high, 17 low
|
||
INIT : IN STD_LOGIC;
|
||
|
||
BIT_OUT : OUT STD_LOGIC;
|
||
|
||
RAND_OUT : OUT std_logic_vector(7 downto 0)
|
||
);
|
||
END component;
|
||
|
||
component pokey_poly_5 IS
|
||
PORT
|
||
(
|
||
CLK : IN STD_LOGIC;
|
||
RESET_N : IN STD_LOGIC;
|
||
ENABLE : IN STD_LOGIC;
|
||
INIT : IN STD_LOGIC;
|
||
|
||
BIT_OUT : OUT STD_LOGIC
|
||
);
|
||
END component;
|
||
|
||
component pokey_poly_4 IS
|
||
PORT
|
||
(
|
||
CLK : IN STD_LOGIC;
|
||
RESET_N : IN STD_LOGIC;
|
||
ENABLE : IN STD_LOGIC;
|
||
INIT : IN STD_LOGIC;
|
||
|
||
BIT_OUT : OUT STD_LOGIC
|
||
);
|
||
END component;
|
||
|
||
component pokey_countdown_timer IS
|
||
generic(UNDERFLOW_DELAY : natural := 3);
|
||
PORT
|
||
(
|
||
CLK : IN STD_LOGIC;
|
||
ENABLE : IN STD_LOGIC;
|
||
ENABLE_UNDERFLOW : IN STD_LOGIC;
|
||
RESET_N : IN STD_LOGIC;
|
||
|
||
WR_EN : IN STD_LOGIC;
|
||
DATA_IN : IN STD_LOGIC_VECTOR(7 downto 0);
|
||
|
||
DATA_OUT : OUT STD_LOGIC
|
||
);
|
||
END component;
|
||
|
||
component pokey_noise_filter IS
|
||
PORT
|
||
(
|
||
CLK : IN STD_LOGIC;
|
||
RESET_N : IN STD_LOGIC;
|
||
|
||
NOISE_SELECT : IN STD_LOGIC_VECTOR(2 downto 0);
|
||
|
||
PULSE_IN : IN STD_LOGIC;
|
||
|
||
NOISE_4 : IN STD_LOGIC;
|
||
NOISE_5 : IN STD_LOGIC;
|
||
NOISE_LARGE : IN STD_LOGIC;
|
||
|
||
SYNC_RESET : IN STD_LOGIC;
|
||
|
||
PULSE_OUT : OUT STD_LOGIC
|
||
);
|
||
END component;
|
||
|
||
COMPONENT complete_address_decoder IS
|
||
generic (width : natural := 1);
|
||
PORT
|
||
(
|
||
addr_in : in std_logic_vector(width-1 downto 0);
|
||
addr_decoded : out std_logic_vector((2**width)-1 downto 0)
|
||
);
|
||
END component;
|
||
|
||
component delay_line IS
|
||
generic(COUNT : natural := 1);
|
||
PORT
|
||
(
|
||
CLK : IN STD_LOGIC;
|
||
SYNC_RESET : IN STD_LOGIC;
|
||
DATA_IN : IN STD_LOGIC;
|
||
ENABLE : IN STD_LOGIC;
|
||
RESET_N : IN STD_LOGIC;
|
||
|
||
DATA_OUT : OUT STD_LOGIC
|
||
);
|
||
END component;
|
||
|
||
component latch_delay_line IS
|
||
generic(COUNT : natural := 1);
|
||
PORT
|
||
(
|
||
CLK : IN STD_LOGIC;
|
||
SYNC_RESET : IN STD_LOGIC;
|
||
DATA_IN : IN STD_LOGIC;
|
||
ENABLE : IN STD_LOGIC;
|
||
RESET_N : IN STD_LOGIC;
|
||
|
||
DATA_OUT : OUT STD_LOGIC
|
||
);
|
||
END component;
|
||
|
||
component pokey_keyboard_scanner is
|
||
port
|
||
(
|
||
clk : in std_logic;
|
||
reset_n : in std_logic;
|
||
|
||
enable : in std_logic; -- typically hsync or equiv timing
|
||
keyboard_response : in std_logic_vector(1 downto 0);
|
||
debounce_disable : in std_logic;
|
||
scan_enable : in std_logic;
|
||
|
||
keyboard_scan : out std_logic_vector(5 downto 0);
|
||
|
||
key_held : out std_logic;
|
||
shift_held : out std_logic;
|
||
keycode : out std_logic_vector(7 downto 0);
|
||
other_key_irq : out std_logic;
|
||
break_irq : out std_logic
|
||
);
|
||
end component;
|
||
|
||
--signal enable_179 : std_logic;
|
||
signal enable_64 : std_logic;
|
||
signal enable_15 : std_logic;
|
||
|
||
signal audf0_reg : std_logic_vector(7 downto 0);
|
||
signal audc0_reg : std_logic_vector(7 downto 0);
|
||
signal audf1_reg : std_logic_vector(7 downto 0);
|
||
signal audc1_reg : std_logic_vector(7 downto 0);
|
||
signal audf2_reg : std_logic_vector(7 downto 0);
|
||
signal audc2_reg : std_logic_vector(7 downto 0);
|
||
signal audf3_reg : std_logic_vector(7 downto 0);
|
||
signal audc3_reg : std_logic_vector(7 downto 0);
|
||
signal audctl_reg : std_logic_vector(7 downto 0);
|
||
signal audf0_next : std_logic_vector(7 downto 0);
|
||
signal audc0_next : std_logic_vector(7 downto 0);
|
||
signal audf1_next : std_logic_vector(7 downto 0);
|
||
signal audc1_next : std_logic_vector(7 downto 0);
|
||
signal audf2_next : std_logic_vector(7 downto 0);
|
||
signal audc2_next : std_logic_vector(7 downto 0);
|
||
signal audf3_next : std_logic_vector(7 downto 0);
|
||
signal audc3_next : std_logic_vector(7 downto 0);
|
||
signal audctl_next : std_logic_vector(7 downto 0);
|
||
|
||
signal audf0_pulse_raw : std_logic;
|
||
signal audf1_pulse_raw : std_logic;
|
||
signal audf2_pulse_raw : std_logic;
|
||
signal audf3_pulse_raw : std_logic;
|
||
|
||
signal audf0_pulse : std_logic;
|
||
signal audf1_pulse : std_logic;
|
||
signal audf2_pulse : std_logic;
|
||
signal audf3_pulse : std_logic;
|
||
|
||
signal audf0_reload : std_logic;
|
||
signal audf1_reload : std_logic;
|
||
signal audf2_reload : std_logic;
|
||
signal audf3_reload : std_logic;
|
||
|
||
signal stimer_write : std_logic;
|
||
signal stimer_write_delayed : std_logic;
|
||
|
||
signal audf0_pulse_noise : std_logic;
|
||
signal audf1_pulse_noise : std_logic;
|
||
signal audf2_pulse_noise : std_logic;
|
||
signal audf3_pulse_noise : std_logic;
|
||
|
||
signal audf0_enable : std_logic;
|
||
signal audf1_enable : std_logic;
|
||
signal audf2_enable : std_logic;
|
||
signal audf3_enable : std_logic;
|
||
|
||
signal chan0_output_next : std_logic;
|
||
signal chan1_output_next : std_logic;
|
||
signal chan2_output_next : std_logic;
|
||
signal chan3_output_next : std_logic;
|
||
signal chan0_output_reg : std_logic;
|
||
signal chan1_output_reg : std_logic;
|
||
signal chan2_output_reg : std_logic;
|
||
signal chan3_output_reg : std_logic;
|
||
|
||
signal chan0_output_del_next : std_logic;
|
||
signal chan1_output_del_next : std_logic;
|
||
signal chan0_output_del_reg : std_logic;
|
||
signal chan1_output_del_reg : std_logic;
|
||
|
||
signal highpass0_next : std_logic;
|
||
signal highpass1_next : std_logic;
|
||
signal highpass0_reg : std_logic;
|
||
signal highpass1_reg : std_logic;
|
||
|
||
signal volume_channel_0_next : std_logic_vector(3 downto 0);
|
||
signal volume_channel_1_next : std_logic_vector(3 downto 0);
|
||
signal volume_channel_2_next : std_logic_vector(3 downto 0);
|
||
signal volume_channel_3_next : std_logic_vector(3 downto 0);
|
||
signal volume_channel_0_reg : std_logic_vector(3 downto 0);
|
||
signal volume_channel_1_reg : std_logic_vector(3 downto 0);
|
||
signal volume_channel_2_reg : std_logic_vector(3 downto 0);
|
||
signal volume_channel_3_reg : std_logic_vector(3 downto 0);
|
||
|
||
signal addr_decoded : std_logic_vector(15 downto 0);
|
||
|
||
signal noise_4 : std_logic;
|
||
signal noise_5 : std_logic;
|
||
signal noise_large : std_logic;
|
||
signal noise_4_next : std_logic_vector(2 downto 0);
|
||
signal noise_4_reg : std_logic_vector(2 downto 0);
|
||
signal noise_5_next : std_logic_vector(2 downto 0);
|
||
signal noise_5_reg : std_logic_vector(2 downto 0);
|
||
signal noise_large_next : std_logic_vector(2 downto 0);
|
||
signal noise_large_reg : std_logic_vector(2 downto 0);
|
||
|
||
signal rand_out : std_logic_vector(7 downto 0); -- snoop part of the shift reg
|
||
|
||
signal initmode : std_logic;
|
||
|
||
signal irqen_next : std_logic_vector(7 downto 0);
|
||
signal irqen_reg : std_logic_vector(7 downto 0);
|
||
|
||
signal irqst_next : std_logic_vector(7 downto 0);
|
||
signal irqst_reg : std_logic_vector(7 downto 0);
|
||
|
||
signal irq_n_next : std_logic;
|
||
signal irq_n_reg : std_logic; -- for output
|
||
|
||
-- serial ports!
|
||
signal serial_ip_ready_interrupt : std_logic;
|
||
signal serial_ip_framing_next : std_logic;
|
||
signal serial_ip_framing_reg : std_logic;
|
||
signal serial_ip_overrun_next : std_logic;
|
||
signal serial_ip_overrun_reg : std_logic;
|
||
signal serial_op_needed_interrupt : std_logic;
|
||
|
||
signal skctl_next : std_logic_vector(7 downto 0);
|
||
signal skctl_reg : std_logic_vector(7 downto 0);
|
||
|
||
signal serin_shift_next : std_logic_vector(9 downto 0);
|
||
signal serin_shift_reg : std_logic_vector(9 downto 0);
|
||
signal serin_next : std_logic_vector(7 downto 0);
|
||
signal serin_reg : std_logic_vector(7 downto 0);
|
||
signal serin_bitcount_next : std_logic_vector(3 downto 0);
|
||
signal serin_bitcount_reg : std_logic_vector(3 downto 0);
|
||
|
||
signal sio_in1_reg : std_logic;
|
||
signal sio_in2_reg : std_logic;
|
||
signal sio_clockin_in1_reg : std_logic;
|
||
signal sio_in_next : std_logic;
|
||
signal sio_in_reg : std_logic;
|
||
|
||
signal sio_out_next : std_logic;
|
||
signal sio_out_reg : std_logic;
|
||
signal serial_out_next : std_logic;
|
||
signal serial_out_reg : std_logic;
|
||
|
||
signal serout_shift_next : std_logic_vector(9 downto 0);
|
||
signal serout_shift_reg : std_logic_vector(9 downto 0);
|
||
|
||
signal serout_holding_full_next : std_logic;
|
||
signal serout_holding_full_reg : std_logic;
|
||
signal serout_holding_next : std_logic_vector(7 downto 0);
|
||
signal serout_holding_reg : std_logic_vector(7 downto 0);
|
||
signal serout_holding_load : std_logic;
|
||
|
||
signal serout_bitcount_next : std_logic_vector(3 downto 0);
|
||
signal serout_bitcount_reg : std_logic_vector(3 downto 0);
|
||
|
||
signal serout_active_next : std_logic;
|
||
signal serout_active_reg : std_logic;
|
||
|
||
signal serial_reset : std_logic;
|
||
signal serout_sync_reset : std_logic;
|
||
signal skrest_write : std_logic;
|
||
|
||
signal serout_enable : std_logic;
|
||
signal serout_enable_delayed : std_logic;
|
||
signal serin_enable : std_logic;
|
||
signal serin_enable_delayed : std_logic;
|
||
|
||
signal async_serial_reset : std_logic;
|
||
signal waiting_for_start_bit : std_logic;
|
||
|
||
signal serin_clock_next : std_logic;
|
||
signal serin_clock_reg : std_logic;
|
||
signal serin_clock_last_next : std_logic;
|
||
signal serin_clock_last_reg : std_logic;
|
||
|
||
signal serout_clock_next : std_logic;
|
||
signal serout_clock_reg : std_logic;
|
||
signal serout_clock_last_next : std_logic;
|
||
signal serout_clock_last_reg : std_logic;
|
||
|
||
signal twotone_reset : std_logic;
|
||
signal twotone_reset_delayed : std_logic;
|
||
signal twotone_next : std_logic;
|
||
signal twotone_reg : std_logic;
|
||
|
||
signal clock_next : std_logic;
|
||
signal clock_reg : std_logic;
|
||
signal clock_sync_next : std_logic;
|
||
signal clock_sync_reg : std_logic;
|
||
signal clock_input : std_logic;
|
||
|
||
-- keyboard
|
||
signal keyboard_overrun_next : std_logic;
|
||
signal keyboard_overrun_reg : std_logic;
|
||
|
||
signal shift_held : std_logic;
|
||
signal break_irq : std_logic;
|
||
signal key_held : std_logic;
|
||
signal other_key_irq : std_logic;
|
||
|
||
signal kbcode : std_logic_vector(7 downto 0);
|
||
|
||
-- pots
|
||
signal pot0_next : std_logic_vector(7 downto 0);
|
||
signal pot0_reg : std_logic_vector(7 downto 0);
|
||
signal pot1_next : std_logic_vector(7 downto 0);
|
||
signal pot1_reg : std_logic_vector(7 downto 0);
|
||
signal pot2_next : std_logic_vector(7 downto 0);
|
||
signal pot2_reg : std_logic_vector(7 downto 0);
|
||
signal pot3_next : std_logic_vector(7 downto 0);
|
||
signal pot3_reg : std_logic_vector(7 downto 0);
|
||
signal pot4_next : std_logic_vector(7 downto 0);
|
||
signal pot4_reg : std_logic_vector(7 downto 0);
|
||
signal pot5_next : std_logic_vector(7 downto 0);
|
||
signal pot5_reg : std_logic_vector(7 downto 0);
|
||
signal pot6_next : std_logic_vector(7 downto 0);
|
||
signal pot6_reg : std_logic_vector(7 downto 0);
|
||
signal pot7_next : std_logic_vector(7 downto 0);
|
||
signal pot7_reg : std_logic_vector(7 downto 0);
|
||
|
||
signal allpot_next : std_logic_vector(7 downto 0);
|
||
signal allpot_reg : std_logic_vector(7 downto 0);
|
||
|
||
signal pot_counter_next : std_logic_vector(7 downto 0);
|
||
signal pot_counter_reg : std_logic_vector(7 downto 0);
|
||
|
||
signal potgo_write : std_logic;
|
||
|
||
signal pot_reset_next : std_logic;
|
||
signal pot_reset_reg : std_logic;
|
||
BEGIN
|
||
-- register
|
||
process(clk,reset_n)
|
||
begin
|
||
if (reset_n = '0') then
|
||
-- FIXME - Pokey does not have RESET - instead this is caused by 'init' sequence
|
||
audf0_reg <= X"00";
|
||
audc0_reg <= X"00";
|
||
audf1_reg <= X"00";
|
||
audc1_reg <= X"00";
|
||
audf2_reg <= X"00";
|
||
audc2_reg <= X"00";
|
||
audf3_reg <= X"00";
|
||
audc3_reg <= X"00";
|
||
audctl_reg <= X"00";
|
||
|
||
irqen_reg <= X"00";
|
||
irqst_reg <= X"FF";
|
||
irq_n_reg <= '1';
|
||
|
||
skctl_reg <= X"00";
|
||
|
||
highpass0_reg <= '0';
|
||
highpass1_reg <= '0';
|
||
|
||
chan0_output_reg <= '0';
|
||
chan1_output_reg <= '0';
|
||
chan2_output_reg <= '0';
|
||
chan3_output_reg <= '0';
|
||
|
||
chan0_output_del_reg <= '0';
|
||
chan1_output_del_reg <= '0';
|
||
|
||
volume_channel_0_reg <= (others=>'0');
|
||
volume_channel_1_reg <= (others=>'0');
|
||
volume_channel_2_reg <= (others=>'0');
|
||
volume_channel_3_reg <= (others=>'0');
|
||
|
||
serin_reg <= (others=>'0');
|
||
serin_shift_reg <= (others=>'0');
|
||
serin_bitcount_reg <= (others=>'0');
|
||
serout_shift_reg <= (others=>'0');
|
||
serout_holding_reg <= (others=>'0');
|
||
serout_holding_full_reg <= '0';
|
||
serout_active_reg <= '0';
|
||
sio_out_reg <= '1';
|
||
serial_out_reg <= '1';
|
||
|
||
serial_ip_framing_reg <= '0';
|
||
serial_ip_overrun_reg <= '0';
|
||
|
||
clock_reg <= '0';
|
||
clock_sync_reg <= '0';
|
||
|
||
keyboard_overrun_reg <= '0';
|
||
|
||
serin_clock_reg <= '0';
|
||
serin_clock_last_reg <= '0';
|
||
serout_clock_reg <= '0';
|
||
serout_clock_last_reg <= '0';
|
||
|
||
twotone_reg <= '0';
|
||
|
||
sio_in_reg <= '0';
|
||
|
||
pot0_reg <= (others=>'0');
|
||
pot1_reg <= (others=>'0');
|
||
pot2_reg <= (others=>'0');
|
||
pot3_reg <= (others=>'0');
|
||
pot4_reg <= (others=>'0');
|
||
pot5_reg <= (others=>'0');
|
||
pot6_reg <= (others=>'0');
|
||
pot7_reg <= (others=>'0');
|
||
|
||
allpot_reg <= (others=>'1');
|
||
|
Also available in: Unified diff
Moved pokey to a folder