Revision 126
Added by markw about 11 years ago
chameleon/atari800core.qsf | ||
---|---|---|
set_global_assignment -name VHDL_FILE chameleon_led.vhd
|
||
set_global_assignment -name VHDL_FILE chameleon_phi_clock_e.vhd
|
||
set_global_assignment -name VHDL_FILE chameleon_phi_clock_a.vhd
|
||
set_global_assignment -name VHDL_FILE chameleon_io.vhd
|
||
set_global_assignment -name VHDL_FILE chameleon_cdtv_remote.vhd
|
||
set_global_assignment -name VHDL_FILE chameleon_c64_joykeyb.vhd
|
||
set_global_assignment -name VHDL_FILE atari800core_chameleon.vhd
|
||
set_global_assignment -name QIP_FILE pll.qip
|
||
set_global_assignment -name RESERVE_DATA0_AFTER_CONFIGURATION "USE AS REGULAR IO"
|
chameleon/atari800core_chameleon.vhd | ||
---|---|---|
|
||
|
||
-- MUX
|
||
signal mux_clk_reg : std_logic := '0';
|
||
signal mux_reg : unsigned(3 downto 0) := (others => '1');
|
||
signal mux_d_reg : unsigned(3 downto 0) := (others => '1');
|
||
-- signal mux_clk_reg : std_logic := '0';
|
||
-- signal mux_reg : unsigned(3 downto 0) := (others => '1');
|
||
-- signal mux_d_reg : unsigned(3 downto 0) := (others => '1');
|
||
|
||
-- reset from chameleon
|
||
signal chameleon_reset_n : std_logic;
|
||
|
||
-- LEDs
|
||
signal led_green : std_logic;
|
||
signal led_red : std_logic;
|
||
-- signal led_green : std_logic;
|
||
-- signal led_red : std_logic;
|
||
|
||
-- clocks...
|
||
signal sysclk : std_logic;
|
||
signal ena_1mhz : std_logic;
|
||
signal ena_1khz : std_logic;
|
||
signal phi2 : std_logic;
|
||
--signal phi2 : std_logic;
|
||
signal no_clock : std_logic;
|
||
|
||
-- Docking station
|
||
... | ... | |
signal docking_joystick3 : unsigned(5 downto 0);
|
||
signal docking_joystick4 : unsigned(5 downto 0);
|
||
|
||
-- IR remote
|
||
signal ir_joya : unsigned(5 downto 0);
|
||
signal ir_joyb : unsigned(5 downto 0);
|
||
signal ir : std_logic;
|
||
signal ir_start : std_logic;
|
||
signal ir_select : std_logic;
|
||
signal ir_option : std_logic;
|
||
signal ir_fkeys : std_logic_vector(11 downto 0);
|
||
|
||
-- PS/2 Keyboard
|
||
signal ps2_keyboard_clk_in : std_logic;
|
||
signal ps2_keyboard_dat_in : std_logic;
|
||
... | ... | |
signal VIDEO_B : std_logic_vector(7 downto 0);
|
||
signal VGA_VS : std_logic;
|
||
signal VGA_HS : std_logic;
|
||
signal scanlines_next : std_logic;
|
||
signal scanlines_reg : std_logic;
|
||
signal freeze_n_reg : std_logic;
|
||
signal freeze_n_sync : std_logic;
|
||
|
||
begin
|
||
pal <= '1' when tv=1 else '0';
|
||
... | ... | |
AUDIO_R => audio_r_raw,
|
||
|
||
-- JOYSTICK
|
||
JOY1_n => std_logic_vector(docking_joystick1)(4 downto 0),
|
||
JOY2_n => std_logic_vector(docking_joystick2)(4 downto 0),
|
||
JOY1_n => std_logic_vector(docking_joystick1 and ir_joya)(4 downto 0),
|
||
JOY2_n => std_logic_vector(docking_joystick2 and ir_joyb)(4 downto 0),
|
||
|
||
KEYBOARD_RESPONSE => KEYBOARD_RESPONSE,
|
||
KEYBOARD_SCAN => KEYBOARD_SCAN,
|
||
... | ... | |
SIO_RXD => zpu_sio_txd,
|
||
SIO_TXD => zpu_sio_rxd,
|
||
|
||
CONSOL_OPTION => CONSOL_OPTION,
|
||
CONSOL_SELECT => CONSOL_SELECT,
|
||
CONSOL_START => CONSOL_START,
|
||
CONSOL_OPTION => CONSOL_OPTION or ir_option,
|
||
CONSOL_SELECT => CONSOL_SELECT or ir_select,
|
||
CONSOL_START => CONSOL_START or ir_start,
|
||
|
||
SDRAM_REQUEST => SDRAM_REQUEST,
|
||
SDRAM_REQUEST_COMPLETE => SDRAM_REQUEST_COMPLETE,
|
||
... | ... | |
-- -----------------------------------------------------------------------
|
||
-- Phi 2
|
||
-- -----------------------------------------------------------------------
|
||
myPhi2: entity work.chameleon_phi_clock
|
||
port map (
|
||
clk => sysclk,
|
||
phiIn => phi2,
|
||
|
||
-- no_clock is high when there are no phiIn changes detected.
|
||
-- This signal allows switching between real I/O and internal emulation.
|
||
no_clock => no_clock,
|
||
|
||
-- docking_station is high when there are no phiIn changes (no_clock) and
|
||
-- the phi signal is low. Without docking station phi is pulled up.
|
||
docking_station => docking_station
|
||
);
|
||
-- myPhi2: entity work.chameleon_phi_clock
|
||
-- port map (
|
||
-- clk => sysclk,
|
||
-- phiIn => phi2,
|
||
--
|
||
-- -- no_clock is high when there are no phiIn changes detected.
|
||
-- -- This signal allows switching between real I/O and internal emulation.
|
||
-- no_clock => no_clock,
|
||
--
|
||
-- -- docking_station is high when there are no phiIn changes (no_clock) and
|
||
-- -- the phi signal is low. Without docking station phi is pulled up.
|
||
-- docking_station => docking_station
|
||
-- );
|
||
--
|
||
-- phi2 <= not phi2_n;
|
||
|
||
phi2 <= not phi2_n;
|
||
|
||
-- -----------------------------------------------------------------------
|
||
-- Docking station
|
||
-- -----------------------------------------------------------------------
|
||
myDockingStation : entity work.chameleon_docking_station
|
||
port map (
|
||
clk => sysclk,
|
||
ena_1mhz => ena_1mhz,
|
||
enable => docking_ena,
|
||
|
||
docking_station => docking_station,
|
||
|
||
dotclock_n => dotclock_n,
|
||
io_ef_n => ioef_n,
|
||
rom_lh_n => romlh_n,
|
||
irq_d => irq_n,
|
||
irq_q => docking_irq,
|
||
|
||
joystick1 => docking_joystick1,
|
||
joystick2 => docking_joystick2,
|
||
joystick3 => docking_joystick3,
|
||
joystick4 => docking_joystick4,
|
||
keys => open,
|
||
restore_key_n => open,
|
||
|
||
amiga_power_led => '0',
|
||
amiga_drive_led => '0',
|
||
amiga_reset_n => open,
|
||
amiga_scancode => open
|
||
);
|
||
-- myDockingStation : entity work.chameleon_docking_station
|
||
-- port map (
|
||
-- clk => sysclk,
|
||
-- ena_1mhz => ena_1mhz,
|
||
-- enable => docking_ena,
|
||
--
|
||
-- docking_station => docking_station,
|
||
--
|
||
-- dotclock_n => dotclock_n,
|
||
-- io_ef_n => ioef_n,
|
||
-- rom_lh_n => romlh_n,
|
||
-- irq_d => irq_n,
|
||
-- irq_q => docking_irq,
|
||
--
|
||
-- joystick1 => docking_joystick1,
|
||
-- joystick2 => docking_joystick2,
|
||
-- joystick3 => docking_joystick3,
|
||
-- joystick4 => docking_joystick4,
|
||
-- keys => open,
|
||
-- restore_key_n => open,
|
||
--
|
||
-- amiga_power_led => '0',
|
||
-- amiga_drive_led => '0',
|
||
-- amiga_reset_n => open,
|
||
-- amiga_scancode => open
|
||
-- );
|
||
|
||
-- -----------------------------------------------------------------------
|
||
-- MUX CPLD
|
||
-- -----------------------------------------------------------------------
|
||
-- MUX clock
|
||
process(sysclk)
|
||
begin
|
||
if rising_edge(sysclk) then
|
||
mux_clk_reg <= not mux_clk_reg;
|
||
end if;
|
||
end process;
|
||
|
||
-- MUX read
|
||
process(sysclk)
|
||
begin
|
||
if rising_edge(sysclk) then
|
||
if mux_clk_reg = '1' then
|
||
case mux_reg is
|
||
when X"6" =>
|
||
irq_n <= mux_q(2);
|
||
when X"B" =>
|
||
--reset_button_n <= mux_q(1);
|
||
--ir <= mux_q(3);
|
||
when X"A" =>
|
||
--vga_id <= mux_q;
|
||
when X"E" =>
|
||
ps2_keyboard_dat_in <= mux_q(0);
|
||
ps2_keyboard_clk_in <= mux_q(1);
|
||
--ps2_mouse_dat_in <= mux_q(2);
|
||
--ps2_mouse_clk_in <= mux_q(3);
|
||
when others =>
|
||
null;
|
||
end case;
|
||
end if;
|
||
end if;
|
||
end process;
|
||
chameleon_io : entity work.chameleon_io
|
||
generic map (
|
||
enable_docking_station => true,
|
||
enable_c64_joykeyb => true,
|
||
enable_c64_4player => false,
|
||
enable_raw_spi => true,
|
||
enable_iec_access => false
|
||
)
|
||
port map (
|
||
clk => clk,
|
||
clk_mux => clk,
|
||
ena_1mhz => ena_1mhz,
|
||
reset => reset_n, -- active low!
|
||
reset_ext => open,
|
||
|
||
-- MUX write
|
||
process(sysclk)
|
||
begin
|
||
if rising_edge(sysclk) then
|
||
docking_ena <= '0';
|
||
if mux_clk_reg = '1' then
|
||
case mux_reg is
|
||
when X"7" =>
|
||
mux_d_reg <= "1111";
|
||
if docking_station = '1' then
|
||
mux_d_reg <= "1" & docking_irq & "11";
|
||
end if;
|
||
mux_reg <= X"6";
|
||
when X"6" =>
|
||
mux_d_reg <= "1111";
|
||
mux_reg <= X"8";
|
||
when X"8" =>
|
||
mux_d_reg <= "1111";
|
||
mux_reg <= X"A";
|
||
when X"A" =>
|
||
mux_d_reg <= "10" & led_green & led_red;
|
||
mux_reg <= X"B";
|
||
when X"B" =>
|
||
mux_d_reg <= "1"&spi_cs_n&spi_mosi&spi_clk;
|
||
mux_reg <= X"C";
|
||
when X"C" =>
|
||
--mux_d_reg <= iec_reg;
|
||
mux_d_reg <= "1111";
|
||
mux_reg <= X"D";
|
||
docking_ena <= '1';
|
||
when X"D" =>
|
||
--mux_d_reg(0) <= ps2_keyboard_dat_out;
|
||
--mux_d_reg(1) <= ps2_keyboard_clk_out;
|
||
--mux_d_reg(2) <= ps2_mouse_dat_out;
|
||
--mux_d_reg(3) <= ps2_mouse_clk_out;
|
||
mux_d_reg <= "1111";
|
||
mux_reg <= X"E";
|
||
when X"E" =>
|
||
mux_d_reg <= "1111";
|
||
mux_reg <= X"7";
|
||
when others =>
|
||
mux_reg <= X"B";
|
||
mux_d_reg <= "10" & led_green & led_red;
|
||
end case;
|
||
end if;
|
||
end if;
|
||
end process;
|
||
|
||
mux_clk <= mux_clk_reg;
|
||
mux_d <= mux_d_reg;
|
||
mux <= mux_reg;
|
||
-- Config
|
||
no_clock => no_clock,
|
||
docking_station => docking_station,
|
||
|
||
-- -----------------------------------------------------------------------
|
||
-- Chameleon FPGA pins
|
||
-- C64 Clocks
|
||
phi2_n => phi2_n,
|
||
dotclock_n => dotclock_n,
|
||
-- C64 cartridge control lines
|
||
io_ef_n => ioef_n,
|
||
rom_lh_n => romlh_n,
|
||
-- SPI bus
|
||
spi_miso => spi_miso,
|
||
-- CPLD multiplexer
|
||
mux_clk => mux_clk,
|
||
mux => mux,
|
||
mux_d => mux_d,
|
||
mux_q => mux_q,
|
||
|
||
-- USB microcontroller (To RX of micro)
|
||
-- to_usb_rx : in std_logic := '1';
|
||
|
||
-- C64 timing (only for C64 related cores)
|
||
phi_mode => not(PAL),
|
||
phi_out => open,
|
||
phi_cnt => open,
|
||
phi_end_0 => open,
|
||
phi_end_1 => open,
|
||
phi_post_1 => open,
|
||
phi_post_2 => open,
|
||
phi_post_3 => open,
|
||
phi_post_4 => open,
|
||
|
||
-- C64 bus
|
||
-- (all disabled by generic for joystick anyway... - otherwise we could map c64 into Atari memory bank - he he ;-))
|
||
c64_irq_n => open,
|
||
c64_nmi_n => open,
|
||
c64_ba => open,
|
||
|
||
-- c64_vic : in std_logic := '0';
|
||
-- c64_cs : in std_logic := '0';
|
||
-- c64_cs_roms : in std_logic := '0';
|
||
-- c64_clockport : in std_logic := '0';
|
||
-- c64_we : in std_logic := '0';
|
||
-- c64_a : in unsigned(15 downto 0) := (others => '0');
|
||
-- c64_d : in unsigned(7 downto 0) := (others => '1');
|
||
-- c64_q : out unsigned(7 downto 0);
|
||
|
||
-- SPI chip-selects
|
||
mmc_cs_n => spi_cs_n,
|
||
flash_cs_n => '1',
|
||
rtc_cs => '0',
|
||
|
||
-- SPI controller (enable_raw_spi must be set to false)
|
||
-- spi_speed : in std_logic := '1';
|
||
-- spi_req : in std_logic := '0';
|
||
-- spi_ack : out std_logic;
|
||
-- spi_d : in unsigned(7 downto 0) := (others => '-');
|
||
-- spi_q : out unsigned(7 downto 0);
|
||
|
||
-- SPI raw signals (enable_raw_spi must be set to true)
|
||
spi_raw_clk => spi_clk,
|
||
spi_raw_mosi => spi_mosi,
|
||
spi_raw_ack => open, -- I guess so Minimig can go as fast as the mux round robin...
|
||
|
||
-- LEDs
|
||
-- -----------------------------------------------------------------------
|
||
myGreenLed : entity work.chameleon_led
|
||
port map (
|
||
clk => sysclk,
|
||
clk_1khz => ena_1khz,
|
||
led_on => '0',
|
||
led_blink => '1',
|
||
led => led_red,
|
||
led_1hz => led_green
|
||
);
|
||
led_green => not(zpu_sio_txd),
|
||
led_red => not(zpu_sio_rxd),
|
||
ir => ir,
|
||
|
||
-- PS/2 Keyboard
|
||
ps2_keyboard_clk_out => '1',
|
||
ps2_keyboard_dat_out => '1',
|
||
ps2_keyboard_clk_in => ps2_keyboard_clk_in,
|
||
ps2_keyboard_dat_in => ps2_keyboard_dat_in,
|
||
|
||
-- PS/2 Mouse
|
||
-- ps2_mouse_clk_out: in std_logic := '1';
|
||
-- ps2_mouse_dat_out: in std_logic := '1';
|
||
-- ps2_mouse_clk_in: out std_logic;
|
||
-- ps2_mouse_dat_in: out std_logic;
|
||
|
||
-- Buttons
|
||
button_reset_n => chameleon_reset_n,
|
||
|
||
-- Joysticks
|
||
joystick1 => docking_joystick1,
|
||
joystick2 => docking_joystick2,
|
||
joystick3 => docking_joystick3,
|
||
joystick4 => docking_joystick4
|
||
|
||
-- Keyboards
|
||
-- 0 = col0, row0
|
||
-- 1 = col1, row0
|
||
-- 8 = col0, row1
|
||
-- 63 = col7, row7
|
||
-- TODO - wire up to Atari keyboard...
|
||
-- When no_clock = 0 its connected to C64...
|
||
-- keys : out unsigned(63 downto 0);
|
||
-- restore_key_n : out std_logic;
|
||
-- amiga_reset_n : out std_logic;
|
||
-- amiga_trigger : out std_logic;
|
||
-- amiga_scancode : out unsigned(7 downto 0);
|
||
|
||
-- IEC bus
|
||
-- iec_clk_out : in std_logic := '1';
|
||
-- iec_dat_out : in std_logic := '1';
|
||
-- iec_atn_out : in std_logic := '1';
|
||
-- iec_srq_out : in std_logic := '1';
|
||
-- iec_clk_in : out std_logic;
|
||
-- iec_dat_in : out std_logic;
|
||
-- iec_atn_in : out std_logic;
|
||
-- iec_srq_in : out std_logic
|
||
);
|
||
|
||
-- CDTV IR decoder
|
||
|
||
myIr : entity work.chameleon_cdtv_remote
|
||
port map (
|
||
clk => clk,
|
||
ena_1mhz => ena_1mhz,
|
||
ir => ir,
|
||
|
||
-- trigger : out std_logic;
|
||
--
|
||
key_1 => ir_fkeys(0),
|
||
key_2 => ir_fkeys(1),
|
||
key_3 => ir_fkeys(2),
|
||
key_4 => ir_fkeys(3),
|
||
-- key_5 => ir_fkeys(4),
|
||
-- key_6 => ir_fkeys(5),
|
||
-- key_7 => ir_fkeys(6),
|
||
-- key_8 => ir_fkeys(7),
|
||
-- key_9 => ir_fkeys(8),
|
||
-- key_0 => ir_fkeys(9),
|
||
-- key_escape : out std_logic;
|
||
-- key_enter : out std_logic;
|
||
key_genlock => ir_fkeys(10),
|
||
key_cdtv => ir_fkeys(11),
|
||
key_power => ir_fkeys(9),
|
||
key_rew => ir_start,
|
||
key_play => ir_select,
|
||
key_ff => ir_option,
|
||
key_stop => ir_fkeys(8),
|
||
-- key_vol_up : out std_logic;
|
||
-- key_vol_dn : out std_logic;
|
||
joystick_a => ir_joya,
|
||
joystick_b => ir_joyb
|
||
-- debug_code : out unsigned(11 downto 0)
|
||
);
|
||
|
||
|
||
-- -- MUX clock
|
||
-- process(sysclk)
|
||
-- begin
|
||
-- if rising_edge(sysclk) then
|
||
-- mux_clk_reg <= not mux_clk_reg;
|
||
-- end if;
|
||
-- end process;
|
||
--
|
||
-- -- MUX read
|
||
-- process(sysclk)
|
||
-- begin
|
||
-- if rising_edge(sysclk) then
|
||
-- if mux_clk_reg = '1' then
|
||
-- case mux_reg is
|
||
-- when X"6" =>
|
||
-- irq_n <= mux_q(2);
|
||
-- when X"B" =>
|
||
-- --reset_button_n <= mux_q(1);
|
||
-- --ir <= mux_q(3);
|
||
-- when X"A" =>
|
||
-- --vga_id <= mux_q;
|
||
-- when X"E" =>
|
||
-- ps2_keyboard_dat_in <= mux_q(0);
|
||
-- ps2_keyboard_clk_in <= mux_q(1);
|
||
-- --ps2_mouse_dat_in <= mux_q(2);
|
||
-- --ps2_mouse_clk_in <= mux_q(3);
|
||
-- when others =>
|
||
-- null;
|
||
-- end case;
|
||
-- end if;
|
||
-- end if;
|
||
-- end process;
|
||
--
|
||
-- -- MUX write
|
||
-- process(sysclk)
|
||
-- begin
|
||
-- if rising_edge(sysclk) then
|
||
-- docking_ena <= '0';
|
||
-- if mux_clk_reg = '1' then
|
||
-- case mux_reg is
|
||
-- when X"7" =>
|
||
-- mux_d_reg <= "1111";
|
||
-- if docking_station = '1' then
|
||
-- mux_d_reg <= "1" & docking_irq & "11";
|
||
-- end if;
|
||
-- mux_reg <= X"6";
|
||
-- when X"6" =>
|
||
-- mux_d_reg <= "1111";
|
||
-- mux_reg <= X"8";
|
||
-- when X"8" =>
|
||
-- mux_d_reg <= "1111";
|
||
-- mux_reg <= X"A";
|
||
-- when X"A" =>
|
||
-- mux_d_reg <= "10" & led_green & led_red;
|
||
-- mux_reg <= X"B";
|
||
-- when X"B" =>
|
||
-- mux_d_reg <= "1"&spi_cs_n&spi_mosi&spi_clk;
|
||
-- mux_reg <= X"C";
|
||
-- when X"C" =>
|
||
-- --mux_d_reg <= iec_reg;
|
||
-- mux_d_reg <= "1111";
|
||
-- mux_reg <= X"D";
|
||
-- docking_ena <= '1';
|
||
-- when X"D" =>
|
||
-- --mux_d_reg(0) <= ps2_keyboard_dat_out;
|
||
-- --mux_d_reg(1) <= ps2_keyboard_clk_out;
|
||
-- --mux_d_reg(2) <= ps2_mouse_dat_out;
|
||
-- --mux_d_reg(3) <= ps2_mouse_clk_out;
|
||
-- mux_d_reg <= "1111";
|
||
-- mux_reg <= X"E";
|
||
-- when X"E" =>
|
||
-- mux_d_reg <= "1111";
|
||
-- mux_reg <= X"7";
|
||
-- when others =>
|
||
-- mux_reg <= X"B";
|
||
-- mux_d_reg <= "10" & led_green & led_red;
|
||
-- end case;
|
||
-- end if;
|
||
-- end if;
|
||
-- end process;
|
||
--
|
||
-- mux_clk <= mux_clk_reg;
|
||
-- mux_d <= mux_d_reg;
|
||
-- mux <= mux_reg;
|
||
|
||
-- -----------------------------------------------------------------------
|
||
-- LEDs
|
||
-- -----------------------------------------------------------------------
|
||
-- myGreenLed : entity work.chameleon_led
|
||
-- port map (
|
||
-- clk => sysclk,
|
||
-- clk_1khz => ena_1khz,
|
||
-- led_on => '0',
|
||
-- led_blink => '1',
|
||
-- led => led_red,
|
||
-- led_1hz => led_green
|
||
-- );
|
||
--
|
||
--
|
||
-- -----------------------------------------------------------------------
|
||
-- SDRAM
|
||
-- -----------------------------------------------------------------------
|
||
sdram_adaptor : entity work.sdram_statemachine
|
||
... | ... | |
|
||
-- external control
|
||
-- switches etc. sector DMA blah blah.
|
||
ZPU_IN1 => X"00000"&FKEYS,
|
||
ZPU_IN1 => X"00000"&(FKEYS or ir_fkeys),
|
||
ZPU_IN2 => X"00000000",
|
||
ZPU_IN3 => X"00000000",
|
||
ZPU_IN4 => X"00000000",
|
||
... | ... | |
);
|
||
|
||
pause_atari <= zpu_out1(0);
|
||
reset_atari <= zpu_out1(1);
|
||
reset_atari <= zpu_out1(1) or not(chameleon_reset_n);
|
||
speed_6502 <= zpu_out1(7 downto 2);
|
||
ram_select <= zpu_out1(10 downto 8);
|
||
rom_select <= zpu_out1(16 downto 11);
|
||
... | ... | |
|
||
colour_enable => half_scandouble_enable_reg,
|
||
doubled_enable => '1',
|
||
scanlines_on => scanlines_reg,
|
||
|
||
-- GTIA interface
|
||
colour_in => VIDEO_B,
|
||
... | ... | |
nHSync <= not(VGA_HS);
|
||
nVSync <= not(VGA_VS);
|
||
|
||
select_sync : entity work.synchronizer
|
||
PORT MAP ( CLK => clk, raw => freeze_n, sync=>freeze_n_sync);
|
||
|
||
process(scanlines_reg, freeze_n_sync, freeze_n_reg)
|
||
begin
|
||
scanlines_next <= scanlines_reg;
|
||
if (freeze_n_reg = '1' and freeze_n_sync = '0')then
|
||
scanlines_next <= not(scanlines_reg);
|
||
end if;
|
||
end process;
|
||
|
||
process(clk,reset_n)
|
||
begin
|
||
if (reset_n='0') then
|
||
scanlines_reg <= '0';
|
||
freeze_n_reg <= '1';
|
||
elsif (clk'event and clk = '1') then
|
||
scanlines_reg <= scanlines_next;
|
||
freeze_n_reg <= freeze_n_sync;
|
||
end if;
|
||
end process;
|
||
|
||
end vhdl;
|
chameleon/chameleon_c64_joykeyb.vhd | ||
---|---|---|
-- -----------------------------------------------------------------------
|
||
--
|
||
-- Turbo Chameleon
|
||
--
|
||
-- Multi purpose FPGA expansion for the Commodore 64 computer
|
||
--
|
||
-- -----------------------------------------------------------------------
|
||
-- Copyright 2005-2013 by Peter Wendrich (pwsoft@syntiac.com)
|
||
-- http://www.syntiac.com
|
||
--
|
||
-- This source file is free software: you can redistribute it and/or modify
|
||
-- it under the terms of the GNU Lesser General Public License as published
|
||
-- by the Free Software Foundation, either version 3 of the License, or
|
||
-- (at your option) any later version.
|
||
--
|
||
-- This source file is distributed in the hope that it will be useful,
|
||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
-- GNU General Public License for more details.
|
||
--
|
||
-- You should have received a copy of the GNU General Public License
|
||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
--
|
||
-- -----------------------------------------------------------------------
|
||
--
|
||
-- Keyboard/joystick readout in cartridge mode
|
||
--
|
||
-- -----------------------------------------------------------------------
|
||
-- clk - system clock
|
||
-- ena_1mhz - Enable must be '1' one clk cycle each 1 Mhz.
|
||
--
|
||
-- joystick* - Joystick outputs (fire1, right, left, down, up) low active
|
||
-- keys - State of the keyboard (low is pressed)
|
||
-- -----------------------------------------------------------------------
|
||
|
||
library IEEE;
|
||
use IEEE.STD_LOGIC_1164.ALL;
|
||
use IEEE.numeric_std.all;
|
||
|
||
-- -----------------------------------------------------------------------
|
||
|
||
entity chameleon_c64_joykeyb is
|
||
generic (
|
||
enable_4player : boolean
|
||
);
|
||
port (
|
||
clk : in std_logic;
|
||
ena_1mhz : in std_logic;
|
||
no_clock : in std_logic;
|
||
reset : in std_logic;
|
||
|
||
-- To C64 cartridge logic
|
||
ba : in std_logic;
|
||
req : out std_logic;
|
||
ack : in std_logic;
|
||
we : out std_logic;
|
||
a : out unsigned(15 downto 0);
|
||
d : in unsigned(7 downto 0);
|
||
q : out unsigned(7 downto 0);
|
||
|
||
joystick1 : out unsigned(4 downto 0);
|
||
joystick2 : out unsigned(4 downto 0);
|
||
joystick3 : out unsigned(4 downto 0);
|
||
joystick4 : out unsigned(4 downto 0);
|
||
-- 0 = col0, row0
|
||
-- 1 = col1, row0
|
||
-- 8 = col0, row1
|
||
-- 63 = col7, row7
|
||
keys : out unsigned(63 downto 0)
|
||
);
|
||
end entity;
|
||
|
||
-- -----------------------------------------------------------------------
|
||
|
||
architecture rtl of chameleon_c64_joykeyb is
|
||
type state_t is (
|
||
INIT_RESET, INIT_DISABLE_VIC, INIT_DISABLE_MOB,
|
||
INIT_CIA1_A, INIT_CIA1_B, INIT_CIA2_B, --INIT_CIA2_A, ,
|
||
SET_COL, READ_ROW, STORE_ROW, SET_NOCOL,
|
||
READ_JOY1, STORE_JOY1, STORE_JOY2,
|
||
READ_JOY34, STORE_JOY34);
|
||
signal state : state_t := INIT_RESET;
|
||
signal req_reg : std_logic := '0';
|
||
signal joy34_flag : std_logic := '0';
|
||
signal cnt : unsigned(3 downto 0) := (others => '0');
|
||
signal col : integer range 0 to 7 := 0;
|
||
signal keys_reg : unsigned(63 downto 0) := (others => '1');
|
||
begin
|
||
keys <= keys_reg;
|
||
req <= req_reg;
|
||
|
||
process(clk)
|
||
begin
|
||
if rising_edge(clk) then
|
||
if ena_1mhz = '1' then
|
||
cnt <= cnt - 1;
|
||
if cnt = 0 then
|
||
cnt <= (others => '0');
|
||
end if;
|
||
end if;
|
||
if (req_reg = ack) and (ba = '1') and (cnt = 0) then
|
||
we <= '-';
|
||
a <= (others => '-');
|
||
q <= (others => '-');
|
||
case state is
|
||
when INIT_RESET =>
|
||
if (reset = '0') and (ba = '1') then
|
||
state <= INIT_DISABLE_VIC;
|
||
end if;
|
||
when INIT_DISABLE_VIC =>
|
||
-- Turn off VIC-II raster DMA, so we don't have to deal with BA.
|
||
we <= '1';
|
||
a <= X"D011";
|
||
q <= X"00";
|
||
req_reg <= not req_reg;
|
||
state <= INIT_DISABLE_MOB;
|
||
when INIT_DISABLE_MOB =>
|
||
-- Turn off VIC-II sprite DMA, so we don't have to deal with BA.
|
||
we <= '1';
|
||
a <= X"D015";
|
||
q <= X"00";
|
||
req_reg <= not req_reg;
|
||
state <= INIT_CIA1_A;
|
||
when INIT_CIA1_A =>
|
||
-- Set keyboard columns port (joy2) to output
|
||
we <= '1';
|
||
a <= X"DC02";
|
||
q <= X"FF";
|
||
req_reg <= not req_reg;
|
||
state <= INIT_CIA1_B;
|
||
when INIT_CIA1_B =>
|
||
-- Set keyboard rows port (joy1) to input
|
||
we <= '1';
|
||
a <= X"DC03";
|
||
q <= X"00";
|
||
req_reg <= not req_reg;
|
||
state <= SET_COL;
|
||
if enable_4player then
|
||
state <= INIT_CIA2_B;
|
||
end if;
|
||
when INIT_CIA2_B =>
|
||
-- Set CIA2 port B for 4 player adapter
|
||
-- Bit7 output and others input.
|
||
we <= '1';
|
||
a <= X"DD03";
|
||
q <= X"80";
|
||
req_reg <= not req_reg;
|
||
state <= SET_COL;
|
||
when SET_COL =>
|
||
we <= '1';
|
||
a <= X"DC00";
|
||
q <= to_unsigned(255 - 2**col, 8);
|
||
req_reg <= not req_reg;
|
||
cnt <= (others => '1');
|
||
state <= READ_ROW;
|
||
when READ_ROW =>
|
||
we <= '0';
|
||
a <= X"DC01";
|
||
req_reg <= not req_reg;
|
||
state <= STORE_ROW;
|
||
when STORE_ROW =>
|
||
keys_reg(0 + col) <= d(0);
|
||
keys_reg(8 + col) <= d(1);
|
||
keys_reg(16 + col) <= d(2);
|
||
keys_reg(24 + col) <= d(3);
|
||
keys_reg(32 + col) <= d(4);
|
||
keys_reg(40 + col) <= d(5);
|
||
keys_reg(48 + col) <= d(6);
|
||
keys_reg(56 + col) <= d(7);
|
||
if col /= 7 then
|
||
col <= col + 1;
|
||
state <= SET_COL;
|
||
else
|
||
col <= 0;
|
||
state <= SET_NOCOL;
|
||
end if;
|
||
when SET_NOCOL =>
|
||
we <= '1';
|
||
a <= X"DC00";
|
||
q <= X"FF";
|
||
req_reg <= not req_reg;
|
||
cnt <= (others => '1');
|
||
state <= READ_JOY1;
|
||
when READ_JOY1 =>
|
||
-- read joystick port 1
|
||
we <= '0';
|
||
a <= X"DC01";
|
||
req_reg <= not req_reg;
|
||
state <= STORE_JOY1;
|
||
when STORE_JOY1 =>
|
||
-- read joystick port 2
|
||
we <= '0';
|
||
a <= X"DC00";
|
||
req_reg <= not req_reg;
|
||
joystick1 <= d(4 downto 0);
|
||
state <= STORE_JOY2;
|
||
when STORE_JOY2 =>
|
||
joystick2 <= d(4 downto 0);
|
||
state <= SET_COL;
|
||
if enable_4player then
|
||
state <= READ_JOY34;
|
||
end if;
|
||
when READ_JOY34 =>
|
||
-- read user port for joystick 3 or 4
|
||
we <= '0';
|
||
a <= X"DD01";
|
||
req_reg <= not req_reg;
|
||
state <= STORE_JOY34;
|
||
when STORE_JOY34 =>
|
||
joystick3(4) <= d(5);
|
||
joystick4(4) <= d(4);
|
||
if joy34_flag = '0' then
|
||
joystick4(3 downto 0) <= d(3 downto 0);
|
||
else
|
||
joystick3(3 downto 0) <= d(3 downto 0);
|
||
end if;
|
||
-- select the other joystick (3 or 4) on the userport
|
||
we <= '1';
|
||
a <= X"DD01";
|
||
q <= joy34_flag & "0000000";
|
||
joy34_flag <= not joy34_flag;
|
||
req_reg <= not req_reg;
|
||
state <= SET_COL;
|
||
end case;
|
||
end if;
|
||
if reset = '1' then
|
||
state <= INIT_RESET;
|
||
end if;
|
||
if no_clock = '1' then
|
||
joystick1 <= (others => '1');
|
||
joystick2 <= (others => '1');
|
||
joystick3 <= (others => '1');
|
||
joystick4 <= (others => '1');
|
||
keys_reg <= (others => '1');
|
||
end if;
|
||
if not enable_4player then
|
||
joystick3 <= (others => '1');
|
||
joystick4 <= (others => '1');
|
||
end if;
|
||
end if;
|
||
end process;
|
||
end architecture;
|
||
|
||
|
chameleon/chameleon_cdtv_remote.vhd | ||
---|---|---|
-- -----------------------------------------------------------------------
|
||
--
|
||
-- Turbo Chameleon
|
||
--
|
||
-- Multi purpose FPGA expansion for the Commodore 64 computer
|
||
--
|
||
-- -----------------------------------------------------------------------
|
||
-- Copyright 2005-2011 by Peter Wendrich (pwsoft@syntiac.com)
|
||
-- http://www.syntiac.com/chameleon.html
|
||
--
|
||
-- This source file is free software: you can redistribute it and/or modify
|
||
-- it under the terms of the GNU Lesser General Public License as published
|
||
-- by the Free Software Foundation, either version 3 of the License, or
|
||
-- (at your option) any later version.
|
||
--
|
||
-- This source file is distributed in the hope that it will be useful,
|
||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
-- GNU General Public License for more details.
|
||
--
|
||
-- You should have received a copy of the GNU General Public License
|
||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
--
|
||
-- -----------------------------------------------------------------------
|
||
--
|
||
-- CDTV IR remote
|
||
--
|
||
-- -----------------------------------------------------------------------
|
||
-- clk - system clock input
|
||
-- ena_1mhz - Enable must be '1' one clk cycle each 1 Mhz.
|
||
-- ir - signal from infra-red detector.
|
||
--
|
||
-- key_1 - high when "1" is pressed on remote
|
||
-- key_2 - high when "2" is pressed on remote
|
||
-- key_3 - high when "3" is pressed on remote
|
||
-- key_4 - high when "4" is pressed on remote
|
||
-- key_5 - high when "5" is pressed on remote
|
||
-- key_6 - high when "6" is pressed on remote
|
||
-- key_7 - high when "7" is pressed on remote
|
||
-- key_8 - high when "8" is pressed on remote
|
||
-- key_9 - high when "9" is pressed on remote
|
||
-- key_0 - high when "0" is pressed on remote
|
||
-- key_escape - high when "ESCAPE" is pressed on remote
|
||
-- key_enter - high when "ENTER" is pressed on remote
|
||
-- key_genlock - high when "GENLOCK" is pressed on remote
|
||
-- key_cdtv - high when "CD/TV" is pressed on remote
|
||
-- key_power - high when "POWER" is pressed on remote
|
||
-- key_rew - high when "REW" is pressed on remote
|
||
-- key_play - high when "PLAY/PAUSE" is pressed on remote
|
||
-- key_ff - high when "FF" is pressed on remote
|
||
-- key_stop - high when "STOP" is pressed on remote
|
||
-- key_vol_up - high when "VOL up" is pressed on remote
|
||
-- key_vol_dn - high when "VOL dn" is pressed on remote
|
||
-- joystick_a - first joystick emulation output (bits are '1' when idle).
|
||
-- This output is active when remote is in MOUSE mode.
|
||
-- joystick_b - second joystick emulation output (bits are '1' when idle).
|
||
-- This output is active when remote is in JOY mode.
|
||
-- debug_code - Current ir code active
|
||
-- -----------------------------------------------------------------------
|
||
|
||
library IEEE;
|
||
use IEEE.STD_LOGIC_1164.ALL;
|
||
use IEEE.numeric_std.all;
|
||
|
||
-- -----------------------------------------------------------------------
|
||
|
||
entity chameleon_cdtv_remote is
|
||
port (
|
||
clk : in std_logic;
|
||
ena_1mhz : in std_logic;
|
||
ir : in std_logic := '1';
|
||
|
||
trigger : out std_logic;
|
||
|
||
key_1 : out std_logic;
|
||
key_2 : out std_logic;
|
||
key_3 : out std_logic;
|
||
key_4 : out std_logic;
|
||
key_5 : out std_logic;
|
||
key_6 : out std_logic;
|
||
key_7 : out std_logic;
|
||
key_8 : out std_logic;
|
||
key_9 : out std_logic;
|
||
key_0 : out std_logic;
|
||
key_escape : out std_logic;
|
||
key_enter : out std_logic;
|
||
key_genlock : out std_logic;
|
||
key_cdtv : out std_logic;
|
||
key_power : out std_logic;
|
||
key_rew : out std_logic;
|
||
key_play : out std_logic;
|
||
key_ff : out std_logic;
|
||
key_stop : out std_logic;
|
||
key_vol_up : out std_logic;
|
||
key_vol_dn : out std_logic;
|
||
joystick_a : out unsigned(5 downto 0);
|
||
joystick_b : out unsigned(5 downto 0);
|
||
|
||
debug_code : out unsigned(11 downto 0)
|
||
);
|
||
end entity;
|
||
|
||
-- -----------------------------------------------------------------------
|
||
|
||
architecture rtl of chameleon_cdtv_remote is
|
||
constant long_timeout : integer := 110000; -- 110 msec, this timeout is used while receiving a code (timeout is extended)
|
||
constant short_timeout : integer := 75000; -- 75 msec, this timeout is used while waiting
|
||
type state_t is (
|
||
STATE_IDLE, -- Nothing received
|
||
STATE_END_CODE, -- Code received, reseting timeouts
|
||
STATE_WAIT_REPEAT, -- Waiting for new code or key-held code (for 75 ms)
|
||
STATE_START, -- Start of new code
|
||
STATE_LOW, -- receive ir signal is low
|
||
STATE_HIGH -- receive ir signal is high
|
||
);
|
||
signal state : state_t := STATE_IDLE;
|
||
|
||
signal pre_trigger : std_logic := '0'; -- trigger out 1 clock later to sync with decoding logic
|
||
signal timer : integer range 0 to long_timeout := 0;
|
||
signal bitlength : integer range 0 to 16000 := 0;
|
||
signal bitcount : integer range 0 to 24 := 0;
|
||
signal shiftreg : unsigned(23 downto 0) := (others => '0');
|
||
signal current_code : unsigned(11 downto 0) := (others => '1');
|
||
begin
|
||
debug_code <= current_code;
|
||
|
||
process(clk)
|
||
begin
|
||
if rising_edge(clk) then
|
||
pre_trigger <= '0';
|
||
-- State machine
|
||
case state is
|
||
when STATE_IDLE =>
|
||
if (ir = '1') and (bitlength > 8500) then
|
||
state <= STATE_START;
|
||
end if;
|
||
bitcount <= 0;
|
||
when STATE_END_CODE =>
|
||
-- Transient state to reset timer.
|
||
-- Wait for next repeat or new code until timeout.
|
||
state <= STATE_WAIT_REPEAT;
|
||
bitcount <= 0;
|
||
when STATE_WAIT_REPEAT =>
|
||
if (ir = '1') and (bitlength > 8500) then
|
||
state <= STATE_START;
|
||
end if;
|
||
bitcount <= 0;
|
||
when STATE_START =>
|
||
if (ir = '0') and (bitlength > 1500) and (bitlength < 3000) then
|
||
-- It is a key-held code. No further processing.
|
||
state <= STATE_END_CODE;
|
||
end if;
|
||
if (ir = '0') and (bitlength >= 3000) then
|
||
state <= STATE_LOW;
|
||
end if;
|
||
bitcount <= 0;
|
||
when STATE_LOW =>
|
||
if ir = '1' then
|
||
state <= STATE_HIGH;
|
||
end if;
|
||
if bitcount = 24 then
|
||
state <= STATE_END_CODE;
|
||
if shiftreg(23 downto 12) = (not shiftreg(11 downto 0)) then
|
||
-- Valid code
|
||
current_code <= shiftreg(23 downto 12);
|
||
pre_trigger <= '1';
|
||
end if;
|
||
end if;
|
||
when STATE_HIGH =>
|
||
if ir = '0' then
|
||
state <= STATE_LOW;
|
||
bitcount <= bitcount + 1;
|
||
if bitlength > 800 then
|
||
-- Long bit (1100)
|
||
shiftreg <= shiftreg(shiftreg'high-1 downto shiftreg'low) & '1';
|
||
else
|
||
-- short bit (420)
|
||
shiftreg <= shiftreg(shiftreg'high-1 downto shiftreg'low) & '0';
|
||
end if;
|
||
end if;
|
||
end case;
|
||
|
||
-- Determine bit-length
|
||
if (ir = '1' and ((state = STATE_IDLE) or (state = STATE_WAIT_REPEAT) or (state = STATE_LOW)))
|
||
or (ir = '0' and ((state = STATE_START) or (state = STATE_HIGH))) then
|
||
bitlength <= 0;
|
||
elsif ena_1mhz = '1' then
|
||
bitlength <= bitlength + 1;
|
||
end if;
|
||
|
||
-- Process timeout
|
||
if (state = STATE_IDLE) or (state = STATE_END_CODE) then
|
||
timer <= 0;
|
||
elsif timer = long_timeout then
|
||
-- Timeout occured, reset statemachine
|
||
state <= STATE_IDLE;
|
||
bitlength <= 0;
|
||
current_code <= (others => '1');
|
||
elsif (timer >= short_timeout) and (state = STATE_WAIT_REPEAT) then
|
||
-- Timeout occured, reset statemachine
|
||
state <= STATE_IDLE;
|
||
bitlength <= 0;
|
||
current_code <= (others => '1');
|
||
elsif ena_1mhz = '1' then
|
||
timer <= timer + 1;
|
||
end if;
|
||
end if;
|
||
end process;
|
||
|
||
decode_ir_code: process(clk)
|
||
begin
|
||
if rising_edge(clk) then
|
||
trigger <= pre_trigger;
|
||
key_1 <= '0';
|
||
key_2 <= '0';
|
||
key_3 <= '0';
|
||
key_4 <= '0';
|
||
key_5 <= '0';
|
||
key_6 <= '0';
|
||
key_7 <= '0';
|
||
key_8 <= '0';
|
||
key_9 <= '0';
|
||
key_0 <= '0';
|
||
key_escape <= '0';
|
||
key_enter <= '0';
|
||
key_genlock <= '0';
|
||
key_cdtv <= '0';
|
||
key_power <= '0';
|
||
key_rew <= '0';
|
||
key_play <= '0';
|
||
key_ff <= '0';
|
||
key_stop <= '0';
|
||
key_vol_up <= '0';
|
||
key_vol_dn <= '0';
|
||
joystick_a <= (others => '1');
|
||
joystick_b <= (others => '1');
|
||
|
||
case current_code(5 downto 0) is
|
||
when "000001" => key_1 <= '1';
|
||
when "100001" => key_2 <= '1';
|
||
when "010001" => key_3 <= '1';
|
||
when "001001" => key_4 <= '1';
|
||
when "101001" => key_5 <= '1';
|
||
when "011001" => key_6 <= '1';
|
||
when "000101" => key_7 <= '1';
|
||
when "100101" => key_8 <= '1';
|
||
when "010101" => key_9 <= '1';
|
||
when "111001" => key_0 <= '1';
|
||
when "110001" => key_escape <= '1';
|
||
when "110101" => key_enter <= '1';
|
||
when "100010" => key_genlock <= '1';
|
||
when "000010" => key_cdtv <= '1';
|
||
when "010010" => key_power <= '1';
|
||
when "110010" => key_rew <= '1';
|
||
when "001010" => key_play <= '1';
|
||
when "011010" => key_ff <= '1';
|
||
when "101010" => key_stop <= '1';
|
||
when "000110" => key_vol_up <= '1';
|
||
when "111010" => key_vol_dn <= '1';
|
||
when others =>
|
||
null;
|
||
end case;
|
||
|
||
if (current_code(11) = '0') and (current_code(1 downto 0) = "00") then
|
||
joystick_a <= not (current_code(6) & current_code(7) & current_code(2) & current_code(3) & current_code(4) & current_code(5));
|
||
end if;
|
||
if (current_code(11) = '1') and (current_code(1 downto 0) = "00") then
|
||
joystick_b <= not (current_code(6) & current_code(7) & current_code(2) & current_code(3) & current_code(4) & current_code(5));
|
||
end if;
|
||
end if;
|
||
end process;
|
||
|
||
end architecture;
|
||
|
||
|
||
|
||
|
||
|
chameleon/chameleon_docking_station.vhd | ||
---|---|---|
-- Multi purpose FPGA expansion for the Commodore 64 computer
|
||
--
|
||
-- -----------------------------------------------------------------------
|
||
-- Copyright 2005-2011 by Peter Wendrich (pwsoft@syntiac.com)
|
||
-- Copyright 2005-2012 by Peter Wendrich (pwsoft@syntiac.com)
|
||
-- All Rights Reserved.
|
||
--
|
||
-- Allowed to be used in your own projects that are targeted for the
|
||
-- Turbo Chameleon 64 cartridge.
|
||
--
|
||
-- http://www.syntiac.com/chameleon.html
|
||
-- -----------------------------------------------------------------------
|
||
--
|
||
-- Chameleon docking station
|
||
--
|
||
-- -----------------------------------------------------------------------
|
||
-- clk - system clock
|
||
-- enable - must be cycle high to advance statemachine (sync with MUX)
|
||
-- ena_1mhz - must be one cycle high each micro-second. Used for timers.
|
||
|
||
-- clk - system clock
|
||
-- docking_station - must be high when docking-station is available.
|
||
-- This can be determined by the state of the phi2 pin.
|
||
-- dotclock_n - Connect to the dotclock_n pin.
|
||
-- io_ef_n - Connect to the io_ef_n pin.
|
||
-- rom_hl_n - Connect to the rom_hl_n pin.
|
||
-- irq_q - IRQ pin output (open drain output, 0 is drive low, 1 is input)
|
||
-- joystick* - Joystick outputs (fire2, fire1, right, left, down, up) low active
|
||
-- keys - State of the keyboard (low is pressed)
|
||
-- restore_key_n - State of the restore key (low is pressed)
|
||
--
|
||
-- amiga_power_led - Control input for the POWER LED on the Amiga keyboard.
|
||
-- amiga_drive_led - Control input for the DRIVE LED on the Amiga keyboard.
|
||
-- amiga_reset_n - Low when the Amiga keyboard does a reset.
|
||
-- amiga_trigger - One clock high when the Amiga keyboard has send a new scancode.
|
||
-- amiga_scancode - Value of the last received scancode from the Amiga keyboard.
|
||
-- -----------------------------------------------------------------------
|
||
|
||
library IEEE;
|
||
... | ... | |
entity chameleon_docking_station is
|
||
port (
|
||
clk : in std_logic;
|
||
enable : in std_logic;
|
||
ena_1mhz : in std_logic;
|
||
|
||
docking_station : in std_logic;
|
||
|
||
dotclock_n : in std_logic;
|
||
io_ef_n : in std_logic;
|
||
rom_lh_n : in std_logic;
|
||
irq_d : in std_logic;
|
||
irq_q : out std_logic;
|
||
|
||
joystick1 : out unsigned(5 downto 0);
|
||
... | ... | |
|
||
architecture rtl of chameleon_docking_station is
|
||
constant shift_reg_bits : integer := 13*8;
|
||
-- We put the out-of-sync detection just before the actual sync-pulse.
|
||
-- Gives it the biggest chance of catching a sync-problem.
|
||
constant out_of_sync_pos : integer := 102;
|
||
signal shift_reg : unsigned(shift_reg_bits-1 downto 0);
|
||
signal bit_cnt : unsigned(7 downto 0) := (others => '0');
|
||
signal once : std_logic := '0';
|
||
... | ... | |
shift_reg <= (not rom_lh_n_reg) & shift_reg(shift_reg'high downto 1);
|
||
bit_cnt <= bit_cnt + 1;
|
||
end if;
|
||
if (io_ef_n_reg = '1') and (bit_cnt = out_of_sync_pos) then
|
||
-- Out of sync detection.
|
||
-- Wait for the MCU on the docking-station to release io_ef
|
||
-- Then we can continue and syncronise on the next io_ef pulse that comes.
|
||
bit_cnt <= to_unsigned(out_of_sync_pos, bit_cnt'length);
|
||
end if;
|
||
if (io_ef_n_reg = '1') and (bit_cnt >= shift_reg_bits) then
|
||
-- Word trigger. Signals start of serial bit-stream.
|
||
bit_cnt <= (others => '0');
|
chameleon/chameleon_io.vhd | ||
---|---|---|
-- -----------------------------------------------------------------------
|
||
--
|
||
-- Turbo Chameleon
|
||
--
|
||
-- Multi purpose FPGA expansion for the Commodore 64 computer
|
||
--
|
||
-- -----------------------------------------------------------------------
|
||
-- Copyright 2005-2013 by Peter Wendrich (pwsoft@syntiac.com)
|
||
-- http://www.syntiac.com
|
||
--
|
||
-- This source file is free software: you can redistribute it and/or modify
|
||
-- it under the terms of the GNU Lesser General Public License as published
|
||
-- by the Free Software Foundation, either version 3 of the License, or
|
||
-- (at your option) any later version.
|
||
--
|
||
-- This source file is distributed in the hope that it will be useful,
|
||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
-- GNU General Public License for more details.
|
||
--
|
||
-- You should have received a copy of the GNU General Public License
|
||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
--
|
||
-- -----------------------------------------------------------------------
|
||
--
|
||
-- For better understanding what this entity does in detail, please refer
|
||
-- to the Chameleon core-developers manual. It has documentation about
|
||
-- the CPLD MUX, signal timing, docking-station protocol and the cartridge port access.
|
||
--
|
||
-- Chameleon timing and I/O driver. Handles all the timing and multiplexing
|
||
-- details of the cartridge port and the CPLD mux.
|
||
-- - Detects the type of mode the chameleon is running in.
|
||
-- - Multiplexes the PS/2 keyboard and mouse signals.
|
||
-- - Gives access to joysticks and keyboard on a C64 in cartridge mode.
|
||
-- - Gives access to joysticks and keyboard on a docking-station
|
||
-- - Gives access to MMC card and serial-flash through the CPLD MUX.
|
||
-- - Drives the two LEDs on the Chameleon (or an optional Amiga keyboard).
|
||
-- - Can optionally give access to the IEC bus
|
||
-- - Can optionally give access to other C64 resources like the SID.
|
||
--
|
||
-- -----------------------------------------------------------------------
|
||
-- enable_docking_station - Enable support for the docking-station.
|
||
-- enable_c64_joykeyb - Automatically read joystick and keyboard on the C64 bus.
|
||
-- Take note this disables the C64 bus access feature on this entity.
|
||
-- enable_c64_4player - Enable 4player support on the user-port of the C64.
|
||
-- The flag enable_c64_joykeyb must be true for this to work.
|
||
-- enable_raw_spi - SPI controller inside this entity is switched off.
|
||
-- And the actual SPI lines are exposed. The maximum speed is limited
|
||
-- as the signals are time multiplexed. The maximum spi speed usable
|
||
-- is around 1/12 of clk. (One line transition each 6 clk cycles)
|
||
-- enable_iec_access - Enables support for the IEC bus on the break-out cable.
|
||
-- Set this to 'false' when the IEC bus is not used to save some logic.
|
||
-- -----------------------------------------------------------------------
|
||
-- clk - system clock
|
||
-- ena_1mhz - Enable must be '1' one clk cycle each 1 Mhz.
|
||
-- reset - Perform a reset of the subsystems
|
||
-- reset_ext - Hardware reset from the cartridge-port (eg. a C64 reset button)
|
||
--
|
||
-- no_clock - '0' when connected to C64 cartridge port.
|
||
-- '1' when in standalone mode or docking-station connected.
|
||
-- docking_station - '0' standalone/cartrdige mode
|
||
-- '1' when docking-station is connected.
|
||
--
|
||
-- to_usb_rx
|
||
--
|
||
-- The following timing signals are only useful when writing C64 related designs.
|
||
-- They can be left unconnected in all other FPGA designs.
|
||
-- phi_mode - Selects timing in standalone mode ('0' is PAL, '1' is NTSC).
|
||
-- phi_out - Regenerated or synthesized phi2 clock.
|
||
-- phi_cnt - Counting the system-clock cycles within one phi2 cycle.
|
||
-- phi_end_0 - The half of the cycle where phi_out is low ends.
|
||
-- phi_end_1 - The half of the cycle where phi_out is high ends.
|
||
-- phi_post_1 - Triggers when phi changes
|
||
-- phi_post_2 - Triggers one cycle after phi changed
|
||
-- phi_post_3 - Triggers two cycles phi changed
|
||
-- phi_post_4 - Triggers three cycles phi changed
|
||
--
|
||
-- c64_irq_n - Status of the C64 IRQ line (cartridge mode only)
|
||
-- c64_nmi_n - Status of the C64 NMI line
|
||
-- c64_ba - status of the C64 BA line
|
||
--
|
||
-- The following signals should be synchronised to the phi_out signal
|
||
-- c64_vic - When set data on c64_d is send to the VIC-II chip.
|
||
-- c64_cs - When set it accesses the C64 databus (uses Ultimax mode, no memory is mapped)
|
||
-- c64_cs_roms - Enables access to the C64 Kernal and Basic ROMs (disables Ultimax mode)
|
||
-- c64_clockport - When set it accesses the clockport.
|
||
-- c64_we - Access is a write when set (note polarity is the inverse of R/W on cartridge port)
|
||
-- c64_a - C64 address bus
|
||
-- c64_d - Data to the C64
|
||
-- c64_q - Data from the C64 (only valid when phi_end_1 is set)
|
||
--
|
||
-- spi_speed - 0 SPI bus runs at slow speed (250 Kbit), SPI bus runs at fast speed (8 Mbit)
|
||
-- spi_req - Toggle to request SPI transfer.
|
||
-- spi_ack - Is made equal to spi_req after transfer is complete.
|
||
-- spi_d - Data input into SPI controller.
|
||
-- spi_q - Data output from SPI controller.
|
||
--
|
||
-- led_green - Control the green LED (0 off, 1 on). Also power LED on Amiga keyboard.
|
||
-- led_red - Control the red LED (0 off, 1 on). Also drive LED on Amiga keyboard.
|
||
-- ir - ir signal. Input for the chameleon_cdtv_remote entity.
|
||
--
|
||
-- ps2_* - PS2 signals for both keyboard and mouse.
|
||
-- button_reset_n - Status of blue reset button (right button) on the Chameleon. Low active.
|
||
-- joystick* - Joystick ports of both docking-station and C64. Bits: fire2, fire1, right, left, down, up
|
||
-- The C64 only supports one button fire1. The signals are low active
|
||
-- keys - C64 keyboard. One bit for each key on the keyboard. Low active.
|
||
-- restore_key_n - Trigger for restore key on docking-station.
|
||
-- On a C64 the restore key is wired to the NMI line instead.
|
||
-- iec_* - IEC signals. Only valid when enable_iec_access is set to true.
|
||
-- -----------------------------------------------------------------------
|
||
|
||
library IEEE;
|
||
use IEEE.STD_LOGIC_1164.ALL;
|
||
use IEEE.numeric_std.all;
|
||
|
||
-- -----------------------------------------------------------------------
|
||
|
||
entity chameleon_io is
|
||
generic (
|
||
enable_docking_station : boolean := true;
|
||
enable_c64_joykeyb : boolean := false;
|
||
enable_c64_4player : boolean := false;
|
||
enable_raw_spi : boolean := false;
|
||
enable_iec_access : boolean := false
|
||
);
|
||
port (
|
||
-- Clocks
|
||
clk : in std_logic;
|
||
clk_mux : in std_logic;
|
||
ena_1mhz : in std_logic;
|
||
reset : in std_logic;
|
||
reset_ext : out std_logic;
|
||
|
||
-- Config
|
||
no_clock : out std_logic;
|
||
docking_station : out std_logic;
|
||
|
||
-- Chameleon FPGA pins
|
||
-- C64 Clocks
|
||
phi2_n : in std_logic;
|
||
dotclock_n : in std_logic;
|
||
-- C64 cartridge control lines
|
||
io_ef_n : in std_logic;
|
||
rom_lh_n : in std_logic;
|
||
-- SPI bus
|
||
spi_miso : in std_logic;
|
||
-- CPLD multiplexer
|
||
mux_clk : out std_logic;
|
||
mux : out unsigned(3 downto 0);
|
||
mux_d : out unsigned(3 downto 0);
|
||
mux_q : in unsigned(3 downto 0);
|
||
|
||
-- USB microcontroller (To RX of micro)
|
||
to_usb_rx : in std_logic := '1';
|
||
|
||
-- C64 timing (only for C64 related cores)
|
||
phi_mode : in std_logic := '0';
|
||
phi_out : out std_logic;
|
||
phi_cnt : out unsigned(7 downto 0);
|
||
phi_end_0 : out std_logic;
|
||
phi_end_1 : out std_logic;
|
||
phi_post_1 : out std_logic;
|
||
phi_post_2 : out std_logic;
|
||
phi_post_3 : out std_logic;
|
||
phi_post_4 : out std_logic;
|
||
|
||
-- C64 bus
|
||
c64_irq_n : out std_logic;
|
||
c64_nmi_n : out std_logic;
|
||
c64_ba : out std_logic;
|
||
|
||
c64_vic : in std_logic := '0';
|
||
c64_cs : in std_logic := '0';
|
||
c64_cs_roms : in std_logic := '0';
|
||
c64_clockport : in std_logic := '0';
|
||
c64_we : in std_logic := '0';
|
||
c64_a : in unsigned(15 downto 0) := (others => '0');
|
||
c64_d : in unsigned(7 downto 0) := (others => '1');
|
||
c64_q : out unsigned(7 downto 0);
|
||
|
||
-- SPI chip-selects
|
||
mmc_cs_n : in std_logic := '1';
|
||
flash_cs_n : in std_logic := '1';
|
||
rtc_cs : in std_logic := '0';
|
||
|
||
-- SPI controller (enable_raw_spi must be set to false)
|
||
spi_speed : in std_logic := '1';
|
||
spi_req : in std_logic := '0';
|
||
spi_ack : out std_logic;
|
||
spi_d : in unsigned(7 downto 0) := (others => '-');
|
||
spi_q : out unsigned(7 downto 0);
|
||
|
||
-- SPI raw signals (enable_raw_spi must be set to true)
|
||
spi_raw_clk : in std_logic := '1';
|
||
spi_raw_mosi : in std_logic := '1';
|
||
spi_raw_ack : out std_logic; -- Added by AMR
|
||
|
||
-- LEDs
|
||
led_green : in std_logic := '0';
|
||
led_red : in std_logic := '0';
|
||
ir : out std_logic;
|
||
|
||
-- PS/2 Keyboard
|
||
ps2_keyboard_clk_out: in std_logic := '1';
|
||
ps2_keyboard_dat_out: in std_logic := '1';
|
||
ps2_keyboard_clk_in: out std_logic;
|
||
ps2_keyboard_dat_in: out std_logic;
|
||
|
||
-- PS/2 Mouse
|
||
ps2_mouse_clk_out: in std_logic := '1';
|
||
ps2_mouse_dat_out: in std_logic := '1';
|
||
ps2_mouse_clk_in: out std_logic;
|
||
ps2_mouse_dat_in: out std_logic;
|
||
|
||
-- Buttons
|
||
button_reset_n : out std_logic;
|
||
|
||
-- Joysticks
|
||
joystick1 : out unsigned(5 downto 0);
|
||
joystick2 : out unsigned(5 downto 0);
|
||
joystick3 : out unsigned(5 downto 0);
|
||
joystick4 : out unsigned(5 downto 0);
|
||
|
||
-- Keyboards
|
||
-- 0 = col0, row0
|
||
-- 1 = col1, row0
|
||
-- 8 = col0, row1
|
||
-- 63 = col7, row7
|
||
keys : out unsigned(63 downto 0);
|
||
restore_key_n : out std_logic;
|
||
amiga_reset_n : out std_logic;
|
||
amiga_trigger : out std_logic;
|
||
amiga_scancode : out unsigned(7 downto 0);
|
||
|
||
-- IEC bus
|
||
iec_clk_out : in std_logic := '1';
|
||
iec_dat_out : in std_logic := '1';
|
||
iec_atn_out : in std_logic := '1';
|
||
iec_srq_out : in std_logic := '1';
|
||
iec_clk_in : out std_logic;
|
||
iec_dat_in : out std_logic;
|
||
iec_atn_in : out std_logic;
|
||
iec_srq_in : out std_logic
|
||
);
|
||
end entity;
|
||
-- -----------------------------------------------------------------------
|
||
|
||
architecture rtl of chameleon_io is
|
||
-- Clocks
|
||
signal no_clock_loc : std_logic;
|
||
signal phi : std_logic;
|
||
signal end_of_phi_0 : std_logic;
|
||
signal end_of_phi_1 : std_logic;
|
||
|
||
-- State
|
||
signal reset_pending : std_logic := '0';
|
||
signal reset_in : std_logic := '0';
|
||
|
||
-- MUX
|
||
type muxstate_t is (
|
||
-- Reset phase
|
||
MUX_RESET,
|
||
-- MMC
|
||
MUX_MMC0L, MUX_MMC0H, MUX_MMC1L, MUX_MMC1H, MUX_MMC2L, MUX_MMC2H, MUX_MMC3L, MUX_MMC3H,
|
||
MUX_MMC4L, MUX_MMC4H, MUX_MMC5L, MUX_MMC5H, MUX_MMC6L, MUX_MMC6H, MUX_MMC7L, MUX_MMC7H,
|
||
-- IEC
|
||
MUX_IEC1, MUX_IEC2, MUX_IEC3, MUX_IEC4,
|
||
-- PS2
|
||
MUX_PS2,
|
||
-- LED
|
||
MUX_LED,
|
Also available in: Unified diff
Switched to using Peters chameleon_io module. Great, gives c64 joystick and cdtv support!