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;

815 markw
ENTITY gtiamax IS
701 markw
PORT
(
PHI2 : IN STD_LOGIC;

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);
A : IN STD_LOGIC_VECTOR(4 DOWNTO 0);
W_N : IN STD_LOGIC;
815 markw
CS_N : IN STD_LOGIC;
714 markw
815 markw
S : INOUT STD_LOGIC_VECTOR(3 DOWNTO 0);
T : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
714 markw
815 markw
AN : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
HALT_N : IN STD_LOGIC;
714 markw
815 markw
OSC : IN STD_LOGIC; -- 2x PHI0 ish, iffy duty cycle at TTL levels (at 4V its ok!)
FO0 : OUT STD_LOGIC; -- as OSC, but corrected duty cycle
PAL : IN STD_LOGIC; -- PAL clock (5/4...)
718 markw
815 markw
GPIO : INOUT STD_LOGIC_VECTOR(11 DOWNTO 0);
1318 markw
NC : IN STD_LOGIC_VECTOR(6 DOWNTO 1);
815 markw
CAD3 : IN STD_LOGIC;

CSYNC : OUT STD_LOGIC;
COLOR : OUT STD_LOGIC;
817 markw
LUM : OUT STD_LOGIC_VECTOR(3 downto 0)
701 markw
);
815 markw
END gtiamax;
701 markw
815 markw
ARCHITECTURE vhdl OF gtiamax 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;
820 markw
c1 : out std_logic;
714 markw
locked : out std_logic
);
end component;
1318 markw
component osc_in is
port (
inclock : in std_logic := '0';
dout : out std_logic_vector(1 downto 0);
pad_in : in std_logic_vector(0 downto 0) := (others => '0')
);
end component osc_in;

component osc_out is
port (
outclock : in std_logic := '0';
din : in std_logic_vector(1 downto 0) := (others => '0');
pad_out : out std_logic_vector(0 downto 0)
);
end component osc_out;

714 markw
signal OSC_CLK : std_logic;
signal PHI2_6X : std_logic;

signal CLK : std_logic;
820 markw
signal FAST_CLK : std_logic;
714 markw
signal RESET_N : std_logic;

signal ENABLE_CYCLE : std_logic;
823 markw
signal DATA_CYCLE : std_logic;
714 markw
716 markw
signal ADDR_IN : std_logic_vector(4 downto 0);
signal WRITE_DATA : std_logic_vector(7 downto 0);
714 markw
716 markw
signal BUS_DATA : std_logic_vector(7 downto 0);
signal BUS_OE : std_logic;

signal REQUEST : std_logic;
signal WRITE_N : std_logic;

815 markw
signal GTIA_DO : std_logic_vector(7 downto 0);
817 markw
signal GTIA_WRITE_ENABLE : std_logic;

819 markw
signal PAL_CLEAN : std_logic;

signal PAL_NTSC_N : std_logic;

1318 markw
signal COLOUR_OSC : std_logic_vector(1 downto 0);
signal COLOUR_OSC_PHASED : std_logic_vector(1 downto 0);
819 markw
817 markw
signal OSC_CLEAN : std_logic;
1405 markw
signal OSC_CLEAN_FAST : std_logic;
820 markw
signal OSC_CLEAN_VIDEO : std_logic;
817 markw
signal OSC_CLEAN_EVENT : std_logic;
1405 markw
signal OSC_CLEAN_FAST_EVENT : std_logic;
signal CC_FALLING_FAST : std_logic;
817 markw
signal CC_FALLING : std_logic;
1405 markw
signal OSC_CLEAN_PREV_REG : std_logic;
817 markw
signal S_OUT : std_logic_vector(3 downto 0);

signal VIDEO_COLOUR : std_logic_vector(7 downto 0);
signal VIDEO_HSYNC : std_logic;
signal VIDEO_VSYNC : std_logic;
signal VIDEO_CSYNC : std_logic;
signal VIDEO_BLANK : std_logic;
signal VIDEO_BURST : std_logic;
signal VIDEO_START_OF_FIELD : std_logic;
signal VIDEO_ODD_LINE : std_logic;
822 markw
signal HALT_N_ADJ : std_logic;
824 markw
signal AN_DEL_NEXT : std_logic_vector(2 downto 0);
signal AN_DEL_REG : std_logic_vector(2 downto 0);
signal AN_DEL2_NEXT : std_logic_vector(2 downto 0);
signal AN_DEL2_REG : std_logic_vector(2 downto 0);
1318 markw
signal ddr_pal : std_logic_vector(1 downto 0);
701 markw
BEGIN
1318 markw
--NC <= (others=>'Z');
815 markw
GPIO <= (others=>'Z');
701 markw
1318 markw
pal_in : osc_in
port map
(
inclock => fast_clk,
dout => colour_osc,
pad_in(0) => pal
);
--colour_osc <= pal_clean when pal_ntsc_n='1' else osc_clean_video;

col_out : osc_out
port map
(
outclock => fast_clk,
din => colour_osc_phased,
pad_out(0)=> color
);
--COLOR <= colour_osc_phased;

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

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,
820 markw
c0 => CLK, -- 56MHz
c1 => FAST_CLK, -- 300MHz
714 markw
locked => RESET_N);

1405 markw
process(cc_falling_fast,reset_n)
824 markw
begin
if (reset_n='0') then
AN_DEL_REG <= (others=>'0');
AN_DEL2_REG <= (others=>'0');
1405 markw
elsif (cc_falling_fast'event and cc_falling_fast='1') then
824 markw
AN_DEL_REG <= AN_DEL_NEXT;
AN_DEL2_REG <= AN_DEL2_NEXT;
end if;
end process;
1405 markw
AN_DEL_NEXT <= AN;
AN_DEL2_NEXT <= AN_DEL_REG;
824 markw
716 markw
bus_adapt : entity work.slave_timing_6502
PORT MAP
(
CLK => CLK,
RESET_N => RESET_N,

-- input from the cart port
PHI2 => PHI2,
bus_addr => A,
bus_data => D,

-- output to the cart port
bus_data_out => BUS_DATA,
bus_drive => BUS_OE,
817 markw
bus_cs => NOT(CS_N),
716 markw
bus_rw_n => W_N,

-- request for a memory bus cycle (read or write)
BUS_REQUEST => REQUEST,
ADDR_IN => ADDR_IN,
DATA_IN => WRITE_DATA,
RW_N => WRITE_N,

717 markw
-- end of cycle
ENABLE_CYCLE => ENABLE_CYCLE,
823 markw
DATA_CYCLE => DATA_CYCLE,
822 markw
HALT_N => HALT_N,
HALT_N_OUT => HALT_N_ADJ,
717 markw
815 markw
DATA_OUT => GTIA_DO
716 markw
);
817 markw
819 markw
820 markw
osc_cleaner3 : entity work.correct_duty
PORT MAP(
CLK => FAST_CLK,
RESET_N => RESET_N,
CLKIN => OSC,
CLKOUT => OSC_CLEAN_VIDEO,
CLKOUT_EVENT => open
);

819 markw
osc_cleaner2 : entity work.correct_duty
PORT MAP(
820 markw
CLK => FAST_CLK,
819 markw
RESET_N => RESET_N,
CLKIN => PAL,
CLKOUT => PAL_CLEAN,
CLKOUT_EVENT => open
);

817 markw
osc_cleaner : entity work.correct_duty
PORT MAP(
1405 markw
CLK => FAST_CLK,
817 markw
RESET_N => RESET_N,
CLKIN => OSC,
1405 markw
CLKOUT => OSC_CLEAN_FAST,
CLKOUT_EVENT => OSC_CLEAN_FAST_EVENT
817 markw
);
1405 markw
CC_FALLING_FAST <= OSC_CLEAN_FAST_EVENT and not(OSC_CLEAN_FAST);
817 markw
1405 markw
sync_clk : entity work.synchronizer
port map
(
CLK => CLK,
RAW => OSC_CLEAN_FAST,
SYNC => OSC_CLEAN
);

process(clk,reset_n)
begin
if (reset_n='0') then
OSC_CLEAN_PREV_REG <= '0';
elsif (clk'event and clk='1') then
OSC_CLEAN_PREV_REG <= OSC_CLEAN;
end if;
end process;

OSC_CLEAN_EVENT <= OSC_CLEAN_PREV_REG xor OSC_CLEAN;
817 markw
CC_FALLING <= OSC_CLEAN_EVENT and not(OSC_CLEAN);

819 markw
pal_ntsc_n <= '1'; -- TODO GPIO

815 markw
gtia1 : entity work.gtia
714 markw
PORT MAP(CLK => CLK,
815 markw
ENABLE_179 => ENABLE_CYCLE,
WR_EN => GTIA_WRITE_ENABLE,
RESET_N => RESET_N,
ADDR => ADDR_IN(4 DOWNTO 0),
817 markw
CPU_DATA_IN => WRITE_DATA(7 DOWNTO 0),
815 markw
DATA_OUT => GTIA_DO,
714 markw
815 markw
-- pmg dma
821 markw
MEMORY_DATA_IN => D,
822 markw
ANTIC_FETCH => not(HALT_N_ADJ),
823 markw
CPU_ENABLE_ORIGINAL => DATA_CYCLE,
725 markw
819 markw
PAL => pal_ntsc_n,
740 markw
815 markw
-- ANTIC interface
817 markw
COLOUR_CLOCK_ORIGINAL => CC_FALLING,
COLOUR_CLOCK => CC_FALLING,
818 markw
COLOUR_CLOCK_HIGHRES => OSC_CLEAN_EVENT,
824 markw
AN => AN_DEL2_REG,
740 markw
815 markw
-- keyboard interface
818 markw
CONSOL_IN => NOT(S),
815 markw
CONSOL_OUT => S_OUT,
737 markw
815 markw
-- keyboard interface
TRIG => T,

-- TO scandoubler...
COLOUR_out => VIDEO_COLOUR,

VSYNC => VIDEO_VSYNC,
HSYNC => VIDEO_HSYNC,
CSYNC => VIDEO_CSYNC,
BLANK => VIDEO_BLANK,
BURST => VIDEO_BURST,
START_OF_FIELD => VIDEO_START_OF_FIELD,
ODD_LINE => VIDEO_ODD_LINE
718 markw
);

815 markw
GTIA_WRITE_ENABLE <= NOT(WRITE_N) and REQUEST;
718 markw
819 markw
col_phase : entity work.hue
PORT MAP
(
820 markw
clk => fast_clk,
819 markw
reset_n => reset_n,

hue => video_colour(7 downto 4),
burst => video_burst,
blank => video_blank,
vpos_lsb => video_odd_line,
pal => pal_ntsc_n,

colour_osc => colour_osc,
colour_osc_phased => colour_osc_phased
);

714 markw
-- Wire up pins
CLK_OUT <= PHI2_6X;

815 markw
D <= BUS_DATA when BUS_OE='1' else (others=>'Z');
714 markw
815 markw
S(0) <= '0' when S_OUT(0)='1' else 'Z';
S(1) <= '0' when S_OUT(1)='1' else 'Z';
S(2) <= '0' when S_OUT(2)='1' else 'Z';
S(3) <= '0' when S_OUT(3)='1' else 'Z';
714 markw
817 markw
CSYNC <= NOT(VIDEO_CSYNC);
1318 markw
--COLOR <= colour_osc_phased;
817 markw
LUM(3 downto 0) <= VIDEO_COLOUR(3 downto 0);

1405 markw
FO0 <= OSC_CLEAN_FAST;
817 markw
701 markw
END vhdl;