2014-05-16 18:28:35 +00:00
-- Copyright: Matthias Heinrichs 2014
-- Free for non-comercial use
-- No warranty just for fun
2014-05-29 20:06:01 +00:00
-- If you want to earn money with this code, ask me first!
2014-05-16 18:28:35 +00:00
2014-05-15 19:16:29 +00:00
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 ;
2014-06-01 20:50:01 +00:00
RW_000 : inout std_logic ;
2014-05-15 19:16:29 +00:00
DS_030 : inout std_logic ;
UDS_000 : inout std_logic ;
LDS_000 : inout std_logic ;
SIZE : inout std_logic_vector ( 1 downto 0 ) ;
2016-08-18 22:22:24 +00:00
AHIGH : inout std_logic_vector ( 31 downto 24 ) ;
A_DECODE : in std_logic_vector ( 23 downto 2 ) ;
A : inout std_logic_vector ( 1 downto 0 ) ;
--A0: inout std_logic;
--A1: in std_logic;
2014-05-16 18:18:55 +00:00
nEXP_SPACE : in std_logic ;
2014-05-15 21:05:08 +00:00
BERR : inout std_logic ;
2014-05-15 19:16:29 +00:00
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 ;
2014-07-18 12:08:15 +00:00
FPU_SENSE : in std_logic ;
2014-05-15 19:16:29 +00:00
IPL_030 : out std_logic_vector ( 2 downto 0 ) ;
IPL : in std_logic_vector ( 2 downto 0 ) ;
2014-06-01 20:50:01 +00:00
DSACK1 : inout std_logic ;
2014-05-15 19:16:29 +00:00
DTACK : inout std_logic ;
AVEC : out std_logic ;
E : out std_logic ;
VPA : in std_logic ;
VMA : out std_logic ;
RST : in std_logic ;
2015-10-10 20:11:10 +00:00
RESET : inout std_logic ;
2014-06-01 20:50:01 +00:00
RW : inout std_logic ;
2014-05-15 19:16:29 +00:00
-- D: inout std_logic_vector ( 31 downto 28 );
FC : in std_logic_vector ( 1 downto 0 ) ;
2014-07-18 12:08:15 +00:00
AMIGA_ADDR_ENABLE : out std_logic ;
2014-05-15 19:16:29 +00:00
AMIGA_BUS_DATA_DIR : out std_logic ;
AMIGA_BUS_ENABLE_LOW : out std_logic ;
2014-07-18 12:08:15 +00:00
AMIGA_BUS_ENABLE_HIGH : out std_logic ;
2014-05-15 19:16:29 +00:00
CIIN : out std_logic
) ;
end BUS68030 ;
architecture Behavioral of BUS68030 is
2016-08-18 22:42:01 +00:00
-- values are determined empirically
2016-08-25 20:30:49 +00:00
constant DS_SAMPLE : integer : = 12 ; -- for 7.09 MHz Clock with a base clock of 100Mhz and CPU running at 25MHZ
2016-08-24 21:34:13 +00:00
--constant DS_SAMPLE : integer := 12; -- for 7.09 MHz Clock with a base clock of 100Mhz and CPU running at 50MHZ
2014-05-15 19:16:29 +00:00
2016-01-24 19:26:06 +00:00
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 ;
2014-05-15 19:16:29 +00:00
--signal Dout:STD_LOGIC_VECTOR(3 downto 0) := "0000";
2014-05-24 19:59:56 +00:00
signal AS_000_INT : STD_LOGIC : = '1' ;
2016-11-30 22:10:23 +00:00
signal AS_000_D0 : STD_LOGIC : = '1' ;
2014-06-01 20:50:01 +00:00
signal RW_000_INT : STD_LOGIC : = '1' ;
2014-09-16 12:51:31 +00:00
signal AMIGA_BUS_ENABLE_DMA_HIGH : STD_LOGIC : = '1' ;
signal AMIGA_BUS_ENABLE_DMA_LOW : STD_LOGIC : = '1' ;
2014-07-18 12:08:15 +00:00
signal AS_030_D0 : STD_LOGIC : = '1' ;
2017-12-30 00:39:22 +00:00
signal AS_030_D1 : STD_LOGIC : = '1' ;
2015-03-15 12:50:46 +00:00
signal nEXP_SPACE_D0 : STD_LOGIC : = '0' ;
2014-07-18 12:08:15 +00:00
signal DS_030_D0 : STD_LOGIC : = '1' ;
2014-05-24 19:59:56 +00:00
signal AS_030_000_SYNC : STD_LOGIC : = '1' ;
signal BGACK_030_INT : STD_LOGIC : = '1' ;
signal BGACK_030_INT_D : STD_LOGIC : = '1' ;
2015-06-26 16:32:40 +00:00
signal BGACK_030_INT_PRE : STD_LOGIC : = '1' ;
2014-05-24 19:59:56 +00:00
signal AS_000_DMA : STD_LOGIC : = '1' ;
signal DS_000_DMA : STD_LOGIC : = '1' ;
2014-06-09 08:29:32 +00:00
signal RW_000_DMA : STD_LOGIC : = '1' ;
2015-02-03 09:22:30 +00:00
signal CYCLE_DMA : STD_LOGIC_VECTOR ( 1 downto 0 ) : = "00" ;
2014-05-24 19:59:56 +00:00
signal SIZE_DMA : STD_LOGIC_VECTOR ( 1 downto 0 ) : = "11" ;
2015-06-26 16:32:40 +00:00
signal IPL_D0 : STD_LOGIC_VECTOR ( 2 downto 0 ) : = "111" ;
2014-05-24 19:59:56 +00:00
signal A0_DMA : STD_LOGIC : = '1' ;
signal VMA_INT : STD_LOGIC : = '1' ;
2014-05-25 19:00:40 +00:00
signal VPA_D : STD_LOGIC : = '1' ;
2014-05-24 19:59:56 +00:00
signal UDS_000_INT : STD_LOGIC : = '1' ;
signal LDS_000_INT : STD_LOGIC : = '1' ;
2014-06-09 08:29:32 +00:00
signal DS_000_ENABLE : STD_LOGIC : = '0' ;
2014-05-24 19:59:56 +00:00
signal DSACK1_INT : STD_LOGIC : = '1' ;
2014-05-28 19:34:35 +00:00
signal CLK_OUT_PRE_50 : STD_LOGIC : = '1' ;
2016-01-24 19:26:06 +00:00
signal CLK_OUT_PRE_25 : STD_LOGIC : = '1' ;
2014-06-09 08:29:32 +00:00
signal CLK_OUT_PRE : STD_LOGIC : = '1' ;
signal CLK_OUT_PRE_D : STD_LOGIC : = '1' ;
2014-05-24 19:59:56 +00:00
signal CLK_OUT_INT : STD_LOGIC : = '1' ;
2016-01-24 19:26:06 +00:00
signal CLK_OUT_EXP_INT : STD_LOGIC : = '1' ;
2014-05-28 19:34:35 +00:00
signal CLK_030_H : STD_LOGIC : = '1' ;
2016-08-18 22:22:24 +00:00
signal CLK_000_D : STD_LOGIC_VECTOR ( DS_SAMPLE downto 0 ) ;
2014-06-09 08:29:32 +00:00
signal CLK_000_PE : STD_LOGIC : = '0' ;
signal CLK_000_NE : STD_LOGIC : = '0' ;
2014-05-28 19:34:35 +00:00
signal DTACK_D0 : STD_LOGIC : = '1' ;
2015-02-03 20:34:33 +00:00
signal RESET_OUT : STD_LOGIC : = '0' ;
2015-02-13 13:50:57 +00:00
signal CLK_030_D0 : STD_LOGIC : = '0' ;
2015-10-10 20:11:10 +00:00
signal RST_DLY : STD_LOGIC_VECTOR ( 2 downto 0 ) : = "000" ;
2016-11-30 22:10:23 +00:00
signal CLK_030_PE : STD_LOGIC_VECTOR ( 1 downto 0 ) : = "00" ;
signal AMIGA_DS : STD_LOGIC : = '1' ;
2017-12-30 00:39:22 +00:00
signal DTACK_DMA : STD_LOGIC : = '1' ;
2014-05-15 19:16:29 +00:00
begin
2016-08-18 22:42:01 +00:00
CLK_000_PE < = CLK_000_D ( 0 ) AND NOT CLK_000_D ( 1 ) ;
CLK_000_NE < = NOT CLK_000_D ( 0 ) AND CLK_000_D ( 1 ) ;
2016-08-18 22:22:24 +00:00
2015-03-15 12:50:46 +00:00
--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.
2016-08-25 20:30:49 +00:00
--However a compilation with no resets on the E-Clock and resets on other signals does not work, either!
2015-02-03 09:22:30 +00:00
pos_clk : process ( CLK_OSZI )
2014-08-12 19:24:42 +00:00
begin
2015-03-15 12:50:46 +00:00
if ( rising_edge ( CLK_OSZI ) ) then
2014-05-28 19:34:35 +00:00
--clk generation :
2015-02-13 13:50:57 +00:00
CLK_030_D0 < = CLK_030 ;
2016-01-24 19:26:06 +00:00
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 ;
2014-08-12 19:24:42 +00:00
2014-05-25 19:20:36 +00:00
2014-06-09 08:29:32 +00:00
--here the clock is selected
2016-10-06 19:37:29 +00:00
--CLK_OUT_PRE_D <= CLK_OUT_PRE_25;
CLK_OUT_PRE_D < = CLK_OUT_PRE_50 ;
2014-06-09 08:29:32 +00:00
2014-05-15 19:16:29 +00:00
-- the external clock to the processor is generated here
2015-03-15 12:50:46 +00:00
CLK_OUT_INT < = CLK_OUT_PRE_D ; --this way we know the clock of the next state: Its like looking in the future, cool!
2016-11-30 22:10:23 +00:00
CLK_OUT_EXP_INT < = CLK_OUT_PRE_D ;
2014-06-01 20:50:01 +00:00
--delayed Clocks and signals for edge detection
2016-08-18 05:48:07 +00:00
CLK_000_D ( 0 ) < = CLK_000 ;
2016-08-18 22:22:24 +00:00
CLK_000_D ( DS_SAMPLE downto 1 ) < = CLK_000_D ( ( DS_SAMPLE - 1 ) downto 0 ) ;
2014-06-09 08:29:32 +00:00
2014-07-18 12:08:15 +00:00
-- e-clock is changed on the FALLING edge!
2016-08-18 22:42:01 +00:00
if ( CLK_000_NE = '1' ) then
2014-05-15 19:16:29 +00:00
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 ;
2014-07-18 12:08:15 +00:00
2015-03-15 12:50:46 +00:00
--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' ;
2014-05-15 19:16:29 +00:00
AS_030_000_SYNC < = '1' ;
2015-03-15 12:50:46 +00:00
UDS_000_INT < = '1' ;
LDS_000_INT < = '1' ;
2014-06-09 08:29:32 +00:00
DS_000_ENABLE < = '0' ;
2015-03-15 12:50:46 +00:00
VMA_INT < = '1' ;
BG_000 < = '1' ;
BGACK_030_INT < = '1' ;
BGACK_030_INT_D < = '1' ;
2015-06-26 16:32:40 +00:00
BGACK_030_INT_PRE < = '1' ;
2015-03-15 12:50:46 +00:00
DSACK1_INT < = '1' ;
2015-06-26 16:32:40 +00:00
IPL_D0 < = "111" ;
2015-03-15 12:50:46 +00:00
IPL_030 < = "111" ;
AS_000_DMA < = '1' ;
DS_000_DMA < = '1' ;
SIZE_DMA < = "11" ;
A0_DMA < = '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' ;
CYCLE_DMA < = "00" ;
2015-10-10 20:11:10 +00:00
RST_DLY < = "000" ;
2015-03-15 12:50:46 +00:00
RESET_OUT < = '0' ;
2016-11-30 22:10:23 +00:00
AS_000_D0 < = '1' ;
AMIGA_DS < = '1' ;
CLK_030_PE < = "00" ;
2015-03-15 12:50:46 +00:00
else
2015-06-26 16:32:40 +00:00
if ( CLK_000_NE = '1' ) then
2015-10-10 20:11:10 +00:00
if ( RST_DLY = "111" ) then
2015-06-26 16:32:40 +00:00
RESET_OUT < = '1' ;
else
RST_DLY < = RST_DLY + 1 ;
end if ;
end if ;
2015-03-28 21:03:17 +00:00
2015-03-15 12:50:46 +00:00
--now: 68000 state machine and signals
--buffering signals
AS_030_D0 < = AS_030 ;
2017-12-30 00:39:22 +00:00
AS_030_D1 < = AS_030_D0 ;
2015-03-15 12:50:46 +00:00
nEXP_SPACE_D0 < = nEXP_SPACE ;
DS_030_D0 < = DS_030 ;
DTACK_D0 < = DTACK ;
VPA_D < = VPA ;
2015-03-28 21:03:17 +00:00
2015-03-15 12:50:46 +00:00
--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' ;
2016-08-24 21:34:13 +00:00
--BGACK_030_INT_PRE<= '0';
2015-03-15 12:50:46 +00:00
elsif ( BGACK_000 = '1'
2016-11-30 22:10:23 +00:00
AND CLK_000_NE = '1'
2015-09-24 15:00:50 +00:00
AND AS_000 = '1' --the amiga AS can be still active while bgack is deasserted, so wait for this signal too!
2015-03-15 12:50:46 +00:00
) then -- BGACK_000 is high here!
2016-08-24 21:34:13 +00:00
--BGACK_030_INT_PRE<= '1';
BGACK_030_INT < = '1' ; --hold this signal high until 7m clock goes low
2015-03-15 12:50:46 +00:00
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)
2016-08-18 22:22:24 +00:00
and nEXP_SPACE = '1' and AS_030_D0 = '1'
2016-08-18 05:48:07 +00:00
and CLK_000_D ( 0 ) = '1'
2015-03-15 12:50:46 +00:00
) then --bus granted no local access and no AS_030 running!
BG_000 < = '0' ;
end if ;
2014-06-09 18:27:37 +00:00
2015-03-15 12:50:46 +00:00
--interrupt buffering to avoid ghost interrupts
2016-10-16 17:58:33 +00:00
IPL_D0 < = IPL ;
2016-11-30 22:10:23 +00:00
if ( IPL = IPL_D0 ) then --and CLK_000_PE = '1')then
2016-10-16 17:58:33 +00:00
IPL_030 < = IPL ;
end if ;
2014-06-09 08:29:32 +00:00
2015-03-15 12:50:46 +00:00
-- as030-sampling and FPU-Select
2016-10-06 19:37:29 +00:00
if ( AS_030 = '1' ) then -- "async" reset of various signals
2015-03-15 12:50:46 +00:00
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
2017-12-30 00:39:22 +00:00
AS_030_D1 = '0' AND --as set
2015-03-15 12:50:46 +00:00
BGACK_030_INT = '1' AND
BGACK_030_INT_D = '1' AND --no dma -cycle
2016-08-18 22:22:24 +00:00
NOT ( FC ( 1 ) = '1' and FC ( 0 ) = '1' and A_DECODE ( 19 ) = '0' and A_DECODE ( 18 ) = '0' and A_DECODE ( 17 ) = '1' and A_DECODE ( 16 ) = '0' ) AND --FPU-Select
nEXP_SPACE = '1' and --not an expansion space cycle
2015-03-15 12:50:46 +00:00
SM_AMIGA = IDLE_P --last amiga cycle terminated
) then
AS_030_000_SYNC < = '0' ;
2014-06-09 08:29:32 +00:00
end if ;
2015-03-15 12:50:46 +00:00
-- VMA generation
if ( CLK_000_NE = '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' ;
2014-06-09 08:29:32 +00:00
end if ;
2015-03-15 12:50:46 +00:00
--uds/lds precalculation
2016-01-24 19:26:06 +00:00
if ( SM_AMIGA = IDLE_N ) then --DS: set udl/lds
2016-08-18 22:22:24 +00:00
if ( A ( 0 ) = '0' ) then
2015-03-15 12:50:46 +00:00
UDS_000_INT < = '0' ;
else
UDS_000_INT < = '1' ;
2014-05-28 19:34:35 +00:00
end if ;
2016-08-18 22:22:24 +00:00
if ( ( A ( 0 ) = '1' OR SIZE ( 0 ) = '0' OR SIZE ( 1 ) = '1' ) ) then
2015-03-15 12:50:46 +00:00
LDS_000_INT < = '0' ;
else
LDS_000_INT < = '1' ;
2014-05-28 19:34:35 +00:00
end if ;
2015-03-15 12:50:46 +00:00
end if ;
--Amiga statemachine
case ( SM_AMIGA ) is
when IDLE_P = > --68000:S0 wait for a falling edge
RW_000_INT < = '1' ;
2016-10-16 17:58:33 +00:00
if ( CLK_000_D ( 3 ) = '0' and CLK_000_D ( 4 ) = '1' and AS_030_000_SYNC = '0' and nEXP_SPACE = '1' ) then -- if this a delayed expansion space detection, do not start an amiga cycle!
2015-03-15 12:50:46 +00:00
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
if ( CLK_000_PE = '1' ) then --go to s2
SM_AMIGA < = AS_SET_P ; --as for amiga set!
2016-08-18 22:42:01 +00:00
RW_000_INT < = RW ;
AS_000_INT < = '0' ;
if ( RW = '1' ) then --read: set udl/lds
DS_000_ENABLE < = '1' ;
end if ;
2015-03-15 12:50:46 +00:00
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
if ( CLK_000_NE = '1' ) 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
-- set DS-Enable without respect to rw: this simplifies the life for the syntesizer
2016-01-24 19:26:06 +00:00
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
2015-03-15 12:50:46 +00:00
SM_AMIGA < = SAMPLE_DTACK_P ;
end if ;
when SAMPLE_DTACK_P = > --68000:S4 wait for dtack or VMA
2016-08-18 22:42:01 +00:00
if ( CLK_000_NE = '1' and --falling edge
2015-03-15 12:50:46 +00:00
( ( VPA_D = '1' AND DTACK_D0 = '0' ) OR --DTACK end cycle
2016-10-06 19:37:29 +00:00
( BERR = '0' ) OR --Bus error
2015-03-15 12:50:46 +00:00
( 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
if ( CLK_000_PE = '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!
2016-08-25 20:30:49 +00:00
--if( (CLK_000_D(DS_SAMPLE-2)='0' AND CLK_000_D((DS_SAMPLE-1))='1' AND not (CLK_030 ='1' and CLK_OUT_PRE_D='0')) OR
-- (CLK_000_D(DS_SAMPLE-1)='0' AND CLK_000_D((DS_SAMPLE-0))='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;
2016-10-06 19:37:29 +00:00
--go to s7 dsack is sampled at the falling edge of the 030-clock
2016-10-16 17:58:33 +00:00
--if(CLK_000_D(0)='0' and CLK_000_D(1)='1')then
if ( CLK_000_NE = '1' ) then
2015-03-15 12:50:46 +00:00
SM_AMIGA < = END_CYCLE_N ;
2016-08-24 21:34:13 +00:00
DSACK1_INT < = '0' ;
2015-03-15 12:50:46 +00:00
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
SM_AMIGA < = IDLE_P ;
RW_000_INT < = '1' ;
end if ;
end case ;
--dma stuff
2016-11-30 22:10:23 +00:00
AS_000_D0 < = AS_000 ;
if ( UDS_000 = '0' or LDS_000 = '0' ) then
AMIGA_DS < = '0' ;
else
AMIGA_DS < = '1' ;
end if ;
2015-03-15 12:50:46 +00:00
if ( BGACK_030_INT = '0' ) then
--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!
2016-11-30 22:10:23 +00:00
2015-03-15 12:50:46 +00:00
if ( UDS_000 = '0' and LDS_000 = '0' ) then
SIZE_DMA < = "10" ; --16bit
else
SIZE_DMA < = "01" ; --8 bit
2014-05-28 19:34:35 +00:00
end if ;
2015-03-15 12:50:46 +00:00
--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 ;
2016-11-30 22:10:23 +00:00
--A0_DMA <= '0';
2015-03-15 12:50:46 +00:00
--A1 is set by the amiga side
--here we determine the upper or lower half of the databus
2016-08-18 22:22:24 +00:00
AMIGA_BUS_ENABLE_DMA_HIGH < = A ( 1 ) ;
AMIGA_BUS_ENABLE_DMA_LOW < = not A ( 1 ) ;
2015-03-15 12:50:46 +00:00
2017-12-30 00:39:22 +00:00
else
2015-03-15 12:50:46 +00:00
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
2016-11-30 22:10:23 +00:00
-- an 68000-memory cycle is three negative edges long!
if ( CLK_000_NE = '1' and CYCLE_DMA < "11" ) then
2015-03-15 12:50:46 +00:00
CYCLE_DMA < = CYCLE_DMA + 1 ;
2014-06-09 08:29:32 +00:00
end if ;
2017-12-30 00:39:22 +00:00
if ( nEXP_SPACE = '0' ) then --presume that all expansion devices can provide a buscycle in 320ns!
DTACK_DMA < = '0' ;
end if ;
2015-03-15 12:50:46 +00:00
else
2017-12-30 00:39:22 +00:00
DTACK_DMA < = '1' ;
2015-03-15 12:50:46 +00:00
CYCLE_DMA < = "00" ;
end if ;
--as can only be done if we know the uds/lds!
2016-11-30 22:10:23 +00:00
if ( CYCLE_DMA > "00"
and AS_000 = '0'
and AMIGA_DS = '0'
2015-03-15 12:50:46 +00:00
and (
2016-11-30 22:10:23 +00:00
CYCLE_DMA < "11"
or RW_000 = '1' )
2015-03-15 12:50:46 +00:00
) then
--set AS_000
2016-11-30 22:10:23 +00:00
if ( not ( CLK_OUT_INT = '0' and CLK_OUT_PRE_D = '1' ) ) then --sampled on rising edges, so we can set AS only if the next clock is not rising!!
AS_000_DMA < = '0' ;
2017-12-30 00:39:22 +00:00
--if(RW_000='1') then
2016-11-30 22:10:23 +00:00
DS_000_DMA < = '0' ;
2017-12-30 00:39:22 +00:00
--end if;
2014-05-28 19:34:35 +00:00
end if ;
2016-11-30 22:10:23 +00:00
2017-12-30 00:39:22 +00:00
--if( CLK_OUT_INT='0' and CLK_OUT_PRE_D ='1' and CLK_030_PE <"11" and AS_000_DMA = '0') then --sample rising edges
-- CLK_030_PE <= CLK_030_PE+1;
--end if;
2015-02-13 13:50:57 +00:00
2017-12-30 00:39:22 +00:00
--if(RW_000='0' and CLK_030_PE="01" and CLK_030='1')then
-- DS_000_DMA <= '0'; -- write: one clock delayed!
--end if;
2016-11-30 22:10:23 +00:00
2015-03-15 12:50:46 +00:00
else
2017-12-30 00:39:22 +00:00
--CLK_030_PE <= "00";
2015-03-15 12:50:46 +00:00
AS_000_DMA < = '1' ;
DS_000_DMA < = '1' ;
end if ;
2016-08-24 21:34:13 +00:00
end if ;
2015-03-15 12:50:46 +00:00
end if ;
end process pos_clk ;
2014-05-15 19:16:29 +00:00
2015-03-15 12:50:46 +00:00
--output clock assignment
2016-01-24 19:26:06 +00:00
CLK_DIV_OUT < = CLK_OUT_INT ;
2016-01-25 17:02:53 +00:00
CLK_EXP < = CLK_OUT_INT ; --not CLK_OUT_EXP_INT;
2016-01-24 19:26:06 +00:00
--CLK_DIV_OUT <= 'Z';
--CLK_EXP <= CLK_030;
2015-02-13 13:50:57 +00:00
2016-11-30 22:10:23 +00:00
RESET < = 'Z' ;
--RESET <= 'Z' when RESET_OUT ='1' else '0';
2015-10-10 20:11:10 +00:00
--RST <= '0' when RESET_OUT_AMIGA = '1' else 'Z';
--RESET <= RESET_OUT;
2014-08-09 12:43:03 +00:00
-- bus drivers
2015-02-19 20:34:28 +00:00
AMIGA_ADDR_ENABLE < = '0' ;
2016-10-16 17:58:33 +00:00
AMIGA_BUS_ENABLE_HIGH < = '0' WHEN BGACK_030_INT = '1' and AS_030_000_SYNC = '0' and AS_030 = '0' else --not (SM_AMIGA = IDLE_P or (SM_AMIGA = END_CYCLE_N and CLK_000 = '1')) ELSE
2014-10-07 17:58:39 +00:00
'0' WHEN BGACK_030_INT = '0' AND AMIGA_BUS_ENABLE_DMA_HIGH = '0' ELSE
2014-09-16 12:51:31 +00:00
'1' ;
2014-10-07 17:58:39 +00:00
AMIGA_BUS_ENABLE_LOW < = '0' WHEN BGACK_030_INT = '0' AND AMIGA_BUS_ENABLE_DMA_LOW = '0' ELSE
2014-09-16 12:51:31 +00:00
'1' ;
2016-10-06 19:37:29 +00:00
AMIGA_BUS_DATA_DIR < = not RW_000 WHEN ( BGACK_030_INT = '1' ) ELSE --Amiga READ/WRITE
--'0' WHEN (RW_000='1' AND BGACK_030_INT ='1') ELSE --Amiga READ
2016-08-18 22:22:24 +00:00
'1' WHEN ( RW_000 = '1' AND BGACK_030_INT = '0' AND nEXP_SPACE = '0' AND AS_000 = '0' ) ELSE --DMA READ to expansion space
2016-10-06 19:37:29 +00:00
--'0' WHEN (RW_000='0' AND BGACK_030_INT ='0' AND AS_000 = '0') ELSE --DMA WRITE to expansion space
2014-08-09 12:43:03 +00:00
'0' ; --Point towarts TK
2014-05-24 19:59:56 +00:00
--dma stuff
2017-12-30 00:39:22 +00:00
DTACK < = 'Z' ; --DTACK will be generated by GARY!
--DTACK <= 'Z' when DTACK_DMA='1' else '0';
2016-08-18 22:22:24 +00:00
2017-12-30 00:39:22 +00:00
AS_030 < = 'Z' when BGACK_030_INT = '1' else
2015-02-13 13:50:57 +00:00
'0' when AS_000_DMA = '0' and AS_000 = '0' else
2014-09-16 12:51:31 +00:00
'1' ;
2017-12-30 00:39:22 +00:00
DS_030 < = 'Z' when BGACK_030_INT = '1' else
2015-02-13 13:50:57 +00:00
'0' when DS_000_DMA = '0' and AS_000 = '0' else
2014-09-16 12:51:31 +00:00
'1' ;
2017-12-30 00:39:22 +00:00
A ( 0 ) < = 'Z' when BGACK_030_INT = '1' --tristate on CPU-Cycle
2016-08-25 20:30:49 +00:00
else A0_DMA ; --drive on DMA-Cycle
2016-08-18 22:22:24 +00:00
A ( 1 ) < = 'Z' ;
2017-12-30 00:39:22 +00:00
AHIGH < = "ZZZZZZZZ" when BGACK_030_INT = '1' else x"00" ;
SIZE < = "ZZ" when BGACK_030_INT = '1' else
2016-10-06 19:37:29 +00:00
SIZE_DMA ;
2015-02-13 13:50:57 +00:00
--rw
2017-12-30 00:39:22 +00:00
RW < = 'Z' when BGACK_030_INT = '1' --tristate on CPU cycle
2016-08-25 20:30:49 +00:00
else RW_000_DMA ; --drive on DMA-Cycle
2014-05-24 19:59:56 +00:00
2015-02-13 13:50:57 +00:00
BGACK_030 < = BGACK_030_INT ;
2014-05-15 19:16:29 +00:00
--fpu
2016-08-18 22:22:24 +00:00
FPU_CS < = '0' when AS_030 = '0' and FC ( 1 ) = '1' and FC ( 0 ) = '1' and A_DECODE ( 19 ) = '0' and A_DECODE ( 18 ) = '0' and A_DECODE ( 17 ) = '1' and A_DECODE ( 16 ) = '0' AND BGACK_000 = '1' AND FPU_SENSE = '0'
2014-06-09 08:29:32 +00:00
else '1' ;
2014-05-15 19:16:29 +00:00
--if no copro is installed:
2016-08-18 22:22:24 +00:00
BERR < = '0' when AS_030 = '0' and FC ( 1 ) = '1' and FC ( 0 ) = '1' and A_DECODE ( 19 ) = '0' and A_DECODE ( 18 ) = '0' and A_DECODE ( 17 ) = '1' and A_DECODE ( 16 ) = '0' AND BGACK_000 = '1' AND FPU_SENSE = '1'
2014-07-18 12:08:15 +00:00
else 'Z' ;
2014-05-15 19:16:29 +00:00
2014-08-09 12:43:03 +00:00
--cache inhibit: Tristate for expansion (it decides) and off for the Amiga
2016-08-18 22:22:24 +00:00
CIIN < = '1' WHEN AHIGH ( 31 downto 24 ) = x"00" and A_DECODE ( 23 downto 20 ) = x"F" and AS_030_D0 = '0' ELSE -- Enable for Kick-rom
'Z' WHEN nEXP_SPACE = '0' ELSE --Tristate for expansion (it decides)
2015-09-24 15:00:50 +00:00
'0' ; --off for the Amiga
2014-05-15 19:16:29 +00:00
--e and VMA
2016-01-24 19:26:06 +00:00
E < = '1' when
cpu_est = E7 or
cpu_est = E8 or
cpu_est = E9 or
cpu_est = E10
else '0' ;
2017-12-30 00:39:22 +00:00
VMA < = 'Z' when BGACK_030_INT = '0' else VMA_INT ;
2014-05-15 19:16:29 +00:00
--AVEC
2015-03-15 12:50:46 +00:00
AVEC < = '1' ;
2014-05-15 19:16:29 +00:00
--as and uds/lds
2017-12-30 00:39:22 +00:00
AS_000 < = 'Z' when BGACK_030_INT = '0' or RST = '0' else
2016-08-25 20:30:49 +00:00
'0' when AS_000_INT = '0' and AS_030 = '0' else
'1' ;
2017-12-30 00:39:22 +00:00
RW_000 < = 'Z' when BGACK_030_INT = '0' or RST = '0' --tristate on DMA-cycle
2016-08-25 20:30:49 +00:00
else RW_000_INT ; -- drive on CPU cycle
2017-12-30 00:39:22 +00:00
UDS_000 < = 'Z' when BGACK_030_INT = '0' or RST = '0' else --tristate on DMA cycle
2016-08-25 20:30:49 +00:00
--'1' when DS_000_ENABLE ='0' else
UDS_000_INT when DS_000_ENABLE = '1' -- output on cpu cycle
else '1' ; -- datastrobe not ready jet
2017-12-30 00:39:22 +00:00
LDS_000 < = 'Z' when BGACK_030_INT = '0' or RST = '0' else --tristate on DMA cycle
2016-08-25 20:30:49 +00:00
--'1' when DS_000_ENABLE ='0' else
LDS_000_INT when DS_000_ENABLE = '1' -- output on cpu cycle
else '1' ; -- datastrobe not ready jet
2014-05-15 19:16:29 +00:00
--dsack
2017-12-30 00:39:22 +00:00
DSACK1 < = 'Z' when nEXP_SPACE = '0' or BGACK_030_INT = '0' else --tristate on expansionboard cycle
2016-10-06 19:37:29 +00:00
DSACK1_INT when AS_030 = '0' else -- output on amiga cycle
2017-12-30 00:39:22 +00:00
--'1' when AS_030 = '1' and AS_030_D0 = '0' else --pull high
2016-10-06 19:37:29 +00:00
'1' ;
2016-08-25 20:30:49 +00:00
2014-09-16 12:51:31 +00:00
2016-08-18 05:48:07 +00:00
end Behavioral ;