-- WARNING: Do NOT edit the input and output ports in this file in a text
-- editor IF you plan to continue editing the block that represents it in
-- the Block Editor! File corruption is VERY likely to occur.

-- Copyright (C) 1991-2008 Altera Corporation
-- Your use of Altera Corporation's design tools, logic functions 
-- and other software and tools, and its AMPP partner logic 
-- functions, and any output files from any of the foregoing 
-- (including device programming or simulation files), and any 
-- associated documentation or information are expressly subject 
-- to the terms and conditions of the Altera Program License 
-- Subscription Agreement, Altera MegaCore Function License 
-- Agreement, or other applicable license agreement, including, 
-- without limitation, that your use is for the sole purpose of 
-- programming logic devices manufactured by Altera and sold by 
-- Altera or its authorized distributors.  Please refer to the 
-- applicable agreement for further details.


-- Generated by Quartus II Version 8.1 (Build Build 163 10/28/2008)
-- Created on Tue Sep 08 16:24:20 2009

LIBRARY work;
    USE work.FalconIO_SDCard_IDE_CF_pkg.ALL;

LIBRARY ieee;
    USE ieee.std_logic_1164.ALL;
    USE ieee.std_logic_unsigned.ALL;


--  Entity Declaration


--  Entity Declaration

ENTITY falconio_sdcard_ide_cf IS
	-- {{ALTERA_IO_BEGIN}} DO NOT REMOVE THIS LINE!
	PORT
	(
		CLK33M          : IN std_logic;
		MAIN_CLK        : IN std_logic;
		CLK2M           : IN std_logic;
		CLK500k         : IN std_logic;
		nFB_CS1         : IN std_logic;
		FB_SIZE0        : IN std_logic;
		FB_SIZE1        : IN std_logic;
		nFB_BURST       : IN std_logic;
		FB_ADR          : IN std_logic_vector(31 DOWNTO 0);
		LP_BUSY         : IN std_logic;
		nACSI_DRQ       : IN std_logic;
		nACSI_INT       : IN std_logic;
		nSCSI_DRQ       : IN std_logic;
		nSCSI_MSG       : IN std_logic;
		MIDI_IN         : IN std_logic;
		RxD             : IN std_logic;
		CTS             : IN std_logic;
		RI              : IN std_logic;
		DCD             : IN std_logic;
		AMKB_RX         : IN std_logic;
		PIC_AMKB_RX     : IN std_logic;
		IDE_RDY         : IN std_logic;
		IDE_INT         : IN std_logic;
		WP_CS_CARD      : IN std_logic;
		nINDEX          : IN std_logic;
		TRACK00         : IN std_logic;
		nRD_DATA        : IN std_logic;
		nDCHG           : IN std_logic;
		SD_DATA0        : IN std_logic;
		SD_DATA1        : IN std_logic;
		SD_DATA2        : IN std_logic;
		SD_CARD_DEDECT  : IN std_logic;
		SD_WP           : IN std_logic;
		nDACK0          : IN std_logic;
		nFB_WR          : IN std_logic;
		WP_CF_CARD      : IN std_logic;
		nWP             : IN std_logic;
		nFB_CS2         : IN std_logic;
		nRSTO           : IN std_logic;
		HD_DD           : IN std_logic;
		nSCSI_C_D       : IN std_logic;
		nSCSI_I_O       : IN std_logic;
		CLK2M4576       : IN std_logic;
		nFB_OE          : IN std_logic;
		VSYNC           : IN std_logic;
		HSYNC           : IN std_logic;
		DSP_INT         : IN std_logic;
		nBLANK          : IN std_logic;
		FDC_CLK         : IN std_logic;
		FB_ALE          : IN std_logic;
		ACP_CONF        : IN std_logic_vector(31 DOWNTO 24);
		nIDE_CS1        : OUT std_logic;
		nIDE_CS0        : OUT std_logic;
		LP_STR          : OUT std_logic;
		LP_DIR          : OUT std_logic;
		nACSI_ACK       : OUT std_logic;
		nACSI_RESET     : OUT std_logic;
		nACSI_CS        : OUT std_logic;
		ACSI_DIR        : OUT std_logic;
		ACSI_A1         : OUT std_logic;
		nSCSI_ACK       : OUT std_logic;
		nSCSI_ATN       : OUT std_logic;
		SCSI_DIR        : OUT std_logic;
		SD_CLK          : OUT std_logic;
		YM_QA           : OUT std_logic;
		YM_QC           : OUT std_logic;
		YM_QB           : OUT std_logic;
		nSDSEL          : OUT std_logic;
		STEP            : OUT std_logic;
		MOT_ON          : OUT std_logic;
		nRP_LDS         : OUT std_logic;
		nRP_UDS         : OUT std_logic;
		nROM4           : OUT std_logic;
		nROM3           : OUT std_logic;
		nCF_CS1         : OUT std_logic;
		nCF_CS0         : OUT std_logic;
		nIDE_RD         : INOUT std_logic;
		nIDE_WR         : INOUT std_logic;
		AMKB_TX         : buffer std_logic;
		IDE_RES         : OUT std_logic;
		DTR             : OUT std_logic;
		RTS             : OUT std_logic;
		TxD             : OUT std_logic;
		MIDI_OLR        : OUT std_logic;
		MIDI_TLR        : OUT std_logic;
		nDREQ0          : OUT std_logic;
		DSA_D           : OUT std_logic;
		nMFP_INT        : OUT std_logic;
		FALCON_IO_TA    : OUT std_logic;
		STEP_DIR        : OUT std_logic;
		WR_DATA         : OUT std_logic;
		WR_GATE         : OUT std_logic;
		DMA_DRQ         : OUT std_logic;
        fb_ad_in        : in std_logic_vector(31 downto 0);
        fb_ad_out       : out std_logic_vector(31 downto 0);
		LP_D            : INOUT std_logic_vector(7 DOWNTO 0);
		SND_A           : INOUT std_logic_vector(7 downto 0);
		ACSI_D          : INOUT std_logic_vector(7 DOWNTO 0);
		SCSI_D          : INOUT std_logic_vector(7 DOWNTO 0);
		SCSI_PAR        : INOUT std_logic;
		nSCSI_SEL       : INOUT std_logic;
		nSCSI_BUSY      : INOUT std_logic;
		nSCSI_RST       : INOUT std_logic;
		SD_CD_DATA3     : INOUT std_logic;
		SD_CDM_D1       : INOUT std_logic
	);
	-- {{ALTERA_IO_END}} DO NOT REMOVE THIS LINE!	
END falconio_sdcard_ide_cf;


--  Architecture Body

ARCHITECTURE rtl OF FalconIO_SDCard_IDE_CF IS
    -- system
    SIGNAL SYS_CLK			        : std_logic;
    SIGNAL RESETn					: std_logic;
    SIGNAL FB_B0					: std_logic;	-- UPPER BYT BEI 16BIT BUS
    SIGNAL FB_B1					: std_logic;	-- LOWER BYT BEI 16BIT BUS
    SIGNAL BYT						: std_logic;	-- WENN BYT -> 1
    SIGNAL LONG					    : std_logic;	-- WENN  -> 1
signal FB_ADI					: STD_LOGIC_VECTOR(15 downto 0);	-- gespeicherte writedaten
signal nResetatio				: STD_LOGIC;	-- reset atari bausteine
    -- KEYBOARD MIDI
    SIGNAL ACIA_CS_I				: std_logic;
    SIGNAL IRQ_KEYBDn			    : std_logic;
    SIGNAL IRQ_MIDIn				: std_logic;
    SIGNAL KEYB_RxD				    : std_logic;
signal AMKB_REG					: STD_LOGIC_VECTOR(3 downto 0);
signal AMKB_TX_sync				: std_logic;
    SIGNAL MIDI_OUT				    : std_logic;
    SIGNAL DATA_OUT_ACIA_I		    : std_logic_vector(7 DOWNTO 0);
    SIGNAL DATA_OUT_ACIA_II	        : std_logic_vector(7 DOWNTO 0);
    -- MFP
    SIGNAL MFP_CS					: std_logic;
    SIGNAL MFP_INTACK				: std_logic;
    SIGNAL LDS						: std_logic;
signal acia_irq					: STD_LOGIC;
    SIGNAL DTACK_OUT_MFPn			: std_logic;
    SIGNAL DINTn					: std_logic;
    SIGNAL DATA_OUT_MFP				: std_logic_vector(7 DOWNTO 0);
    SIGNAL TDO						: std_logic;
    -- SOUND
    SIGNAL SNDCS					: std_logic;
    SIGNAL SNDCS_I					: std_logic;
    SIGNAL SNDIR_I					: std_logic;
    SIGNAL LP_DIR_X					: std_logic;
    SIGNAL DA_OUT_X					: std_logic_vector(7 DOWNTO 0);
signal SND_A_X					: STD_LOGIC_VECTOR(7 downto 0);
    SIGNAL LP_D_X					: std_logic_vector(7 DOWNTO 0);
signal nLP_STR					: STD_LOGIC;
-- DMA SOUND
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);
    -- DIV
    SIGNAL SUB_BUS					: std_logic;	-- SUB BUS MIT ROM-PORT, CF UND IDE
    SIGNAL ROM_CS					: std_logic;
    -- DMA UND FLOPPY
    SIGNAL DMA_DATEN_CS				: std_logic;
    SIGNAL DMA_MODUS_CS				: std_logic;
    SIGNAL DMA_MODUS				: std_logic_vector(15 DOWNTO 0);
    SIGNAL WDC_BSL_CS				: std_logic;
    SIGNAL WDC_BSL					: std_logic_vector(1 DOWNTO 0);
    SIGNAL HD_DD_OUT				: std_logic;
    SIGNAL FDCS_In					: std_logic;
    SIGNAL CA0						: std_logic;
    SIGNAL CA1						: std_logic;
    SIGNAL CA2						: std_logic;
    SIGNAL FDINT					: std_logic;
    SIGNAL FDRQ						: std_logic;
    SIGNAL CD_OUT_FDC				: std_logic_vector(7 DOWNTO 0);
    SIGNAL CD_IN_FDC				: std_logic_vector(7 DOWNTO 0);
    SIGNAL DMA_TOP_CS				: std_logic;
    SIGNAL DMA_TOP					: std_logic_vector(7 DOWNTO 0);
    SIGNAL DMA_HIGH_CS				: std_logic;
    SIGNAL DMA_HIGH					: std_logic_vector(7 DOWNTO 0);
    SIGNAL DMA_MID_CS				: std_logic;
    SIGNAL DMA_MID					: std_logic_vector(7 DOWNTO 0);
    SIGNAL DMA_LOW_CS				: std_logic;
    SIGNAL DMA_LOW					: std_logic_vector(7 DOWNTO 0);
    SIGNAL DMA_DIRM_CS				: std_logic;
    SIGNAL DMA_ADR_CS				: std_logic;
    SIGNAL DMA_STATUS				: std_logic_vector(2 DOWNTO 0);
    SIGNAL DMA_DIR_OLD				: std_logic;
    SIGNAL DMA_BYT_CNT_CS			: std_logic;
    SIGNAL DMA_BYT_CNT				: std_logic_vector(31 DOWNTO 0);
    SIGNAL CLR_FIFO					: std_logic;
    SIGNAL DMA_DRQ_I				: std_logic;
    SIGNAL DMA_DRQ_REG				: std_logic_vector(1 DOWNTO 0);
    SIGNAL DMA_DRQQ					: std_logic;
    SIGNAL DMA_DRQ_Q				: std_logic;
    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 RDF_DIN					: std_logic_vector(7 DOWNTO 0);
    SIGNAL WRF_DOUT					: 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 nFDC_WR					: std_logic;
    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 DMA_REQ					: std_logic;
    SIGNAL FDC_CS					: std_logic;
    SIGNAL FCF_CS					: std_logic;
    SIGNAL FCF_APH					: std_logic;
    SIGNAL DMA_AZ_CS				: std_logic;
    SIGNAL DMA_ACTIV				: std_logic;
    SIGNAL DMA_ACTIV_NEW			: std_logic;
    SIGNAL FDC_OUT					: std_logic_vector(7 DOWNTO 0);
    -- SCSI
    SIGNAL SCSI_CS					: std_logic;
    SIGNAL SCSI_CSn					: std_logic;
    SIGNAL SCSI_DOUT				: std_logic_vector(7 DOWNTO 0);
    SIGNAL nSCSI_DACK				: std_logic;
    SIGNAL SCSI_DRQ					: std_logic;
    SIGNAL SCSI_INT					: std_logic;
    SIGNAL DB_OUTn					: std_logic_vector(7 DOWNTO 0);
    SIGNAL DB_EN					: std_logic;
    SIGNAL DBP_OUTn					: std_logic;
    SIGNAL DBP_EN					: std_logic;
    SIGNAL RST_OUTn					: std_logic;
    SIGNAL RST_EN					: std_logic;
    SIGNAL BSY_OUTn					: std_logic;
    SIGNAL BSY_EN					: std_logic;
    SIGNAL SEL_OUTn					: std_logic;
    SIGNAL SEL_EN					: std_logic;
    -- IDE
    SIGNAL nnIDE_RES				: std_logic;
    SIGNAL IDE_CF_CS				: std_logic;
    SIGNAL IDE_CF_TA				: std_logic;
    SIGNAL NEXT_nIDE_RD				: std_logic;
    SIGNAL NEXT_nIDE_WR				: std_logic;
    type CMD_STATES is(	IDLE, T1, T6, T7);
    SIGNAL CMD_STATE				: CMD_STATES;
    SIGNAL NEXT_CMD_STATE			: CMD_STATES;
-- Paddle
    SIGNAL paddle_cs				: std_logic;
        
BEGIN
    LONG  <= '1' WHEN FB_SIZE1 = '0' AND FB_SIZE0 = '0' ELSE '0';
    BYT   <= '1' WHEN FB_SIZE1 = '0' AND FB_SIZE0 = '1' ELSE '0';
    FB_B0 <= '1' WHEN FB_ADR(0) = '0' OR BYT = '0' ELSE '0';
    FB_B1 <= '1' WHEN FB_ADR(0) = '1' OR BYT = '0' ELSE '0';
    
    FALCON_IO_TA <= '1' when ACIA_CS_I = '1' or DTACK_OUT_MFPn = '0' or DMA_MODUS_CS ='1' or dma_snd_cs = '1' or paddle_cs = '1'
				 or DMA_ADR_CS = '1' or DMA_DIRM_CS = '1' or DMA_BYT_CNT_CS = '1' or FCF_CS = '1' or IDE_CF_TA = '1' else '0';--SNDCS = '1' or 
    SUB_BUS <= '1' WHEN nFB_WR = '1' AND ROM_CS = '1'    ELSE
               '1' WHEN nFB_WR = '1' AND IDE_CF_CS = '1' ELSE
               '1' WHEN nFB_WR = '0' AND nIDE_WR = '0'   ELSE '0';
    nRP_UDS <= '0' when nFB_CS1 = '0' and SUB_BUS = '1' and FB_B0 = '1' else '1'; 
    nRP_LDS <= '0' when nFB_CS1 = '0' and SUB_BUS = '1' and FB_B1 = '1' else '1'; 
    nDREQ0 <= '0';

    -- input daten halten
    p_hold_input_data : PROCESS(MAIN_CLK, nFB_WR, fb_ad_in(31 DOWNTO 16), FB_ADI(15 DOWNTO 0))
	BEGIN
		IF rising_edge(MAIN_CLK) THEN
			IF nFB_WR = '0' THEN
				FB_ADI <= fb_ad_in(31 downto 16); 
			ELSE
				FB_ADI <= FB_ADI; 
			END IF;
		ELSE
			FB_ADI <= FB_ADI; 
		END IF;
	END PROCESS;
    ----------------------------------------------------------------------------
    -- SD
    ----------------------------------------------------------------------------
    SD_CLK <= 'Z';
    SD_CD_DATA3 <= 'Z';
    SD_CDM_D1 <= 'Z';
    ----------------------------------------------------------------------------
    -- IDE
    ----------------------------------------------------------------------------
    CMD_REG: PROCESS(nRSTO, MAIN_CLK, CMD_STATE, NEXT_CMD_STATE)
	BEGIN
		IF nRSTO = '0' THEN
			CMD_STATE <= IDLE;
		ELSIF rising_edge(MAIN_CLK) THEN
				CMD_STATE <= NEXT_CMD_STATE; 	-- go to next
				nIDE_RD   <= NEXT_nIDE_RD; 		-- go to next
				nIDE_WR   <= NEXT_nIDE_WR; 		-- go to next
			ELSE
				CMD_STATE <= CMD_STATE; 		-- halten
				nIDE_RD   <= nIDE_RD;			-- halten
				nIDE_WR   <= nIDE_WR;			-- halten
			END IF;
	END PROCESS CMD_REG;

	CMD_DECODER: PROCESS(CMD_STATE, NEXT_CMD_STATE, NEXT_nIDE_RD, NEXT_nIDE_WR, IDE_RDY, IDE_CF_TA)
	BEGIN
		case CMD_STATE is
			WHEN IDLE =>
				IDE_CF_TA <= '0';
				IF  IDE_CF_CS = '1' THEN
					NEXT_nIDE_RD <= not nFB_WR;
					NEXT_nIDE_WR <=     nFB_WR;
					NEXT_CMD_STATE <= T1;
				ELSE
					NEXT_nIDE_RD <= '1';
					NEXT_nIDE_WR <= '1';
					NEXT_CMD_STATE <= IDLE; 		 
				END IF;
			WHEN T1 =>
				IDE_CF_TA <= '0';
				NEXT_nIDE_RD <= not nFB_WR;
				NEXT_nIDE_WR <=     nFB_WR;
				NEXT_CMD_STATE <= T6;
			WHEN T6 =>
				IF IDE_RDY = '1' THEN
					IDE_CF_TA <= '1';
					NEXT_nIDE_RD <= '1';
					NEXT_nIDE_WR <= '1';
					NEXT_CMD_STATE <= T7;
				ELSE
					IDE_CF_TA <= '0';
					NEXT_nIDE_RD <= not nFB_WR;
					NEXT_nIDE_WR <=     nFB_WR;
					NEXT_CMD_STATE <= T6;
				END IF;
			WHEN T7 => 
				IDE_CF_TA <= '0';
				NEXT_nIDE_RD <= '1';
				NEXT_nIDE_WR <= '1';
				NEXT_CMD_STATE <= IDLE;
		END CASE;
	END PROCESS CMD_DECODER;
	
    IDE_RES <= NOT nnIDE_RES AND nRSTO;
    IDE_CF_CS <= '1' WHEN nFB_CS1 = '0' AND FB_ADR(19 DOWNTO 7) = x"0" ELSE '0';				-- FFF0'0000/80
    nCF_CS0   <= '0' WHEN ACP_CONF(31) = '0' AND FB_ADR(19 DOWNTO 5) = x"0" ELSE 				-- FFFO'0000-FFF0'001F
                 '0' WHEN ACP_CONF(31) = '1' AND FB_ADR(19 DOWNTO 5) = x"2" ELSE '1'; 			-- FFFO'0040-FFF0'005F
    nCF_CS1   <= '0' WHEN ACP_CONF(31) = '0' AND FB_ADR(19 DOWNTO 5) = x"1" ELSE	 			-- FFF0'0020-FFF0'003F
                 '0' WHEN ACP_CONF(31) = '1' AND FB_ADR(19 DOWNTO 5) = x"3" ELSE '1'; 			-- FFFO'0060-FFF0'007F
    nIDE_CS0  <= '0' WHEN ACP_CONF(30) = '0' AND FB_ADR(19 DOWNTO 5) = x"2" ELSE				-- FFF0'0040-FFF0'005F 
                 '0' WHEN ACP_CONF(30) = '1' AND FB_ADR(19 DOWNTO 5) = x"0" ELSE '1'; 			-- FFFO'0000-FFF0'001F
    nIDE_CS1  <= '0' WHEN ACP_CONF(30) = '0' AND FB_ADR(19 DOWNTO 5) = x"3" ELSE				-- FFF0'0060-FFF0'007F 
                 '0' WHEN ACP_CONF(30) = '1' AND FB_ADR(19 DOWNTO 5) = x"1" ELSE '1'; 			-- FFFO'0020-FFF0'003F
    -----------------------------------------------------------------------------------------------------------------------------------------
    -- ACSI, SCSI UND FLOPPY WD1772 
    -------------------------------------------------------------------------------------------------------------------------------------------
    -- daten read fifo
	RDF: dcfifo0
		PORT MAP(
			aclr				=> CLR_FIFO,
			data				=> RDF_DIN,
			rdclk				=> MAIN_CLK,
			rdreq				=> RDF_RDE,
			wrclk				=> FDC_CLK,
			wrreq				=> RDF_WRE,
			q					=> RDF_DOUT,
			wrusedw				=> RDF_AZ
        );
    FCF_CS  <= '1' WHEN nFB_CS2 = '0' AND FB_ADR(26 DOWNTO 0) = x"0020110" AND LONG = '1' ELSE '0';		-- F002'0110 LONG ONLY
    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_RDE <= '1' WHEN FCF_APH = '1' AND nFB_WR = '1' ELSE '0';										-- AKTIVIEREN IN ADRESSPHASE
    fb_ad_out <= RDF_DOUT(7 DOWNTO 0) & RDF_DOUT(15 DOWNTO 8) & RDF_DOUT(23 DOWNTO 16) & RDF_DOUT(31 DOWNTO 24) WHEN FCF_CS = '1' and nFB_OE = '0'
                ELSE (OTHERS => 'Z');
                
    RDF_DIN <= CD_OUT_FDC WHEN DMA_MODUS(7) = '1' ELSE SCSI_DOUT;
    -- daten write fifo
	WRF: dcfifo1
		PORT MAP(
			aclr				=> CLR_FIFO,
			data				=> fb_ad_in(7 DOWNTO 0) & fb_ad_in(15 DOWNTO 8) & fb_ad_in(23 DOWNTO 16) & fb_ad_in(31 DOWNTO 24),
			rdclk				=> FDC_CLK,
			rdreq				=> WRF_RDE,
			wrclk				=> MAIN_CLK,
			wrreq				=> WRF_WRE,
			q					=> WRF_DOUT,
			rdusedw				=> WRF_AZ
        );
    CD_IN_FDC <=  WRF_DOUT WHEN DMA_ACTIV = '1' and DMA_MODUS(8) = '1' ELSE FB_ADI(7 DOWNTO 0); 							-- BEI DMA WRITE <-FIFO SONST <-FB
    DMA_AZ_CS  <= '1' WHEN nFB_CS2 = '0' AND FB_ADR(26 DOWNTO 0) = x"002010C" ELSE '0';										-- F002'010C LONG
    fb_ad_out <= DMA_DRQ_Q & DMA_DRQ_REG & IDE_INT & FDINT & SCSI_INT & RDF_AZ & "0" & DMA_STATUS & "00" & WRF_AZ WHEN DMA_AZ_CS = '1' and nFB_OE = '0'
        ELSE (OTHERS => 'Z');
    DMA_DRQ_Q <= '1' WHEN DMA_DRQ_REG = "11" and DMA_MODUS(6) = '0' ELSE '0';

    -- FIFO WRITE: GENAU 1 MAIN_CLK  -------------------------------------------------------------------------
	p_fifo_write : PROCESS(MAIN_CLK, nRSTO, WRF_WRE, nFB_WR, FCF_APH)
	BEGIN
		IF nRSTO = '0' THEN
			WRF_WRE <= '0';
		ELSIF rising_edge(MAIN_CLK) THEN
			IF FCF_APH = '1' AND nFB_WR = '0' THEN
				WRF_WRE <= '1';
			ELSE
				WRF_WRE <= '0';
			END IF;
		ELSE
			WRF_WRE <= WRF_WRE;
		END IF;
	END PROCESS;
 
    FCF_REG: PROCESS(nRSTO, FDC_CLK, FCF_STATE, NEXT_FCF_STATE, DMA_ACTIV)
	BEGIN
		IF nRSTO = '0' THEN
			FCF_STATE <= FCF_IDLE;
			DMA_ACTIV <= '0';
		ELSIF rising_edge(FDC_CLK) THEN
			FCF_STATE <= NEXT_FCF_STATE; 			-- go to next
			DMA_ACTIV <= DMA_ACTIV_NEW;
		ELSE
			FCF_STATE <= FCF_STATE; 					-- halten
			DMA_ACTIV <= DMA_ACTIV;
		END IF;
	END PROCESS FCF_REG;

    FDC_REG: PROCESS(nRSTO, FDC_CLK, FDC_OUT, FDCS_In, CD_OUT_FDC)
	BEGIN
		IF nRSTO = '0' THEN
			FDC_OUT <= x"00";
		ELSIF rising_edge(FDC_CLK) AND FDCS_In = '0' THEN
			FDC_OUT <= CD_OUT_FDC; 						-- set
		ELSE
			FDC_OUT <= FDC_OUT; 						-- halten
		END IF;
	END PROCESS FDC_REG;

    DMA_REQ <= '1' WHEN ((DMA_DRQ_I = '1' AND DMA_MODUS(7) = '1') OR (SCSI_DRQ = '1' AND DMA_MODUS(7) = '0')) AND DMA_STATUS(1) = '1' AND DMA_MODUS(6) = '0' AND CLR_FIFO = '0' ELSE '0';
    FDC_CS   <= '1' WHEN DMA_DATEN_CS = '1' AND DMA_MODUS(4 DOWNTO 3) = "00" AND FB_B1 = '1' ELSE '0';
    SCSI_CS  <= '1' WHEN DMA_DATEN_CS = '1' AND DMA_MODUS(4 DOWNTO 3) = "01" AND FB_B1 = '1' ELSE '0';

	FCF_DECODER: PROCESS(FCF_STATE, NEXT_FCF_STATE, DMA_REQ,FDC_CS, RDF_WRE, WRF_RDE, SCSI_DRQ, nSCSI_DACK, DMA_MODUS, DMA_ACTIV, FDCS_In,SCSI_CS, SCSI_CSn)
	BEGIN
		CASE FCF_STATE IS
			WHEN FCF_IDLE =>
				SCSI_CSn <= '1';
				FDCS_In <= '1';
				RDF_WRE <= '0';
				WRF_RDE <= '0';
				nSCSI_DACK <= '1';
				IF DMA_REQ = '1' OR FDC_CS = '1' OR SCSI_CS = '1' THEN 	 
					DMA_ACTIV_NEW <= DMA_REQ;
					NEXT_FCF_STATE <= FCF_T0;
				ELSE
					DMA_ACTIV_NEW <= '0';
					NEXT_FCF_STATE <= FCF_IDLE; 		 
				END IF;
			WHEN FCF_T0 =>
				SCSI_CSn <= '1';
				FDCS_In <= '1';
				RDF_WRE <= '0';
				nSCSI_DACK <= '1';
				DMA_ACTIV_NEW <= DMA_REQ;
				WRF_RDE <= DMA_MODUS(8) AND DMA_REQ;				-- WRITE -> READ FROM FIFO
				IF 	DMA_REQ = '0' AND DMA_ACTIV = '1' THEN			-- spike?
					NEXT_FCF_STATE <= FCF_IDLE;						-- ja -> zum start
				ELSE
					NEXT_FCF_STATE <= FCF_T1;
				END IF;
			WHEN FCF_T1 =>
				RDF_WRE <= '0';
				WRF_RDE <= '0';
				DMA_ACTIV_NEW <= DMA_ACTIV;
				SCSI_CSn <= NOT SCSI_CS;
				FDCS_In <= DMA_MODUS(4) OR DMA_MODUS(3);
				nSCSI_DACK <= DMA_MODUS(7) AND DMA_ACTIV;
				NEXT_FCF_STATE <= FCF_T2;
			WHEN FCF_T2 =>
				RDF_WRE <= '0';
				WRF_RDE <= '0';
				DMA_ACTIV_NEW <= DMA_ACTIV;
				SCSI_CSn <= NOT SCSI_CS;
				FDCS_In <= DMA_MODUS(4) OR DMA_MODUS(3);
				nSCSI_DACK <= DMA_MODUS(7) AND DMA_ACTIV;
				NEXT_FCF_STATE <= FCF_T3;
			WHEN FCF_T3 =>
				RDF_WRE <= '0';
				WRF_RDE <= '0';
				DMA_ACTIV_NEW <= DMA_ACTIV;
				SCSI_CSn <= NOT SCSI_CS;
				FDCS_In <= DMA_MODUS(4) OR DMA_MODUS(3);
				nSCSI_DACK <= DMA_MODUS(7) AND DMA_ACTIV;
				NEXT_FCF_STATE <= FCF_T6;
			WHEN FCF_T6 =>
				WRF_RDE <= '0';
				DMA_ACTIV_NEW <= DMA_ACTIV;
				SCSI_CSn <= NOT SCSI_CS;
				FDCS_In <= DMA_MODUS(4) OR DMA_MODUS(3);
				nSCSI_DACK <= DMA_MODUS(7)  AND DMA_ACTIV;
				RDF_WRE <= NOT DMA_MODUS(8) AND DMA_ACTIV;		-- READ -> WRITE IN FIFO
				NEXT_FCF_STATE <= FCF_T7;
			WHEN FCF_T7 =>
				SCSI_CSn <= '1';
				FDCS_In <= '1';
				RDF_WRE <= '0';
				WRF_RDE <= '0';
				nSCSI_DACK <= '1';
				DMA_ACTIV_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;

	i_fdc : WF1772IP_TOP_SOC
		PORT MAP(
            CLK					=> FDC_CLK,
			RESETn				=> nResetatio,
			CSn					=> FDCS_In,
			RWn					=> nFDC_WR,
			A1					=> CA2,
			A0					=> CA1,
			DATA_IN				=> CD_IN_FDC,
			DATA_OUT			=> CD_OUT_FDC,
--			DATA_EN				=> CD_EN_FDC,
			RDn					=> nRD_DATA,
			TR00n				=> TRACK00,
			IPn					=> nINDEX,
			WPRTn				=> nWP,
			DDEn				=> '0', -- Fixed to MFM.
			HDTYPE				=> HD_DD_OUT,  
			MO					=> MOT_ON,
			WG					=> WR_GATE,
			WD					=> WR_DATA,
			STEP				=> STEP,
			DIRC				=> STEP_DIR,
			DRQ					=> DMA_DRQ_I,
			INTRQ				=> FDINT 
		);
    DMA_DATEN_CS <= '1' WHEN nFB_CS1 = '0' AND FB_ADR(19 DOWNTO 1) = x"7C302" ELSE '0';						-- F8604/2 
    DMA_MODUS_CS <= '1' WHEN nFB_CS1 = '0' AND FB_ADR(19 DOWNTO 1) = x"7C303" ELSE '0';						-- F8606/2
    WDC_BSL_CS   <= '1' WHEN nFB_CS1 = '0' AND FB_ADR(19 DOWNTO 1) = x"7C307" ELSE '0';						-- F860E/2
    HD_DD_OUT <= HD_DD WHEN ACP_CONF(29) = '0' ELSE WDC_BSL(0);
    nFDC_WR <= (not DMA_MODUS(8)) WHEN DMA_ACTIV = '1' ELSE nFB_WR;
    CA0 <= '1' WHEN DMA_ACTIV = '1' ELSE DMA_MODUS(0);
    CA1 <= '1' WHEN DMA_ACTIV = '1' ELSE DMA_MODUS(1);
    CA2 <= '1' WHEN DMA_ACTIV = '1' ELSE DMA_MODUS(2);
    
    fb_ad_out(23 downto 16) <= "0000" & (not DMA_STATUS(1)) & "0" & WDC_BSL(1) & HD_DD when WDC_BSL_CS = '1' and nFB_OE = '0' else (OTHERS => 'Z');
    fb_ad_out(31 downto 24) <= "00000000" when DMA_DATEN_CS = '1'                               and nFB_OE = '0' ELSE "ZZZZZZZZ";
    fb_ad_out(23 DOWNTO 16) <= FDC_OUT WHEN DMA_DATEN_CS = '1' AND DMA_MODUS(4 DOWNTO 3) = "00" AND nFB_OE = '0' ELSE
                         SCSI_DOUT WHEN DMA_DATEN_CS = '1' AND DMA_MODUS(4 DOWNTO 3) = "01" AND nFB_OE = '0' ELSE 
      DMA_BYT_CNT(16 downto 9) when DMA_DATEN_CS = '1' and DMA_MODUS(4) = '1'           and nFB_OE = '0' else "ZZZZZZZZ";
    --- WDC BSL REGISTER -------------------------------------------------------
	PROCESS(MAIN_CLK, nRSTO, WDC_BSL_CS, WDC_BSL, nFB_WR, FB_B0, FB_B1)
	BEGIN
		IF nRSTO = '0' THEN
			WDC_BSL <= "00";
		ELSIF rising_edge(MAIN_CLK) AND WDC_BSL_CS = '1' AND nFB_WR = '0' THEN
			IF FB_B0 = '1' THEN
				WDC_BSL(1 DOWNTO 0) <= fb_ad_in(25 DOWNTO 24);
			ELSE
				WDC_BSL(1 DOWNTO 0) <= WDC_BSL(1 DOWNTO 0);
			END IF;
		END IF;
	END PROCESS;
--- DMA MODUS REGISTER -------------------------------------------------------
	PROCESS(MAIN_CLK, nRSTO, DMA_MODUS_CS, DMA_MODUS, nFB_WR, FB_B0, FB_B1)
	BEGIN
		IF nRSTO = '0' THEN
			DMA_MODUS <= x"0000";
		ELSIF rising_edge(MAIN_CLK) AND DMA_MODUS_CS = '1' AND nFB_WR = '0' THEN
			IF FB_B0 = '1' THEN
				DMA_MODUS(15 DOWNTO 8) <= fb_ad_in(31 DOWNTO 24);
			ELSE
				DMA_MODUS(15 DOWNTO 8) <= DMA_MODUS(15 DOWNTO 8);
			END IF;
			IF FB_B1 = '1' THEN
				DMA_MODUS(7 DOWNTO 0) <= fb_ad_in(23 DOWNTO 16);
			ELSE
				DMA_MODUS(7 DOWNTO 0) <= DMA_MODUS(7 DOWNTO 0);
			END IF;
		ELSE
			DMA_MODUS <= DMA_MODUS;
		END IF;
	END PROCESS;
    -- BYT COUNTER, SECTOR COUNTER ----------------------------------------------------
	PROCESS(MAIN_CLK, nRSTO, DMA_DATEN_CS, DMA_BYT_CNT_CS, DMA_BYT_CNT, nFB_WR, FB_B0, FB_B1, DMA_MODUS, CLR_FIFO)
	BEGIN
		IF nRSTO = '0' OR CLR_FIFO = '1' THEN
			DMA_BYT_CNT <= x"00000000";													 
		ELSIF rising_edge(MAIN_CLK) AND nFB_WR = '0' AND DMA_DATEN_CS = '1' AND nFB_WR = '0' AND DMA_MODUS(4) = '1' AND FB_B1 = '1' THEN
				DMA_BYT_CNT(31 downto 17) <= "000000000000000";
				DMA_BYT_CNT(16 DOWNTO 9) <= fb_ad_in(23 DOWNTO 16);
				DMA_BYT_CNT(8 downto 0) <= "000000000";
			ELSIF rising_edge(MAIN_CLK) AND nFB_WR = '0' AND DMA_BYT_CNT_CS = '1' THEN
				DMA_BYT_CNT <= fb_ad_in;
			ELSE
				DMA_BYT_CNT <= DMA_BYT_CNT;
			END IF;
	END PROCESS;
    --------------------------------------------------------------------
    fb_ad_out(31 downto 16) <= "0000000000000" & DMA_STATUS when DMA_MODUS_CS = '1' and nFB_OE = '0' else "ZZZZZZZZZZZZZZZZ";
    DMA_STATUS(0) <= '1';													-- DMA OK
    DMA_STATUS(1) <= '1' WHEN DMA_BYT_CNT /= 0 AND DMA_BYT_CNT(31) = '0' ELSE '0';					-- WENN byts UND NICHT MINUS
    DMA_STATUS(2) <= '0' WHEN DMA_DRQ_I = '1' OR SCSI_DRQ = '1' ELSE '0'; 
    DMA_DRQQ <= '1' WHEN DMA_STATUS(1) = '1' AND DMA_MODUS(8) = '0' AND RDF_AZ >  15 AND DMA_MODUS(6) = '0' ELSE 
                '1' WHEN DMA_STATUS(1) = '1' AND DMA_MODUS(8) = '1' AND WRF_AZ < 512 AND DMA_MODUS(6) = '0' ELSE '0';
    DMA_DRQ <= '1' WHEN DMA_DRQ_REG = "11" AND DMA_MODUS(6) = '0' ELSE '0';
    -- DMA REQUEST: SPIKES AUSFILTERN  ------------------------------------------
	PROCESS(FDC_CLK, nRSTO, DMA_DRQ_REG)
	BEGIN
		IF nRSTO = '0' THEN
			DMA_DRQ_REG <= "00";
		ELSIF rising_edge(FDC_CLK) THEN
			DMA_DRQ_REG(0) <= DMA_DRQQ;
			DMA_DRQ_REG(1) <= DMA_DRQ_REG(0) and DMA_DRQQ;
		ELSE
			DMA_DRQ_REG <= DMA_DRQ_REG;
		END IF;
	END PROCESS;
    -- DMA ADRESSE ------------------------------------------------------
	PROCESS(MAIN_CLK, nRSTO, DMA_TOP_CS, DMA_TOP, nFB_WR, DMA_ADR_CS)
	BEGIN
		IF nRSTO = '0' THEN
			DMA_TOP <= x"00";
		ELSIF rising_edge(MAIN_CLK) AND nFB_WR = '0' AND (DMA_TOP_CS = '1' OR DMA_ADR_CS = '1') THEN
			DMA_TOP <= fb_ad_in(31 DOWNTO 24);
		ELSE 
			DMA_TOP <= DMA_TOP;
		END IF;
	END PROCESS;
	PROCESS(MAIN_CLK, nRSTO, DMA_HIGH_CS, DMA_HIGH, nFB_WR, DMA_ADR_CS)
	BEGIN
		IF nRSTO = '0' THEN
			DMA_HIGH <= x"00";
		ELSIF rising_edge(MAIN_CLK) AND nFB_WR = '0' AND (DMA_HIGH_CS = '1' OR DMA_ADR_CS = '1') THEN
			DMA_HIGH <= fb_ad_in(23 DOWNTO 16);
		ELSE
			DMA_HIGH <= DMA_HIGH;
		END IF;
	END PROCESS;
	PROCESS(MAIN_CLK, nRSTO, DMA_MID_CS, DMA_MID, nFB_WR)
	BEGIN
		DMA_MID <= DMA_MID;
		IF nRSTO = '0' THEN
			DMA_MID <= x"00";
		ELSIF rising_edge(MAIN_CLK) AND nFB_WR = '0' THEN
			IF DMA_MID_CS = '1' THEN
				DMA_MID <= fb_ad_in(23 DOWNTO 16);
			ELSIF DMA_ADR_CS = '1' THEN
				DMA_MID <= fb_ad_in(15 DOWNTO 8);
			END IF;
		END IF;
	END PROCESS;
	PROCESS(MAIN_CLK, nRSTO, DMA_LOW_CS, DMA_LOW, nFB_WR)
	BEGIN
		DMA_LOW <= DMA_LOW;
		IF nRSTO = '0' THEN
			DMA_LOW <= x"00";
		ELSIF rising_edge(MAIN_CLK) AND nFB_WR = '0' THEN
            IF DMA_LOW_CS = '1'THEN
				DMA_LOW <= fb_ad_in(23 DOWNTO 16);
			ELSIF DMA_ADR_CS = '1' THEN
				DMA_LOW <= fb_ad_in(7 DOWNTO 0);
            END IF;
		END IF;
	END PROCESS;
    --------------------------------------------------------------------------------------------
    DMA_TOP_CS <= '1' WHEN nFB_CS1 = '0'  AND FB_ADR(19 DOWNTO 1) = x"7C304" AND FB_B0 = '1' ELSE '0';			-- F8608/2
    DMA_HIGH_CS <= '1' WHEN nFB_CS1 = '0' AND FB_ADR(19 DOWNTO 1) = x"7C304" AND FB_B1 = '1' ELSE '0';			-- F8609/2		
    DMA_MID_CS <= '1' WHEN nFB_CS1 = '0'  AND FB_ADR(19 DOWNTO 1) = x"7C305" AND FB_B1 = '1' ELSE '0';			-- F860B/2		
    DMA_LOW_CS <= '1' WHEN nFB_CS1 = '0'  AND FB_ADR(19 DOWNTO 1) = x"7C306" AND FB_B1 = '1' ELSE '0';			-- F860D/2
    
    fb_ad_out(31 DOWNTO 24) <= DMA_TOP  WHEN DMA_TOP_CS = '1'  and nFB_OE = '0' ELSE "ZZZZZZZZ";
    fb_ad_out(23 DOWNTO 16) <= DMA_HIGH WHEN DMA_HIGH_CS = '1' and nFB_OE = '0' ELSE "ZZZZZZZZ";
    fb_ad_out(23 DOWNTO 16) <= DMA_MID  WHEN DMA_MID_CS = '1'  and nFB_OE = '0' ELSE "ZZZZZZZZ";
    fb_ad_out(23 DOWNTO 16) <= DMA_LOW  WHEN DMA_LOW_CS = '1'  and nFB_OE = '0' ELSE "ZZZZZZZZ";
    -- DIRECTZUGRIFF
    DMA_DIRM_CS <= '1' WHEN nFB_CS2 = '0' AND     FB_ADR(26 DOWNTO 0) = x"20100" ELSE '0';						-- F002'0100 WORD 
    DMA_ADR_CS  <= '1' WHEN nFB_CS2 = '0' AND     FB_ADR(26 DOWNTO 0) = x"20104" ELSE '0';						-- F002'0104 LONG 
    DMA_BYT_CNT_CS  <= '1' WHEN nFB_CS2 = '0' AND FB_ADR(26 DOWNTO 0) = x"20108" ELSE '0';						-- F002'0108 LONG

    fb_ad_out <= DMA_TOP & DMA_HIGH & DMA_MID & DMA_LOW when DMA_ADR_CS = '1'  and nFB_OE = '0' else "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
    fb_ad_out(31 DOWNTO 16) <= DMA_MODUS WHEN DMA_DIRM_CS = '1' and nFB_OE = '0' ELSE "ZZZZZZZZZZZZZZZZ";
    fb_ad_out <= DMA_BYT_CNT WHEN DMA_BYT_CNT_CS = '1'  and nFB_OE = '0' ELSE "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";

    -- DMA RW TOGGLE ------------------------------------------
	PROCESS(MAIN_CLK, nRSTO, DMA_MODUS_CS, DMA_MODUS, DMA_DIR_OLD)
	BEGIN
		IF nRSTO = '0' THEN
			DMA_DIR_OLD <= '0';
		ELSIF rising_edge(MAIN_CLK) AND  DMA_MODUS_CS = '0' THEN
				DMA_DIR_OLD <= DMA_MODUS(8);
			ELSE
				DMA_DIR_OLD <= DMA_DIR_OLD;
			END IF;
	END PROCESS;
    CLR_FIFO <= DMA_MODUS(8) XOR DMA_DIR_OLD;	
    -- SCSI ----------------------------------------------------------------------------------
    i_scsi : WF5380_TOP_SOC
        PORT MAP(
            CLK					=> FDC_CLK,
            RESETn				=> nResetatio,
			ADR			        => CA2 & CA1 & CA0,
			DATA_IN		        => CD_IN_FDC,	
			DATA_OUT			=> SCSI_DOUT,
			--DATA_EN			: out bit;
            -- Bus and DMA controls:
			CSn			        => SCSI_CSn,
			RDn		            => (not nFDC_WR) or (not SCSI_CS),
			WRn	                =>      nFDC_WR  or (not SCSI_CS),
            EOPn                => '1',
			DACKn	            => nSCSI_DACK,
			DRQ		            => SCSI_DRQ,
			INT		            => SCSI_INT,
--            READY                	=> 
            -- SCSI bus:
            DB_INn		        => SCSI_D,
            DB_OUTn		        => DB_OUTn,
            DB_EN               => DB_EN,
            DBP_INn		        => SCSI_PAR,
            DBP_OUTn	        => DBP_OUTn,
            DBP_EN              => DBP_EN,				-- wenn 1 dann output
            RST_INn             => nSCSI_RST,
            RST_OUTn            => RST_OUTn,
            RST_EN              => RST_EN,
            BSY_INn             => nSCSI_BUSY,
            BSY_OUTn            => BSY_OUTn,
            BSY_EN              => BSY_EN,
            SEL_INn             => nSCSI_SEL,
            SEL_OUTn            => SEL_OUTn,
            SEL_EN              => SEL_EN,
            ACK_INn             => '1',
            ACK_OUTn            => nSCSI_ACK,
--            ACK_EN              => ACK_EN,
            ATN_INn             => '1',
            ATN_OUTn            => nSCSI_ATN,
--            ATN_EN              => ATN_EN,
            REQ_INn             => nSCSI_DRQ,
--            REQ_OUTn            => REQ_OUTn,
--            REQ_EN              => REQ_EN,
            IOn_IN              => nSCSI_I_O,
--            IOn_OUT             => IOn_OUT,
--            IO_EN               => IO_EN,
            CDn_IN              => nSCSI_C_D,
--            CDn_OUT             => CDn_OUT,
--            CD_EN               => CD_EN,
            MSG_INn             => nSCSI_MSG
--            MSG_OUTn            => MSG_OUTn,
--            MSG_EN              => MSG_EN
        );              
    -- SCSI ACSI ---------------------------------------------------------------
    SCSI_D <= "ZZZZZZZZ";       --DB_OUTn when DB_EN = '1' else "ZZZZZZZZ";
    SCSI_DIR <= '1';-- when DB_EN = '1' else '1';	 
    SCSI_PAR <= DBP_OUTn WHEN DBP_EN = '1' ELSE 'Z';
    nSCSI_RST <= 'Z';--RST_OUTn when RST_EN = '1' else 'Z';
    nSCSI_BUSY <= 'Z';--BSY_OUTn when BSY_EN = '1' else 'Z';
    nSCSI_SEL <= 'Z';--SEL_OUTn when SEL_EN = '1' else 'Z';
    
    ACSI_DIR <= '0';
    ACSI_D <= "ZZZZZZZZ";
    nACSI_CS <= '1';
    ACSI_A1 <= CA1;
    nACSI_RESET <= nRSTO;
    nACSI_ACK <= '1';
    nResetatio <= '0' when nRSTO = '0' or ACP_CONF(24) = '1' else '1';

    ----------------------------------------------------------------------------
    -- ROM-PORT TA KOMMT FROM DEFAULT TA = 16 BUSCYCLEN = 500ns
    ----------------------------------------------------------------------------
    ROM_CS <= '1' WHEN nFB_CS1 = '0' AND nFB_WR = '1' AND FB_ADR(19 DOWNTO 17) = x"5" ELSE '0';		-- FFF A'0000/2'0000
    nROM4 <= '0' WHEN ROM_CS = '1' AND FB_ADR(16) = '0' ELSE '1';
    nROM3 <= '0' WHEN ROM_CS = '1' AND FB_ADR(16) = '1' ELSE '1';

    ----------------------------------------------------------------------------
    -- ACIA KEYBOARD
    ----------------------------------------------------------------------------
	i_acia_keyboard : WF6850IP_TOP_SOC
	  PORT MAP(
			CLK					=> MAIN_CLK,
			RESETn				=> nResetatio,

			CS2n				=> FB_ADR(2),
			CS1					=> '1',
			CS0					=> ACIA_CS_I,
            E					=> ACIA_CS_I,
			RWn					=> nFB_WR,
			RS					=> FB_ADR(1),

			DATA_IN				=> FB_ADI(15 downto 8),
			DATA_OUT			=> DATA_OUT_ACIA_I,
--			DATA_EN				=> DATA_EN_ACIA_I,

			TXCLK				=> CLK500k,
			RXCLK				=> CLK500k,
			RXDATA				=> KEYB_RxD,

			CTSn				=> '0',
			DCDn				=> '0',
        
			IRQn				=> IRQ_KEYBDn,
			TXDATA				=> AMKB_TX_sync
			--RTSn				=> -- Not used.
		);                                              
    ACIA_CS_I <= '1' WHEN nFB_CS1 = '0'AND FB_ADR(19 DOWNTO 3) = x"1FF80" ELSE '0';		-- FFC00-FFC07 FFC00/8
    KEYB_RxD <= '0' WHEN AMKB_REG(3) = '0' or PIC_AMKB_RX = '0' ELSE '1';				-- TASTATUR DATEN VOM PIC(PS2) OR NORMAL  // 
    fb_ad_out(31 DOWNTO 24) <= DATA_OUT_ACIA_I  WHEN ACIA_CS_I = '1' and FB_ADR(2) = '0' and nFB_OE = '0' ELSE  
					   DATA_OUT_ACIA_II WHEN ACIA_CS_I = '1' and FB_ADR(2) = '1' and nFB_OE = '0' ELSE (others => 'Z');

    -- AMKB_TX: SPIKES AUSFILTERN  und sychronisieren ------------------------------------------
	PROCESS(CLK2M, AMKB_RX, AMKB_REG)
	BEGIN
		if rising_edge(CLK500k) then
			AMKB_TX <= AMKB_TX_sync;
			IF AMKB_RX = '0' THEN
				IF AMKB_REG < 8 THEN
					AMKB_REG <= "0000";
				ELSE
					AMKB_REG <= AMKB_REG - 1;
				END IF;
			ELSE
				IF AMKB_REG > 7 THEN
					AMKB_REG <= "1111";
				ELSE
					AMKB_REG <= AMKB_REG + 1;
				END IF;
			END IF;
		ELSE
			AMKB_TX <= AMKB_TX;
			AMKB_REG <= AMKB_REG;
		END IF;
	END PROCESS;

    -- acia interrupt  ------------------------------------------
    acia_irq <= '0' WHEN IRQ_KEYBDn = '0' or IRQ_MIDIn = '0' ELSE '1';

    ----------------------------------------------------------------------------
    -- ACIA MIDI
    ----------------------------------------------------------------------------
	i_acia_midi : WF6850IP_TOP_SOC
		PORT MAP(
			CLK					=> MAIN_CLK,
			RESETn				=> nResetatio,

			CS2n				=> '0',
			CS1					=> FB_ADR(2),
			CS0					=> ACIA_CS_I,
            E					=> ACIA_CS_I,
			RWn					=> nFB_WR,
			RS					=> FB_ADR(1),

			DATA_IN				=> FB_ADI(15 downto 8),
			DATA_OUT			=> DATA_OUT_ACIA_II,
--			DATA_EN				=> DATA_EN_ACIA_II,

			TXCLK				=> CLK500k,
			RXCLK				=> CLK500k,
			RXDATA				=> MIDI_IN,
			CTSn				=> '0',
			DCDn				=> '0',
        
			IRQn				=> IRQ_MIDIn,
			TXDATA				=> MIDI_OUT
			--RTSn				=> -- Not used.
	    ); 
    MIDI_TLR <= MIDI_IN;
    MIDI_OLR <= MIDI_OUT;
    ----------------------------------------------------------------------------
    -- MFP
    ----------------------------------------------------------------------------
	i_mfp : WF68901IP_TOP_SOC
		PORT MAP(  
			-- System control:
			CLK					=> not MAIN_CLK,
			RESETn				=> nResetatio,
			-- Asynchronous bus control:
			DSn					=> NOT LDS,
			CSn					=> NOT MFP_CS,
			RWn					=> nFB_WR,
 			DTACKn				=> DTACK_OUT_MFPn,
			-- Data and Adresses:
			RS					=> FB_ADR(5 DOWNTO 1),
			DATA_IN				=> fb_ad_in(23 DOWNTO 16),
			DATA_OUT			=> DATA_OUT_MFP,
--			DATA_EN				=> DATA_EN_MFP,
            GPIP_IN(7)			=> NOT DMA_DRQ_Q,
            GPIP_IN(6)			=> NOT RI,
			GPIP_IN(5)			=> DINTn,
			GPIP_IN(4)			=> acia_irq,
			GPIP_IN(3)			=> DSP_INT,
            GPIP_IN(2)			=> NOT CTS,
            GPIP_IN(1)			=> NOT DCD,
            GPIP_IN(0)			=> LP_BUSY,
			-- GPIP_OUT			=>, -- Not used; all GPIPs are direction input.
			-- GPIP_EN			=>, -- Not used; all GPIPs are direction input.
			-- Interrupt control:
			IACKn				=> NOT MFP_INTACK,
			IEIn				=> '0',
			-- IEOn				=>, -- Not used.
			IRQn				=> nMFP_INT,
			-- Timers and timer control:
			XTAL1				=> CLK2M4576,
            TAI					=> '0',
			TBI				    => nBLANK,
            -- TAO				=>,
			-- TBO				=>,
            -- TCO				=>,
			TDO					=> TDO,
			-- Serial I/O control:
			RC					=> TDO,
			TC					=> TDO,
			SI					=> RxD, 
			SO					=> TxD
			-- SO_EN			=> MFP_SO_EN
			-- DMA control:
			-- RRn				=>,
			-- TRn				=>
		);

    MFP_CS <= '1' WHEN nFB_CS1 = '0' AND FB_ADR(19 DOWNTO 6) = x"3FE8" ELSE '0';		-- FFA00/40
    MFP_INTACK <= '1' WHEN nFB_CS2 = '0' AND FB_ADR(26 DOWNTO 0) = x"20000" ELSE '0'; 	--F002'0000
    LDS <= '1' WHEN MFP_CS = '1' OR MFP_INTACK = '1' ELSE '0';

    fb_ad_out(23 DOWNTO 16) <= DATA_OUT_MFP WHEN MFP_CS = '1' and nFB_OE = '0' ELSE (others => 'Z');
    fb_ad_out(31 DOWNTO 10) <= "0000000000000000000000" WHEN MFP_INTACK = '1' and nFB_OE = '0' ELSE (others => 'Z');
    fb_ad_out(9 DOWNTO 2) <= DATA_OUT_MFP when MFP_INTACK = '1' and nFB_OE = '0' ELSE (others => 'Z');
    fb_ad_out(1 DOWNTO 0) <= "00" WHEN MFP_INTACK = '1' AND nFB_OE = '0' ELSE (others => 'Z');
    DINTn <= '0' WHEN IDE_INT = '1' AND ACP_CONF(28) = '1' ELSE
             '0' WHEN FDINT = '1' ELSE
             '0' WHEN SCSI_INT = '1' AND ACP_CONF(28) = '1' ELSE '1';
    ----------------------------------------------------------------------------
    -- Sound
    ----------------------------------------------------------------------------
 	i_sound : WF2149IP_TOP_SOC
		PORT MAP(
			SYS_CLK				=> not MAIN_CLK,
			RESETn				=> nResetatio,

			WAV_CLK				=> CLK2M,
			SELn				=> '1',

			BDIR				=> SNDIR_I,
			BC2					=> '1',
			BC1					=> SNDCS_I,

			A9n					=> '0',
			A8					=> '1',
			DA_IN				=> FB_ADI(15 downto 8),
			DA_OUT 				=> DA_OUT_X,

			IO_A_IN				=> SND_A,	
			IO_A_OUT			=> SND_A_X,
--          IO_A_EN			    =>, -- Not required.
			IO_B_IN				=> LP_D,
			IO_B_OUT			=> LP_D_X,
--			IO_B_EN				=> IO_B_EN,

			OUT_A				=> YM_QA,
			OUT_B				=> YM_QB,
			OUT_C				=> YM_QC
		);

    SNDCS <= '1' WHEN nFB_CS1 = '0' AND FB_ADR(19 DOWNTO 2) = x"3E200" ELSE '0';		-- 8800-8803 F8800/4
    SNDCS_I <= '1' WHEN SNDCS = '1' AND FB_ADR (1 DOWNTO 1) = "0" ELSE '0';
    SNDIR_I <= '1' WHEN SNDCS = '1' AND nFB_WR = '0' ELSE '0';

    fb_ad_out(31 DOWNTO 24) <= DA_OUT_X WHEN SNDCS_I = '1' and nFB_OE = '0' ELSE (others => 'Z');

    nnIDE_RES <= SND_A_X(7);
    LP_DIR_X  <= SND_A_X(6);
    LP_STR    <= SND_A_X(5);
    DTR       <= SND_A_X(4); 
    RTS		  <= SND_A_X(3);

    -- FDD_D1SEL   <= SND_A_X(2)
    DSA_D	  <= SND_A_X(1);
    nSDSEL    <= SND_A_X(0);
    SND_A <= SND_A_X;
    LP_D <= LP_D_X WHEN LP_DIR_X = '0' ELSE (others => 'Z');
    LP_DIR <= LP_DIR_X; 


    ----------------------------------------------------------------------------
    -- DMA Sound register
    ----------------------------------------------------------------------------

    dma_snd_cs <= '1' WHEN nFB_CS1 = '0' and FB_ADR(19 DOWNTO 6) = x"3E24" ELSE '0';	-- F8900-F893F

	PROCESS(nRSTO,MAIN_CLK, FB_ADR(5 DOWNTO 1), dma_snd_cs)
	BEGIN
		IF nRSTO = '0' THEN
			sndmactl <= x"00";
		ELSIF rising_edge(MAIN_CLK) and dma_snd_cs = '1' and FB_ADR(5 DOWNTO 1) = x"0" and nFB_WR = '0' and FB_B1 ='1' THEN
				sndmactl <= fb_ad_in(23 DOWNTO 16);
			ELSE
				sndmactl <= sndmactl;
			END IF;
	END PROCESS;

    fb_ad_out(23 DOWNTO 16) <= sndmactl WHEN dma_snd_cs = '1' and FB_ADR(5 DOWNTO 1) = x"0" and nFB_OE = '0' ELSE (others => 'Z');

	PROCESS(nRSTO, MAIN_CLK, FB_ADR(5 DOWNTO 1), dma_snd_cs)
	begin
		IF nRSTO = '0' THEN
			sndbashi <= x"00";
		ELSIF rising_edge(MAIN_CLK) and dma_snd_cs = '1' and FB_ADR(5 DOWNTO 1) = x"1" and nFB_WR = '0' and FB_B1 ='1' THEN
			sndbashi <= fb_ad_in(23 DOWNTO 16);
		ELSE
			sndbashi <= sndbashi;
		END IF;
	END PROCESS;
    
    fb_ad_out(23 DOWNTO 16) <= sndbashi WHEN dma_snd_cs = '1' and FB_ADR(5 DOWNTO 1) = x"1" and nFB_OE = '0' ELSE (others => 'Z');

	PROCESS(nRSTO,MAIN_CLK,FB_ADR(5 DOWNTO 1), dma_snd_cs)
	BEGIN
		IF nRSTO = '0' THEN
			sndbasmi <= x"00";
		ELSIF rising_edge(MAIN_CLK) and dma_snd_cs = '1' and FB_ADR(5 DOWNTO 1) = x"2" and nFB_WR = '0' and FB_B1 ='1' THEN
			sndbasmi <= fb_ad_in(23 DOWNTO 16);
		ELSE
			sndbasmi <= sndbasmi;
		END IF;
	END PROCESS;

    fb_ad_out(23 DOWNTO 16) <= sndbasmi WHEN dma_snd_cs = '1' and FB_ADR(5 DOWNTO 1) = x"2" and nFB_OE = '0' ELSE (others => 'Z');

	PROCESS(nRSTO, MAIN_CLK, FB_ADR(5 DOWNTO 1), dma_snd_cs)
	BEGIN
		IF nRSTO = '0' THEN
			sndbaslo <= x"00";
		ELSIF rising_edge(MAIN_CLK) and dma_snd_cs = '1' and FB_ADR(5 DOWNTO 1) = x"3" and nFB_WR = '0' and FB_B1 ='1' THEN
				sndbaslo <= fb_ad_in(23 DOWNTO 16);
		ELSE
			sndbaslo <= sndbaslo;
		END IF;
	END PROCESS;
    
    fb_ad_out(23 DOWNTO 16) <= sndbaslo WHEN dma_snd_cs = '1' and FB_ADR(5 DOWNTO 1) = x"3" and nFB_OE = '0' ELSE (others => 'Z');

	PROCESS(nRSTO,MAIN_CLK,FB_ADR(5 DOWNTO 1), dma_snd_cs)
	BEGIN
		IF nRSTO = '0' THEN
			sndadrhi <= x"00";
		ELSIF rising_edge(MAIN_CLK) and dma_snd_cs = '1' and FB_ADR(5 DOWNTO 1) = x"4" and nFB_WR = '0' and FB_B1 ='1' THEN
			sndadrhi <= fb_ad_in(23 DOWNTO 16);
		ELSE
			sndadrhi <= sndadrhi;
		END IF;
	END PROCESS;

    fb_ad_out(23 DOWNTO 16) <= sndadrhi WHEN dma_snd_cs = '1' and FB_ADR(5 DOWNTO 1) = x"4" and nFB_OE = '0' ELSE (others => 'Z');

	PROCESS(nRSTO, MAIN_CLK, FB_ADR(5 DOWNTO 1), dma_snd_cs)
	BEGIN
		IF nRSTO = '0' THEN
			sndadrmi <= x"00";
		ELSIF rising_edge(MAIN_CLK) and dma_snd_cs = '1' and FB_ADR(5 DOWNTO 1) = x"5" and nFB_WR = '0' and FB_B1 ='1' THEN
			sndadrmi <= fb_ad_in(23 DOWNTO 16);
		ELSE
			sndadrmi <= sndadrmi;
		END IF;
	END PROCESS;

    fb_ad_out(23 DOWNTO 16) <= sndadrmi WHEN dma_snd_cs = '1' and FB_ADR(5 DOWNTO 1) = x"5" and nFB_OE = '0' else (others => 'Z');

	PROCESS(nRSTO, MAIN_CLK, FB_ADR(5 DOWNTO 1), dma_snd_cs)
	BEGIN
		IF nRSTO = '0' THEN
			sndadrlo <= x"00";
		ELSIF rising_edge(MAIN_CLK) and dma_snd_cs = '1' and FB_ADR(5 DOWNTO 1) = x"6" and nFB_WR = '0' and FB_B1 ='1' THEN
			sndadrlo <= fb_ad_in(23 DOWNTO 16);
		ELSE
			sndadrlo <= sndadrlo;
		END IF;
	END PROCESS;
    
    fb_ad_out(23 DOWNTO 16) <= sndadrlo WHEN dma_snd_cs = '1' and FB_ADR(5 DOWNTO 1) = x"6" and nFB_OE = '0' ELSE (others => 'Z');

	PROCESS(nRSTO, MAIN_CLK, FB_ADR(5 DOWNTO 1), dma_snd_cs)
	BEGIN
		IF nRSTO = '0' THEN
			sndendhi <= x"00";
		ELSIF rising_edge(MAIN_CLK) and dma_snd_cs = '1' and FB_ADR(5 DOWNTO 1) = x"7" and nFB_WR = '0' and FB_B1 ='1' THEN
			sndendhi <= fb_ad_in(23 DOWNTO 16);
		ELSE
			sndendhi <= sndendhi;
		END IF;
	END PROCESS;

    fb_ad_out(23 DOWNTO 16) <= sndendhi WHEN dma_snd_cs = '1' and FB_ADR(5 DOWNTO 1) = x"7" and nFB_OE = '0' ELSE (others => 'Z');

	PROCESS(nRSTO, MAIN_CLK, FB_ADR(5 DOWNTO 1), dma_snd_cs)
	BEGIN
		IF nRSTO = '0' THEN
			sndendmi <= x"00";
		ELSIF rising_edge(MAIN_CLK) and dma_snd_cs = '1' and FB_ADR(5 DOWNTO 1) = x"8" and nFB_WR = '0' and FB_B1 ='1' THEN
			sndendmi <= fb_ad_in(23 DOWNTO 16);
		ELSE
			sndendmi <= sndendmi;
		END IF;
	END PROCESS;
    
    fb_ad_out(23 DOWNTO 16) <= sndendmi WHEN dma_snd_cs = '1' and FB_ADR(5 DOWNTO 1) = x"8" and nFB_OE = '0' ELSE (others => 'Z');

	PROCESS(nRSTO, MAIN_CLK, FB_ADR(5 DOWNTO 1), dma_snd_cs)
	BEGIN
		IF nRSTO = '0' THEN
			sndendlo <= x"00";
		ELSIF rising_edge(MAIN_CLK) and dma_snd_cs = '1' and FB_ADR(5 DOWNTO 1) = x"9" and nFB_WR = '0' and FB_B1 ='1' THEN
			sndendlo <= fb_ad_in(23 DOWNTO 16);
		ELSE
			sndendlo <= sndendlo;
		END IF;
	END PROCESS;

    fb_ad_out(23 DOWNTO 16) <= sndendlo WHEN dma_snd_cs = '1' and FB_ADR(5 DOWNTO 1) = x"9" and nFB_OE = '0' ELSE (others => 'Z');

	PROCESS(nRSTO, MAIN_CLK, FB_ADR(5 DOWNTO 1), dma_snd_cs)
	BEGIN
		IF nRSTO = '0' THEN
			sndmode <= x"00";
		ELSIF rising_edge(MAIN_CLK) and dma_snd_cs = '1' and FB_ADR(5 DOWNTO 1) = x"10" and nFB_WR = '0' and FB_B1 ='1' THEN
			sndmode <= fb_ad_in(23 DOWNTO 16);
		ELSE
			sndmode <= sndmode;
		END IF;
	END PROCESS;
    
    fb_ad_out(23 DOWNTO 16) <= sndmode WHEN dma_snd_cs = '1' and FB_ADR(5 DOWNTO 1) = x"10" and nFB_OE = '0' ELSE (others => 'Z');

    ----------------------------------------------------------------------------
    -- Paddle
    ----------------------------------------------------------------------------
    
    paddle_cs <= '1' WHEN nFB_CS1 = '0' and FB_ADR(19 DOWNTO 6) = x"3E48" ELSE '0';	-- F9200-F923F
    
    fb_ad_out(31 DOWNTO 16) <= x"bfff" WHEN paddle_cs = '1' and FB_ADR(5 DOWNTO 1) = x"0" and nFB_OE = '0' ELSE (others => 'Z');
    fb_ad_out(31 DOWNTO 16) <= x"ffff" WHEN paddle_cs = '1' and FB_ADR(5 DOWNTO 1) = x"1" and nFB_OE = '0' ELSE (others => 'Z');
    fb_ad_out(31 DOWNTO 16) <= x"ffff" WHEN paddle_cs = '1' and FB_ADR(5 DOWNTO 1) = x"8" and nFB_OE = '0' ELSE (others => 'Z');
    fb_ad_out(31 DOWNTO 16) <= x"ffff" WHEN paddle_cs = '1' and FB_ADR(5 DOWNTO 1) = x"9" and nFB_OE = '0' ELSE (others => 'Z');
    fb_ad_out(31 DOWNTO 16) <= x"ffff" WHEN paddle_cs = '1' and FB_ADR(5 DOWNTO 1) = x"A" and nFB_OE = '0' ELSE (others => 'Z');
    fb_ad_out(31 DOWNTO 16) <= x"ffff" WHEN paddle_cs = '1' and FB_ADR(5 DOWNTO 1) = x"B" and nFB_OE = '0' ELSE (others => 'Z');
    fb_ad_out(31 DOWNTO 16) <= x"0000" WHEN paddle_cs = '1' and FB_ADR(5 DOWNTO 1) = x"10" and nFB_OE = '0' ELSE (others => 'Z');
    fb_ad_out(31 DOWNTO 16) <= x"0000" WHEN paddle_cs = '1' and FB_ADR(5 DOWNTO 1) = x"11" and nFB_OE = '0' ELSE (others => 'Z');

END rtl;
