--------------------------------------------------------------------------- -- NES-Controller Module --------------------------------------------------------------------------- -- This file is a part of "Aeon Lite" project -- Dmitriy Schapotschkin aka ILoveSpeccy '2014 -- ilovespeccy@speccyland.net -- Project homepage: www.speccyland.net --------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; ------------------ -- Bit - Button -- -- (1 = pressed) ------------------ -- 7 A -- 6 B -- 5 Select -- 4 Start -- 3 Up -- 2 Down -- 1 Left -- 0 Right ------------------ entity nes_gamepad is generic ( CLK_FREQ : integer := 25000000; TICK_FREQ : integer := 20000 ); port ( CLK : in std_logic; RESET : in std_logic; JOY_CLK : out std_logic; JOY_LOAD : out std_logic; JOY_DATA0 : in std_logic; JOY_DATA1 : in std_logic; JOY0_BUTTONS : out std_logic_vector(7 downto 0); JOY1_BUTTONS : out std_logic_vector(7 downto 0); JOY0_CONNECTED : out std_logic; -- 1 when gamepad connected JOY1_CONNECTED : out std_logic ); end nes_gamepad; architecture RTL of nes_gamepad is signal TICK : integer range 0 to (CLK_FREQ / TICK_FREQ); signal STATE : integer range 0 to 17; signal DATA0 : std_logic_vector(7 downto 0); signal DATA1 : std_logic_vector(7 downto 0); begin process (CLK) begin if rising_edge(CLK) then if RESET = '1' then STATE <= 0; JOY_CLK <= '0'; JOY_LOAD <= '0'; TICK <= 0; JOY0_BUTTONS <= "00000000"; JOY0_BUTTONS <= "00000000"; JOY0_CONNECTED <= '0'; JOY1_CONNECTED <= '0'; else TICK <= TICK + 1; if TICK = (CLK_FREQ / TICK_FREQ) then TICK <= 0; STATE <= STATE + 1; case STATE is when 0 => JOY_LOAD <= '1'; when 1 => JOY_LOAD <= '0'; DATA0(7) <= JOY_DATA0; DATA1(7) <= JOY_DATA1; when 2 | 4 | 6 | 8 | 10 | 12 | 14 | 16 => JOY_CLK <= '1'; when 3 => JOY_CLK <= '0'; DATA0(6) <= JOY_DATA0; DATA1(6) <= JOY_DATA1; when 5 => JOY_CLK <= '0'; DATA0(5) <= JOY_DATA0; DATA1(5) <= JOY_DATA1; when 7 => JOY_CLK <= '0'; DATA0(4) <= JOY_DATA0; DATA1(4) <= JOY_DATA1; when 9 => JOY_CLK <= '0'; DATA0(3) <= JOY_DATA0; DATA1(3) <= JOY_DATA1; when 11 => JOY_CLK <= '0'; DATA0(2) <= JOY_DATA0; DATA1(2) <= JOY_DATA1; when 13 => JOY_CLK <= '0'; DATA0(1) <= JOY_DATA0; DATA1(1) <= JOY_DATA1; when 15 => JOY_CLK <= '0'; DATA0(0) <= JOY_DATA0; DATA1(0) <= JOY_DATA1; when 17 => JOY_CLK <= '0'; JOY0_BUTTONS <= "00000000"; JOY1_BUTTONS <= "00000000"; JOY0_CONNECTED <= '0'; JOY1_CONNECTED <= '0'; STATE <= 0; if DATA0 /= "00000000" then -- gamepad connected JOY0_BUTTONS <= not DATA0; JOY0_CONNECTED <= '1'; end if; if DATA1 /= "00000000" then -- gamepad connected JOY1_BUTTONS <= not DATA1; JOY1_CONNECTED <= '1'; end if; when OTHERS => NULL; end case; end if; end if; end if; end process; end RTL;