-- Copyright: Matthias Heinrichs 2014
-- Free for non-comercial use
-- No warranty just for fun
-- If you want to earn money with this code, ask me first!



library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity BUS68030 is

port( 
	AS_030: inout std_logic ;
	AS_000: inout std_logic ;
	RW_000: inout std_logic ;
	DS_030: inout std_logic ;
	UDS_000: inout std_logic;
	LDS_000: inout std_logic;
	SIZE: inout std_logic_vector ( 1 downto 0 );
	A: in std_logic_vector ( 31 downto 2 );
	A0: inout std_logic;
	A1: in std_logic;
	nEXP_SPACE: in std_logic ;
	BERR: inout std_logic ;
	BG_030: in std_logic ;
	BG_000: out std_logic ;
	BGACK_030: out std_logic ;
	BGACK_000: in std_logic ;
	CLK_030: in std_logic ;
	CLK_000: in std_logic ;
	CLK_OSZI: in std_logic ;
	CLK_DIV_OUT: out std_logic ;
	CLK_EXP: out std_logic	; 
	FPU_CS: out std_logic ;
	FPU_SENSE: in std_logic ;
	IPL_030: out std_logic_vector ( 2 downto 0 );
	IPL: in std_logic_vector ( 2 downto 0 );
	DSACK1: inout std_logic;
	DTACK: inout std_logic ;
	AVEC: out std_logic ;
	E: out std_logic ;
	VPA: in std_logic ;
	VMA: out std_logic ;
	RST: in std_logic ;
	RESET: inout std_logic ;
	RW: inout std_logic ;
--	D: inout std_logic_vector ( 31 downto 28 );
	FC: in std_logic_vector ( 1 downto 0 );
	AMIGA_ADDR_ENABLE: out std_logic ;
	AMIGA_BUS_DATA_DIR: out std_logic ;
	AMIGA_BUS_ENABLE_LOW: out std_logic;
	AMIGA_BUS_ENABLE_HIGH: out std_logic;
	CIIN: out std_logic
	);
end BUS68030;

architecture Behavioral of BUS68030 is




TYPE SM_E IS (
				E1,
				E2,
				E3,
				E4,
				E5,
				E6,
				E7,
				E8,
				E9,
				E10
				);



signal cpu_est : SM_E;

TYPE SM_68000 IS (
				IDLE_P,
				IDLE_N,
				AS_SET_P,
				AS_SET_N,
				SAMPLE_DTACK_P,
				DATA_FETCH_N,
				DATA_FETCH_P,
				END_CYCLE_N
				);


signal SM_AMIGA : SM_68000;
  
--signal	Dout:STD_LOGIC_VECTOR(3 downto 0) := "0000";
signal	AS_000_INT:STD_LOGIC		:= '1';
signal	RW_000_INT:STD_LOGIC		:= '1';
signal	AMIGA_BUS_ENABLE_INT:STD_LOGIC		:= '1';
signal	AMIGA_BUS_ENABLE_DMA_HIGH:STD_LOGIC		:= '1';
signal	AMIGA_BUS_ENABLE_DMA_LOW:STD_LOGIC		:= '1';
signal	AS_030_D0:STD_LOGIC			:= '1';
signal	nEXP_SPACE_D0:STD_LOGIC		:= '0';
signal	DS_030_D0:STD_LOGIC			:= '1';
signal	AS_030_000_SYNC:STD_LOGIC	:= '1';
signal	BGACK_030_INT:STD_LOGIC		:= '1';
signal	BGACK_030_INT_D:STD_LOGIC	:= '1';
signal	BGACK_030_INT_PRE:STD_LOGIC	:= '1';
signal	AS_000_DMA:STD_LOGIC		:= '1';
signal	DS_000_DMA:STD_LOGIC		:= '1';
signal	RW_000_DMA:STD_LOGIC		:= '1';
signal  CYCLE_DMA: STD_LOGIC_VECTOR ( 1 downto 0 ) 	:= "00";
signal  SIZE_DMA: STD_LOGIC_VECTOR ( 1 downto 0 ) 	:= "11";
signal  IPL_D0: STD_LOGIC_VECTOR ( 2 downto 0 ) 	:= "111";
signal	A0_DMA: STD_LOGIC			:= '1';
signal	VMA_INT: STD_LOGIC			:= '1';
signal	VPA_D: STD_LOGIC			:= '1';
signal	UDS_000_INT: STD_LOGIC		:= '1';
signal	LDS_000_INT: STD_LOGIC		:= '1';
signal	DS_000_ENABLE: STD_LOGIC	:= '0';
signal  DSACK1_INT: STD_LOGIC		:= '1';
signal	CLK_OUT_PRE_50: STD_LOGIC	:= '1';
signal	CLK_OUT_PRE_25: STD_LOGIC	:= '1';
signal	CLK_OUT_PRE: STD_LOGIC		:= '1';
signal	CLK_OUT_PRE_D: STD_LOGIC	:= '1';
signal	CLK_OUT_INT: STD_LOGIC		:= '1';
signal	CLK_030_H: STD_LOGIC		:= '1';
signal	CLK_000_D0: STD_LOGIC 		:= '1';
signal	CLK_000_D1: STD_LOGIC 		:= '1';
signal	CLK_000_D2: STD_LOGIC 		:= '1';
signal	CLK_000_D3: STD_LOGIC 		:= '1';
signal	CLK_000_D4: STD_LOGIC 		:= '1';
signal	CLK_000_P_SYNC: STD_LOGIC_VECTOR ( 12 downto 0 ) 	:= "0000000000000";
signal	CLK_000_N_SYNC: STD_LOGIC_VECTOR ( 12 downto 0 ) 	:= "0000000000000";
signal	CLK_000_PE: STD_LOGIC 		:= '0';
signal	CLK_000_NE: STD_LOGIC 		:= '0';
signal	CLK_000_NE_D0: STD_LOGIC 		:= '0';
signal	DTACK_D0: STD_LOGIC 		:= '1';
signal  RESET_OUT: STD_LOGIC 		:= '0';
signal	CLK_030_D0: STD_LOGIC 		:= '0';
--signal  NO_RESET: STD_LOGIC 		:= '0';
signal	RST_DLY: STD_LOGIC_VECTOR ( 2 downto 0 ) 	:= "000";
--signal	RST_DLY_AMIGA: STD_LOGIC_VECTOR ( 7 downto 0 ) 	:= "00000000";
--signal  RESET_OUT_AMIGA: STD_LOGIC 		:= '0';
begin

	--pos edge clock process
	--no ansynchronious reset! the reset is sampled synchroniously
	--this mut be because of the e-clock: The E-Clock has to run CONSTANTLY 
	--or the Amiga will fail to boot from a reset. 
	--However a compilation with no resets on thEe-Clock and resets on other signals does not work, either!
	pos_clk: process(CLK_OSZI)
	begin
		if(rising_edge(CLK_OSZI)) then
			--clk generation :
			CLK_030_D0 <=CLK_030;
		  CLK_OUT_PRE_50	<=	not CLK_OUT_PRE_50;		  
		  if(CLK_OUT_PRE_50 = '1' )then
		  	CLK_OUT_PRE_25<=	not CLK_OUT_PRE_25;		    
		  end if;
						
			
			--here the clock is selected
			CLK_OUT_PRE_D 	<= CLK_OUT_PRE_50;
			
			-- the external clock to the processor is generated here
			CLK_OUT_INT	<= CLK_OUT_PRE_D; --this way we know the clock of the next state: Its like looking in the future, cool!
			--delayed Clocks and signals for edge detection
			CLK_000_D0 	<= CLK_000;
			CLK_000_D1 	<= CLK_000_D0;
			CLK_000_D2 	<= CLK_000_D1;
			CLK_000_D3 	<= CLK_000_D2;
			CLK_000_D4 	<= CLK_000_D3;

			--shift registers for edge detection
			CLK_000_P_SYNC( 12 downto 1 ) 	<= CLK_000_P_SYNC( 11 downto 0 );
			CLK_000_P_SYNC(0)				<= CLK_000_D0 AND NOT CLK_000_D1;
			CLK_000_N_SYNC( 12 downto 1 ) 	<= CLK_000_N_SYNC( 11 downto 0 );
			CLK_000_N_SYNC(0)				<= NOT CLK_000_D0 AND CLK_000_D1;
			
			-- values are determined empiracally for 7.09 MHz Clock
			-- since the clock is not symmetrically these values differ!
			CLK_000_PE <= CLK_000_P_SYNC(9);
			CLK_000_NE <= CLK_000_N_SYNC(11);
			CLK_000_NE_D0 <= CLK_000_NE;
			
			-- e-clock is changed on the FALLING edge!

			if(CLK_000_NE_D0 = '1' ) then
			--if(CLK_000_D0='0' AND CLK_000_D1='1') then
				case (cpu_est) is
					when E1 => cpu_est <= E2 ; 
					when E2 => cpu_est <= E3 ;
					when E3 => cpu_est <= E4;
					when E4  => cpu_est <= E5 ;
					when E5  => cpu_est <= E6 ;
					when E6  => cpu_est <= E7 ;
					when E7  => cpu_est <= E8 ;
					when E8  => cpu_est <= E9 ;
					when E9  => cpu_est <= E10;
					when E10 => cpu_est <= E1 ;
				end case;
			end if;
			
			--this is a statemachine to propagate an internal reset to the amiga
			--if(	(RESET = '0' and RESET_OUT = '1') or RST_DLY_AMIGA /= "11111111") then --reset condition from the tk-board
			--	if(RST_DLY_AMIGA = "11111111") then --start of reset
			--		RESET_OUT_AMIGA <= '1';
			--		RST_DLY_AMIGA <= "00000000";
			--	else
			--		RST_DLY_AMIGA <= RST_DLY_AMIGA+1;
			--	end if;					
			--else
			--	RST_DLY_AMIGA	<= "11111111";
			--	RESET_OUT_AMIGA <= '0';
			--end if;

			
			--the statemachine
			if(RST = '0' ) then
				VPA_D			<= '1';
				DTACK_D0		<= '1';
				SM_AMIGA		<= IDLE_P;
				AS_000_INT 		<= '1';
				RW_000_INT		<= '1';
				RW_000_DMA		<= '1';
				AS_030_000_SYNC <= '1';
				UDS_000_INT		<= '1';
				LDS_000_INT		<= '1';
				DS_000_ENABLE	<= '0';
				VMA_INT			<= '1';
				BG_000			<= '1';
				BGACK_030_INT	<= '1';
				BGACK_030_INT_D <= '1';
				BGACK_030_INT_PRE<= '1';
				DSACK1_INT		<= '1';
				IPL_D0			<= "111";
				IPL_030			<= "111";
				AS_000_DMA		<= '1';
				DS_000_DMA		<= '1';
				SIZE_DMA		<= "11";
				A0_DMA			<= '1';
				AMIGA_BUS_ENABLE_INT <= '1';
				AMIGA_BUS_ENABLE_DMA_HIGH <= '1';
				AMIGA_BUS_ENABLE_DMA_LOW <= '1';
				AS_030_D0		<= '1';
				nEXP_SPACE_D0	<= '1';
				DS_030_D0		<= '1';
				CLK_030_H		<= '0';	
				CYCLE_DMA		<= "00";
				RST_DLY			<= "000";
				RESET_OUT 		<= '0';
			else 
				
				if(CLK_000_NE='1')then
					if(RST_DLY="111")then
						RESET_OUT 		<= '1';
					else
						RST_DLY <= RST_DLY+1;						
					end if;
				end if;

				--now: 68000 state machine and signals
				
				--buffering signals
				AS_030_D0 <= AS_030;
				nEXP_SPACE_D0 <= nEXP_SPACE;
				DS_030_D0 <= DS_030;
				DTACK_D0	<= DTACK;
				VPA_D 		<= VPA;
	

				--bgack is simple: assert as soon as Amiga asserts but hold bg_ack for one amiga-clock 
				if(BGACK_000='0') then
					BGACK_030_INT	<= '0';
				elsif (	BGACK_000='1' 
						AND CLK_000_PE='1'
						AND AS_000 = '1' --the amiga AS can be still active while bgack is deasserted, so wait for this signal too!
						--AND CLK_000_D0='1' and CLK_000_D1='0'
						) then -- BGACK_000 is high here!
					BGACK_030_INT_PRE<= '1';
					BGACK_030_INT 	<= BGACK_030_INT_PRE; --hold this signal high until 7m clock goes low
				end if;
				BGACK_030_INT_D <= BGACK_030_INT;
	
				
	
				--bus grant only in idle state
				if(BG_030= '1')then
					BG_000	<= '1';
				elsif(	BG_030= '0' --AND (SM_AMIGA 	= IDLE_P)
						and nEXP_SPACE_D0 = '1' and AS_030_D0='1'
						and CLK_000_D0='1' 
						--and CLK_000_D0='1' AND CLK_000_D1='0'  
						) then --bus granted no local access and no AS_030 running!
						BG_000 	<= '0';
				end if;
	
			
				--interrupt buffering to avoid ghost interrupts
				--if(CLK_000_NE='1')then
				--if(CLK_000_D0='0' and CLK_000_D1='1')then
					IPL_D0<=IPL;			
					if(IPL = IPL_D0)then
						IPL_030<=IPL;
					end if;
				--end if;
			
				-- as030-sampling and FPU-Select
	
				
				if(AS_030_D0 ='1' or BERR='0') then -- "async" reset of various signals
					AS_030_000_SYNC <= '1';
					DSACK1_INT		<= '1';
					AS_000_INT  	<= '1';
					DS_000_ENABLE	<= '0';
					--RW_000_INT		<= '1';	
				elsif(	--CLK_030  		= '1'  AND --68030 has a valid AS on high clocks					
						AS_030_D0			= '0'  AND --as set
						BGACK_030_INT='1' AND 
						BGACK_030_INT_D='1' AND --no dma -cycle
						NOT (FC(1)='1' and FC(0)='1' and A(19)='0' and A(18)='0' and A(17)='1' and A(16)='0') AND --FPU-Select
						nEXP_SPACE_D0 ='1' and --not an expansion space cycle
						SM_AMIGA = IDLE_P --last amiga cycle terminated
						) then
						AS_030_000_SYNC <= '0';					
				end if;
				
	
				-- VMA generation
				if(CLK_000_NE='1' AND VPA_D='0' AND cpu_est = E4)then --assert
				--if(CLK_000_D0='0' AND CLK_000_D1='1' AND VPA_D='0' AND cpu_est = E4)then --assert
					VMA_INT <= '0';
				elsif(CLK_000_PE='1' AND cpu_est=E1)then --deassert
					VMA_INT <= '1';										
				end if;
				
				--uds/lds precalculation
				if (SM_AMIGA = IDLE_N) then --DS: set udl/lds 	
					if(A0='0') then
						UDS_000_INT <= '0';
					else
						UDS_000_INT <= '1';
					end if;
					if((A0='1' OR SIZE(0)='0' OR SIZE(1)='1')) then
						LDS_000_INT <= '0';
					else
						LDS_000_INT <= '1';
					end if;
				end if;
	
	
				--Amiga statemachine
	
				if(BERR='0')then --"async" reset on errors
					SM_AMIGA<=IDLE_P;
				end if;
	
				case (SM_AMIGA) is
					when IDLE_P 	 => --68000:S0 wait for a falling edge
						RW_000_INT		<= '1';		
						AMIGA_BUS_ENABLE_INT <= CLK_000_D1;
						if( CLK_000_D0='0' and CLK_000_D1= '1' and AS_030_000_SYNC = '0' and nEXP_SPACE_D0 ='1')then -- if this a delayed expansion space detection, do not start an amiga cycle!
							SM_AMIGA<=IDLE_N;  --go to s1
						end if;
					when IDLE_N 	 => --68000:S1 place Adress on bus and wait for rising edge, on a rising CLK_000 look for a amiga adressrobe
						AMIGA_BUS_ENABLE_INT <= '0' ;--for now: allways on for amiga
						if(CLK_000_PE='1')then --go to s2
						--if(CLK_000_D0='1')then --go to s2
							SM_AMIGA <= AS_SET_P; --as for amiga set! 
						end if;
					when AS_SET_P	 => --68000:S2 Amiga cycle starts here: since AS is asserted during transition to this state we simply wait here
						RW_000_INT <= RW;						
						AS_000_INT <= '0';
						if (RW='1' ) then --read: set udl/lds 	
							DS_000_ENABLE	<= '1';
						end if;
						if(CLK_000_NE='1')then --go to s3
						--if(CLK_000_D0='0')then --go to s3
							SM_AMIGA<=AS_SET_N; 
						end if;
					when AS_SET_N	 => --68000:S3: nothing happens here; on a transition to s4: assert uds/lds on write 
						
						if(CLK_000_PE='1')then --go to s4
						--if(CLK_000_D0='1')then --go to s4
							-- set DS-Enable without respect to rw: this simplifies the life for the syntesizer
							DS_000_ENABLE	<= '1';--write: set udl/lds earlier than in the specs. this does not seem to harm anything and is saver, than sampling uds/lds too late 				 
							SM_AMIGA <= SAMPLE_DTACK_P; 
						end if;
					when SAMPLE_DTACK_P=> --68000:S4 wait for dtack or VMA
						DS_000_ENABLE	<= '1';
						if(	CLK_000_NE_D0='1' and --falling edge
						--if(	CLK_000_D0 = '0' and CLK_000_D1='1' and --falling edge
							((VPA_D = '1' AND DTACK_D0='0') OR --DTACK end cycle
							(VPA_D='0' AND cpu_est=E9 AND VMA_INT='0')) --VPA end cycle
							)then --go to s5
							SM_AMIGA<=DATA_FETCH_N;
						end if;
					when DATA_FETCH_N=> --68000:S5 nothing happens here just wait for positive clock
						DS_000_ENABLE	<= '1';
						if(CLK_000_PE = '1')then --go to s6
						--if(CLK_000_D0='1')then --go to s6
							SM_AMIGA<=DATA_FETCH_P;
						end if;
					when DATA_FETCH_P => --68000:S6: READ: here comes the data on the bus!
						DS_000_ENABLE	<= '1';
						if( (CLK_000_N_SYNC( 8)='1' AND not (CLK_030 ='1' and CLK_OUT_PRE_D='0')) OR
							(CLK_000_N_SYNC(9)='1' )) then --go to s7 next 030-clock is not a falling edge: dsack is sampled at the falling edge
							DSACK1_INT <='0'; 
						end if;
						--if( CLK_000_D3 ='1' AND CLK_000_D4 = '0' ) then --go to s7 next 030-clock is high: dsack is sampled at the falling edge
						--	DSACK1_INT <='0'; 
						--end if;
						if( CLK_000_NE ='1') then --go to s7 next 030-clock is high: dsack is sampled at the falling edge
						--if( CLK_000_D0 ='0') then --go to s7 next 030-clock is high: dsack is sampled at the falling edge
							--DSACK1_INT <='0'; 
							SM_AMIGA<=END_CYCLE_N;
						end if;
					when END_CYCLE_N =>--68000:S7: Latch/Store data. Wait here for new cycle and go to IDLE on high clock
						if(CLK_000_PE='1')then --go to s0	
						--if(CLK_000_D0='1')then --go to s0																	
							SM_AMIGA<=IDLE_P;	
							RW_000_INT		<= '1';	
							--AMIGA_BUS_ENABLE_INT <= '1';					
						end if;
				end case;
	
				--dma stuff
				if(BGACK_030_INT='0')then			
					--switch amiga bus on for DMA-Cycles
					AMIGA_BUS_ENABLE_INT <= '0' ;
					--set some signals NOT linked to AS_000='0'
					RW_000_DMA	<= RW_000;
					-- now determine the size: if both uds and lds is set its 16 bit else 8 bit!
					if(UDS_000='0' and LDS_000='0') then
						SIZE_DMA		<= "10"; --16bit
					else
						SIZE_DMA		<= "01"; --8 bit
					end if;
					--now calculate the offset: 
					--if uds is set low, a0 is so too.
					--if only lds is set a1 is high
					--therefore a1 = uds 
					--great! life is simple here!
					A0_DMA <= UDS_000;		
					--A1 is set by the amiga side													
					--here  we determine the upper or lower half of the databus
					AMIGA_BUS_ENABLE_DMA_HIGH 	<= A1;
					AMIGA_BUS_ENABLE_DMA_LOW 	<= not A1;				
	
				elsif(BGACK_030_INT_D='0' and BGACK_030_INT='1')then			
					AMIGA_BUS_ENABLE_INT <= '1' ;
					RW_000_DMA		<= '1';	
					SIZE_DMA		<= "00";
					A0_DMA			<= '0';	
					AMIGA_BUS_ENABLE_DMA_HIGH 	<= '1';
					AMIGA_BUS_ENABLE_DMA_LOW 	<= '1';				
				end if;
						
				if(BGACK_030_INT='0' and AS_000='0')then 
					-- an 68000-memory cycle is three positive edges long!
					if(CLK_000_P_SYNC(10)='1')then
						CYCLE_DMA <= CYCLE_DMA+1;
					end if;
				else
					CYCLE_DMA		<= "00";
				end if;		
											
				--as can only be done if we know the uds/lds!
				if(	BGACK_030_INT='0'
					and AS_000='0' 
					and(UDS_000='0' or LDS_000='0')
					and (					
						--CYCLE_DMA ="00" or
						CYCLE_DMA ="01"
						or CYCLE_DMA ="10"
						--or CYCLE_DMA ="11"
						)				
					)then 
					--set AS_000
					if( CLK_030='1') then 
						AS_000_DMA 	<= '0'; --sampled on rising edges!					
					end if;
					
					--delayed clock for write cycle
					if(AS_000_DMA = '0' and CLK_030='0')then
						CLK_030_H		<= '1';
					end if;
					
					if(RW_000='1') then
						DS_000_DMA	<='0';
					elsif(RW_000='0' and CLK_030_H = '1' and CLK_030='1')then
						DS_000_DMA	<=AS_000_DMA; -- write: one clock delayed!
					end if;					
				else
					AS_000_DMA		<= '1';
					DS_000_DMA		<= '1';
					CLK_030_H		<= '0';		
				end if;		
			end if;					
		end if;
	end process pos_clk;

	--output clock assignment
	CLK_DIV_OUT	<= CLK_OUT_INT;
	CLK_EXP		<= CLK_OUT_INT;
	--CLK_DIV_OUT	<= 'Z';
	--CLK_EXP		<= CLK_030;


	
	RESET	<= 'Z' when RESET_OUT ='1' else '0';
	--RST		<= '0' when RESET_OUT_AMIGA = '1' else 'Z';
	--RESET	<=  RESET_OUT;

	-- bus drivers
	--AMIGA_ADDR_ENABLE	<= AMIGA_BUS_ENABLE_INT;
	AMIGA_ADDR_ENABLE	<= '0';
	AMIGA_BUS_ENABLE_HIGH <= '0' WHEN BGACK_030_INT ='1' and not (SM_AMIGA = IDLE_P) ELSE 
							 '0' WHEN BGACK_030_INT ='0' AND AMIGA_BUS_ENABLE_DMA_HIGH = '0' ELSE
							 '1';
	AMIGA_BUS_ENABLE_LOW <=  '0' WHEN BGACK_030_INT ='0' AND AMIGA_BUS_ENABLE_DMA_LOW = '0'   ELSE
							 '1';  
	
	
	AMIGA_BUS_DATA_DIR 	 <= '1' WHEN (RW_000='0' AND BGACK_030_INT ='1') ELSE --Amiga WRITE
							'0' WHEN (RW_000='1' AND BGACK_030_INT ='1') ELSE --Amiga READ
							'1' WHEN (RW_000='1' AND BGACK_030_INT ='0' AND nEXP_SPACE_D0 = '0' AND AS_000 = '0') ELSE --DMA READ to expansion space
							'0' WHEN (RW_000='0' AND BGACK_030_INT ='0' AND AS_000 = '0') ELSE --DMA WRITE to expansion space
							'0'; --Point towarts TK
	
	
	--dma stuff
	DTACK	<= 	'Z';
	--DTACK	<= 	'Z' when BGACK_030_INT ='1' OR nEXP_SPACE_D0 = '1' else
	--			'0' when DSACK1 ='0' else 
	--		   	'1';
	AS_030	<= 	'Z' when BGACK_030_INT ='1' OR nEXP_SPACE_D0 = '1' or RESET_OUT ='0' else
			   	'0' when AS_000_DMA ='0' and AS_000 ='0' else 
			   	'1';
	DS_030	<= 	'Z' when BGACK_030_INT ='1' OR nEXP_SPACE_D0 = '1' or RESET_OUT ='0' else
				'0' when DS_000_DMA ='0' and AS_000 ='0' else 
			   	'1';
	A0		<= 	'Z' when BGACK_030_INT ='1' OR nEXP_SPACE_D0 = '1' or RESET_OUT ='0' else
				'0' when A0_DMA ='0' else 
			   	'1';
	SIZE	<= 	"ZZ" when BGACK_030_INT ='1' OR nEXP_SPACE_D0 = '1' else
				"10" when SIZE_DMA ="10" else 
			   	"01" when SIZE_DMA ="01" else
			   	"00";
	--rw
	RW		<= 	'Z' when BGACK_030_INT ='1' or RESET_OUT ='0' else
				'0' when RW_000_DMA ='0' else 
			   	'1';
	
	BGACK_030	<= BGACK_030_INT;	

	--fpu
	FPU_CS		<=	'0' when AS_030 ='0' and FC(1)='1' and FC(0)='1' and A(19)='0' and A(18)='0' and A(17)='1' and A(16)='0' AND BGACK_000='1' AND FPU_SENSE ='0'
					else '1';
	
	--if no copro is installed:
	BERR		<=	'0' when AS_030 ='0' and FC(1)='1' and FC(0)='1' and A(19)='0' and A(18)='0' and A(17)='1' and A(16)='0' AND BGACK_000='1' AND FPU_SENSE ='1'
					else 'Z';
	--BERR		<=	'Z';



	--cache inhibit:  Tristate for expansion (it decides) and off for the Amiga 
	CIIN <= '1' WHEN A(31 downto 20) = x"00F" and AS_030_D0 ='0' ELSE -- Enable for Kick-rom
			'Z' WHEN nEXP_SPACE_D0 = '0' ELSE --Tristate for expansion (it decides)
			'0'; --off for the Amiga
		
	--e and VMA		
	E		<= '1' when 
							cpu_est = E7 or
							cpu_est = E8 or
							cpu_est = E9 or
							cpu_est = E10 						
						else '0';
	VMA		<= VMA_INT;
	
	
	--AVEC
	AVEC 	<=	'1';
		
	--as and uds/lds
	AS_000	<=  'Z' when BGACK_030_INT ='0' or RESET_OUT ='0' else
				'0' when AS_000_INT ='0' and AS_030 ='0' else 
			   	'1';
	RW_000	<=  'Z' when BGACK_030_INT ='0' or RESET_OUT ='0' else
				'0' when RW_000_INT ='0' else 
			   	'1';

	UDS_000	<=  'Z' when BGACK_030_INT ='0' or RESET_OUT ='0' else -- output on cpu cycle
			    --'1' when DS_000_ENABLE ='0' else 
				'0' when UDS_000_INT ='0' and DS_000_ENABLE ='1' else -- datastrobe not ready jet
			   	'1';
	LDS_000	<= 	'Z' when BGACK_030_INT ='0' or RESET_OUT ='0' else -- output on cpu cycle
			   	--'1' when DS_000_ENABLE ='0' else 
				'0' when LDS_000_INT ='0' and DS_000_ENABLE ='1' else -- datastrobe not ready jet
			   	'1';

	--dsack
	DSACK1	<= 	'Z' when nEXP_SPACE_D0 = '0' else -- output on amiga cycle
				'0' when DSACK1_INT ='0' else 
			   	'1';
	
end Behavioral;