Project

General

Profile

« Previous | Next » 

Revision 285

Added by markw over 10 years ago

Share the USB PS2 override logic. Wire up USB to controllers on the MCC216

View differences:

mcctv/ps2_over_usb_to_atari800.vhdl
---------------------------------------------------------------------------
-- (c) 2013 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.
---------------------------------------------------------------------------
---------------------------------------------------------------------------
-- (ILoveSpeccy) Added PS2_KEYS Output
---------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
use ieee.numeric_std.all;
ENTITY ps2_over_usb_to_atari800 IS
PORT
(
CLK : IN STD_LOGIC;
RESET_N : IN STD_LOGIC;
INPUT : IN STD_LOGIC_VECTOR(31 downto 0);
KEYBOARD_SCAN : IN STD_LOGIC_VECTOR(5 downto 0);
KEYBOARD_RESPONSE : OUT STD_LOGIC_VECTOR(1 downto 0);
CONSOL_START : OUT STD_LOGIC;
CONSOL_SELECT : OUT STD_LOGIC;
CONSOL_OPTION : OUT STD_LOGIC;
FKEYS : OUT STD_LOGIC_VECTOR(11 downto 0);
FREEZER_ACTIVATE : OUT STD_LOGIC;
PS2_KEYS : OUT STD_LOGIC_VECTOR(511 downto 0);
PS2_KEYS_NEXT_OUT : OUT STD_LOGIC_VECTOR(511 downto 0)
);
END ps2_over_usb_to_atari800;
ARCHITECTURE vhdl OF ps2_over_usb_to_atari800 IS
signal ps2_keys_next : std_logic_vector(511 downto 0);
signal ps2_keys_reg : std_logic_vector(511 downto 0);
signal key_value : std_logic_vector(7 downto 0);
signal key_extended : std_logic;
signal key_down : std_logic;
signal CONSOL_START_INT : std_logic;
signal CONSOL_SELECT_INT : std_logic;
signal CONSOL_OPTION_INT : std_logic;
signal FKEYS_INT : std_logic_vector(11 downto 0);
signal FREEZER_ACTIVATE_INT : std_logic;
signal atari_keyboard : std_logic_vector(63 downto 0);
SIGNAL SHIFT_PRESSED : STD_LOGIC;
SIGNAL BREAK_PRESSED : STD_LOGIC;
SIGNAL CONTROL_PRESSED : STD_LOGIC;
BEGIN
process(clk,reset_n)
begin
if (reset_n='0') then
ps2_keys_reg <= (others=>'0');
elsif (clk'event and clk='1') then
ps2_keys_reg <= ps2_keys_next;
end if;
end process;
-- 1 bit per PS2 key
key_value <= input(7 downto 0);
key_extended <= input(12);
key_down <= input(16);
process(key_value,key_extended,key_down, ps2_keys_reg)
begin
ps2_keys_next <= ps2_keys_reg;
ps2_keys_next(to_integer(unsigned(KEY_EXTENDED&KEY_VALUE))) <= key_down;
end process;
-- map to atari key code
process(ps2_keys_reg)
begin
atari_keyboard <= (others=>'0');
shift_pressed <= '0';
control_pressed <= '0';
break_pressed <= '0';
consol_start_int <= '0';
consol_select_int <= '0';
consol_option_int <= '0';
atari_keyboard(63)<=ps2_keys_reg(16#1C#);
atari_keyboard(21)<=ps2_keys_reg(16#32#);
atari_keyboard(18)<=ps2_keys_reg(16#21#);
atari_keyboard(58)<=ps2_keys_reg(16#23#);
atari_keyboard(42)<=ps2_keys_reg(16#24#);
atari_keyboard(56)<=ps2_keys_reg(16#2B#);
atari_keyboard(61)<=ps2_keys_reg(16#34#);
atari_keyboard(57)<=ps2_keys_reg(16#33#);
atari_keyboard(13)<=ps2_keys_reg(16#43#);
atari_keyboard(1)<=ps2_keys_reg(16#3B#);
atari_keyboard(5)<=ps2_keys_reg(16#42#);
atari_keyboard(0)<=ps2_keys_reg(16#4B#);
atari_keyboard(37)<=ps2_keys_reg(16#3A#);
atari_keyboard(35)<=ps2_keys_reg(16#31#);
atari_keyboard(8)<=ps2_keys_reg(16#44#);
atari_keyboard(10)<=ps2_keys_reg(16#4D#);
atari_keyboard(47)<=ps2_keys_reg(16#15#);
atari_keyboard(40)<=ps2_keys_reg(16#2D#);
atari_keyboard(62)<=ps2_keys_reg(16#1B#);
atari_keyboard(45)<=ps2_keys_reg(16#2C#);
atari_keyboard(11)<=ps2_keys_reg(16#3C#);
atari_keyboard(16)<=ps2_keys_reg(16#2A#);
atari_keyboard(46)<=ps2_keys_reg(16#1D#);
atari_keyboard(22)<=ps2_keys_reg(16#22#);
atari_keyboard(43)<=ps2_keys_reg(16#35#);
atari_keyboard(23)<=ps2_keys_reg(16#1A#);
atari_keyboard(50)<=ps2_keys_reg(16#45#);
atari_keyboard(31)<=ps2_keys_reg(16#16#);
atari_keyboard(30)<=ps2_keys_reg(16#1E#);
atari_keyboard(26)<=ps2_keys_reg(16#26#);
atari_keyboard(24)<=ps2_keys_reg(16#25#);
atari_keyboard(29)<=ps2_keys_reg(16#2E#);
atari_keyboard(27)<=ps2_keys_reg(16#36#);
atari_keyboard(51)<=ps2_keys_reg(16#3D#);
atari_keyboard(53)<=ps2_keys_reg(16#3E#);
atari_keyboard(48)<=ps2_keys_reg(16#46#);
--atari_keyboard(17)<=ps2_keys_reg(16#ec#);
--atari_keyboard(17)<=ps2_keys_reg(16#16c#);
atari_keyboard(17)<=ps2_keys_reg(16#16c#) or ps2_keys_reg(16#03#);
atari_keyboard(52)<=ps2_keys_reg(16#66#);
atari_keyboard(28)<=ps2_keys_reg(16#76#);
--atari_keyboard(39)<=ps2_keys_reg(16#91#);
atari_keyboard(39)<=ps2_keys_reg(16#111#);
atari_keyboard(60)<=ps2_keys_reg(16#58#);
atari_keyboard(44)<=ps2_keys_reg(16#0D#);
atari_keyboard(12)<=ps2_keys_reg(16#5A#);
atari_keyboard(33)<=ps2_keys_reg(16#29#);
atari_keyboard(54)<=ps2_keys_reg(16#4E#);
atari_keyboard(55)<=ps2_keys_reg(16#55#);
atari_keyboard(15)<=ps2_keys_reg(16#5B#);
atari_keyboard(14)<=ps2_keys_reg(16#54#);
atari_keyboard(6)<=ps2_keys_reg(16#52#);
atari_keyboard(7)<=ps2_keys_reg(16#5D#);
atari_keyboard(38)<=ps2_keys_reg(16#4A#);
atari_keyboard(2)<=ps2_keys_reg(16#4C#);
atari_keyboard(32)<=ps2_keys_reg(16#41#);
atari_keyboard(34)<=ps2_keys_reg(16#49#);
atari_keyboard(3)<=ps2_keys_reg(16#05#);
atari_keyboard(4)<=ps2_keys_reg(16#06#);
atari_keyboard(19)<=ps2_keys_reg(16#04#);
atari_keyboard(20)<=ps2_keys_reg(16#0c#);
consol_start_int<=ps2_keys_reg(16#0B#);
consol_select_int<=ps2_keys_reg(16#83#);
consol_option_int<=ps2_keys_reg(16#0a#);
shift_pressed<=ps2_keys_reg(16#12#) or ps2_keys_reg(16#59#);
--control_pressed<=ps2_keys_reg(16#14#) or ps2_keys_reg(16#94#);
control_pressed<=ps2_keys_reg(16#14#) or ps2_keys_reg(16#114#);
break_pressed<=ps2_keys_reg(16#77#);
fkeys_int(0)<=ps2_keys_reg(16#05#);
fkeys_int(1)<=ps2_keys_reg(16#06#);
fkeys_int(2)<=ps2_keys_reg(16#04#);
fkeys_int(3)<=ps2_keys_reg(16#0C#);
fkeys_int(4)<=ps2_keys_reg(16#03#);
fkeys_int(5)<=ps2_keys_reg(16#0B#);
fkeys_int(6)<=ps2_keys_reg(16#83#);
fkeys_int(7)<=ps2_keys_reg(16#0a#);
fkeys_int(8)<=ps2_keys_reg(16#01#);
fkeys_int(9)<=ps2_keys_reg(16#09#);
fkeys_int(10)<=ps2_keys_reg(16#78#);
fkeys_int(11)<=ps2_keys_reg(16#07#);
-- use scroll lock or delete to activate freezer (same key on my keyboard + scroll lock does not seem to work on mist!)
freezer_activate_int <= ps2_keys_reg(16#7e#) or ps2_keys_reg(16#171#);
end process;
-- provide results as if we were a grid to pokey...
process(keyboard_scan, atari_keyboard, control_pressed, shift_pressed, break_pressed)
begin
keyboard_response <= (others=>'1');
if (atari_keyboard(to_integer(unsigned(not(keyboard_scan)))) = '1') then
keyboard_response(0) <= '0';
end if;
if (keyboard_scan(5 downto 4)="00" and break_pressed = '1') then
keyboard_response(1) <= '0';
end if;
if (keyboard_scan(5 downto 4)="10" and shift_pressed = '1') then
keyboard_response(1) <= '0';
end if;
if (keyboard_scan(5 downto 4)="11" and control_pressed = '1') then
keyboard_response(1) <= '0';
end if;
end process;
-- outputs
CONSOL_START <= CONSOL_START_INT;
CONSOL_SELECT <= CONSOL_SELECT_INT;
CONSOL_OPTION <= CONSOL_OPTION_INT;
FKEYS <= FKEYS_INT;
FREEZER_ACTIVATE <= FREEZER_ACTIVATE_INT;
PS2_KEYS <= ps2_keys_reg;
PS2_KEYS_NEXT_OUT <= ps2_keys_next;
END vhdl;
common/a8core/ps2_to_atari800.vhdl
ENTITY ps2_to_atari800 IS
GENERIC
(
ps2_enable : integer := 1;
direct_enable : integer := 0
);
PORT
(
CLK : IN STD_LOGIC;
RESET_N : IN STD_LOGIC;
PS2_CLK : IN STD_LOGIC;
PS2_DAT : IN STD_LOGIC;
PS2_CLK : IN STD_LOGIC := '1';
PS2_DAT : IN STD_LOGIC := '1';
INPUT : IN STD_LOGIC_VECTOR(31 downto 0) := (others=>'0');
KEYBOARD_SCAN : IN STD_LOGIC_VECTOR(5 downto 0);
KEYBOARD_RESPONSE : OUT STD_LOGIC_VECTOR(1 downto 0);
......
signal ps2_keys_next : std_logic_vector(511 downto 0);
signal ps2_keys_reg : std_logic_vector(511 downto 0);
signal ps2_key_event : std_logic;
signal ps2_key_value : std_logic_vector(7 downto 0);
signal ps2_key_extended : std_logic;
signal ps2_key_up : std_logic;
signal direct_key_event : std_logic;
signal direct_key_value : std_logic_vector(7 downto 0);
signal direct_key_extended : std_logic;
signal direct_key_up : std_logic;
signal key_event : std_logic;
signal key_value : std_logic_vector(7 downto 0);
signal key_extended : std_logic;
......
SIGNAL BREAK_PRESSED : STD_LOGIC;
SIGNAL CONTROL_PRESSED : STD_LOGIC;
BEGIN
process(clk,reset_n)
begin
if (reset_n='0') then
ps2_keys_reg <= (others=>'0');
elsif (clk'event and clk='1') then
ps2_keys_reg <= ps2_keys_next;
end if;
end process;
gen_ps2_on : if ps2_enable=1 generate
keyboard1: entity work.ps2_keyboard
PORT MAP
(
......
PS2_CLK => PS2_CLK,
PS2_DAT => PS2_DAT,
KEY_EVENT => KEY_EVENT,
KEY_VALUE => KEY_VALUE,
KEY_EXTENDED => KEY_EXTENDED,
KEY_UP => KEY_UP
KEY_EVENT => PS2_KEY_EVENT,
KEY_VALUE => PS2_KEY_VALUE,
KEY_EXTENDED => PS2_KEY_EXTENDED,
KEY_UP => PS2_KEY_UP
-- KEY_EVENT : OUT STD_LOGIC; -- high for 1 cycle on new key pressed(or repeated)/released
-- KEY_VALUE : OUT STD_LOGIC_VECTOR(7 downto 0); -- valid on event, raw scan code
-- KEY_EXTENDED : OUT STD_LOGIC; -- valid on event, if scan code extended
-- KEY_UP : OUT STD_LOGIC -- value on event, if key released
);
end generate;
process(clk,reset_n)
begin
if (reset_n='0') then
ps2_keys_reg <= (others=>'0');
elsif (clk'event and clk='1') then
ps2_keys_reg <= ps2_keys_next;
end if;
end process;
gen_ps2_off : if ps2_enable=0 generate
PS2_KEY_EVENT <= '0';
PS2_KEY_VALUE <= (others=>'0');
PS2_KEY_EXTENDED <= '0';
PS2_KEY_UP <= '0';
end generate;
-- 1 bit per PS2 key
gen_direct_on : if direct_enable=1 generate
direct_key_value <= input(7 downto 0);
direct_key_extended <= input(12);
direct_key_up <= not(input(16));
direct_key_event <= '1';
end generate;
gen_direct_off : if direct_enable=0 generate
DIRECT_KEY_EVENT <= '0';
DIRECT_KEY_VALUE <= (others=>'0');
DIRECT_KEY_EXTENDED <= '0';
DIRECT_KEY_UP <= '0';
end generate;
KEY_EVENT <= DIRECT_KEY_EVENT or PS2_KEY_EVENT;
KEY_VALUE <= PS2_KEY_VALUE when PS2_KEY_EVENT='1' else DIRECT_KEY_VALUE;
KEY_EXTENDED <= PS2_KEY_EXTENDED when PS2_KEY_EVENT='1' else DIRECT_KEY_EXTENDED;
KEY_UP <= PS2_KEY_UP when PS2_KEY_EVENT='1' else DIRECT_KEY_UP;
process(KEY_EVENT, KEY_VALUE, KEY_EXTENDED, KEY_UP, ps2_keys_reg)
begin
ps2_keys_next <= ps2_keys_reg;
mcc216/atari800core_mcc.vhd
signal JOY1_IN_n : std_logic_vector(4 downto 0);
signal JOY2_IN_n : std_logic_vector(4 downto 0);
signal JOY1_USB : std_logic_vector(5 downto 0);
signal JOY2_USB : std_logic_vector(5 downto 0);
signal JOY1_USB_n : std_logic_vector(4 downto 0);
signal JOY2_USB_n : std_logic_vector(4 downto 0);
signal PLL1_LOCKED : std_logic;
signal CLK_PLL1 : std_logic;
......
signal ZPU_OUT2 : std_logic_vector(31 downto 0);
signal ZPU_OUT3 : std_logic_vector(31 downto 0);
signal ZPU_OUT4 : std_logic_vector(31 downto 0);
signal ZPU_OUT5 : std_logic_vector(31 downto 0);
signal zpu_pokey_enable : std_logic;
signal zpu_sio_txd : std_logic;
......
signal USBWireVMout : std_logic;
signal USBWireOE_n : std_logic;
signal PS2_KEYS : STD_LOGIC_VECTOR(511 downto 0);
signal PS2_KEYS_NEXT : STD_LOGIC_VECTOR(511 downto 0);
-- paddles
signal paddle_mode_next : std_logic;
signal paddle_mode_reg : std_logic;
signal JOY1X : std_logic_vector(7 downto 0);
signal JOY1Y : std_logic_vector(7 downto 0);
signal JOY2X : std_logic_vector(7 downto 0);
signal JOY2Y : std_logic_vector(7 downto 0);
BEGIN
USB2_N <= USBWireVPout when USBWireOE_n='0' else 'Z';
......
-- PS2 to pokey
keyboard_map1 : entity work.ps2_to_atari800
GENERIC MAP
(
ps2_enable => 1,
direct_enable => 1
)
PORT MAP
(
CLK => clk,
RESET_N => reset_n,
PS2_CLK => ps2k_clk,
PS2_DAT => ps2k_dat,
INPUT => zpu_out4,
KEYBOARD_SCAN => KEYBOARD_SCAN,
KEYBOARD_RESPONSE => KEYBOARD_RESPONSE,
......
CONSOL_OPTION => CONSOL_OPTION,
FKEYS => FKEYS,
FREEZER_ACTIVATE => freezer_activate
FREEZER_ACTIVATE => freezer_activate,
PS2_KEYS_NEXT_OUT => ps2_keys_next,
PS2_KEYS => ps2_keys
);
PAL <= '1' when TV=1 else '0';
-- hack for paddles
process(clk,RESET_N)
begin
if (RESET_N = '0') then
paddle_mode_reg <= '0';
elsif (clk'event and clk='1') then
paddle_mode_reg <= paddle_mode_next;
end if;
end process;
JOY1_USB <= zpu_out2(5 downto 4)&zpu_out2(0)&zpu_out2(1)&zpu_out2(2)&zpu_out2(3);
JOY2_USB <= zpu_out3(5 downto 4)&zpu_out3(0)&zpu_out3(1)&zpu_out3(2)&zpu_out3(3);
JOY1X <= zpu_out5(7 downto 0);
JOY1Y <= zpu_out5(15 downto 8);
JOY2X <= zpu_out5(23 downto 16);
JOY2Y <= zpu_out5(31 downto 24);
process(paddle_mode_reg, joy1_usb, joy2_usb)
begin
joy1_usb_n <= (others=>'1');
joy2_usb_n <= (others=>'1');
if (paddle_mode_reg = '1') then
joy1_usb_n <= "111"&not(joy1_usb(4)&joy1_usb(5)); --FLRDU
joy2_usb_n <= "111"&not(joy2_usb(4)&joy2_usb(5));
else
joy1_usb_n <= not(joy1_usb(4 downto 0));
joy2_usb_n <= not(joy2_usb(4 downto 0));
end if;
end process;
paddle_mode_next <= paddle_mode_reg xor (not(ps2_keys(16#11F#)) and ps2_keys_next(16#11F#)); -- left windows key
atarixl_simple_sdram1 : entity work.atari800core_simple_sdram
GENERIC MAP
(
......
AUDIO_L => AUDIO_L_PCM,
AUDIO_R => AUDIO_R_PCM,
JOY1_n => JOY1_IN_n,
JOY2_n => JOY2_IN_n,
JOY1_n => JOY1_IN_n and JOY1_USB_n,
JOY2_n => JOY2_IN_n and JOY2_USB_n,
PADDLE0 => signed(joy1x),
PADDLE1 => signed(joy1y),
PADDLE2 => signed(joy2x),
PADDLE3 => signed(joy2y),
KEYBOARD_RESPONSE => KEYBOARD_RESPONSE,
KEYBOARD_SCAN => KEYBOARD_SCAN,
......
-- external control
-- switches etc. sector DMA blah blah.
ZPU_IN1 => X"00000"&FKEYS,
ZPU_IN1 => X"000"&
"00"&ps2_keys(16#76#)&ps2_keys(16#5A#)&ps2_keys(16#174#)&ps2_keys(16#16B#)&ps2_keys(16#172#)&ps2_keys(16#175#)& -- (esc)FLRDU
FKEYS,
ZPU_IN2 => X"00000000",
ZPU_IN3 => X"00000000",
ZPU_IN4 => X"00000000",
-- ouputs - e.g. Atari system control, halt, throttle, rom select
ZPU_OUT1 => zpu_out1,
ZPU_OUT2 => zpu_out2,
ZPU_OUT3 => zpu_out3,
ZPU_OUT4 => zpu_out4,
ZPU_OUT2 => zpu_out2, --joy0
ZPU_OUT3 => zpu_out3, --joy1
ZPU_OUT4 => zpu_out4, --keyboard
ZPU_OUT5 => zpu_out5, --analog stick
-- USB host
CLK_USB => CLK_USB,
mcctv/atari800core.qsf
set_global_assignment -name SDC_FILE atari800core.sdc
set_global_assignment -name VERILOG_FILE sdram_ctrl_3_ports.v
set_global_assignment -name VHDL_FILE zpu_rom.vhdl
set_global_assignment -name VHDL_FILE ps2_over_usb_to_atari800.vhdl
set_global_assignment -name VHDL_FILE atari800core_mcc.vhd
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
mcctv/atari800core_mcc.vhd
PAL <= '1' when TV=1 else '0';
-- PS2 to pokey
keyboard_map1 : entity work.ps2_over_usb_to_atari800
keyboard_map1 : entity work.ps2_to_atari800
GENERIC MAP
(
ps2_enable => 0,
direct_enable => 1
)
PORT MAP
(
CLK => clk,

Also available in: Unified diff