Files
FireBee_SVN/vhdl/rtl/vhdl/DMA/fbee_dma.vhd
2014-06-09 20:35:29 +00:00

589 lines
26 KiB
VHDL

----------------------------------------------------------------------
---- ----
---- This file is part of the 'Firebee' project. ----
---- http://acp.atari.org ----
---- ----
---- Description: ----
---- This design unit provides the DMA controller of the 'Firebee'----
---- computer. It is optimized for the use of an Altera Cyclone ----
---- FPGA (EP3C40F484). This IP-Core is based on the first edi- ----
---- tion of the Firebee configware originally provided by Fredi ----
---- Ashwanden and Wolfgang Förster. This release is in compa- ----
---- rision to the first edition completely written in VHDL. ----
---- ----
---- Author(s): ----
---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2012 Fredi Aschwanden, Wolfgang Förster ----
---- ----
---- This source file 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 2 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, write to the Free ----
---- Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ----
---- Boston, MA 02110-1301, USA. ----
---- ----
----------------------------------------------------------------------
--
-- Revision History
--
-- Revision 2K12B 20120801 WF
-- Initial Release of the second edition.
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity FBEE_DMA is
port(
RESET : in std_logic;
CLK_MAIN : in std_logic;
CLK_FDC : in std_logic;
FB_ADR : in std_logic_vector(26 downto 0);
FB_ALE : in std_logic;
FB_SIZE : in std_logic_vector(1 downto 0);
FB_CSn : in std_logic_vector(2 downto 1);
FB_OEn : in std_logic;
FB_WRn : in std_logic;
FB_AD_IN : in std_logic_vector(31 downto 0);
FB_AD_OUT : out std_logic_vector(31 downto 0);
FB_AD_EN_31_24 : out std_logic;
FB_AD_EN_23_16 : out std_logic;
FB_AD_EN_15_8 : out std_logic;
FB_AD_EN_7_0 : out std_logic;
ACSI_DIR : out std_logic;
ACSI_D_IN : in std_logic_vector(7 downto 0);
ACSI_D_OUT : out std_logic_vector(7 downto 0);
ACSI_D_EN : out std_logic;
ACSI_CSn : out std_logic;
ACSI_A1 : out std_logic;
ACSI_RESETn : out std_logic;
ACSI_DRQn : in std_logic;
ACSI_ACKn : out std_logic;
DATA_IN_FDC : in std_logic_vector(7 downto 0);
DATA_IN_SCSI : in std_logic_vector(7 downto 0);
DATA_OUT_FDC_SCSI : out std_logic_vector(7 downto 0);
DMA_DRQ_IN : in std_logic; -- From 1772.
DMA_DRQ_OUT : out std_logic; -- To Interrupt handler.
DMA_DRQ11 : out std_logic; -- To MFP.
SCSI_DRQ : in std_logic;
SCSI_DACKn : out std_logic;
SCSI_INT : in std_logic;
SCSI_CSn : out std_logic;
SCSI_CS : out std_logic;
CA : out std_logic_vector(2 downto 0);
FLOPPY_HD_DD : in std_logic;
WDC_BSL0 : out std_logic;
FDC_CSn : out std_logic;
FDC_WRn : out std_logic;
FD_INT : in std_logic;
IDE_INT : in std_logic;
DMA_CS : out std_logic
);
end entity FBEE_DMA;
architecture BEHAVIOUR of FBEE_DMA is
component dcfifo0 is
port(
aclr : in std_logic := '0';
data : in std_logic_vector (7 downto 0);
rdclk : in std_logic ;
rdreq : in std_logic ;
wrclk : in std_logic ;
wrreq : in std_logic ;
q : out std_logic_vector (31 downto 0);
wrusedw : out std_logic_vector (9 downto 0)
);
end component;
component dcfifo1 is
port(
aclr : in std_logic := '0';
data : in std_logic_vector (31 downto 0);
rdclk : in std_logic ;
rdreq : in std_logic ;
wrclk : in std_logic ;
wrreq : in std_logic ;
q : out std_logic_vector (7 downto 0);
rdusedw : out std_logic_vector (9 downto 0)
);
end component;
type FCF_STATES is( FCF_IDLE, FCF_T0, FCF_T1, FCF_T2, FCF_T3, FCF_T6, FCF_T7);
signal FCF_STATE : FCF_STATES;
signal NEXT_FCF_STATE : FCF_STATES;
signal FCF_CS : std_logic;
signal FCF_APH : std_logic;
signal DMA_MODE_CS : std_logic;
signal DMA_DATA_CS : std_logic;
signal DMA_MODE : std_logic_vector(15 downto 0);
signal DMA_DRQQ : std_logic;
signal DMA_DRQ11_I : std_logic;
signal DMA_REQ : std_logic;
signal DMA_ACTIVE : std_logic;
signal DMA_ACTIVE_NEW : std_logic;
signal DMA_DRQ_REG : std_logic_vector(1 downto 0);
signal DMA_STATUS : std_logic_vector(2 downto 0);
signal DMA_AZ_CS : std_logic;
signal DMA_BYTECNT_CS : std_logic;
signal DMA_DIRECT_CS : std_logic;
signal DMA_TOP_CS : std_logic;
signal DMA_HIGH_CS : std_logic;
signal DMA_MID_CS : std_logic;
signal DMA_LOW_CS : std_logic;
signal DMA_ADR_CS : std_logic;
signal DMA_BYTECNT : std_logic_vector(31 downto 0);
signal DMA_TOP : std_logic_vector(7 downto 0);
signal DMA_HIGH : std_logic_vector(7 downto 0);
signal DMA_MID : std_logic_vector(7 downto 0);
signal DMA_LOW : std_logic_vector(7 downto 0);
signal DMA_SND_CS : std_logic;
signal SNDMACTL : std_logic_vector(7 downto 0);
signal SNDBASHI : std_logic_vector(7 downto 0);
signal SNDBASMI : std_logic_vector(7 downto 0);
signal SNDBASLO : std_logic_vector(7 downto 0);
signal SNDADRHI : std_logic_vector(7 downto 0);
signal SNDADRMI : std_logic_vector(7 downto 0);
signal SNDADRLO : std_logic_vector(7 downto 0);
signal SNDENDHI : std_logic_vector(7 downto 0);
signal SNDENDMI : std_logic_vector(7 downto 0);
signal SNDENDLO : std_logic_vector(7 downto 0);
signal SNDMODE : std_logic_vector(7 downto 0);
signal WDC_BSL : std_logic_vector(1 downto 0);
signal FDC_CS_In : std_logic;
signal CLR_FIFO : std_logic;
signal FDC_OUT : std_logic_vector(7 downto 0);
signal RDF_DIN : std_logic_vector(7 downto 0);
signal RDF_DOUT : std_logic_vector(31 downto 0);
signal RDF_AZ : std_logic_vector(9 downto 0);
signal RDF_RDE : std_logic;
signal RDF_WRE : std_logic;
signal WRF_DATA_OUT : std_logic_vector(7 downto 0);
signal WRF_AZ : std_logic_vector(9 downto 0);
signal WRF_RDE : std_logic;
signal WRF_WRE : std_logic;
signal WDC_BSL_CS : std_logic;
signal CA_I : std_logic_vector(2 downto 0);
signal FDC_CS : std_logic;
signal SCSI_CS_I : std_logic;
signal LONG : std_logic;
signal BYTE : std_logic;
signal FB_B1 : std_logic;
signal FB_B0 : std_logic;
signal WRF_DOUT : std_logic_vector(7 downto 0);
signal FB_AD_I : std_logic_vector(7 downto 0);
signal d : std_logic_vector(31 downto 0);
begin
LONG <= '1' when FB_SIZE(1) = '0' and FB_SIZE(0) = '0' else '0';
BYTE <= '1' when FB_SIZE(1) = '0' and FB_SIZE(0) = '1' else '0';
FB_B0 <= '1' when FB_ADR(0) = '0' or BYTE = '0' else '0';
FB_B1 <= '1' when FB_ADR(0) = '1' or BYTE = '0' else '0';
FB_AD_OUT(31 downto 24) <= DMA_TOP when DMA_TOP_CS = '1' and FB_OEn = '0' else
x"00" when DMA_DATA_CS = '1' and FB_OEn = '0' else
DMA_TOP when DMA_ADR_CS = '1' and FB_OEn = '0' else
DMA_BYTECNT(31 downto 24) when DMA_BYTECNT_CS = '1' and FB_OEn = '0' else
DMA_MODE(15 downto 8) when DMA_DIRECT_CS = '1' and FB_OEn = '0' else
x"00" when DMA_MODE_CS = '1' and FB_OEn = '0' else
DMA_DRQ11_I & DMA_DRQ_REG & IDE_INT & FD_INT & SCSI_INT & RDF_AZ(9 downto 8) when DMA_AZ_CS = '1' and FB_OEn = '0' else
RDF_DOUT(7 downto 0) when FCF_CS = '1' and FB_OEn = '0' else x"00";
FB_AD_OUT(23 downto 16) <= "00000" & DMA_STATUS when DMA_MODE_CS = '1' and FB_OEn = '0' else
FDC_OUT when DMA_DATA_CS = '1' and DMA_MODE(4 downto 3) = "00" and FB_OEn = '0' else
DATA_IN_SCSI when DMA_DATA_CS = '1' and DMA_MODE(4 downto 3) = "01" and FB_OEn = '0' else
DMA_BYTECNT(16 downto 9) when DMA_DATA_CS = '1' and DMA_MODE(4) = '1' and FB_OEn = '0' else
"0000" & (not DMA_STATUS(1)) & "0" & WDC_BSL(1) & FLOPPY_HD_DD when WDC_BSL_CS = '1' and FB_OEn = '0' else
RDF_AZ(7 downto 0) when DMA_AZ_CS = '1' and FB_OEn = '0' else
SNDMACTL when DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"0" and FB_OEn = '0' else
SNDBASHI when DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"1" and FB_OEn = '0' else
SNDBASMI when DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"2" and FB_OEn = '0' else
SNDBASLO when DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"3" and FB_OEn = '0' else
SNDADRHI when DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"4" and FB_OEn = '0' else
SNDADRMI when DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"5" and FB_OEn = '0' else
SNDADRLO when DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"6" and FB_OEn = '0' else
SNDENDHI when DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"7" and FB_OEn = '0' else
SNDENDMI when DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"8" and FB_OEn = '0' else
SNDENDLO when DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"9" and FB_OEn = '0' else
SNDMODE when DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"10" and FB_OEn = '0' else
DMA_HIGH when DMA_HIGH_CS = '1' and FB_OEn = '0' else
DMA_MID when DMA_MID_CS = '1' and FB_OEn = '0' else
DMA_LOW when DMA_LOW_CS = '1' and FB_OEn = '0' else
DMA_MODE(7 downto 0) when DMA_DIRECT_CS = '1' and FB_OEn = '0' else
DMA_HIGH when DMA_ADR_CS = '1' and FB_OEn = '0' else
DMA_BYTECNT(23 downto 16) when DMA_BYTECNT_CS = '1' and FB_OEn = '0' else
RDF_DOUT(15 downto 8) when FCF_CS = '1' and FB_OEn = '0' else x"00";
FB_AD_OUT(15 downto 8) <= "0" & DMA_STATUS & "00" & WRF_AZ(9 downto 8) when DMA_AZ_CS = '1' and FB_OEn = '0' else
DMA_MID when DMA_ADR_CS = '1' and FB_OEn = '0' else
DMA_BYTECNT(15 downto 8) when DMA_BYTECNT_CS = '1' and FB_OEn = '0' else
RDF_DOUT(23 downto 16) when FCF_CS = '1' and FB_OEn = '0' else x"00";
FB_AD_OUT(7 downto 0) <= WRF_AZ(7 downto 0) when DMA_AZ_CS = '1' and FB_OEn = '0' else
DMA_LOW when DMA_ADR_CS = '1' and FB_OEn = '0' else
DMA_BYTECNT(7 downto 0) when DMA_BYTECNT_CS = '1' and FB_OEn = '0' else
RDF_DOUT(31 downto 24) when FCF_CS = '1' and FB_OEn = '0' else x"00";
FB_AD_EN_31_24 <= (DMA_TOP_CS or DMA_DATA_CS or DMA_ADR_CS or DMA_BYTECNT_CS or DMA_DIRECT_CS or
DMA_MODE_CS or DMA_AZ_CS or FCF_CS) and not FB_OEn;
FB_AD_EN_23_16 <= (DMA_MODE_CS or DMA_DATA_CS or WDC_BSL_CS or DMA_AZ_CS or DMA_SND_CS or DMA_HIGH_CS or
DMA_MID_CS or DMA_LOW_CS or DMA_DIRECT_CS or DMA_ADR_CS or DMA_BYTECNT_CS or FCF_CS) and not FB_OEn;
FB_AD_EN_15_8 <= (DMA_AZ_CS or DMA_ADR_CS or DMA_BYTECNT_CS or FCF_CS) and not FB_OEn;
FB_AD_EN_7_0 <= (DMA_AZ_CS or DMA_ADR_CS or DMA_BYTECNT_CS or FCF_CS) and not FB_OEn;
INBUFFER: process(CLK_MAIN)
begin
if rising_edge(CLK_MAIN) then
if FB_WRn = '0' THEN
FB_AD_I <= FB_AD_IN(23 downto 16);
end if;
end if;
end process INBUFFER;
-- ACSI is currently disabled.
ACSI_DIR <= '0';
ACSI_D_OUT <= x"00";
ACSI_D_EN <= '0';
ACSI_CSn <= '1';
ACSI_A1 <= CA_I(1);
ACSI_RESETn <= not RESET;
ACSI_ACKn <= '1';
SCSI_CS <= SCSI_CS_I;
DMA_MODE_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = x"7C303" else '0'; -- F8606/2
DMA_DATA_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = x"7C302" else '0'; -- F8604/2
FDC_CS <= '1' when DMA_DATA_CS = '1' and DMA_MODE(4 downto 3) = "00" and FB_B1 = '1' else '0';
SCSI_CS_I <= '1' when DMA_DATA_CS = '1' and DMA_MODE(4 downto 3) = "01" and FB_B1 = '1' else '0';
DMA_AZ_CS <= '1' when FB_CSn(2) = '0' and FB_ADR(26 downto 0) = x"002010C" else '0'; -- F002'010C LONG
DMA_TOP_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = x"7C304" and FB_B0 = '1' else '0'; -- F8608/2
DMA_HIGH_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = x"7C304" and FB_B1 = '1' else '0'; -- F8609/2
DMA_MID_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = x"7C305" and FB_B1 = '1' else '0'; -- F860B/2
DMA_LOW_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = x"7C306" and FB_B1 = '1' else '0'; -- F860D/2
DMA_DIRECT_CS <= '1' when FB_CSn(2) = '0' and FB_ADR(26 downto 0) = x"20100" else '0'; -- F002'0100 WORD
DMA_ADR_CS <= '1' when FB_CSn(2) = '0' and FB_ADR(26 downto 0) = x"20104" else '0'; -- F002'0104 LONG
DMA_BYTECNT_CS <= '1' when FB_CSn(2) = '0' and FB_ADR(26 downto 0) = x"20108" else '0'; -- F002'0108 LONG
DMA_SND_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 6) = x"3E24" else '0'; -- F8900-F893F
FCF_CS <= '1' when FB_CSn(2) = '0' and FB_ADR(26 downto 0) = x"0020110" and LONG = '1' else '0'; -- F002'0110 LONG ONLY
DMA_CS <= FCF_CS or DMA_MODE_CS or DMA_SND_CS or DMA_ADR_CS or DMA_DIRECT_CS or DMA_BYTECNT_CS;
WDC_BSL_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = x"7C307" else '0'; -- F860E/2
FCF_APH <= '1' when FB_ALE = '1' and FB_AD_IN(31 downto 0) = x"F0020110" and LONG = '1' else '0'; -- ADRESSPHASE F0020110 LONG ONLY
RDF_DIN <= DATA_IN_FDC when DMA_MODE(7) = '1' else DATA_IN_SCSI;
RDF_RDE <= '1' when FCF_APH = '1' and FB_WRn = '1' else '0'; -- AKTIVIEREN IN ADRESSPHASE
DATA_OUT_FDC_SCSI <= WRF_DOUT when DMA_ACTIVE = '1' and DMA_MODE(8) = '1' else FB_AD_I; -- BEI DMA WRITE <-FIFO SONST <-FB
CA_I(0) <= '1' when DMA_ACTIVE = '1' else DMA_MODE(0);
CA_I(1) <= '1' when DMA_ACTIVE = '1' else DMA_MODE(1);
CA_I(2) <= '1' when DMA_ACTIVE = '1' else DMA_MODE(2);
CA <= CA_I;
FDC_WRn <= (not DMA_MODE(8)) when DMA_ACTIVE = '1' else FB_WRn;
DMA_MODE_REGISTER: process(RESET, CLK_MAIN)
begin
if RESET = '1' then
DMA_MODE <= x"0000";
elsif rising_edge(CLK_MAIN) then
if DMA_MODE_CS = '1' and FB_WRn = '0' and FB_B0 = '1' then
DMA_MODE(15 downto 8) <= FB_AD_IN(31 downto 24);
elsif DMA_MODE_CS = '1' and FB_WRn = '0' and FB_B1 = '1' then
DMA_MODE(7 downto 0) <= FB_AD_IN(23 downto 16);
end if;
end if;
end process DMA_MODE_REGISTER;
BYTECOUNTER: process(RESET, CLR_FIFO, CLK_MAIN)
begin
if RESET = '1' or CLR_FIFO = '1' THEN
DMA_BYTECNT <= x"00000000";
elsif rising_edge(CLK_MAIN) then
if DMA_DATA_CS = '1' and FB_WRn = '0' and DMA_MODE(4) = '1' and FB_B1 = '1' then
DMA_BYTECNT(31 downto 17) <= "000000000000000";
DMA_BYTECNT(16 downto 9) <= FB_AD_IN(23 downto 16);
DMA_BYTECNT(8 downto 0) <= "000000000";
elsif DMA_BYTECNT_CS = '1' and FB_WRn = '0' then
DMA_BYTECNT <= FB_AD_IN;
end if;
end if;
end process BYTECOUNTER;
WDC_BSL_REG: process(RESET, CLK_MAIN)
begin
if RESET = '1' THEN
WDC_BSL <= "00";
elsif rising_edge(CLK_MAIN) then
if WDC_BSL_CS = '1' and FB_WRn = '0' and FB_B0 = '1' then
WDC_BSL <= FB_AD_IN(25 downto 24);
end if;
WDC_BSL0 <= WDC_BSL(0);
end if;
end process WDC_BSL_REG;
-- Rausoptimieren?
FDC_REG: process(RESET, CLK_FDC, FDC_CS_In)
begin
if RESET = '1' then
FDC_OUT <= x"00";
elsif rising_edge(CLK_FDC) then
if FDC_CS_In = '0' then
FDC_OUT <= DATA_IN_FDC;
end if;
end if;
FDC_CSn <= FDC_CS_In;
end process FDC_REG;
DMA_ADRESSREGISTERS: process(RESET, CLK_MAIN)
begin
if RESET = '1' THEN
DMA_TOP <= x"00";
DMA_HIGH <= x"00";
DMA_MID <= x"00";
DMA_LOW <= x"00";
elsif rising_edge(CLK_MAIN) then
if FB_WRn = '0' and (DMA_TOP_CS = '1' or DMA_ADR_CS = '1') then
DMA_TOP <= FB_AD_IN(31 downto 24);
end if;
if FB_WRn = '0' and (DMA_HIGH_CS = '1' or DMA_ADR_CS = '1') then
DMA_HIGH <= FB_AD_IN(23 downto 16);
end if;
if FB_WRn = '0' and DMA_MID_CS = '1' then
DMA_MID <= FB_AD_IN(23 downto 16);
elsif FB_WRn = '0' and DMA_ADR_CS = '1' then
DMA_MID <= FB_AD_IN(15 downto 8);
end if;
if FB_WRn = '0' and DMA_LOW_CS = '1' then
DMA_LOW <= FB_AD_IN(23 downto 16);
elsif FB_WRn = '0' and DMA_ADR_CS = '1' then
DMA_LOW <= FB_AD_IN(7 downto 0);
end if;
end if;
end process DMA_ADRESSREGISTERS;
DMA_STATUS(0) <= '1'; -- DMA OK
DMA_STATUS(1) <= '1' when DMA_BYTECNT /= x"00000000" and DMA_BYTECNT(31) = '0' else '0'; -- When byts and not negative.
DMA_STATUS(2) <= '0' when DMA_DRQ_IN = '1' or SCSI_DRQ = '1' else '0';
DMA_REQ <= '1' when ((DMA_DRQ_IN = '1' and DMA_MODE(7) = '1') or (SCSI_DRQ = '1' and DMA_MODE(7) = '0')) and DMA_STATUS(1) = '1' and DMA_MODE(6) = '0' and CLR_FIFO = '0' else '0';
DMA_DRQ_OUT <= '1' when DMA_DRQ_REG = "11" and DMA_MODE(6) = '0' else '0';
DMA_DRQQ <= '1' when DMA_STATUS(1) = '1' and DMA_MODE(8) = '0' and RDF_AZ > 15 and DMA_MODE(6) = '0' else
'1' when DMA_STATUS(1) = '1' and DMA_MODE(8) = '1' and WRF_AZ < 512 and DMA_MODE(6) = '0' else '0';
DMA_DRQ11_I <= '1' when DMA_DRQ_REG = "11" and DMA_MODE(6) = '0' else '0';
DMA_DRQ11 <= DMA_DRQ11_I;
SPIKEFILTER: process(RESET, CLK_FDC)
begin
if RESET = '1' THEN
DMA_DRQ_REG <= "00";
elsif rising_edge(CLK_FDC) then
DMA_DRQ_REG(0) <= DMA_DRQQ;
DMA_DRQ_REG(1) <= DMA_DRQ_REG(0) and DMA_DRQQ;
end if;
end process SPIKEFILTER;
READ_FIFO: dcfifo0
port map(
aclr => CLR_FIFO,
data => RDF_DIN,
rdclk => CLK_MAIN,
rdreq => RDF_RDE,
wrclk => CLK_FDC,
wrreq => RDF_WRE,
q => RDF_DOUT,
wrusedw => RDF_AZ
);
FIFO_WRITE_CTRL: process(RESET, CLK_MAIN)
begin
if RESET = '1' THEN
WRF_WRE <= '0';
elsif rising_edge(CLK_MAIN) then
if FCF_APH = '1' and FB_WRn = '0' then
WRF_WRE <= '1';
else
WRF_WRE <= '0';
end if;
end if;
end process FIFO_WRITE_CTRL;
d <= FB_AD_IN(7 downto 0) & FB_AD_IN(15 downto 8) & FB_AD_IN(23 downto 16) & FB_AD_IN(31 downto 24);
WRITE_FIFO: dcfifo1
port map(
aclr => CLR_FIFO,
data => d,
rdclk => CLK_FDC,
rdreq => WRF_RDE,
wrclk => CLK_MAIN,
wrreq => WRF_WRE,
q => WRF_DOUT,
rdusedw => WRF_AZ
);
SOUNDREGS: process(RESET, CLK_MAIN)
begin
if RESET = '1' then
SNDMACTL <= x"00";
SNDBASHI <= x"00";
SNDBASMI <= x"00";
SNDBASLO <= x"00";
SNDADRHI <= x"00";
SNDADRMI <= x"00";
SNDADRLO <= x"00";
SNDENDHI <= x"00";
SNDENDMI <= x"00";
SNDENDLO <= x"00";
SNDMODE <= x"00";
elsif CLK_MAIN = '1' and CLK_MAIN' event then
if DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"0" and FB_WRn = '0' and FB_B1 ='1' then
SNDMACTL <= FB_AD_IN(23 downto 16);
elsif DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"1" and FB_WRn = '0' and FB_B1 ='1' then
SNDBASHI <= FB_AD_IN(23 downto 16);
elsif DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"2" and FB_WRn = '0' and FB_B1 ='1' then
SNDBASMI <= FB_AD_IN(23downto 16);
elsif DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"3" and FB_WRn = '0' and FB_B1 ='1' then
SNDBASLO <= FB_AD_IN(23 downto 16);
elsif DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"4" and FB_WRn = '0' and FB_B1 ='1' then
SNDADRHI <= FB_AD_IN(23 downto 16);
elsif DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"5" and FB_WRn = '0' and FB_B1 ='1' then
SNDADRMI <= FB_AD_IN(23 downto 16);
elsif DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"6" and FB_WRn = '0' and FB_B1 ='1' then
SNDADRLO <= FB_AD_IN(23 downto 16);
elsif DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"7" and FB_WRn = '0' and FB_B1 ='1' then
SNDENDHI <= FB_AD_IN(23 downto 16);
elsif DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"8" and FB_WRn = '0' and FB_B1 ='1' then
SNDENDMI <= FB_AD_IN(23 downto 16);
elsif DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"9" and FB_WRn = '0' and FB_B1 ='1' then
SNDENDLO <= FB_AD_IN(23 downto 16);
elsif DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"10" and FB_WRn = '0' and FB_B1 ='1' then
SNDMODE <= FB_AD_IN(23 downto 16);
end if;
end if;
end process SOUNDREGS;
CLEAR_BY_TOGGLE: process(RESET, CLK_MAIN, DMA_MODE)
variable DMA_DIR_OLD : std_logic;
begin
if RESET = '1' THEN
DMA_DIR_OLD := '0';
elsif CLK_MAIN = '1' and CLK_MAIN' event then
if DMA_MODE_CS = '0' then
DMA_DIR_OLD := DMA_MODE(8);
end if;
end if;
CLR_FIFO <= DMA_MODE(8) xor DMA_DIR_OLD;
end process CLEAR_BY_TOGGLE;
FCF_REG: process(RESET, CLK_FDC)
begin
if RESET = '1' then
FCF_STATE <= FCF_IDLE;
DMA_ACTIVE <= '0';
elsif rising_edge(CLK_FDC) then
FCF_STATE <= NEXT_FCF_STATE;
DMA_ACTIVE <= DMA_ACTIVE_NEW;
end if;
end process FCF_REG;
FCF_DECODER: process(FCF_STATE, DMA_REQ, FDC_CS, SCSI_CS_I, DMA_ACTIVE, DMA_MODE)
begin
case FCF_STATE is
when FCF_IDLE =>
SCSI_CSn <= '1';
FDC_CS_In <= '1';
RDF_WRE <= '0';
WRF_RDE <= '0';
SCSI_DACKn <= '1';
if DMA_REQ = '1' or FDC_CS = '1' or SCSI_CS_I = '1' then
DMA_ACTIVE_NEW <= DMA_REQ;
NEXT_FCF_STATE <= FCF_T0;
else
DMA_ACTIVE_NEW <= '0';
NEXT_FCF_STATE <= FCF_IDLE;
end if;
when FCF_T0 =>
SCSI_CSn <= '1';
FDC_CS_In <= '1';
RDF_WRE <= '0';
SCSI_DACKn <= '1';
DMA_ACTIVE_NEW <= DMA_REQ;
WRF_RDE <= DMA_MODE(8) and DMA_REQ; -- Write -> Read from FIFO
if DMA_REQ = '0' and DMA_ACTIVE = '1' then -- Spike?
NEXT_FCF_STATE <= FCF_IDLE; -- Yes -> Start
else
NEXT_FCF_STATE <= FCF_T1;
end if;
when FCF_T1 =>
RDF_WRE <= '0';
WRF_RDE <= '0';
DMA_ACTIVE_NEW <= DMA_ACTIVE;
SCSI_CSn <= not SCSI_CS_I;
FDC_CS_In <= DMA_MODE(4) or DMA_MODE(3);
SCSI_DACKn <= DMA_MODE(7) and DMA_ACTIVE;
NEXT_FCF_STATE <= FCF_T2;
when FCF_T2 =>
RDF_WRE <= '0';
WRF_RDE <= '0';
DMA_ACTIVE_NEW <= DMA_ACTIVE;
SCSI_CSn <= not SCSI_CS_I;
FDC_CS_In <= DMA_MODE(4) or DMA_MODE(3);
SCSI_DACKn <= DMA_MODE(7) and DMA_ACTIVE;
NEXT_FCF_STATE <= FCF_T3;
when FCF_T3 =>
RDF_WRE <= '0';
WRF_RDE <= '0';
DMA_ACTIVE_NEW <= DMA_ACTIVE;
SCSI_CSn <= not SCSI_CS_I;
FDC_CS_In <= DMA_MODE(4) or DMA_MODE(3);
SCSI_DACKn <= DMA_MODE(7) and DMA_ACTIVE;
NEXT_FCF_STATE <= FCF_T6;
when FCF_T6 =>
WRF_RDE <= '0';
DMA_ACTIVE_NEW <= DMA_ACTIVE;
SCSI_CSn <= not SCSI_CS_I;
FDC_CS_In <= DMA_MODE(4) or DMA_MODE(3);
SCSI_DACKn <= DMA_MODE(7) and DMA_ACTIVE;
RDF_WRE <= not DMA_MODE(8) and DMA_ACTIVE; -- Read -> Write to FIFO
NEXT_FCF_STATE <= FCF_T7;
when FCF_T7 =>
SCSI_CSn <= '1';
FDC_CS_In <= '1';
RDF_WRE <= '0';
WRF_RDE <= '0';
SCSI_DACKn <= '1';
DMA_ACTIVE_NEW <= '0';
if FDC_CS = '1' and DMA_REQ = '0' then
NEXT_FCF_STATE <= FCF_T7;
else
NEXT_FCF_STATE <= FCF_IDLE;
end if;
end case;
end process FCF_DECODER;
end architecture BEHAVIOUR;