Index: eclaireXL/atari800core_eclaireXL.qsf
===================================================================
--- eclaireXL/atari800core_eclaireXL.qsf	(revision 405)
+++ eclaireXL/atari800core_eclaireXL.qsf	(revision 406)
@@ -63,6 +63,8 @@
 set_global_assignment -name QIP_FILE pll_ntsc.qip
 set_global_assignment -name QIP_FILE pll.qip
 set_global_assignment -name QIP_FILE pll_usb.qip
+set_global_assignment -name QIP_FILE gpioram.qip
+#set_global_assignment -name QIP_FILE serial_loader/synthesis/serial_loader.qip
 set_global_assignment -name VHDL_FILE zpu_rom.vhdl
 set_location_assignment PIN_H16 -to CLOCK_5
 
Index: eclaireXL/gpioram.cmp
===================================================================
--- eclaireXL/gpioram.cmp	(nonexistent)
+++ eclaireXL/gpioram.cmp	(revision 406)
@@ -0,0 +1,26 @@
+--Copyright (C) 1991-2015 Altera Corporation. All rights reserved.
+--Your use of Altera Corporation's design tools, logic functions 
+--and other software and tools, and its AMPP partner logic 
+--functions, and any output files from any of the foregoing 
+--(including device programming or simulation files), and any 
+--associated documentation or information are expressly subject 
+--to the terms and conditions of the Altera Program License 
+--Subscription Agreement, the Altera Quartus II License Agreement,
+--the Altera MegaCore Function License Agreement, or other 
+--applicable license agreement, including, without limitation, 
+--that your use is for the sole purpose of programming logic 
+--devices manufactured by Altera and sold by Altera or its 
+--authorized distributors.  Please refer to the applicable 
+--agreement for further details.
+
+
+component gpioram
+	PORT
+	(
+		address		: IN STD_LOGIC_VECTOR (5 DOWNTO 0);
+		clock		: IN STD_LOGIC  := '1';
+		data		: IN STD_LOGIC_VECTOR (71 DOWNTO 0);
+		wren		: IN STD_LOGIC ;
+		q		: OUT STD_LOGIC_VECTOR (71 DOWNTO 0)
+	);
+end component;

Property changes on: eclaireXL/gpioram.cmp
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: eclaireXL/gpioram.qip
===================================================================
--- eclaireXL/gpioram.qip	(nonexistent)
+++ eclaireXL/gpioram.qip	(revision 406)
@@ -0,0 +1,5 @@
+set_global_assignment -name IP_TOOL_NAME "RAM: 1-PORT"
+set_global_assignment -name IP_TOOL_VERSION "15.0"
+set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone V}"
+set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "gpioram.vhd"]
+set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "gpioram.cmp"]

Property changes on: eclaireXL/gpioram.qip
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: eclaireXL/gpioram.vhd
===================================================================
--- eclaireXL/gpioram.vhd	(nonexistent)
+++ eclaireXL/gpioram.vhd	(revision 406)
@@ -0,0 +1,157 @@
+-- megafunction wizard: %RAM: 1-PORT%
+-- GENERATION: STANDARD
+-- VERSION: WM1.0
+-- MODULE: altsyncram 
+
+-- ============================================================
+-- File Name: gpioram.vhd
+-- Megafunction Name(s):
+-- 			altsyncram
+--
+-- Simulation Library Files(s):
+-- 			altera_mf
+-- ============================================================
+-- ************************************************************
+-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+--
+-- 15.0.2 Build 153 07/15/2015 SJ Web Edition
+-- ************************************************************
+
+
+--Copyright (C) 1991-2015 Altera Corporation. All rights reserved.
+--Your use of Altera Corporation's design tools, logic functions 
+--and other software and tools, and its AMPP partner logic 
+--functions, and any output files from any of the foregoing 
+--(including device programming or simulation files), and any 
+--associated documentation or information are expressly subject 
+--to the terms and conditions of the Altera Program License 
+--Subscription Agreement, the Altera Quartus II License Agreement,
+--the Altera MegaCore Function License Agreement, or other 
+--applicable license agreement, including, without limitation, 
+--that your use is for the sole purpose of programming logic 
+--devices manufactured by Altera and sold by Altera or its 
+--authorized distributors.  Please refer to the applicable 
+--agreement for further details.
+
+
+LIBRARY ieee;
+USE ieee.std_logic_1164.all;
+
+LIBRARY altera_mf;
+USE altera_mf.altera_mf_components.all;
+
+ENTITY gpioram IS
+	PORT
+	(
+		address		: IN STD_LOGIC_VECTOR (5 DOWNTO 0);
+		clock		: IN STD_LOGIC  := '1';
+		data		: IN STD_LOGIC_VECTOR (71 DOWNTO 0);
+		wren		: IN STD_LOGIC ;
+		q		: OUT STD_LOGIC_VECTOR (71 DOWNTO 0)
+	);
+END gpioram;
+
+
+ARCHITECTURE SYN OF gpioram IS
+
+	SIGNAL sub_wire0	: STD_LOGIC_VECTOR (71 DOWNTO 0);
+
+BEGIN
+	q    <= sub_wire0(71 DOWNTO 0);
+
+	altsyncram_component : altsyncram
+	GENERIC MAP (
+		clock_enable_input_a => "BYPASS",
+		clock_enable_output_a => "BYPASS",
+		intended_device_family => "Cyclone V",
+		lpm_hint => "ENABLE_RUNTIME_MOD=YES,INSTANCE_NAME=GPIO",
+		lpm_type => "altsyncram",
+		numwords_a => 36,
+		operation_mode => "SINGLE_PORT",
+		outdata_aclr_a => "NONE",
+		outdata_reg_a => "CLOCK0",
+		power_up_uninitialized => "FALSE",
+		read_during_write_mode_port_a => "NEW_DATA_NO_NBE_READ",
+		widthad_a => 6,
+		width_a => 72,
+		width_byteena_a => 1
+	)
+	PORT MAP (
+		address_a => address,
+		clock0 => clock,
+		data_a => data,
+		wren_a => wren,
+		q_a => sub_wire0
+	);
+
+
+
+END SYN;
+
+-- ============================================================
+-- CNX file retrieval info
+-- ============================================================
+-- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
+-- Retrieval info: PRIVATE: AclrAddr NUMERIC "0"
+-- Retrieval info: PRIVATE: AclrByte NUMERIC "0"
+-- Retrieval info: PRIVATE: AclrData NUMERIC "0"
+-- Retrieval info: PRIVATE: AclrOutput NUMERIC "0"
+-- Retrieval info: PRIVATE: BYTE_ENABLE NUMERIC "0"
+-- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "9"
+-- Retrieval info: PRIVATE: BlankMemory NUMERIC "1"
+-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0"
+-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
+-- Retrieval info: PRIVATE: Clken NUMERIC "0"
+-- Retrieval info: PRIVATE: DataBusSeparated NUMERIC "1"
+-- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
+-- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A"
+-- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
+-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone V"
+-- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "1"
+-- Retrieval info: PRIVATE: JTAG_ID STRING "GPIO"
+-- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
+-- Retrieval info: PRIVATE: MIFfilename STRING ""
+-- Retrieval info: PRIVATE: NUMWORDS_A NUMERIC "36"
+-- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
+-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3"
+-- Retrieval info: PRIVATE: RegAddr NUMERIC "1"
+-- Retrieval info: PRIVATE: RegData NUMERIC "1"
+-- Retrieval info: PRIVATE: RegOutput NUMERIC "1"
+-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
+-- Retrieval info: PRIVATE: SingleClock NUMERIC "1"
+-- Retrieval info: PRIVATE: UseDQRAM NUMERIC "1"
+-- Retrieval info: PRIVATE: WRCONTROL_ACLR_A NUMERIC "0"
+-- Retrieval info: PRIVATE: WidthAddr NUMERIC "6"
+-- Retrieval info: PRIVATE: WidthData NUMERIC "72"
+-- Retrieval info: PRIVATE: rden NUMERIC "0"
+-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
+-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS"
+-- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS"
+-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone V"
+-- Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=YES,INSTANCE_NAME=GPIO"
+-- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
+-- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "36"
+-- Retrieval info: CONSTANT: OPERATION_MODE STRING "SINGLE_PORT"
+-- Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE"
+-- Retrieval info: CONSTANT: OUTDATA_REG_A STRING "CLOCK0"
+-- Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE"
+-- Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_PORT_A STRING "NEW_DATA_NO_NBE_READ"
+-- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "6"
+-- Retrieval info: CONSTANT: WIDTH_A NUMERIC "72"
+-- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
+-- Retrieval info: USED_PORT: address 0 0 6 0 INPUT NODEFVAL "address[5..0]"
+-- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock"
+-- Retrieval info: USED_PORT: data 0 0 72 0 INPUT NODEFVAL "data[71..0]"
+-- Retrieval info: USED_PORT: q 0 0 72 0 OUTPUT NODEFVAL "q[71..0]"
+-- Retrieval info: USED_PORT: wren 0 0 0 0 INPUT NODEFVAL "wren"
+-- Retrieval info: CONNECT: @address_a 0 0 6 0 address 0 0 6 0
+-- Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
+-- Retrieval info: CONNECT: @data_a 0 0 72 0 data 0 0 72 0
+-- Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0
+-- Retrieval info: CONNECT: q 0 0 72 0 @q_a 0 0 72 0
+-- Retrieval info: GEN_FILE: TYPE_NORMAL gpioram.vhd TRUE
+-- Retrieval info: GEN_FILE: TYPE_NORMAL gpioram.inc FALSE
+-- Retrieval info: GEN_FILE: TYPE_NORMAL gpioram.cmp TRUE
+-- Retrieval info: GEN_FILE: TYPE_NORMAL gpioram.bsf FALSE
+-- Retrieval info: GEN_FILE: TYPE_NORMAL gpioram_inst.vhd FALSE
+-- Retrieval info: LIB_FILE: altera_mf

Property changes on: eclaireXL/gpioram.vhd
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: eclaireXL/gpiov3.vhd
===================================================================
--- eclaireXL/gpiov3.vhd	(revision 405)
+++ eclaireXL/gpiov3.vhd	(revision 406)
@@ -75,8 +75,25 @@
 end gpiov3;
 
 architecture vhdl of gpiov3 is
-	signal shift_next : std_logic_vector(71 downto 0);
-	signal shift_reg : std_logic_vector(71 downto 0);
+	signal gpio0_out_next : std_logic_vector(35 downto 0);
+	signal gpio0_out_reg : std_logic_vector(35 downto 0);
+	signal gpio1_out_next : std_logic_vector(35 downto 0);
+	signal gpio1_out_reg : std_logic_vector(35 downto 0);
+	signal gpio0_dir_next : std_logic_vector(35 downto 0);
+	signal gpio0_dir_reg : std_logic_vector(35 downto 0);
+	signal gpio1_dir_next : std_logic_vector(35 downto 0);
+	signal gpio1_dir_reg : std_logic_vector(35 downto 0);
+
+	signal bit_next : std_logic_vector(5 downto 0);
+	signal bit_reg : std_logic_vector(5 downto 0);
+
+	constant state_clear : std_logic_vector(1 downto 0) := "00";
+	constant state_read : std_logic_vector(1 downto 0) := "01";
+	constant state_drive : std_logic_vector(1 downto 0) := "10";
+	signal state_next : std_logic_vector(1 downto 0);
+	signal state_reg : std_logic_vector(1 downto 0);
+
+	signal mem_write : std_logic;
 begin	
 	CA2_in <= '1';
 	CB2_in <= '1';
@@ -100,28 +117,97 @@
 	process(clk,reset_n)
 	begin
 		if (reset_n='0') then
-			shift_reg(71 downto 1) <= (others=>'0');
-			shift_reg(0) <= '1';
+			bit_reg <= (others=>'0');
+			gpio0_out_reg <= (others=>'0');
+			gpio1_out_reg <= (others=>'0');
+			gpio0_dir_reg <= (others=>'1');
+			gpio1_dir_reg <= (others=>'1');
+			state_reg <= state_clear;
 		elsif (clk'event and clk='1') then
-			shift_reg <= shift_next;
+			bit_reg <= bit_next;
+			gpio0_out_reg <= gpio0_out_next;
+			gpio1_out_reg <= gpio1_out_next;
+			gpio0_dir_reg <= gpio0_dir_next;
+			gpio1_dir_reg <= gpio1_dir_next;
+			state_reg <= state_next;
 		end if;
 	end process;
 
-	process(shift_reg,enable_179_early)
+	-- Process is as follows
+	-- i) drive all to 0, drive on everywhere
+	-- ii) drive a bit to 1, drive on only that bit
+	-- iii) read the value of all gpios and store
+	-- iv) next bit
+	process(enable_179_early,state_reg,bit_reg,gpio0_out_reg,gpio0_dir_reg,gpio1_out_reg,gpio1_dir_reg,gpio_0_in,gpio_1_in)
 	begin
-		shift_next <= shift_reg;
+		bit_next <= bit_reg;
+		gpio0_out_next <= gpio0_out_reg;
+		gpio1_out_next <= gpio1_out_reg;
+		gpio0_dir_next <= gpio0_dir_reg;
+		gpio1_dir_next <= gpio1_dir_reg;
+		state_next <= state_reg;
+		mem_write <= '0';
+
 		if (enable_179_early = '1') then
-			shift_next(71 downto 1) <= shift_reg(70 downto 0);
-			shift_next(0) <= shift_reg(71);
+			case state_reg is
+				when state_clear =>
+					state_next <= state_drive;
+
+					-- prepare to drive
+					gpio0_out_next <= (others=>'0');
+					gpio1_out_next <= (others=>'0');
+					gpio0_dir_next <= (others=>'0');
+					gpio1_dir_next <= (others=>'0');
+					gpio0_out_next(to_integer(unsigned(bit_reg))) <= '1';
+					gpio0_dir_next(to_integer(unsigned(bit_reg))) <= '1';
+
+				when state_drive =>
+					state_next <= state_read;
+
+					--preare to read
+					gpio0_out_next <= (others=>'0');
+					gpio1_out_next <= (others=>'0');
+					gpio0_dir_next <= (others=>'0');
+					gpio1_dir_next <= (others=>'0');
+
+				when state_read =>
+					state_next <= state_clear;
+
+					-- store to ram
+					mem_write <= '1';
+
+					-- prepare to clear
+					gpio0_out_next <= (others=>'0');
+					gpio1_out_next <= (others=>'0');
+					gpio0_dir_next <= (others=>'1');
+					gpio1_dir_next <= (others=>'1');
+
+					-- next bit!
+					bit_next <= std_logic_vector(unsigned(bit_reg)+1);
+					if (bit_reg=std_logic_vector(to_unsigned(35,6))) then
+						bit_next <= (others=>'0');
+					end if;
+
+				when others=>
+					state_next <= state_clear;
+			end case;
 		end if;
 	end process;
 
-	GPIO_0_OUT <= shift_reg(71 downto 36);
-	--GPIO_0_DIR_OUT <= shift_reg(71 downto 36);
-	GPIO_0_DIR_OUT <= (others=>'1');
-	GPIO_1_OUT <= shift_reg(35 downto 0);
-	--GPIO_1_DIR_OUT <= shift_reg(35 downto 0);
-	GPIO_1_DIR_OUT <= (others=>'1');
+gpioram: ENTITY work.gpioram
+	PORT MAP
+	(
+		address => bit_reg,
+		clock => clk,
+		data => gpio_0_in&gpio_1_in,
+		wren => mem_write,
+		q => open
+	);
 
+	GPIO_0_OUT <= gpio0_out_reg;
+	GPIO_0_DIR_OUT <= gpio0_dir_reg;
+	GPIO_1_OUT <= gpio1_out_reg;
+	GPIO_1_DIR_OUT <= gpio1_dir_reg;
+
 end vhdl;
 
