Index: chameleon/atari800core.qsf
===================================================================
--- chameleon/atari800core.qsf	(revision 125)
+++ chameleon/atari800core.qsf	(revision 126)
@@ -199,6 +199,9 @@
 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"
Index: chameleon/atari800core_chameleon.vhd
===================================================================
--- chameleon/atari800core_chameleon.vhd	(revision 125)
+++ chameleon/atari800core_chameleon.vhd	(revision 126)
@@ -119,19 +119,22 @@
 
 
 -- 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
@@ -145,6 +148,15 @@
 	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;
@@ -204,6 +216,10 @@
 	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';
@@ -301,8 +317,8 @@
 		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,
@@ -311,9 +327,9 @@
 		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,
@@ -396,155 +412,323 @@
 -- -----------------------------------------------------------------------
 -- 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
@@ -646,7 +830,7 @@
 
 		-- 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",
@@ -659,7 +843,7 @@
 	);
 
 	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);
@@ -704,6 +888,7 @@
 
 		colour_enable => half_scandouble_enable_reg,
 		doubled_enable => '1',
+		scanlines_on => scanlines_reg,
 		
 		-- GTIA interface
 		colour_in => VIDEO_B,
@@ -721,4 +906,26 @@
 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;
Index: chameleon/chameleon_c64_joykeyb.vhd
===================================================================
--- chameleon/chameleon_c64_joykeyb.vhd	(nonexistent)
+++ chameleon/chameleon_c64_joykeyb.vhd	(revision 126)
@@ -0,0 +1,244 @@
+-- -----------------------------------------------------------------------
+--
+-- 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;
+
+
Index: chameleon/chameleon_cdtv_remote.vhd
===================================================================
--- chameleon/chameleon_cdtv_remote.vhd	(nonexistent)
+++ chameleon/chameleon_cdtv_remote.vhd	(revision 126)
@@ -0,0 +1,278 @@
+-- -----------------------------------------------------------------------
+--
+-- 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;
+
+
+
+
+
Index: chameleon/chameleon_docking_station.vhd
===================================================================
--- chameleon/chameleon_docking_station.vhd	(revision 125)
+++ chameleon/chameleon_docking_station.vhd	(revision 126)
@@ -5,9 +5,12 @@
 -- 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
 -- -----------------------------------------------------------------------
 --
@@ -14,10 +17,22 @@
 -- 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;
@@ -29,15 +44,11 @@
 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);
@@ -64,6 +75,9 @@
 
 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';
@@ -116,6 +130,12 @@
 				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');
Index: chameleon/chameleon_io.vhd
===================================================================
--- chameleon/chameleon_io.vhd	(nonexistent)
+++ chameleon/chameleon_io.vhd	(revision 126)
@@ -0,0 +1,918 @@
+-- -----------------------------------------------------------------------
+--
+-- 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,
+		-- PHI=0
+		MUX_WAIT0,
+		MUX_A3_C, MUX_BUSVIC,
+		MUX_D0VIC, MUX_D1VIC,
+		MUX_NMIIRQ1, MUX_NMIIRQ2,
+		MUX_ULTIMAX,
+		MUX_END0,
+		-- PHI=1
+		MUX_WAIT1,
+		MUX_BUS, MUX_CLKPORT,
+		MUX_A0, MUX_A1, MUX_A2, MUX_A3,
+		MUX_D0WR, MUX_D1WR, MUX_D0WR_1, MUX_D1WR_1, MUX_D0WR_2, MUX_D1WR_2,
+		MUX_D0RD_1, MUX_D1RD_1, MUX_D0RD_2, MUX_D1RD_2
+	);
+	signal mux_state : muxstate_t;
+	signal mux_toggle : std_logic := '0';
+
+	signal mux_c128_timeout : unsigned(7 downto 0) := (others => '1');
+	signal mux_clk_reg : std_logic := '0';
+	signal mux_d_reg : unsigned(mux_d'range) := X"F";
+	signal mux_reg : unsigned(mux'range) := X"F";
+	signal mux_d_mmc : unsigned(1 downto 0) := "11";
+
+-- C64 bus
+	signal c64_reset_reg : std_logic := '0';
+	signal c64_ba_reg : std_logic := '1';
+	signal c64_data_reg : unsigned(7 downto 0) := (others => '1');
+	signal c64_addr : unsigned(15 downto 0) := (others => '0');
+	signal c64_to_io : unsigned(7 downto 0) := (others => '0');
+	
+	signal c64_we_loc : std_logic := '0';
+	signal c64_vic_loc : std_logic := '0';
+	signal c64_cs_loc : std_logic := '0';
+	signal c64_roms_loc : std_logic := '0';
+	signal c64_clockport_loc : std_logic := '0';
+	
+-- C64 joystick/keyboard
+	signal c64_kb_req : std_logic := '0';
+	signal c64_kb_ack : std_logic := '0';
+	signal c64_kb_we : std_logic := '1';
+	signal c64_kb_a : unsigned(15 downto 0) := (others => '0');
+	signal c64_kb_q : unsigned(7 downto 0) := (others => '1');
+	signal c64_joystick1 : unsigned(4 downto 0);
+	signal c64_joystick2 : unsigned(4 downto 0);
+	signal c64_joystick3 : unsigned(4 downto 0);
+	signal c64_joystick4 : unsigned(4 downto 0);
+	signal c64_keys : unsigned(63 downto 0);
+
+-- Docking-station
+	signal docking_station_loc : std_logic;
+	signal docking_irq : std_logic;
+	signal docking_joystick1 : unsigned(5 downto 0);
+	signal docking_joystick2 : unsigned(5 downto 0);
+	signal docking_joystick3 : unsigned(5 downto 0);
+	signal docking_joystick4 : unsigned(5 downto 0);
+	signal docking_keys : unsigned(63 downto 0);
+	signal docking_amiga_reset_n : std_logic;
+	signal docking_amiga_scancode : unsigned(7 downto 0);
+
+-- MMC
+	signal mmc_state : unsigned(5 downto 0) := (others => '0');
+	signal spi_q_reg : unsigned(7 downto 0) := (others => '1');
+	signal spi_run : std_logic := '0';
+	signal spi_sample : std_logic := '0';
+	signal mmc_shift_req : std_logic;
+	signal mmc_shift_ack : std_logic := '0';
+
+-- IEC
+	signal iec_clk_reg : std_logic := '1';
+	signal iec_dat_reg : std_logic := '1';
+	signal iec_atn_reg : std_logic := '1';
+	signal iec_srq_reg : std_logic := '1';
+begin
+	reset_ext <= reset_in;
+	no_clock <= no_clock_loc;
+	docking_station <= docking_station_loc;
+	--
+	phi_out <= phi;
+	phi_end_0 <= end_of_phi_0;
+	phi_end_1 <= end_of_phi_1;
+	--
+	c64_ba <= c64_ba_reg;
+	c64_q <= c64_data_reg;
+	--
+	spi_q <= spi_q_reg;
+	--
+	joystick1 <= docking_joystick1 and ("1" & c64_joystick1);
+	joystick2 <= docking_joystick2 and ("1" & c64_joystick2);
+	joystick3 <= docking_joystick3 and ("1" & c64_joystick3);
+	joystick4 <= docking_joystick4 and ("1" & c64_joystick4);
+	keys <= docking_keys and c64_keys;
+
+-- -----------------------------------------------------------------------
+-- PHI2 clock sync
+-- -----------------------------------------------------------------------
+	phiInstance : entity work.chameleon_phi_clock
+		port map (
+			clk => clk,
+			phi2_n => phi2_n,
+			mode => phi_mode,
+
+			no_clock => no_clock_loc,
+			docking_station => docking_station_loc,
+
+			phiLocal => phi,
+			phiCnt => phi_cnt,
+			phiPreHalf => end_of_phi_0,
+			phiPreEnd => end_of_phi_1,
+			phiPost1 => phi_post_1,
+			phiPost2 => phi_post_2,
+			phiPost3 => phi_post_3,
+			phiPost4 => phi_post_4
+		);
+
+-- -----------------------------------------------------------------------
+-- Docking-station
+-- To enable set enable_docking_station to true.
+-- -----------------------------------------------------------------------
+	genDockingStation : if enable_docking_station generate
+		myDockingStation : entity work.chameleon_docking_station
+			port map (
+				clk => clk,
+				
+				docking_station => docking_station_loc,
+				
+				dotclock_n => dotclock_n,
+				io_ef_n => io_ef_n,
+				rom_lh_n => rom_lh_n,
+				irq_q => docking_irq,
+				
+				joystick1 => docking_joystick1,
+				joystick2 => docking_joystick2,
+				joystick3 => docking_joystick3,
+				joystick4 => docking_joystick4,
+				keys => docking_keys,
+				restore_key_n => restore_key_n,
+				
+				amiga_power_led => led_green,
+				amiga_drive_led => led_red,
+				amiga_reset_n => amiga_reset_n,
+				amiga_trigger => amiga_trigger,
+				amiga_scancode => amiga_scancode
+			);
+	end generate;
+
+	noDockingStation : if not enable_docking_station generate
+		docking_joystick1 <= (others => '1');
+		docking_joystick2 <= (others => '1');
+		docking_joystick3 <= (others => '1');
+		docking_joystick4 <= (others => '1');
+		docking_keys <= (others => '1');
+	end generate;
+
+-- -----------------------------------------------------------------------
+-- C64 keyboard and joystick support
+-- To enable set enable_c64_joykeyb to true.
+-- -----------------------------------------------------------------------
+	genC64JoyKeyb : if enable_c64_joykeyb generate
+		myC64JoyKeyb : entity work.chameleon_c64_joykeyb
+			generic map (
+				enable_4player => enable_c64_4player
+			)
+			port map (
+				clk => clk,
+				ena_1mhz => ena_1mhz,
+				no_clock => no_clock_loc,
+				reset => reset,
+				
+				ba => c64_ba_reg,
+				req => c64_kb_req,
+				ack => c64_kb_ack,
+				we => c64_kb_we,
+				a => c64_kb_a,
+				d => c64_data_reg,
+				q => c64_kb_q,
+				
+				joystick1 => c64_joystick1,
+				joystick2 => c64_joystick2,
+				joystick3 => c64_joystick3,
+				joystick4 => c64_joystick4,
+				keys => c64_keys
+			);
+
+		c64_addr <= c64_kb_a;
+		c64_to_io <= c64_kb_q;
+		c64_vic_loc <= '0';
+		c64_roms_loc <= '0';
+		c64_clockport_loc <= '0';
+		c64_we_loc <= c64_kb_we;
+
+		process(clk)
+		begin
+			if rising_edge(clk) then
+				if end_of_phi_1 = '1' then
+					c64_cs_loc <= '0';
+					if c64_kb_req /= c64_kb_ack then
+						if c64_cs_loc = '1' then
+							c64_kb_ack <= c64_kb_req;
+						else
+							c64_cs_loc <= '1';
+						end if;
+					end if;
+				end if;
+			end if;
+		end process;
+	end generate;
+	
+	noC64JoyKeyb : if not enable_c64_joykeyb generate
+		c64_joystick1 <= (others => '1');
+		c64_joystick2 <= (others => '1');
+		c64_joystick3 <= (others => '1');
+		c64_joystick4 <= (others => '1');
+		c64_keys <= (others => '1');
+		
+		c64_addr <= c64_a;
+		c64_to_io <= c64_d;
+
+		c64_vic_loc <= c64_vic;
+		c64_cs_loc <= c64_cs;
+		c64_roms_loc <= c64_cs_roms;
+		c64_clockport_loc <= c64_clockport;
+		c64_we_loc <= c64_we;
+	end generate;
+
+-- -----------------------------------------------------------------------
+-- MUX CPLD
+-- -----------------------------------------------------------------------
+	-- MUX clock
+	process(clk_mux)
+	begin
+		if rising_edge(clk_mux) then
+			mux_clk_reg <= not mux_clk_reg;
+		end if;
+	end process;
+
+	-- MUX sequence
+	process(clk_mux)
+	begin
+		if rising_edge(clk_mux) then
+			if mux_clk_reg = '1' then
+				mux_toggle <= not mux_toggle;
+				case mux_state is
+				when MUX_RESET   =>
+					if phi = '1' then
+						mux_state <= MUX_WAIT0;
+					end if;
+-- PHI2  0
+				when MUX_WAIT0   =>
+					if phi = '0' then
+						mux_state <= MUX_MMC0L;
+						if mux_c128_timeout /= 0 then
+							mux_c128_timeout <= mux_c128_timeout - 1;
+						end if;
+					end if;
+				when MUX_MMC0L   => mux_state <= MUX_A3_C;
+				when MUX_A3_C    => mux_state <= MUX_ULTIMAX;
+				when MUX_ULTIMAX => mux_state <= MUX_MMC0H;
+				when MUX_MMC0H   => mux_state <= MUX_BUSVIC;
+				when MUX_BUSVIC  => mux_state <= MUX_IEC1;
+				when MUX_IEC1    => mux_state <= MUX_MMC1L;
+				when MUX_MMC1L   => mux_state <= MUX_PS2;
+				when MUX_PS2     => mux_state <= MUX_A2;
+				when MUX_A2      => mux_state <= MUX_MMC1H;
+				when MUX_MMC1H   => mux_state <= MUX_NMIIRQ1;
+				when MUX_NMIIRQ1 => mux_state <= MUX_LED;
+				when MUX_LED     => mux_state <= MUX_MMC2L;
+				when MUX_MMC2L   => mux_state <= MUX_A0;
+				when MUX_A0      => mux_state <= MUX_IEC4;
+				when MUX_IEC4    => mux_state <= MUX_MMC2H;
+				when MUX_MMC2H   => mux_state <= MUX_A1;
+				when MUX_A1      => mux_state <= MUX_D0VIC;
+				when MUX_D0VIC   => mux_state <= MUX_D1VIC;
+				when MUX_D1VIC   => mux_state <= MUX_MMC3L;
+				when MUX_MMC3L   => mux_state <= MUX_IEC3;
+				when MUX_IEC3    => mux_state <= MUX_MMC3H;
+				when MUX_MMC3H   => mux_state <= MUX_END0;
+				when MUX_END0    => mux_state <= MUX_WAIT1;
+-- PHI2  1
+				when MUX_WAIT1 =>
+					if phi = '1' then
+						mux_state <= MUX_MMC4L;
+					end if;
+				when MUX_MMC4L   => mux_state <= MUX_BUS;
+				when MUX_BUS     => mux_state <= MUX_D0WR;
+				when MUX_D0WR    => mux_state <= MUX_D1WR;
+				when MUX_D1WR    => mux_state <= MUX_MMC4H;
+				when MUX_MMC4H   => mux_state <= MUX_A3;
+				when MUX_A3      => mux_state <= MUX_CLKPORT;
+				when MUX_CLKPORT => mux_state <= MUX_MMC5L;
+				when MUX_MMC5L   => mux_state <= MUX_NMIIRQ2;
+				when MUX_NMIIRQ2 => mux_state <= MUX_MMC5H;
+				when MUX_MMC5H   => mux_state <= MUX_D0WR_1;
+				when MUX_D0WR_1  => mux_state <= MUX_D1WR_1;
+				when MUX_D1WR_1  => mux_state <= MUX_MMC6L;
+				when MUX_MMC6L   => mux_state <= MUX_IEC2;
+				when MUX_IEC2    => mux_state <= MUX_MMC6H;
+				--when MUX_LED     => mux_state <= MUX_MMC6H;
+				when MUX_MMC6H   => mux_state <= MUX_D0WR_2;
+				when MUX_D0WR_2  => mux_state <= MUX_D1WR_2;
+				when MUX_D1WR_2  => mux_state <= MUX_MMC7L;
+				when MUX_MMC7L   => mux_state <= MUX_D0RD_1;
+				when MUX_D0RD_1  => mux_state <= MUX_D1RD_1;
+				when MUX_D1RD_1  => mux_state <= MUX_MMC7H;
+				when MUX_MMC7H   => mux_state <= MUX_D0RD_2;
+				when MUX_D0RD_2  => mux_state <= MUX_D1RD_2;
+				when MUX_D1RD_2  => mux_state <= MUX_WAIT0;
+				end case;
+			end if;
+			if reset = '1' then
+				mux_c128_timeout <= (others => '1');
+-- 				system_wait <= '1';
+			end if;
+		end if;
+	end process;
+
+	-- MUX read
+	process(clk_mux)
+	begin
+		if rising_edge(clk_mux) then
+			if mux_clk_reg = '1' then
+				case mux_reg is
+				when X"0" =>
+					c64_data_reg(3 downto 0) <= mux_q;
+				when X"1" =>
+					c64_data_reg(7 downto 4) <= mux_q;
+				when X"6" =>
+					c64_reset_reg <= not mux_q(0);
+					c64_irq_n <= mux_q(2);
+					c64_nmi_n <= mux_q(3);
+					reset_pending <= reset or c64_reset_reg;
+					if reset_pending = '0' then
+						reset_in <= c64_reset_reg;
+					else
+						reset_in <= '0';
+					end if;
+					if no_clock_loc = '1' then
+						c64_irq_n <= '1';
+					end if;
+				when X"7" =>
+					c64_ba_reg <= mux_q(1);
+					if no_clock_loc = '1' then
+						c64_ba_reg <= '1';
+					end if;
+				when X"B" =>
+					button_reset_n <= mux_q(1);
+					ir <= mux_q(3);
+				when X"D" =>
+					iec_dat_reg <= mux_q(0);
+					iec_clk_reg <= mux_q(1);
+					iec_srq_reg <= mux_q(2);
+					iec_atn_reg <= mux_q(3);
+				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;
+				if spi_sample = '1' then
+					spi_q_reg <= spi_q_reg(6 downto 0) & spi_miso;
+				end if;
+			end if;
+			iec_dat_in <= iec_dat_reg;
+			iec_clk_in <= iec_clk_reg;
+			iec_srq_in <= iec_srq_reg;
+			iec_atn_in <= iec_atn_reg;
+		end if;
+	end process;
+
+	-- MUX write
+	process(clk_mux)
+	begin
+		if rising_edge(clk_mux) then
+			spi_raw_ack <= '0';
+			if mux_clk_reg = '1' then
+				spi_sample <= '0';
+				case mux_state is
+--
+-- RESET
+				when MUX_RESET =>
+					mux_d_reg <= (others => '-');
+					mux_reg <= X"F";
+--
+-- MMC
+				when MUX_MMC0L =>
+					-- Remember current state for lowspeed transfer.
+					-- Register is accessed another 15 times in
+					-- system cycle, but should not be updated when running on 250khz speed.
+					mux_d_mmc(0) <= mmc_state(1) or (not mmc_state(5));
+					mux_d_mmc(1) <= spi_d(7 - to_integer(mmc_state(4 downto 2)));
+					-- Update register
+					mux_d_reg(0) <= mmc_state(1) or (not mmc_state(5));
+					mux_d_reg(1) <= spi_d(7 - to_integer(mmc_state(4 downto 2)));
+					mux_d_reg(2) <= mmc_cs_n; 
+					mux_d_reg(3) <= to_usb_rx;
+					mux_reg <= X"C";
+					if mmc_state(5) = '1' then
+						if spi_speed = '0' then
+							-- Slow speed. Only toggle once in two cycles
+							mmc_state <= mmc_state + "000001";
+							if mmc_state(1 downto 0) = "11" then
+								spi_sample <= '1';
+							end if;
+						else
+							-- Fast speed. Toggle 16 times in a cycle
+							mmc_state <= mmc_state + "000010";
+							if mmc_state(1) = '1' then
+								spi_sample <= '1';
+							end if;
+						end if;
+					end if;
+					if enable_raw_spi then
+						mux_d_reg(0) <= spi_raw_clk;
+						mux_d_reg(1) <= spi_raw_mosi;
+						mux_d_reg(2) <= mmc_cs_n; 
+						mux_d_reg(3) <= to_usb_rx;
+						mux_reg <= X"C";
+						spi_raw_ack <= '1';
+					end if;
+				when MUX_MMC1L | MUX_MMC2L | MUX_MMC3L
+				   | MUX_MMC4L | MUX_MMC5L | MUX_MMC6L | MUX_MMC7L =>
+					mux_d_reg(0) <= mux_d_mmc(0);
+					mux_d_reg(1) <= mux_d_mmc(1);
+					mux_d_reg(2) <= mmc_cs_n; 
+					mux_d_reg(3) <= to_usb_rx;
+					mux_reg <= X"C";
+					-- Only update register on when running at fast speed (8Mhz).
+					if (mmc_state(5) = '1') and (spi_speed = '1') then
+						mux_d_reg(0) <= mmc_state(1);
+						mux_d_reg(1) <= spi_d(7 - to_integer(mmc_state(4 downto 2)));
+						-- Fast speed. Toggle 16 times in a cycle
+						mmc_state <= mmc_state + "000010";
+						if mmc_state(1) = '1' then
+							spi_sample <= '1';
+						end if;
+					end if;
+					if enable_raw_spi then
+						mux_d_reg(0) <= spi_raw_clk;
+						mux_d_reg(1) <= spi_raw_mosi;
+						mux_d_reg(2) <= mmc_cs_n;
+						mux_d_reg(3) <= to_usb_rx;
+						mux_reg <= X"C";
+						spi_raw_ack <= '1';
+					end if;
+
+				when MUX_MMC0H | MUX_MMC1H | MUX_MMC2H | MUX_MMC3H
+				   | MUX_MMC4H | MUX_MMC5H | MUX_MMC6H | MUX_MMC7H =>
+					mux_d_reg(0) <= mux_d_mmc(0);
+					mux_d_reg(1) <= mux_d_mmc(1);
+					mux_d_reg(2) <= mmc_cs_n;
+					mux_d_reg(3) <= to_usb_rx;
+					mux_reg <= X"C";
+					if (mmc_state(5) = '1') and (spi_speed = '1') then
+						-- Only update register on when running at fast speed (8Mhz).
+						mux_d_reg(0) <= mmc_state(1);
+						mux_d_reg(1) <= spi_d(7 - to_integer(mmc_state(4 downto 2)));
+						-- Fast speed. Toggle 16 times in a cycle
+						mmc_state <= mmc_state + "000010";
+						if mmc_state(1) = '1' then
+							spi_sample <= '1';
+						end if;
+					elsif enable_iec_access then
+						-- When MMC transfer is not pending use some of the MMC cycles for IEC transfers.
+						mux_d_reg(0) <= iec_dat_out;
+						mux_d_reg(1) <= iec_clk_out;
+						mux_d_reg(2) <= iec_srq_out;
+						mux_d_reg(3) <= iec_atn_out;
+						mux_reg <= X"D";
+					end if;
+					if enable_raw_spi then
+						mux_d_reg(0) <= spi_raw_clk;
+						mux_d_reg(1) <= spi_raw_mosi;
+						mux_d_reg(2) <= mmc_cs_n;
+						mux_d_reg(3) <= to_usb_rx;
+						mux_reg <= X"C";
+						spi_raw_ack <= '1';
+					end if;
+				when MUX_NMIIRQ1 | MUX_NMIIRQ2=>
+					mux_d_reg <= "110" & (not reset);
+					mux_reg <= X"6";
+					if docking_station_loc = '1' then
+						mux_d_reg(2) <= docking_irq;
+					end if;
+--
+-- IEC
+				when MUX_IEC1 | MUX_IEC2 | MUX_IEC3 | MUX_IEC4 =>
+					mux_d_reg(0) <= iec_dat_out;
+					mux_d_reg(1) <= iec_clk_out;
+					mux_d_reg(2) <= iec_srq_out;
+					mux_d_reg(3) <= iec_atn_out;
+					mux_reg <= X"D";
+--
+-- USART, LEDs and IR
+				when MUX_LED =>
+					mux_d_reg <= flash_cs_n & rtc_cs & led_green & led_red;
+					mux_reg <= X"B";
+--
+-- PS2
+				when MUX_PS2 =>
+					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_reg <= X"E";
+--
+-- WAITS
+				when MUX_WAIT0 =>
+					if spi_req /= spi_run then
+						spi_run <= spi_req;
+						mmc_state <= "100000";
+					end if;
+					-- Use dead time to do IEC reads/writes
+					mux_d_reg(0) <= iec_dat_out;
+					mux_d_reg(1) <= iec_clk_out;
+					mux_d_reg(2) <= iec_srq_out;
+					mux_d_reg(3) <= iec_atn_out;
+					mux_reg <= X"D";
+					if enable_raw_spi then
+						mux_d_reg(0) <= spi_raw_clk;
+						mux_d_reg(1) <= spi_raw_mosi;
+						mux_d_reg(2) <= mmc_cs_n;
+						mux_d_reg(3) <= to_usb_rx;
+						mux_reg <= X"C";
+						spi_raw_ack <= '1';
+					end if;
+				when MUX_WAIT1 =>
+					-- Continue BUSVIC output at end of phi2=0, so we sample BA a few times.
+					mux_d_reg <= "0101";
+					if docking_station_loc = '1' then
+						mux_d_reg <= "1111";
+					end if;
+					mux_reg <= X"7";
+					-- Toggle between SPI/IEC and updating BUSVIC.
+					if mux_toggle = '1' then
+						if enable_iec_access then
+							mux_d_reg(0) <= iec_dat_out;
+							mux_d_reg(1) <= iec_clk_out;
+							mux_d_reg(2) <= iec_srq_out;
+							mux_d_reg(3) <= iec_atn_out;
+							mux_reg <= X"D";
+						end if;
+						if enable_raw_spi then
+							mux_d_reg(0) <= spi_raw_clk;
+							mux_d_reg(1) <= spi_raw_mosi;
+							mux_d_reg(2) <= mmc_cs_n;
+							mux_d_reg(3) <= to_usb_rx;
+							mux_reg <= X"C";
+							spi_raw_ack <= '1';
+						end if;
+					end if;
+--
+-- PHI2  0
+				when MUX_A3_C =>
+					mux_d_reg <= X"C";
+					mux_reg <= X"5";
+				when MUX_BUSVIC =>
+					mux_d_reg <= "0101";
+					if docking_station_loc = '1' then
+						mux_d_reg <= "1111";
+					end if;
+					mux_reg <= X"7";
+				when MUX_ULTIMAX =>
+					mux_d_reg <= "1011";
+					mux_reg <= X"8";
+				when MUX_D0VIC =>
+					mux_d_reg <= c64_to_io(3 downto 0);
+					mux_reg <= X"0";
+				when MUX_D1VIC =>
+					mux_d_reg <= c64_to_io(7 downto 4);
+					mux_reg <= X"1";
+				when MUX_END0 =>
+					mux_d_reg <= "0111";
+					if docking_station_loc = '1' then
+						mux_d_reg <= "1111";
+					end if;
+					mux_reg <= X"7";
+--
+-- PHI2  1
+				when MUX_A0 =>
+					mux_d_reg <= c64_addr(3 downto 0);
+					mux_reg <= X"2";
+				when MUX_A1 =>
+					mux_d_reg <= c64_addr(7 downto 4);
+					mux_reg <= X"3";
+				when MUX_A2 =>
+					mux_d_reg <= c64_addr(11 downto 8);
+					mux_reg <= X"4";
+				when MUX_BUS =>
+					if c64_vic_loc = '0' then
+						if c64_cs_loc = '1' then
+							mux_d_reg <= "00" & (not c64_we_loc) & (not c64_we_loc);
+							mux_reg <= X"7";
+						end if;
+					else
+						-- A15..12 driven, A11..0 not driven, Data driven, no write.
+						mux_d_reg <= "0101";
+						mux_reg <= X"7";
+					end if;
+				when MUX_CLKPORT =>
+					-- GAME = low unless accessing roms
+					mux_d_reg <= "1" & c64_roms_loc & "11";
+					if c64_clockport_loc = '1' then
+						if c64_we_loc = '0' then
+							-- Clockport read
+							mux_d_reg <= "1010";
+						else
+							-- Clockport write
+							mux_d_reg <= "1001";
+						end if;
+					end if;
+					mux_reg <= X"8";
+				when MUX_A3 =>
+					if c64_vic_loc = '0' then
+						if c64_cs_loc = '1' then
+							mux_d_reg <= c64_addr(15 downto 12);
+							mux_reg <= X"5";
+						end if;
+					end if;
+--				when MUX_D0WR | MUX_D0WR_1 | MUX_D0WR_2 =>
+				when MUX_D0WR | MUX_D0WR_1 | MUX_D0WR_2 | MUX_D0RD_1 | MUX_D0RD_2 =>
+					mux_d_reg <= c64_to_io(3 downto 0);
+					mux_reg <= X"0";
+--				when MUX_D1WR | MUX_D1WR_1 | MUX_D1WR_2 =>
+				when MUX_D1WR | MUX_D1WR_1 | MUX_D1WR_2 | MUX_D1RD_1 | MUX_D1RD_2 =>
+					mux_d_reg <= c64_to_io(7 downto 4);
+					mux_reg <= X"1";
+				when others =>
+					null;
+				end case;
+			end if;
+		end if;
+	end process;
+
+	process(clk_mux)
+	begin
+		if rising_edge(clk_mux) then
+			if mmc_state(5) = '0' then
+				spi_ack <= spi_run;
+			end if;
+		end if;
+	end process;
+
+	mux_clk <= mux_clk_reg;
+	mux_d <= mux_d_reg;
+	mux <= mux_reg;
+end architecture;
Index: chameleon/chameleon_phi_clock_a.vhd
===================================================================
--- chameleon/chameleon_phi_clock_a.vhd	(revision 125)
+++ chameleon/chameleon_phi_clock_a.vhd	(revision 126)
@@ -5,7 +5,7 @@
 -- Multi purpose FPGA expansion for the Commodore 64 computer
 --
 -- -----------------------------------------------------------------------
--- Copyright 2005-2010 by Peter Wendrich (pwsoft@syntiac.com)
+-- Copyright 2005-2012 by Peter Wendrich (pwsoft@syntiac.com)
 -- http://www.syntiac.com/chameleon.html
 -- -----------------------------------------------------------------------
 --
@@ -23,10 +23,8 @@
 --constant phaseShift : integer := 5; -- Number of cycles that FPGA runs ahead of measured phi.
 constant phaseShift : integer := 8; -- Number of cycles that FPGA runs ahead of measured phi.
 constant guardBits : integer := 4; -- Extra bits to reduce rounding errors in calculations
-signal phiReg1 : std_logic;
-signal phiReg2 : std_logic;
-signal phiReg3 : std_logic;
-signal phiSync : boolean;
+signal phi2_n_reg : unsigned(7 downto 0);
+signal phiSync : std_logic := '0';
 
 signal locCnt : unsigned(7 downto 0) := (others => '0');
 signal fracCnt : unsigned(guardBits-1 downto 0) := (others => '0');
@@ -48,9 +46,6 @@
 signal localPost3 : std_logic := '0';
 signal localPost4 : std_logic := '0';
 begin
-	-- Copy of input phi (deglitched)
-	phiBuffer <= phiReg3;
-	
 	-- Average phi length
 	phiLength <= avgLen((7+guardBits) downto guardBits);
 	
@@ -74,12 +69,14 @@
 	process(clk) is
 	begin
 		if rising_edge(clk) then
-			phiReg1 <= phiIn;
-			phiReg2 <= phiReg1;
-			phiReg3 <= phiReg2;
+			phiSync <= '0';
+			phi2_n_reg <= phi2_n_reg(phi2_n_reg'high-1 downto 0) & phi2_n;
+			-- Detect falling edge of phi2 (is rising edge here as phi2_n input is inverted).
+			if phi2_n_reg = "00000001" then
+				phiSync <= '1';
+			end if;
 		end if;
 	end process;
-	phiSync <= (phiReg1 = '0') and (phiReg2 = '0') and (phiReg3 = '1');
 
 	-- Determine cycle length
 	process(clk) is
@@ -104,12 +101,12 @@
 					-- NTSC mode 1.022727 Mhz
 					avgLen <= to_unsigned(1643, 8+guardBits);
 				end if;
-				if (phiReg1 = '0') and (phiReg2 = '0') and (phiReg3 = '0') then
+				if (phi2_n_reg(1) = '1') and (phi2_n_reg(2) = '1') and (phi2_n_reg(3) = '1') then
 					docking_station <= '1';
 				end if;
 				no_clock <= '1';
 			end if;
-			if phiSync then
+			if phiSync = '1' then
 				avgDelta <= signed("0" & c64Cnt) - signed("0" & avgLen((7+guardBits) downto guardBits));
 				c64Cnt <= (others => '0');
 			end if;
Index: chameleon/chameleon_phi_clock_e.vhd
===================================================================
--- chameleon/chameleon_phi_clock_e.vhd	(revision 125)
+++ chameleon/chameleon_phi_clock_e.vhd	(revision 126)
@@ -5,7 +5,7 @@
 -- Multi purpose FPGA expansion for the Commodore 64 computer
 --
 -- -----------------------------------------------------------------------
--- Copyright 2005-2010 by Peter Wendrich (pwsoft@syntiac.com)
+-- Copyright 2005-2012 by Peter Wendrich (pwsoft@syntiac.com)
 -- http://www.syntiac.com/chameleon.html
 -- -----------------------------------------------------------------------
 --
@@ -22,13 +22,12 @@
 entity chameleon_phi_clock is
 	port (
 		clk : in std_logic;
-		phiIn : in std_logic;
+		phi2_n : in std_logic;
 		
 		-- Standalone mode, 0=PAL and 1=NTSC
 		mode : in std_logic := '0';
 		
-		-- Buffered phiIn (delayed)
-		phiBuffer : out std_logic;
+		-- Buffered and inverted phi_n (delayed)
 		phiLength : out unsigned(7 downto 0);
 		
 		-- no_clock is high when there are no phiIn changes detected.
Index: chameleon/hwtest_readme.txt
===================================================================
--- chameleon/hwtest_readme.txt	(revision 125)
+++ chameleon/hwtest_readme.txt	(revision 126)
@@ -1,4 +1,5 @@
 The chameleon_* files are taken from the hwtest2 project for the Chameleon.
+Also some form the minimig project
 They are under the lgpl license, which I believe allows linking, such as it is in hardware...
 ---
 Hi,
Index: chameleon/output_file.cof
===================================================================
--- chameleon/output_file.cof	(nonexistent)
+++ chameleon/output_file.cof	(revision 126)
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="US-ASCII" standalone="yes"?>
+<cof>
+	<eprom_name>CFI_128Mb</eprom_name>
+	<output_filename>output_files/atari800core.rbf</output_filename>
+	<n_pages>1</n_pages>
+	<width>1</width>
+	<mode>0</mode>
+	<sof_data>
+		<user_name>Page_0</user_name>
+		<page_flags>1</page_flags>
+		<bit0>
+			<sof_filename>output_files/atari800core.sof<compress_bitstream>1</compress_bitstream></sof_filename>
+		</bit0>
+	</sof_data>
+	<version>5</version>
+	<create_cvp_file>0</create_cvp_file>
+	<options>
+	</options>
+</cof>
