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;

ENTITY pokeymax IS
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);
835 markw
A : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
701 markw
W_N : IN STD_LOGIC;
IRQ : INOUT STD_LOGIC;
SOD : OUT STD_LOGIC;
725 markw
ACLK : OUT STD_LOGIC;
701 markw
BCLK : INOUT STD_LOGIC;
SID : IN STD_LOGIC;
834 markw
CS1 : IN STD_LOGIC;
CS0_N : IN STD_LOGIC;
714 markw
835 markw
AUD : OUT STD_LOGIC;
714 markw
834 markw
PADDLE : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0);
714 markw
834 markw
KEYBOARD_SCAN : OUT STD_LOGIC_VECTOR(5 downto 0);
KEYBOARD_RESPONSE : IN STD_LOGIC_VECTOR(1 downto 0)
701 markw
);
END pokeymax;

ARCHITECTURE vhdl OF pokeymax IS
component int_osc is
port (
clkout : out std_logic; -- clkout.clk
oscena : in std_logic := '0' -- oscena.oscena
);
end component;
714 markw
component hq_dac
port (
reset :in std_logic;
clk :in std_logic;
clk_ena : in std_logic;
pcm_in : in std_logic_vector(19 downto 0);
dac_out : out std_logic
);
end component;

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;

signal ENABLE_CYCLE : std_logic;

-- POKEY
SIGNAL POKEY_DO : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL POKEY_WRITE_ENABLE : STD_LOGIC;
signal POKEY1_CHANNEL0 : std_logic_vector(3 downto 0);
signal POKEY1_CHANNEL1 : std_logic_vector(3 downto 0);
signal POKEY1_CHANNEL2 : std_logic_vector(3 downto 0);
signal POKEY1_CHANNEL3 : std_logic_vector(3 downto 0);

signal SIO_CLOCKIN_IN : std_logic;
signal SIO_CLOCKIN_OUT : std_logic;
signal SIO_CLOCKIN_OE : std_logic;
signal SIO_CLOCKOUT : std_logic;

signal SIO_TXD : std_logic;
signal SIO_RXD : std_logic;

signal POKEY_IRQ : std_logic;

718 markw
signal POT_RESET : 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
signal AUDIO_L : std_logic_vector(15 downto 0);

signal AUDIO_LEFT : std_logic;

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;

signal DO_MUX : std_logic_vector(7 downto 0);
718 markw
834 markw
signal CS_COMB : 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);

834 markw
CS_COMB <= not(CS0_N) and CS1;

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

-- input from the cart port
PHI2 => PHI2,
835 markw
bus_addr(3 downto 0) => A,
bus_addr(4) => '0',
716 markw
bus_data => D,

-- output to the cart port
bus_data_out => BUS_DATA,
bus_drive => BUS_OE,
bus_cs => CS_COMB,
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,

716 markw
DATA_OUT => DO_MUX
);
714 markw
pokey_mixer_both : entity work.pokey_mixer_mux
PORT MAP(CLK => CLK,
ENABLE_179 => ENABLE_CYCLE,
CHANNEL_L_0 => POKEY1_CHANNEL0,
CHANNEL_L_1 => POKEY1_CHANNEL1,
CHANNEL_L_2 => POKEY1_CHANNEL2,
CHANNEL_L_3 => POKEY1_CHANNEL3,
834 markw
CHANNEL_R_0 => (others=>'0'),
CHANNEL_R_1 => (others=>'0'),
CHANNEL_R_2 => (others=>'0'),
CHANNEL_R_3 => (others=>'0'),
VOLUME_OUT_M => open,
714 markw
VOLUME_OUT_L => AUDIO_L,
834 markw
VOLUME_OUT_R => open);
714 markw
pokey1 : entity work.pokey
726 markw
GENERIC MAP
(
834 markw
custom_keyboard_scan => 0
726 markw
)
714 markw
PORT MAP(CLK => CLK,
ENABLE_179 => ENABLE_CYCLE,
WR_EN => POKEY_WRITE_ENABLE,
RESET_N => RESET_N,
SIO_IN1 => SIO_RXD,
SIO_IN2 => '1',
SIO_IN3 => '1',
SIO_CLOCKIN_IN => SIO_CLOCKIN_IN,
SIO_CLOCKIN_OUT => SIO_CLOCKIN_OUT,
SIO_CLOCKIN_OE => SIO_CLOCKIN_OE,
ADDR => ADDR_IN(3 DOWNTO 0),
DATA_IN => WRITE_DATA(7 DOWNTO 0),
keyboard_response => KEYBOARD_RESPONSE,
725 markw
POT_IN => PADDLE,
714 markw
IRQ_N_OUT => POKEY_IRQ,
SIO_OUT1 => SIO_TXD,
SIO_OUT2 => open,
SIO_OUT3 => open,
SIO_CLOCKOUT => SIO_CLOCKOUT,
POT_RESET => POT_RESET,
CHANNEL_0_OUT => POKEY1_CHANNEL0,
CHANNEL_1_OUT => POKEY1_CHANNEL1,
CHANNEL_2_OUT => POKEY1_CHANNEL2,
CHANNEL_3_OUT => POKEY1_CHANNEL3,
DATA_OUT => POKEY_DO,
834 markw
keyboard_scan => KEYBOARD_SCAN
726 markw
);
714 markw
725 markw
DO_MUX <= POKEY_DO;

POKEY_WRITE_ENABLE <= NOT(WRITE_N) and REQUEST;
714 markw
834 markw
dac_mixed : hq_dac
714 markw
port map
(
reset => not(reset_n),
clk => clk,
clk_ena => '1',
pcm_in => AUDIO_L&"0000",
dac_out => AUDIO_LEFT
);

718 markw
-- io extension
-- drive to 0 for pot reset (otherwise high imp)
-- drive keyboard lines
834 markw
-- pot_reset=>pot_reset,
-- keyboard_scan=>keyboard_scan,
-- keyboard_scan_enable=>keyboard_scan_enable,
-- keyboard_response=>keyboard_response
718 markw
714 markw
-- Wire up pins
CLK_OUT <= PHI2_6X;

ACLK <= SIO_CLOCKOUT;
BCLK <= '0' when (SIO_CLOCKIN_OE='1' and SIO_CLOCKIN_OUT='0') else 'Z';
SIO_CLOCKIN_IN <= BCLK;

SOD <= '0' when SIO_TXD='0' else 'Z';
SIO_RXD <= SID;

733 markw
--gnd
--
--1->pin37
835 markw
AUD <= AUDIO_LEFT;
714 markw
IRQ <= '0' when POKEY_IRQ='0' else 'Z';

716 markw
D <= BUS_DATA when BUS_OE='1' else (others=>'Z');

834 markw
PADDLE <= (others=>'0') when POT_RESET='1' else (others=>'Z');

701 markw
END vhdl;