--
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
--
--
entity gide is
port ( ECBRes : in std_logic;
A : in std_logic_vector (7 downto 0);
JUMPER_A : in std_logic_vector (3 downto 0);
IORQ : in std_logic;
RD : in std_logic;
WR : in std_logic;
D : inout std_logic_vector (7 downto 0);
CLK : in std_logic;
IDE_D : inout std_logic_vector (15 downto 0);
IDE_CS0 : out std_logic;
IDE_CS1 : out std_logic;
IDE_RD : out std_logic;
IDE_WR : out std_logic;
IDE_A : out std_logic_vector (2 downto 0)
);
end gide;
--
architecture Behavioral of gide is
signal DOUT : std_logic_vector(7 downto 0);
signal DIDEOUT : std_logic_vector(15 downto 0);
signal CS_READ : std_logic;
signal CS : std_logic;
signal CS_16BIT : std_logic;
signal WAS_16BIT : std_logic;
signal READ_ACTIVE : std_logic;
signal READ_BUFFER : std_logic_vector(7 downto 0);
signal CS_WRITE : std_logic;
signal ACCESS_HIGH : std_logic;
signal ADDRESSOK : std_logic;
signal SELECTDISK_WR: std_logic;
signal READSTATE : integer range 0 to 2;
--
signal TOGGLERSTATE : integer range 0 to 2;
signal IDE_RD_INT : std_logic;
--
begin
ADDRESSOK <= '1' when A (7 downto 4) = JUMPER_A else '0';
--
CS <= '1' when (IORQ = '0') and (ADDRESSOK = '1') else '0';
--
CS_16BIT <= '1' when (CS = '1') and (A(3 downto 0) = "1000") else '0';
--
CS_READ <= '1' when (CS = '1') and (RD = '0') else '0';
--
CS_WRITE <= '1' when (CS = '1') and (WR = '0') else '0';
--
--
LatchIDE_WR:process(SELECTDISK_WR,WR)
begin
if WR = '1' then
IDE_WR <= '1';
elsif rising_edge(SELECTDISK_WR) then
IDE_WR <= '0';
end if;
end process;
--
--
LatchAddr:process(ECBRES,CLK)
begin
if (ECBRES = '0') then
IDE_CS0 <= '0';
IDE_CS1 <= '0';
IDE_A <= "000";
elsif falling_edge(CLK) then
IDE_CS0 <= not A(3);
IDE_CS1 <= A(3);
IDE_A <= A(2 downto 0);
end if;
end process;
--
LatchIdeRd:process(IDE_RD_INT,IORQ)
begin
if IORQ = '1' then
IDE_RD <= '1';
elsif falling_edge(IDE_RD_INT) then
IDE_RD <= '0';
end if;
end process;
--
--
HighLowToggler:process(CLK,ECBRes,CS)
begin
if ECBRes = '0' then
ACCESS_HIGH <= '0';
TOGGLERSTATE <= 0;
WAS_16BIT <= '0';
elsif rising_edge(CLK) then
case TOGGLERSTATE is
when 0 => if CS = '1' then
TOGGLERSTATE <= 1;
if A(3 downto 0) = "1000" then
WAS_16BIT <= '1';
else
WAS_16BIT <= '0';
end if;
end if;
when 1 => if CS = '0' then
TOGGLERSTATE <= 2;
end if;
when 2 => if WAS_16BIT = '1' then
ACCESS_HIGH <= not ACCESS_HIGH;
else
ACCESS_HIGH <= '0';
end if;
TOGGLERSTATE <= 0;
end case;
end if;
end process;
--
--
writeData:process(CS_WRITE)
begin
if rising_edge(CS_WRITE) then
if A(3 downto 0) = "1000" then
if ACCESS_HIGH = '0' then
DIDEOUT(7 downto 0) <= D;
else
DIDEOUT(15 downto 8) <= D;
end if;
else
DIDEOUT(15 downto 8) <= "00000000";
DIDEOUT(7 downto 0) <= D;
end if;
end if;
end process;
--
--
SetWriteActive:process(CLK,ECBRes,CS_WRITE,ACCESS_HIGH)
begin
if ECBRes = '0' then
SELECTDISK_WR <= '0';
elsif falling_edge(CLK) then
if CS_WRITE = '1' then
if A(3 downto 0) = "1000" then
if ACCESS_HIGH = '1' then
SELECTDISK_WR <= '1';
else
SELECTDISK_WR <= '0';
end if;
else
SELECTDISK_WR <= '1';
end if;
else
SELECTDISK_WR <= '0';
end if;
end if;
end process;
--
--
SetReadActive:process(CLK,ECBRes)
begin
if ECBRes = '0' then
READ_Active <= '0';
IDE_RD_INT <= '1';
READSTATE <= 0;
elsif falling_edge(CLK) then
if CS_READ = '1' then
if READ_Active = '0' then
READ_Active <= '1';
end if;
if READSTATE = 0 then
if (ACCESS_HIGH = '0') or (CS_16BIT = '0') then
IDE_RD_INT <= '0';
else
IDE_RD_INT <= '1';
end if;
READSTATE <= READSTATE + 1;
elsif READSTATE = 1 then
IDE_RD_INT <= '1';
READSTATE <= READSTATE + 1;
end if;
else
READ_Active <= '0';
IDE_RD_INT <= '1';
READSTATE <= 0;
end if;
end if;
end process;
--
READER:process(CLK,CS_16BIT,ACCESS_HIGH)
begin
if rising_edge(CLK) then
if READSTATE = 1 then
if CS_16BIT = '1' then
if ACCESS_HIGH = '0' then
DOUT <= IDE_D(7 downto 0);
READ_BUFFER <= IDE_D(15 downto 8);
else
DOUT <= READ_BUFFER;
end if;
else
DOUT <= IDE_D(7 downto 0);
end if;
end if;
end if;
end process;
--
D <= DOUT when (CS_READ = '1') else "ZZZZZZZZ";
--
IDE_D <= DIDEOUT when (CS_WRITE = '1') else "ZZZZZZZZZZZZZZZZ";
--
end Behavioral;
--