Project

General

Profile

---------------------------------------------------------------------------
-- 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;
(10-10/13)