Index: chameleon/atari800core.qsf
===================================================================
--- chameleon/atari800core.qsf	(revision 144)
+++ chameleon/atari800core.qsf	(revision 145)
@@ -202,6 +202,8 @@
 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 gen_usart.vhd
+set_global_assignment -name VHDL_FILE chameleon_usb.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 144)
+++ chameleon/atari800core_chameleon.vhd	(revision 145)
@@ -9,6 +9,7 @@
 LIBRARY ieee;
 USE ieee.std_logic_1164.all; 
 use ieee.numeric_std.all;
+use IEEE.STD_LOGIC_MISC.all;
 
 LIBRARY work;
 
@@ -126,8 +127,14 @@
 --	signal mux_d_reg : unsigned(3 downto 0) := (others => '1');
 
 -- reset from chameleon
-	signal chameleon_reset_n_next : std_logic;
-	signal chameleon_reset_n_reg : std_logic;
+	signal chameleon_reset_n_next : std_logic_vector(9 downto 0);
+	signal chameleon_reset_n_reg : std_logic_vector(9 downto 0);
+	signal reset_short_next : std_logic;
+	signal reset_short_reg : std_logic;
+	signal reset_long_next : std_logic;
+	signal reset_long_reg : std_logic;
+	signal reconfig_next : std_logic;
+	signal reconfig_reg : std_logic;
 
 -- LEDs
 --	signal led_green : std_logic;
@@ -134,11 +141,15 @@
 --	signal led_red : std_logic;
 
 -- clocks...
-	signal ena_1mhz : std_logic;
+	signal ena_1mhz : std_logic; --fast clk
 	signal ena_1khz : std_logic;
+
 	--signal phi2 : std_logic;
 	signal no_clock : std_logic;
 
+	signal ena_10khz : std_logic; --slow clk
+	signal ena_10hz : std_logic;	
+	
 -- Docking station
 	signal docking_station : std_logic;
 	--signal docking_ena : std_logic;
@@ -222,8 +233,12 @@
 	signal scanlines_next : std_logic;
 	signal scanlines_reg : std_logic;
 	signal freeze_n_reg : std_logic;
+	signal freeze_n_next : std_logic;
 	signal freeze_n_sync : std_logic;
 
+	-- microcontroller (for slot flash)
+	signal to_usb_rx : std_logic;
+
 begin
 pal <= '1' when tv=1 else '0';
 vga <= '1' when video=2 else '0';
@@ -421,6 +436,7 @@
 			ena_1khz => ena_1khz
 		);
 
+		
 -- -----------------------------------------------------------------------
 -- Phi 2
 -- -----------------------------------------------------------------------
@@ -509,7 +525,7 @@
 		mux_q => mux_q,
 
 -- USB microcontroller (To RX of micro)
---		to_usb_rx : in std_logic := '1';
+		to_usb_rx => to_usb_rx,
 
 -- C64 timing (only for C64 related cores)
 		phi_mode => not(PAL),
@@ -572,7 +588,7 @@
 --		ps2_mouse_dat_in: out std_logic;
 
 -- Buttons
-		button_reset_n => chameleon_reset_n_next,
+		button_reset_n => chameleon_reset_n_next(0),
 		
 -- Joysticks
 		joystick1 => docking_joystick1,
@@ -855,7 +871,7 @@
 	);
 
 	pause_atari <= zpu_out1(0);
-	reset_atari <= zpu_out1(1) or not(chameleon_reset_n_reg);
+	reset_atari <= zpu_out1(1) or reset_short_reg;
 	speed_6502 <= zpu_out1(7 downto 2);
 	ram_select <= zpu_out1(10 downto 8);
 	rom_select <= zpu_out1(16 downto 11);
@@ -921,11 +937,15 @@
 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)
+process(scanlines_reg, freeze_n_sync, freeze_n_reg, ena_10hz)
 begin
 	scanlines_next <= scanlines_reg;
-	if (freeze_n_reg = '1' and freeze_n_sync = '0')then
-		scanlines_next <= not(scanlines_reg);
+	freeze_n_next <= freeze_n_reg;
+	if (ena_10hz = '1') then
+		freeze_n_next <= freeze_n_sync;
+		if (freeze_n_reg = '1' and freeze_n_sync = '0')then
+			scanlines_next <= not(scanlines_reg);
+		end if;
 	end if;
 end process;
 
@@ -934,14 +954,90 @@
 	if (reset_n='0') then
 		scanlines_reg <= '0';
 		freeze_n_reg <= '1';
-		chameleon_reset_n_reg <= '1';
+		chameleon_reset_n_reg <= (others=>'1');
 		ir_fkeys_reg <= (others=>'0');
+		reconfig_reg <= '0';
+		reset_long_reg <= '0';
+		reset_short_reg <= '0';
 	elsif (clk'event and clk = '1') then
 		scanlines_reg <= scanlines_next;
-		freeze_n_reg <= freeze_n_sync;
+		freeze_n_reg <= freeze_n_next;
 		chameleon_reset_n_reg <= chameleon_reset_n_next;
 		ir_fkeys_reg <= ir_fkeys_next;
+		reconfig_reg <= reconfig_next;
+		reset_long_reg <= reset_long_next;
+		reset_short_reg <= reset_short_next;
 	end if;
 end process;
 
+-- 10hz for crappy debounce!
+	my10khz : entity work.enable_divider
+		generic map (
+			count => 5700
+		)
+		port map (
+			clk => clk,
+			reset_n => reset_n,
+			enable_in => '1',
+			enable_out => ena_10khz
+		);
+
+		my10hz : entity work.enable_divider
+		generic map (
+			count => 1000
+		)
+		port map (
+			clk => clk,
+			reset_n => reset_n,
+			enable_in => ena_10khz,
+			enable_out => ena_10hz
+		);
+		
+process(ena_10hz, chameleon_reset_n_reg, reconfig_reg, reset_long_reg, reset_short_reg)
+begin
+	reconfig_next <= reconfig_reg;
+	chameleon_reset_n_next(9 downto 1) <= chameleon_reset_n_reg(9 downto 1);
+	reset_short_next <= reset_short_reg;
+	reset_long_next <= reset_long_reg;
+	reconfig_next <= reconfig_reg or reset_long_reg;
+	
+	if (ena_10hz = '1') then
+		reset_short_next <= '0';
+		reset_long_next <= '0';
+	
+		chameleon_reset_n_next(9 downto 1) <= chameleon_reset_n_reg(8 downto 0);
+
+		if (chameleon_reset_n_reg(0) = '0') then
+			reset_short_next <= '1';
+		end if;
+		if (or_reduce(chameleon_reset_n_reg(9 downto 0)) = '0') then
+			reset_long_next <= '1';
+		end if;
+	end if;
+end process;
+
+usb : entity work.chameleon_usb
+	port map (
+		clk => clk_sdram,
+		
+		req => open,
+		we => open,
+		a => open,
+		q => open,
+		
+		reconfig => reconfig_reg,
+		reconfig_slot => "0000",
+		
+		flashslot => open,
+		
+		-- talk to microcontroller
+		serial_clk => usart_clk,
+		serial_rxd => usart_tx,
+		serial_txd => to_usb_rx,
+		serial_cts_n => usart_rts,
+		
+		serial_debug_trigger => open,
+		serial_debug_data => open
+	);
+
 end vhdl;
Index: chameleon/build.sh
===================================================================
--- chameleon/build.sh	(revision 144)
+++ chameleon/build.sh	(revision 145)
@@ -76,6 +76,7 @@
 	`cp *pll*.* $dir`;
 	`cp *.vhdl $dir`;
 	`cp chameleon_*.* $dir`;
+	`cp gen_*.* $dir`;
 	`cp zpu_rom.vhdl $dir`;
 	`cp atari800core.sdc $dir`;
 	`mkdir $dir/common`;
Index: chameleon/chameleon_usb.vhd
===================================================================
--- chameleon/chameleon_usb.vhd	(nonexistent)
+++ chameleon/chameleon_usb.vhd	(revision 145)
@@ -0,0 +1,225 @@
+-- -----------------------------------------------------------------------
+--
+-- Turbo Chameleon
+--
+-- Multi purpose FPGA expansion for the Commodore 64 computer
+--
+-- -----------------------------------------------------------------------
+-- Copyright 2005-2010 by Peter Wendrich (pwsoft@syntiac.com)
+-- All Rights Reserved.
+--
+-- http://www.syntiac.com/chameleon.html
+-- -----------------------------------------------------------------------
+--
+-- Chameleon USB micro communication
+--
+-- -----------------------------------------------------------------------
+-- clk          - system clock
+-- req          - toggles on a access request (read & write)
+-- ack          - toggled by system when the request is processed.
+-- we           - write enable, is high during write actions
+-- a            - 32 bits address bus
+-- d            - data input
+-- q            - data output
+-- flashslot    - Slot number (0-15) in flash where FPGA is started from.
+--                Highest bit is valid-bit, is set when slot number is valid.
+-- serial_clk   - clock of synchronous serial communication
+-- serial_rxd   - serial receive data
+-- serial_txd   - serial send data
+-- serial_cts_n - clear to send inverted. When low USB micro is ready to
+--                receive bytes.
+-- -----------------------------------------------------------------------
+
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.numeric_std.all;
+
+-- -----------------------------------------------------------------------
+
+entity chameleon_usb is
+	port (
+		clk : in std_logic;
+		
+		req : out std_logic;
+		ack : in std_logic := '0';
+		we : out std_logic;
+		a : out unsigned(31 downto 0);
+		d : in unsigned(7 downto 0) := (others => '0');
+		q : out unsigned(7 downto 0);
+		
+		reconfig : in std_logic := '0';
+		reconfig_slot : in unsigned(3 downto 0) := (others => '0');
+		
+		flashslot : out unsigned(4 downto 0);
+		
+		serial_clk : in std_logic;
+		serial_rxd : in std_logic := '1';
+		serial_txd : out std_logic;
+		serial_cts_n : in std_logic := '0';
+		
+		serial_debug_trigger : out std_logic;
+		serial_debug_data : out unsigned(8 downto 0)
+	);
+end entity;
+
+-- -----------------------------------------------------------------------
+
+architecture rtl of chameleon_usb is
+	type state_t is (
+		STATE_RESET, STATE_IDLE,
+		STATE_READ, STATE_READ_ACK, STATE_WRITE, STATE_WRITE_ACK,
+		STATE_ADDR0, STATE_ADDR1, STATE_ADDR2, STATE_ADDR3,
+		STATE_LEN0, STATE_LEN1, STATE_LEN2);
+	type command_t is (
+		CMD_NONE, CMD_READ, CMD_WRITE);
+	
+	signal req_reg : std_logic := '0';
+	signal state : state_t := STATE_RESET;
+	signal flashslot_reg : unsigned(4 downto 0) := (others => '0');
+
+	signal recv_trigger : std_logic;
+	signal recv_data : unsigned(8 downto 0) := (others => '0');
+	
+	signal send_trigger : std_logic := '0';
+	signal send_empty : std_logic;
+	signal send_data : unsigned(8 downto 0) := (others => '0');
+	
+	signal command : command_t := CMD_NONE;
+	signal cmd_length : unsigned(23 downto 0) := (others => '0');
+	signal cmd_address : unsigned(31 downto 0) := (others => '0');
+begin
+	req <= req_reg;
+	we <= '1' when ((state = STATE_WRITE) or (state = STATE_WRITE_ACK)) else '0';
+	a <= cmd_address;
+	flashslot <= flashslot_reg;
+	
+	serial_debug_trigger <= recv_trigger;
+	serial_debug_data <= recv_data;
+
+-- -----------------------------------------------------------------------
+
+	myUsart : entity work.gen_usart
+		generic map (
+			bits => 9
+		)
+		port map (
+			clk => clk,
+			
+			d => send_data,
+			d_trigger => send_trigger,
+			d_empty => send_empty,
+			q => recv_data,
+			q_trigger => recv_trigger,
+			
+			serial_clk => serial_clk,
+			serial_rxd => serial_rxd,
+			serial_txd => serial_txd,
+			serial_cts_n => serial_cts_n
+		);
+
+	process(clk)
+	begin
+		if rising_edge(clk) then
+			send_trigger <= '0';
+			case state is
+			when STATE_RESET =>
+				if send_empty = '1' then
+					send_data <= "100101010"; -- 42, 0x12A
+					send_trigger <= '1';
+				end if;
+			when STATE_IDLE =>
+				if (send_empty = '1') and (reconfig = '1') then
+					send_data <= "11111" & reconfig_slot;
+					send_trigger <= '1';
+				end if;
+			when STATE_READ =>
+				if (req_reg = ack) and (send_empty = '1') then
+					req_reg <= not req_reg;
+					state <= STATE_READ_ACK;
+				end if;
+			when STATE_READ_ACK =>
+				if (req_reg = ack) then
+					send_data <= "0" & d;
+					send_trigger <= '1';
+					cmd_address <= cmd_address + 1;
+					if cmd_length = 0 then
+						state <= STATE_IDLE;
+					else
+						cmd_length <= cmd_length - 1;
+						state <= STATE_READ;
+					end if;
+				end if;
+			when STATE_WRITE_ACK =>
+				if req_reg = ack then
+					cmd_address <= cmd_address + 1;
+					state <= STATE_WRITE;
+				end if;
+			when others =>
+				null;
+			end case;
+			if recv_trigger = '1' then
+				if recv_data(8) = '1' then
+					case recv_data(7 downto 0) is
+					when X"00" =>
+						command <= CMD_NONE;
+						state <= STATE_IDLE;
+					when X"01" =>
+						command <= CMD_WRITE;
+						state <= STATE_ADDR3;
+					when X"02" =>
+						command <= CMD_READ;
+						state <= STATE_ADDR3;
+					when X"10" | X"11" | X"12" | X"13" | X"14" | X"15" | X"16" | X"17"
+					   | X"18" | X"19" | X"1A" | X"1B" | X"1C" | X"1D" | X"1E" | X"1F" =>
+						flashslot_reg <= recv_data(4 downto 0);
+						command <= CMD_NONE;
+						state <= STATE_IDLE;
+					when others =>
+						command <= CMD_NONE;
+						state <= STATE_IDLE;
+					end case;
+				else
+					case state is
+					when STATE_WRITE =>
+						q <= recv_data(7 downto 0);
+						req_reg <= not req_reg;
+						state <= STATE_WRITE_ACK;
+					when STATE_ADDR0 =>
+						cmd_address(7 downto 0) <= recv_data(7 downto 0);
+						case command is
+						when CMD_READ =>
+							state <= STATE_LEN2;
+						when CMD_WRITE =>
+							state <= STATE_WRITE;
+						when others =>
+							state <= STATE_IDLE;
+						end case;
+					when STATE_ADDR1 =>
+						cmd_address(15 downto 8) <= recv_data(7 downto 0);
+						state <= STATE_ADDR0;
+					when STATE_ADDR2 =>
+						cmd_address(23 downto 16) <= recv_data(7 downto 0);
+						state <= STATE_ADDR1;
+					when STATE_ADDR3 =>
+						cmd_address(31 downto 24) <= recv_data(7 downto 0);
+						state <= STATE_ADDR2;
+					when STATE_LEN0 =>
+						cmd_length(7 downto 0) <= recv_data(7 downto 0);
+						state <= STATE_READ;
+					when STATE_LEN1 =>
+						cmd_length(15 downto 8) <= recv_data(7 downto 0);
+						state <= STATE_LEN0;
+					when STATE_LEN2 =>
+						cmd_length(23 downto 16) <= recv_data(7 downto 0);
+						state <= STATE_LEN1;
+					when others =>
+						null;
+					end case;
+				end if;
+			end if;
+		end if;
+	end process;
+		
+end architecture;
+
+
Index: chameleon/gen_usart.vhd
===================================================================
--- chameleon/gen_usart.vhd	(nonexistent)
+++ chameleon/gen_usart.vhd	(revision 145)
@@ -0,0 +1,143 @@
+-- -----------------------------------------------------------------------
+--
+-- Syntiac's generic VHDL support files.
+--
+-- -----------------------------------------------------------------------
+-- Copyright 2005-2010 by Peter Wendrich (pwsoft@syntiac.com)
+-- http://www.syntiac.com/?.html
+-- -----------------------------------------------------------------------
+--
+-- gen_usart.vhd
+--
+-- -----------------------------------------------------------------------
+--
+-- USART - Synchronous serial receiver/transmitter
+--
+-- -----------------------------------------------------------------------
+
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.numeric_std.ALL;
+
+-- -----------------------------------------------------------------------
+
+entity gen_usart is
+	generic (
+		bits : integer := 8
+	);
+	port (
+		clk : in std_logic;
+
+		d : in unsigned(bits-1 downto 0) := (others => '0');
+		d_trigger : in std_logic := '0';
+		d_empty : out std_logic;
+		q : out unsigned(bits-1 downto 0);
+		q_trigger : out std_logic;
+
+		serial_clk : in std_logic;
+		serial_rxd : in std_logic := '1';
+		serial_txd : out std_logic;
+		serial_cts_n : in std_logic := '0'
+	);
+end entity;
+
+-- -----------------------------------------------------------------------
+
+architecture rtl of gen_usart is
+	type state_t is (
+		STATE_IDLE,
+		STATE_BITS,
+		STATE_STOP);
+	signal serial_clk_reg : std_logic := '0';
+	signal serial_clk_dly : std_logic := '0';
+	signal receive_state : state_t := STATE_IDLE;
+	signal receive_shift : unsigned(bits-1 downto 0) := (others => '0');
+	signal receive_cnt : integer range 0 to bits-1 := 0;
+
+	signal transmit_state : state_t := STATE_IDLE;
+	signal transmit_empty : std_logic := '1';
+	signal transmit_buffer : unsigned(bits-1 downto 0) := (others => '0');
+	signal transmit_shift : unsigned(bits-1 downto 0) := (others => '0');
+	signal transmit_cnt : integer range 0 to bits-1 := 0;
+begin
+	d_empty <= transmit_empty and (not d_trigger);
+
+	process(clk)
+	begin
+		if rising_edge(clk) then
+			serial_clk_reg <= serial_clk;
+			serial_clk_dly <= serial_clk_reg;
+		end if;
+	end process;
+
+	receive_process: process(clk)
+	begin
+		if rising_edge(clk) then
+			q_trigger <= '0';
+			-- Detect rising edge
+			if (serial_clk_reg = '1') and (serial_clk_dly = '0') then
+				case receive_state is
+				when STATE_IDLE =>
+					receive_cnt <= 0;
+					if serial_rxd = '0' then
+						receive_state <= STATE_BITS;
+					end if;
+				when STATE_BITS =>
+					receive_shift <= serial_rxd & receive_shift(receive_shift'high downto 1);
+					if receive_cnt = bits-1 then
+						receive_state <= STATE_STOP;
+					else
+						receive_cnt <= receive_cnt + 1;
+					end if;
+				when STATE_STOP =>
+					receive_state <= STATE_IDLE;
+					if serial_rxd = '1' then
+						q <= receive_shift;
+						q_trigger <= '1';
+					end if;
+				end case;
+			end if;
+		end if;
+	end process;
+	
+	transmit_process: process(clk)
+	begin
+		if rising_edge(clk) then
+			-- Detect falling edge
+			if (serial_clk_reg = '0') and (serial_clk_dly = '1') then
+				case transmit_state is
+				when STATE_IDLE =>
+					transmit_cnt <= 0;
+					if (transmit_empty = '0') and (serial_cts_n = '0') then
+						transmit_shift <= transmit_buffer;
+						transmit_empty <= '1';
+						transmit_state <= STATE_BITS;
+						serial_txd <= '0';
+					else
+						serial_txd <= '1';
+					end if;
+				when STATE_BITS =>
+					serial_txd <= transmit_shift(transmit_cnt);
+					if transmit_cnt = bits-1 then
+						transmit_state <= STATE_STOP;
+					else
+						transmit_cnt <= transmit_cnt + 1;
+					end if;
+				when STATE_STOP =>
+					serial_txd <= '1';
+					transmit_state <= STATE_IDLE;
+				end case;
+			end if;
+			if d_trigger = '1' then
+				transmit_buffer <= d;
+				transmit_empty <= '0';
+			end if;
+		end if;
+	end process;
+	
+end architecture;
+
+
+
+
+
