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 ; -- DS_030: inout std_logic ; UDS_000: inout std_logic; LDS_000: inout std_logic; SIZE: inout std_logic_vector ( 1 downto 0 ); A: inout std_logic_vector ( 31 downto 0 ); CPU_SPACE: in std_logic ; -- BERR: inout std_logic ; --error: this is connected to a global input pin :( 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 ; IPL_030: out std_logic_vector ( 2 downto 0 ); IPL: in std_logic_vector ( 2 downto 0 ); DSACK: inout std_logic_vector ( 1 downto 0 ); DTACK: inout std_logic ; AVEC: out std_logic ; -- AVEC_EXP: inout std_logic ; --this is a "free pin" E: out std_logic ; VPA: in std_logic ; VMA: out std_logic ; RST: in std_logic ; RESET: out std_logic ; RW: in std_logic ; -- D: inout std_logic_vector ( 31 downto 28 ); FC: in std_logic_vector ( 1 downto 0 ); AMIGA_BUS_ENABLE: out std_logic ; AMIGA_BUS_DATA_DIR: out std_logic ; AMIGA_BUS_ENABLE_LOW: out std_logic; CIIN: out std_logic ); end BUS68030; architecture Behavioral of BUS68030 is subtype ESTATE is std_logic_vector(3 downto 0); constant E1 : ESTATE := "0110"; constant E2 : ESTATE := "0111"; constant E3 : ESTATE := "0100"; constant E4 : ESTATE := "0101"; constant E5 : ESTATE := "0010"; constant E6 : ESTATE := "0011"; constant E7 : ESTATE := "1010"; constant E8 : ESTATE := "1011"; constant E9 : ESTATE := "1100"; constant E10 : ESTATE := "1111"; -- Illegal states constant E20 : ESTATE := "0000"; constant E4a : ESTATE := "0001"; constant E21 : ESTATE := "1000"; constant E22 : ESTATE := "1001"; constant E23 : ESTATE := "1101"; constant E24 : ESTATE := "1110"; signal cpu_est : ESTATE := E20; subtype AMIGA_STATE is std_logic_vector(1 downto 0); constant IDLE : AMIGA_STATE := "00"; constant AS_SET : AMIGA_STATE := "01"; constant DATA_FETCH : AMIGA_STATE := "10"; constant END_CYCLE : AMIGA_STATE := "11"; signal SM_AMIGA : AMIGA_STATE; signal SM_AMIGA_LAST : AMIGA_STATE; --signal Dout:STD_LOGIC_VECTOR(3 downto 0) := "0000"; signal ZorroII:STD_LOGIC:= '0'; signal AS_000_INT:STD_LOGIC:= '1'; signal AS_000_INT_D:STD_LOGIC:= '1'; signal BGACK_030_INT:STD_LOGIC:= '1'; signal DTACK_DMA:STD_LOGIC:= '1'; signal DTACK_INT:STD_LOGIC:= '1'; signal DTACK_SYNC:STD_LOGIC:= '1'; signal DTACK_SYNC_D:STD_LOGIC:= '1'; signal DTACK_SYNC_DD:STD_LOGIC:= '1'; signal FPU_CS_INT:STD_LOGIC:= '1'; signal E_INT: STD_LOGIC:='1'; signal VPA_SYNC: STD_LOGIC:='1'; signal VMA_INT: STD_LOGIC:='1'; signal VMA_INT_D: STD_LOGIC:='1'; signal UDS_000_INT: STD_LOGIC:='1'; signal LDS_000_INT: STD_LOGIC:='1'; signal UDS_LOGIC: STD_LOGIC:='1'; signal LDS_LOGIC: STD_LOGIC:='1'; --signal AS_030_delay: STD_LOGIC:='1'; signal SM_AMIGA_ENABLE: STD_LOGIC:='1'; --signal DS_030_INT: STD_LOGIC:='Z'; --signal A_INT: STD_LOGIC_VECTOR ( 1 downto 0 ) := "00"; --signal SIZE_INT: STD_LOGIC_VECTOR ( 1 downto 0 ) := "00"; signal DSACK_INT: STD_LOGIC_VECTOR ( 1 downto 0 ) := "11"; signal CLK_CNT: STD_LOGIC_VECTOR ( 1 downto 0 ) := "00"; signal CLK_OUT_INT: STD_LOGIC:='1'; signal CLK_000_D: STD_LOGIC := '1'; begin --clk generation : up to now just half the clock cpu_clk: process(CLK_OSZI) begin if(rising_edge(CLK_OSZI)) then if(CLK_CNT="01") then CLK_OUT_INT <= not CLK_OUT_INT; CLK_CNT <= "00"; else CLK_CNT <= CLK_CNT+1; end if; end if; end process cpu_clk; CLK_DIV_OUT <= CLK_OUT_INT; CLK_EXP <= CLK_OUT_INT; clk_delay: process(CLK_030) begin if(rising_edge(CLK_030)) then CLK_000_D <= CLK_000; end if; end process clk_delay; --ZORROII (Amiga) space? ZorroII <= '1' when (A(31 downto 24)= x"00") else '0'; -- 24-bit addres space. --BG_ACK is simple: BGACK_030_gen: process (CLK_000,BGACK_000) begin if(BGACK_000='0') then BGACK_030_INT <= '0'; elsif rising_edge(CLK_000) then BGACK_030_INT <= '1'; --hold this signal high until 7m clock goes high end if; end process BGACK_030_gen; BGACK_030 <= BGACK_030_INT; --DTACK DTACK <= 'Z' when BGACK_030_INT ='1' else DTACK_DMA; DTACK_DMA <= '0' when AS_000_INT ='0' AND DSACK(1) ='0' else '1'; --CO-Processor Chip select FPU_CS_INT <= '0' when 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='0' else '1'; FPU_CS <= FPU_CS_INT; --if no copro is installed: -- BERR <= 'Z' when FPU_CS_INT ='1' else '0'; --reset buffer RESET <= RST; --cache inhibit: For now: disable CIIN <= '1' WHEN A(31 downto 20) = x"00F" ELSE '1' WHEN A(31 downto 16) = x"00E0" ELSE '0'; --bus buffers AMIGA_BUS_ENABLE <= '0'; --for now: allways on AMIGA_BUS_DATA_DIR <='1' WHEN RW='0' ELSE '0'; AMIGA_BUS_ENABLE_LOW <= '1'; --for now: allways off -- vma and e clock e_clk: process (CLK_000) begin if rising_edge(CLK_000) then -- next state. 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 ; -- Illegal states when E4a => cpu_est <= E5 ; when E20 => cpu_est <= E10; when E21 => cpu_est <= E10; when E22 => cpu_est <= E9 ; when E23 => cpu_est <= E9 ; when E24 => cpu_est <= E10; when others => null; end case; end if; end process e_clk; vma_gen: process (CLK_000,AS_030) begin if(AS_030='1') then VMA_INT <= '1'; VPA_SYNC <= '1'; elsif falling_edge(CLK_000) then VPA_SYNC <= VPA; if(cpu_est = E3 AND VPA_SYNC = '0' AND AS_000_INT = '0') then VMA_INT <= '0'; -- low active ! end if; if(cpu_est = E10) then VMA_INT <= '1'; end if; end if; end process vma_gen; vma_delay: process(CLK_030) begin if(rising_edge(CLK_030)) then VMA_INT_D<=VMA_INT; end if; end process vma_delay; E_INT <= cpu_est(3); E <= E_INT; VMA <= VMA_INT AND VMA_INT_D; --AVEC --AVEC <= '0' WHEN VMA='1' AND cpu_est = E10 -- -- ELSE '1'; AVEC <= '1'; --IPL: Buffer interrupts for a CPU-Cycle to avoid fake interupts ipl_amiga: process(CLK_000) begin if(rising_edge(CLK_000)) then IPL_030<=IPL; end if; end process ipl_amiga; --BG bg_amiga: process(CLK_030,BG_030) begin if(BG_030= '1')then BG_000 <= '1'; elsif(falling_edge(CLK_030)) then if(SM_AMIGA = IDLE and CPU_SPACE = '0' and AS_030='1') then --bus granted no local access and no AS_030 running! BG_000 <= '0'; else BG_000 <='1'; end if; end if; end process bg_amiga; --as uds/lds generation UDS_LOGIC <= '0' WHEN AS_030 = '0' AND A(0)='0' ELSE '1'; LDS_LOGIC <= '0' WHEN AS_030 = '0' AND (A(0)='1' OR SIZE(0)='0' OR SIZE(1)='1') ELSE '1'; --state machine for amiga-cycle sm_amiga: process(RST, CLK_030) begin if(RST='0') then SM_AMIGA <= IDLE; DTACK_INT <= '1'; DSACK_INT <="11"; UDS_000_INT <='1'; LDS_000_INT <='1'; AS_000_INT <='1'; SM_AMIGA_ENABLE <='0'; elsif(rising_edge(CLK_030)) then case (SM_AMIGA) is when IDLE => if(CLK_000 ='0') then SM_AMIGA_ENABLE<='1'; end if; if ( AS_030 = '0' -- obviously as must be low AND CPU_SPACE = '0' -- expansion board not in action AND CLK_000 = '1' --AND CLK_000_D = '1' -- as is sampled at falling edge on a 68000/010 thus it is set during high CLK_000 AND SM_AMIGA_ENABLE = '1' ) then AS_000_INT <= '0'; if (RW='1') then --read: set udl/lds UDS_000_INT <= UDS_LOGIC; LDS_000_INT <= LDS_LOGIC; end if; SM_AMIGA_ENABLE <='0'; SM_AMIGA <= AS_SET; else DSACK_INT<="11"; UDS_000_INT <='1'; LDS_000_INT <='1'; AS_000_INT <='1'; end if; when AS_SET => if(CLK_000 ='0') then SM_AMIGA_ENABLE<='1'; end if; if ( CLK_000 = '1' and SM_AMIGA_ENABLE='1' ) then UDS_000_INT <= UDS_LOGIC; LDS_000_INT <= LDS_LOGIC; if(VPA_SYNC = '1' AND DTACK='0') then DTACK_INT<= '0'; SM_AMIGA_ENABLE <='0'; SM_AMIGA <= DATA_FETCH ; elsif(E10=cpu_est AND VPA_SYNC='0' AND VMA_INT='0') then --vpa/vma cycle DTACK_INT<= '0'; SM_AMIGA_ENABLE <='0'; SM_AMIGA <= DATA_FETCH ; end if; end if; when DATA_FETCH => --here the data is written/read DSACK_INT<="01"; if(CLK_000_D ='0') then SM_AMIGA_ENABLE<='1'; end if; if(AS_030 ='1') then DSACK_INT<="11"; UDS_000_INT <='1'; LDS_000_INT <='1'; AS_000_INT <='1'; end if; if( CLK_000 = '1' AND SM_AMIGA_ENABLE = '1')then SM_AMIGA_ENABLE <='0'; SM_AMIGA <= END_CYCLE; end if; when END_CYCLE => -- internal DTACK is high here. end cycle! if(CLK_000 ='0') then SM_AMIGA_ENABLE<='1'; end if; if(AS_030 ='1') then DSACK_INT<="11"; UDS_000_INT <='1'; LDS_000_INT <='1'; AS_000_INT <='1'; end if; if ( CLK_000 = '1' and SM_AMIGA_ENABLE <='1' ) then SM_AMIGA_ENABLE <='0'; SM_AMIGA <= IDLE ; end if; end case; end if; end process sm_amiga; AS_000 <= 'Z' when BGACK_030_INT ='0' else AS_000_INT; UDS_000 <= 'Z' when BGACK_030_INT ='0' else -- output on cpu cycle UDS_000_INT; LDS_000 <= 'Z' when BGACK_030_INT ='0' else -- output on cpu cycle LDS_000_INT; DSACK <= "ZZ" when CPU_SPACE = '1' else -- output on amiga cycle DSACK_INT; -- signal assignment --DS_030 <= "ZZ"; --DS_030 <= "ZZ" when BGACK_030_INT ='1' else -- output on dma cycle -- DS_030_INT; --A(1) <= 'Z'; --A(0) <= 'Z'; --A[1 downto 0] <= "ZZ" when BGACK_030_INT ='1' else -- output on dma cycle -- A_INT; --SIZE <= "ZZ"; --SIZE <= "ZZ" when BGACK_030_INT ='1' else -- output on dma cycle -- SIZE_INT; end Behavioral;