Project

General

Profile

701 markw
---------------------------------------------------------------------------
-- (c) 2018 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.numeric_std.all;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;

LIBRARY work;

825 markw
ENTITY anticmax IS
701 markw
PORT
(
825 markw
-- Reminder
-- OSC->GTIA->FO0->ANTIC->PHI0->CPU->PHI2->...

701 markw
PHI2 : IN STD_LOGIC;
829 markw
RST_N : IN STD_LOGIC;
825 markw
FO0 : IN STD_LOGIC;
PHI0 : OUT STD_LOGIC;
701 markw
CLK_OUT : OUT STD_LOGIC; -- Use PHI2 and internal oscillator to create a clock, feed out here
CLK_SLOW : IN STD_LOGIC; -- ... and back in here, then to pll!

D : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0);
826 markw
A : INOUT STD_LOGIC_VECTOR(15 DOWNTO 0);
829 markw
RW_N : IN STD_LOGIC;
714 markw
825 markw
LP_N : IN STD_LOGIC; -- light pen
714 markw
825 markw
NMI_N : OUT STD_LOGIC;
RNMI_N : IN STD_LOGIC; -- Internal pull-up
714 markw
826 markw
RDY : OUT STD_LOGIC; -- Open drain
825 markw
REF_N : OUT STD_LOGIC; -- Driven, but... turbo freezer!! Try internal pull-ups?
HALT_N : OUT STD_LOGIC; -- Driven, but... future devices like freezer? Try internal pull-ups?
718 markw
825 markw
NC : IN STD_LOGIC_VECTOR(2 downto 1);

AN : OUT STD_LOGIC_VECTOR(2 DOWNTO 0);

GPIO : INOUT STD_LOGIC_VECTOR(11 downto 0)
701 markw
);
825 markw
END anticmax;
701 markw
825 markw
ARCHITECTURE vhdl OF anticmax IS
701 markw
component int_osc is
port (
clkout : out std_logic; -- clkout.clk
oscena : in std_logic := '0' -- oscena.oscena
);
end component;
714 markw
component pll
port (
inclk0 : in std_logic := '0';
c0 : out std_logic;
locked : out std_logic
);
end component;

signal OSC_CLK : std_logic;
signal PHI2_6X : std_logic;

signal CLK : std_logic;
signal RESET_N : std_logic;

825 markw
signal PHI0_REG : std_logic;

714 markw
signal ENABLE_CYCLE : std_logic;

825 markw
-- ANTIC
SIGNAL ANTIC_DO : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL ANTIC_WRITE_ENABLE : STD_LOGIC;
714 markw
825 markw
signal ADDR_IN : std_logic_vector(15 downto 0);
716 markw
signal WRITE_DATA : std_logic_vector(7 downto 0);
714 markw
826 markw
signal BUS_ADDR : std_logic_vector(15 downto 0);
signal BUS_ADDR_OE : std_logic;

716 markw
signal BUS_DATA : std_logic_vector(7 downto 0);
826 markw
signal BUS_DATA_OE : std_logic;
716 markw
signal REQUEST : std_logic;
827 markw
signal DMA_COMPLETE : std_logic;
716 markw
signal WRITE_N : std_logic;

825 markw
SIGNAL PAL_NTSC_N : STD_LOGIC;
730 markw
826 markw
SIGNAL DMA_FETCH_ADDR : STD_LOGIC_VECTOR(15 downto 0);
825 markw
SIGNAL AN_OUT : STD_LOGIC_VECTOR(2 downto 0);
SIGNAL AN_OUT_ENABLE : STD_LOGIC;

826 markw
SIGNAL ANTIC_NEXT_CYCLE : STD_LOGIC_VECTOR(2 downto 0); --000=cpu,001=dma,010=refresh,011=undef,100=undef,101=dma_wsync,110=refresh_wsync,101=undef

SIGNAL RDY_DATA : STD_LOGIC;
SIGNAL REF_N_DATA : STD_LOGIC;
SIGNAL REF_N_OE : STD_LOGIC;
SIGNAL HALT_N_DATA : STD_LOGIC;
SIGNAL HALT_N_OE : STD_LOGIC;

SIGNAL ANTIC_LP : STD_LOGIC;
701 markw
BEGIN
oscillator : int_osc
port map
(
714 markw
clkout => OSC_CLK,
701 markw
oscena => '1'
);

714 markw
730 markw
--phi_multiplier : entity work.phi_mult
--port map
--(
-- clkin => OSC_CLK,
-- phi2 => PHI2,
-- clkout => PHI2_6X -- 6x phi2, aligned!
--);

PHI2_6X <= OSC_CLK;
714 markw
pll_inst : pll
PORT MAP(inclk0 => CLK_SLOW,
c0 => CLK, -- 27MHz
locked => RESET_N);

825 markw
process(FO0)
begin
if (FO0'EVENT and FO0='1') then
PHI0_REG <= not(PHI0_REG);
end if;
end process;
PHI0 <= PHI0_REG;

826 markw
bus_adapt : entity work.timing_antic
716 markw
PORT MAP
(
CLK => CLK,
RESET_N => RESET_N,

826 markw
-- input from the pins
716 markw
PHI2 => PHI2,
bus_addr => A,
bus_data => D,
826 markw
bus_lp_n => lp_n,
bus_rnmi_n => rnmi_n,

716 markw
-- output to the cart port
826 markw
bus_addr_out => BUS_ADDR,
bus_addr_oe => BUS_ADDR_OE,
716 markw
bus_data_out => BUS_DATA,
826 markw
bus_data_oe => BUS_DATA_OE,
829 markw
bus_rw_n => RW_N,
826 markw
bus_rdy => RDY_DATA,
bus_ref_n => REF_N_DATA,
bus_ref_n_oe => REF_N_OE,
bus_halt_n => HALT_N_DATA,
bus_halt_n_oe => HALT_N_OE,
bus_an_out => AN,
716 markw
-- request for a memory bus cycle (read or write)
826 markw
-- into antic
-- requests from the cpu
716 markw
BUS_REQUEST => REQUEST,
ADDR_IN => ADDR_IN,
DATA_IN => WRITE_DATA,
RW_N => WRITE_N,
826 markw
LIGHTPEN => ANTIC_LP,
716 markw
826 markw
-- response to the request, out of antic
DATA_OUT => ANTIC_DO,

-- antic dma master
CYCLE_TYPE => antic_next_cycle,
ADDR_OUT => dma_fetch_addr,
827 markw
DMA_COMPLETE => dma_complete,
826 markw
-- antic an0 output
AN_OUT => AN_OUT,
AN_OUT_ENABLE => AN_OUT_ENABLE,
FO0 => FO0,

717 markw
-- end of cycle
826 markw
ENABLE_CYCLE => ENABLE_CYCLE
716 markw
);
825 markw
PAL_NTSC_N <= '1'; -- TODO, GPIO!

antic1 : entity work.antic
829 markw
GENERIC MAP(cycle_length=>32)
714 markw
PORT MAP(CLK => CLK,
825 markw
ANTIC_ENABLE_179 => ENABLE_CYCLE,
WR_EN => ANTIC_WRITE_ENABLE,
RESET_N => RESET_N,
ADDR => ADDR_IN(3 DOWNTO 0),
CPU_DATA_IN => WRITE_DATA(7 DOWNTO 0),
MEMORY_READY_CPU => REQUEST,
DATA_OUT => ANTIC_DO,
714 markw
825 markw
-- ANTIC DMA!
MEMORY_DATA_IN => WRITE_DATA(7 DOWNTO 0),
827 markw
MEMORY_READY_ANTIC => dma_complete,
826 markw
dma_fetch_out => open,
dma_address_out => dma_fetch_addr,
725 markw
825 markw
-- IRQs
RNMI_N => RNMI_N,
NMI_N_OUT => NMI_N,

-- TV system (in fact just how many lines...)
PAL => PAL_NTSC_N,
740 markw
826 markw
lightpen => ANTIC_LP,
740 markw
825 markw
-- WSYNC
826 markw
ANTIC_READY => open,
825 markw
-- GTIA interface
AN => AN_OUT, -- needs to be 1 cycle earlier?
COLOUR_CLOCK_ORIGINAL_OUT => AN_OUT_ENABLE, -- input from FO0, urg, back to front...
COLOUR_CLOCK_OUT => open,
HIGHRES_COLOUR_CLOCK_OUT => open, -- gtia makes this...
826 markw
-- next cycle
next_cycle_type => antic_next_cycle,
825 markw
-- refresh
826 markw
refresh_out => open,
740 markw
825 markw
-- if we are in turbo mode -- would be cool to get 2x and 4x colour clock but needs much more work, possibly new hardware too
turbo_out => open,
737 markw
825 markw
-- for debugging
shift_out => open,
dma_clock_out => open,
hcount_out => open,
vcount_out => open
718 markw
);

826 markw
ANTIC_WRITE_ENABLE <= NOT(WRITE_N) and REQUEST;
718 markw
825 markw
-- Wire up pins
CLK_OUT <= PHI2_6X;

826 markw
D <= BUS_DATA when BUS_DATA_OE='1' else (others=>'Z');
A <= BUS_ADDR when BUS_ADDR_OE='1' else (others=>'Z');
HALT_N <= HALT_N_DATA when HALT_N_OE='1' else 'Z';
REF_N <= REF_N_DATA when REF_N_OE='1' else 'Z';
RDY <= '0' when RDY_DATA='0' else 'Z';
726 markw
701 markw
END vhdl;