Project

General

Profile

311 markw
---------------------------------------------------------------------------
-- (c) 2014 mark watson
-- I am happy for anyone to use this for non-commercial use.
-- If my vhdl files are used commercially or otherwise sold,
-- please contact me for explicit permission at scrameta (gmail).
-- This applies for source and binary form and derived works.
---------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_misc.all;

ENTITY avalon_atari_dma IS
PORT
(
CLK : IN STD_LOGIC;
RESET_N : IN STD_LOGIC;

-- avalon signals
CHIPSELECT : IN STD_LOGIC;
ADDRESS : IN STD_LOGIC_VECTOR(21 downto 0);
READ: IN STD_LOGIC;
READDATA : OUT STD_LOGIC_VECTOR(31 downto 0);
WRITE : IN STD_LOGIC;
WRITEDATA : IN STD_LOGIC_VECTOR(31 downto 0);
BYTEENABLE : IN STD_LOGIC_VECTOR(3 downto 0);
WAITREQUEST : OUT STD_LOGIC;

-- atari dma signals
DMA_FETCH : OUT STD_LOGIC;
DMA_READ_ENABLE : OUT STD_LOGIC;
DMA_32BIT_WRITE_ENABLE : OUT STD_LOGIC; -- cough, width for read or writes...
DMA_8BIT_WRITE_ENABLE : OUT STD_LOGIC;
DMA_ADDR : OUT STD_LOGIC_VECTOR(23 downto 0);
DMA_WRITE_DATA : OUT STD_LOGIC_VECTOR(31 downto 0);
MEMORY_READY_DMA : IN STD_LOGIC;
DMA_MEMORY_DATA : IN STD_LOGIC_VECTOR(31 downto 0)
);
END avalon_atari_dma;

ARCHITECTURE vhdl OF avalon_atari_dma IS
SIGNAL BYTE_ADDRESS : STD_LOGIC_VECTOR(1 downto 0);
317 markw
SIGNAL SPECIAL_MEM : STD_LOGIC;
SIGNAL DMA_MEMORY_DATA_LOW : STD_LOGIC_VECTOR(7 downto 0);
311 markw
BEGIN
DMA_FETCH <= (READ or WRITE) and CHIPSELECT;
DMA_READ_ENABLE <= READ;
DMA_ADDR <= ADDRESS&BYTE_ADDRESS;
WAITREQUEST <= NOT(MEMORY_READY_DMA) or not(RESET_N);

317 markw
process(ADDRESS)
begin
special_mem <= '0';
-- $00000-$0FFFF = Own ROM/RAM
-- $10000-$1FFFF = Atari
-- $20000-$2FFFF = Atari - savestate (gtia/antic/pokey have memory behind them)
if (or_reduce(std_logic_vector(ADDRESS(21 downto 19))) = '0') then -- special area
special_mem <= ADDRESS(15);
end if;
end process;

process(SPECIAL_MEM, DMA_MEMORY_DATA)
311 markw
begin
317 markw
DMA_MEMORY_DATA_LOW <= DMA_MEMORY_DATA(7 downto 0);
if (SPECIAL_MEM = '1') then
DMA_MEMORY_DATA_LOW <= DMA_MEMORY_DATA(15 downto 8);
end if;
end process;

process(BYTEENABLE, DMA_MEMORY_DATA_LOW, WRITEDATA, SPECIAL_MEM)
begin
311 markw
BYTE_ADDRESS <= "00";
DMA_8BIT_WRITE_ENABLE <= '0';
DMA_32BIT_WRITE_ENABLE <= '0';
READDATA <= DMA_MEMORY_DATA;
DMA_WRITE_DATA <= WRITEDATA;

case BYTEENABLE is
when "0001" =>
DMA_8BIT_WRITE_ENABLE <= '1';
317 markw
READDATA <= DMA_MEMORY_DATA_LOW&DMA_MEMORY_DATA_LOW&DMA_MEMORY_DATA_LOW&DMA_MEMORY_DATA_LOW;
311 markw
DMA_WRITE_DATA <= x"000000"&WRITEDATA(7 downto 0);
when "0010" =>
BYTE_ADDRESS <= "01";
DMA_8BIT_WRITE_ENABLE <= '1';
317 markw
READDATA <= DMA_MEMORY_DATA_LOW&DMA_MEMORY_DATA_LOW&DMA_MEMORY_DATA_LOW&DMA_MEMORY_DATA_LOW;
311 markw
DMA_WRITE_DATA <= x"000000"&WRITEDATA(15 downto 8);
when "0100" =>
BYTE_ADDRESS <= "10";
DMA_8BIT_WRITE_ENABLE <= '1';
317 markw
READDATA <= DMA_MEMORY_DATA_LOW&DMA_MEMORY_DATA_LOW&DMA_MEMORY_DATA_LOW&DMA_MEMORY_DATA_LOW;
311 markw
DMA_WRITE_DATA <= x"000000"&WRITEDATA(23 downto 16);
when "1000" =>
BYTE_ADDRESS <= "11";
DMA_8BIT_WRITE_ENABLE <= '1';
317 markw
READDATA <= DMA_MEMORY_DATA_LOW&DMA_MEMORY_DATA_LOW&DMA_MEMORY_DATA_LOW&DMA_MEMORY_DATA_LOW;
311 markw
DMA_WRITE_DATA <= x"000000"&WRITEDATA(31 downto 24);
when "1111" =>
DMA_32BIT_WRITE_ENABLE <= '1';
when others =>
-- invalid
end case;
end process;
END vhdl;