---------------------------------------------------------------------------
-- (c) 2013 mark watson
-- I am happy for anyone to use this for non-commercial use.
-- If my vhdl files are used commercially or otherwise sold,
-- please contact me for explicit permission at scrameta (gmail).
-- This applies for source and binary form and derived works.
---------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
use ieee.numeric_std.all;
USE ieee.math_real.ceil;
USE ieee.math_real.log2;
use IEEE.STD_LOGIC_MISC.all;

ENTITY antic IS
GENERIC
(
	cycle_length : integer := 16 -- or 32...
);
PORT 
( 
	CLK : IN STD_LOGIC;
	ADDR : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
	CPU_DATA_IN : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
	WR_EN : IN STD_LOGIC;
	
	RESET_N : IN STD_LOGIC;
	RNMI_N : IN STD_LOGIC := '1';
	
	MEMORY_READY_ANTIC : IN STD_LOGIC;
	MEMORY_READY_CPU : IN STD_LOGIC;
	MEMORY_DATA_IN : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
	ANTIC_ENABLE_179 : IN std_logic;
	
	PAL : IN STD_LOGIC;
	
	lightpen : in std_logic;
	
	-- CPU interface
	DATA_OUT : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
	NMI_N_OUT : OUT std_logic;
	ANTIC_READY : OUT std_logic; -- taken low by wsync writes
	
	-- GTIA interface
	AN : OUT STD_LOGIC_VECTOR(2 downto 0);
	COLOUR_CLOCK_ORIGINAL_OUT : out std_logic;
	COLOUR_CLOCK_OUT : out std_logic;
	HIGHRES_COLOUR_CLOCK_OUT : out std_logic; -- 2x to allow for half pixel modes
	
	-- DMA fetch
	dma_fetch_out : out std_logic;
	dma_address_out : out std_logic_vector(15 downto 0);
	
	-- refresh
	refresh_out : out std_logic; -- used by sdram

	-- next cycle
	next_cycle_type : out STD_LOGIC_VECTOR(2 downto 0); --000=cpu,001=dma,010=refresh,011=undef,100=undef,101=dma_wsync,110=refresh_wsync,101=undef

	-- if we are in turbo mode
	turbo_out : out std_logic;
	
	-- for debugging
	shift_out : out std_logic_vector(7 downto 0);
	dma_clock_out : out std_logic_vector(3 downto 0);
	hcount_out : out std_logic_vector(7 downto 0);
	vcount_out : out std_logic_vector(8 downto 0)
);
END antic;

ARCHITECTURE vhdl OF antic IS
	COMPONENT complete_address_decoder IS
	generic (width : natural := 1);
	PORT 
	( 
		addr_in : in std_logic_vector(width-1 downto 0);			
		addr_decoded : out std_logic_vector((2**width)-1 downto 0)
	);
	END component;
	
	COMPONENT antic_dma_clock_del IS
	PORT 
	( 
		CLK : IN STD_LOGIC;
		RESET_n : IN STD_LOGIC;
		enable_dma : IN STD_LOGIC;
		
		playfield_start : in std_logic;
		playfield_end : in std_logic;
		vblank : in std_logic;
		
		slow_dma : in std_logic;
		medium_dma : in std_logic;
		fast_dma : in std_logic;
				
		dma_clock_out_0 : out std_logic;
		dma_clock_out_1 : out std_logic;
		dma_clock_out_2 : out std_logic;
		dma_clock_out_3 : out std_logic
	);
	END component;
	
	component antic_counter IS
	generic
	(
		STORE_WIDTH : natural := 1;
		COUNT_WIDTH : natural := 1
	);
	PORT 
	( 
		CLK : IN STD_LOGIC;
		RESET_n : IN STD_LOGIC;
		increment : in std_logic;
		load : IN STD_LOGIC;
		load_value : in std_logic_vector(STORE_WIDTH-1 downto 0);

		current_value : out std_logic_vector(STORE_WIDTH-1 downto 0)
	);
	END component;
	
	component simple_counter IS
	generic
	(
		COUNT_WIDTH : natural := 1
	);
	PORT 
	( 
		CLK : IN STD_LOGIC;
		RESET_n : IN STD_LOGIC;
		increment : in std_logic;
		load : IN STD_LOGIC;
		load_value : in std_logic_vector(COUNT_WIDTH-1 downto 0);

		current_value : out std_logic_vector(COUNT_WIDTH-1 downto 0)
	);
	END component;

	function To_Std_Logic(L: BOOLEAN) return std_ulogic is
	begin
		if L then
			return('1');
		else
			return('0');
		end if;
	end function To_Std_Logic;
	
	signal addr_decoded : std_logic_vector(15 downto 0);
	
	signal enable_dma : std_logic;
	signal dma_clock_character_name : std_logic;
	signal dma_clock_character_inc : std_logic;
	signal dma_clock_bitmap_data : std_logic;
	signal dma_clock_character_data : std_logic;
	
	signal wsync_next : std_logic;
	signal wsync_reg : std_logic;
	signal wsync_reset : std_logic;
	signal wsync_write : std_logic;
	signal wsync_delayed_write : std_logic;
	
	signal nmi_next : std_logic;
	signal nmi_reg : std_logic;
	
	signal nmist_next : std_logic_vector(7 downto 5); -- dli/vbi/reset
	signal nmist_reg : std_logic_vector(7 downto 5);
	
	signal nmist_reset : std_logic;
	
	signal nmien_raw_next : std_logic_vector(7 downto 6); -- dli/vbi (reset always active)
	signal nmien_raw_reg : std_logic_vector(7 downto 6);
	signal nmien_delayed_reg : std_logic_vector(7 downto 6);
	
	signal dli_nmi_next : std_logic;
	signal vbi_nmi_next : std_logic;
	signal dli_nmi_reg : std_logic;
	signal vbi_nmi_reg : std_logic;
	
	signal nmi_reset : std_logic;
	--signal nmi_pending_next : std_logic; -- looks like on t65 the nmi_n is blocked by rdy being low, but not on real hardware?? XXX verify
	--signal nmi_pending_reg : std_logic;
	
	signal playfield_dma_start_raw : std_logic;
	signal playfield_dma_start_next : std_logic_vector(63 downto 0);
	signal playfield_dma_start_reg : std_logic_vector(63 downto 0);
	signal playfield_dma_start : std_logic;

	signal playfield_dma_end_raw : std_logic;
	signal playfield_dma_end_next : std_logic_vector(63 downto 0);
	signal playfield_dma_end_reg : std_logic_vector(63 downto 0);
	signal playfield_dma_end : std_logic;

	signal playfield_display_active_next : std_logic;
	signal playfield_display_active_reg : std_logic;
	
	signal dmactl_raw_next : std_logic_vector(6 downto 0);
	signal dmactl_raw_reg : std_logic_vector(6 downto 0);
	signal dmactl_delayed_reg : std_logic_vector(6 downto 0);
	signal dmactl_delayed_enabled : std_logic;

	signal playfield_dma_enabled : std_logic;
	
	signal chactl_next : std_logic_vector(2 downto 0);
	signal chactl_reg : std_logic_vector(2 downto 0);
	
	-- dma is only allowed during certain portions of the display
	signal allow_real_dma_next : std_logic;
	signal allow_real_dma_reg : std_logic;
	
	-- dma fetch handling
	-- dma is scheduled one cycle before it happens, so that registers can directly drive output	
	signal dma_fetch_next : std_logic;
	signal dma_fetch_reg : std_logic;
	signal dma_address_next : std_logic_vector(15 downto 0);
	signal dma_address_reg : std_logic_vector(15 downto 0);

	signal dma_cache_next : std_logic_vector(7 downto 0);
	signal dma_cache_reg : std_logic_vector(7 downto 0);
	signal dma_cache_ready_next : std_logic;
	signal dma_cache_ready_reg : std_logic;
	
	constant dma_fetch_line_buffer : std_logic_vector(2 downto 0) := "000";
	constant dma_fetch_shiftreg : std_logic_vector(2 downto 0) := "001";
	constant dma_fetch_null : std_logic_vector(2 downto 0) := "010";
	constant dma_fetch_instruction : std_logic_vector(2 downto 0) := "011";
	constant dma_fetch_list_low : std_logic_vector(2 downto 0) := "100";
	constant dma_fetch_list_high : std_logic_vector(2 downto 0) := "101";
	signal dma_fetch_destination_next : std_logic_vector(2 downto 0);
	signal dma_fetch_destination_reg : std_logic_vector(2 downto 0);
	signal dma_fetch_request : std_logic;
	
	signal display_list_address_low_temp_next : std_logic_vector(7 downto 0);
	signal display_list_address_low_temp_reg : std_logic_vector(7 downto 0);
	
	signal character_next : std_logic_vector(7 downto 0);
	signal character_reg : std_logic_vector(7 downto 0);
	signal displayed_character_next : std_logic_vector(7 downto 0);
	signal displayed_character_reg : std_logic_vector(7 downto 0);

	-- instruction decode
	signal instruction_next : std_logic_vector(7 downto 0);
	signal instruction_reg : std_logic_vector(7 downto 0);
	
	signal first_line_of_instruction_next : std_logic;
	signal first_line_of_instruction_reg: std_logic;

	signal last_line_of_instruction_live : std_logic;
	signal last_line_of_instruction_next : std_logic;
	signal last_line_of_instruction_reg: std_logic;
	
	signal force_final_row : std_logic;
	
	signal instruction_blank_reg : std_logic;
	signal instruction_blank_next : std_logic;

	--type dma_speed_type is (no_dma,slow_dma,medium_dma,fast_dma);
	--signal dma_speed_next : dma_speed_type;
	--signal dma_speed_reg : dma_speed_type;
	constant no_dma : std_logic_vector(1 downto 0) := "00";
	constant slow_dma : std_logic_vector(1 downto 0) := "01";
	constant medium_dma : std_logic_vector(1 downto 0) := "10";
	constant fast_dma : std_logic_vector(1 downto 0) := "11";
	signal dma_speed_next : std_logic_vector(1 downto 0);
	signal dma_speed_reg : std_logic_vector(1 downto 0);
	signal slow_dma_s,medium_dma_s,fast_dma_s : std_logic; -- remove me XXX
	
	--type instruction_type is (mode_character, mode_bitmap, mode_jvb, mode_jump, mode_blank);
	--signal instruction_type_next : instruction_type;
	--signal instruction_type_reg : instruction_type;
	constant mode_character : std_logic_vector(2 downto 0) := "000";
	constant mode_bitmap : std_logic_vector(2 downto 0) := "001";
	constant mode_jvb : std_logic_vector(2 downto 0) := "010";
	constant mode_jump : std_logic_vector(2 downto 0) := "011";
	constant mode_blank : std_logic_vector(2 downto 0) := "100";
	signal instruction_type_next : std_logic_vector(2 downto 0);
	signal instruction_type_reg : std_logic_vector(2 downto 0);
	
	signal two_part_instruction_next : std_logic;
	signal two_part_instruction_reg : std_logic;

		-- e.g. if instruction is 8 lines long then the final row is 7
	signal instruction_final_row_next : std_logic_vector(3 downto 0);
	signal instruction_final_row_reg : std_logic_vector(3 downto 0);
		
	--type shift_rate_type is (slow_shift,medium_shift,fast_shift);
	--signal shift_rate_next : shift_rate_type;
	--signal shift_rate_reg : shift_rate_type;
	constant slow_shift : std_logic_vector(1 downto 0) := "00";
	constant medium_shift : std_logic_vector(1 downto 0) := "01";
	constant fast_shift : std_logic_vector(1 downto 0) := "10";
	signal shift_rate_next : std_logic_vector(1 downto 0);
	signal shift_rate_reg : std_logic_vector(1 downto 0);
	
	signal shift_twobit_next : std_logic; -- Provide AN0 and AN1, or just AN0
	signal shift_twobit_reg : std_logic;
	
	signal twopixel_next : std_logic; -- GTIA should interpret output as two pixels
	signal twopixel_reg : std_logic;	
	
	signal single_colour_character_next : std_logic; -- for antic 6/7 where high two bits of character code determine colour
	signal single_colour_character_reg : std_logic;

	signal multi_colour_character_next : std_logic; -- for antic 4/5 where 2 bits + 1 bit of of character code determin colour
	signal multi_colour_character_reg : std_logic;
	
	signal twoline_character_next : std_logic; -- for antic 5/7
	signal twoline_character_reg : std_logic;
	
	signal map_background_next : std_logic; -- background,pf0,pf1,pf2 graphics modes or background,pf0 modes
	signal map_background_reg : std_logic;
	
	signal dli_enabled_next : std_logic;
	signal dli_enabled_reg : std_logic;
	
	signal descenders_next : std_logic; -- for mode 3
	signal descenders_reg : std_logic;
		
	-- Shift register used to output to AN2-AN0	
	-- Can either be loaded from memory or from the line buffer
	signal display_shift_next : std_logic_vector(7 downto 0);
	signal display_shift_reg : std_logic_vector(7 downto 0);
	
	signal delay_display_shift_next : std_logic_vector(24 downto 0);
	signal delay_display_shift_reg : std_logic_vector(24 downto 0);
	
	signal data_live : std_logic_vector(1 downto 0); -- helper for chatctl
	
	signal load_display_shift_from_memory : std_logic;
	signal load_display_shift_from_line_buffer : std_logic;
	
	signal enable_shift : std_logic;
	signal shiftclock_next : std_logic_vector(3 downto 0);
	signal shiftclock_reg : std_logic_vector(3 downto 0);
	
	signal playfield_reset : std_logic;
	signal playfield_load : std_logic;
	
	-- position in frame	
	signal hcount_next : std_logic_vector(9 downto 0);
	signal hcount_reg : std_logic_vector(9 downto 0);
	signal cycle_latter : std_logic;
	
	signal vcount_next : std_logic_vector(8 downto 0);
	signal vcount_reg : std_logic_vector(8 downto 0);
	
	signal vblank_next : std_logic;
	signal vblank_reg : std_logic;
	signal vsync_next : std_logic;
	signal vsync_reg : std_logic;
	
	signal hblank_next : std_logic;
	signal hblank_reg : std_logic;
	
	signal playfield_dma_start_cycle : std_logic_vector(9 downto 0);
	signal playfield_dma_end_cycle : std_logic_vector(9 downto 0);
	signal playfield_display_start_cycle : std_logic_vector(7 downto 0);
	signal playfield_display_end_cycle : std_logic_vector(7 downto 0);
	
	signal hcount_reset : std_logic;
	signal vcount_reset : std_logic;
	signal vcount_increment : std_logic;
	
	-- scrolling	
	signal hscrol_reg : std_logic_vector(3 downto 0);
	signal hscrol_next : std_logic_vector(3 downto 0);
	signal hscrol_adj : std_logic_vector(4 downto 0);

	signal vscrol_raw_reg : std_logic_vector(3 downto 0);
	signal vscrol_raw_next : std_logic_vector(3 downto 0);
	signal vscrol_delayed_reg : std_logic_vector(3 downto 0);
	
	signal vscrol_enabled_reg : std_logic;
	signal vscrol_enabled_next : std_logic;
	signal vscrol_last_enabled_reg : std_logic;
	signal vscrol_last_enabled_next : std_logic;
	
	signal update_row_count : std_logic;
	
	signal hscrol_enabled_reg : std_logic;
	signal hscrol_enabled_next : std_logic;

	-- refresh
	signal refresh_pending_next : std_logic;
	signal refresh_pending_reg : std_logic;

	signal refresh_fetch_next : std_logic;
	signal refresh_fetch_reg : std_logic;
	
	-- Counter signals
	signal increment_display_list_address : std_logic;
	signal load_display_list_address : std_logic;
	signal display_list_address_next : std_logic_vector(15 downto 0);
	signal display_list_address_reg : std_logic_vector(15 downto 0);
	signal load_display_list_address_cpu : std_logic;
	signal load_display_list_address_dma : std_logic;
	signal display_list_address_next_cpu : std_logic_vector(15 downto 0);
	signal display_list_address_next_dma : std_logic_vector(15 downto 0);	

	signal increment_memory_scan_address : std_logic;
	signal load_memory_scan_address : std_logic;
	signal memory_scan_address_next : std_logic_vector(15 downto 0);
	signal memory_scan_address_reg : std_logic_vector(15 downto 0);

	signal increment_line_buffer_address : std_logic;
	signal load_line_buffer_address : std_logic;
	signal line_buffer_address_next : std_logic_vector(7 downto 0);
	signal line_buffer_address_reg : std_logic_vector(7 downto 0);

	signal increment_row_count : std_logic;
	signal load_row_count : std_logic;
	signal row_count_next : std_logic_vector(3 downto 0);
	signal row_count_reg : std_logic_vector(3 downto 0);

	signal increment_refresh_count : std_logic;
	signal load_refresh_count : std_logic;
	signal refresh_count_next : std_logic_vector(3 downto 0);
	signal refresh_count_reg : std_logic_vector(3 downto 0);
	
	signal pmbase_reg : std_logic_vector(7 downto 2);
	signal pmbase_next : std_logic_vector(7 downto 2);

	signal chbase_raw_reg : std_logic_vector(7 downto 1);
	signal chbase_raw_next : std_logic_vector(7 downto 1);
	signal chbase_delayed_reg : std_logic_vector(7 downto 1);
	
	signal line_buffer_write : std_logic;
	signal line_buffer_data_in : std_logic_vector(7 downto 0);
	signal line_buffer_data_out : std_logic_vector(7 downto 0);
	
	-- output registers
	signal an_current_raw : std_logic_vector(2 downto 0); -- live unregistered calculation of next output (not gated by cc)
	signal an_current : std_logic_vector(2 downto 0); -- 0 colour clock delay for hscrol (after adjustment for 2x and 4x)
	signal an_prev : std_logic_vector(2 downto 0); -- 1 colour clock delay for hscrol (after adjustment for 2x and 4x)
	signal an_next : std_logic_vector(2 downto 0);
	signal an_reg : std_logic_vector(2 downto 0);
	type an_shift_type is array(3 downto 0) of std_logic_vector(2 downto 0);
	signal an_current_next : an_shift_type;
	signal an_current_reg : an_shift_type; -- delay shift output to align 2x and 4x
	
	-- light pendin
	signal penv_next : std_logic_vector(7 downto 0);
	signal penv_reg : std_logic_vector(7 downto 0);
	signal penh_next : std_logic_vector(7 downto 0);
	signal penh_reg : std_logic_vector(7 downto 0);
	
	-- high res modes
	signal colour_clock_8x : std_logic;
	signal colour_clock_4x : std_logic;
	signal colour_clock_2x : std_logic;
	signal colour_clock_1x : std_logic;
	signal colour_clock_half_x : std_logic;
	signal colour_clock_selected : std_logic;
	signal colour_clock_selected_highres : std_logic;
	
	signal colour_clock_shift0_reg : std_logic_vector(cycle_length-1 downto 0);
	signal colour_clock_shift0_next : std_logic_vector(cycle_length-1 downto 0);
	signal colour_clock_shift2_reg : std_logic_vector(cycle_length/4-1 downto 0);
	signal colour_clock_shift2_next : std_logic_vector(cycle_length/4-1 downto 0);
	signal colour_clock_shift4_reg : std_logic_vector(cycle_length/8-1 downto 0);
	signal colour_clock_shift4_next : std_logic_vector(cycle_length/8-1 downto 0);
	signal colour_clock_shift8_reg : std_logic_vector(cycle_length/16-1 downto 0);
	signal colour_clock_shift8_next : std_logic_vector(cycle_length/16-1 downto 0);
	
	signal memory_ready_both : std_logic;
	
BEGIN
	-- register
	process(clk,reset_n)
	begin
		if (reset_n = '0') then
			nmi_reg <= '0';
			wsync_reg <= '0';
			vcount_reg <= (others=>'0');
			--hcount_reg <= X"01";
			hcount_reg <= (others=>'0');
			dmactl_raw_reg <= (others=>'0');
			chactl_reg <= (others=>'0');
			vblank_reg <= '0';			
			vsync_reg <= '0';
			pmbase_reg <= (others=>'0');
			allow_real_dma_reg <= '0';
			display_shift_reg <= (others=>'0');
			chbase_raw_reg <= (others=>'0');
			
			instruction_reg <= (others=>'0');
			first_line_of_instruction_reg <= '0';
			last_line_of_instruction_reg <= '0';
			dma_speed_reg <= no_dma;
			instruction_type_reg <= mode_blank;
			instruction_final_row_reg <= (others=>'0');
			shift_rate_reg <= slow_shift;
			shift_twobit_reg <= '0';
			twopixel_reg <= '0';
			single_colour_character_reg <= '0';
			multi_colour_character_reg <= '0';
			twoline_character_reg <= '0';
			map_background_reg <= '0';
			dli_enabled_reg <= '0';
			two_part_instruction_reg <= '0';
			descenders_reg <='0';
			
			hscrol_reg <= (others=>'0');
			vscrol_raw_reg <= (others=>'0');			
			vscrol_enabled_reg <= '0';
			vscrol_last_enabled_reg <= '0';
			hscrol_enabled_reg <= '0';
			
			shiftclock_reg <= (others=>'0');
			
			hblank_reg <= '0';
			
			an_reg <= (others=>('0'));
			an_current_reg <= (others=>(others=>('0')));
			
			dma_fetch_reg <= '0';
			dma_address_reg <= (others=>'0');			
			dma_cache_reg <= (others=>'0');
			dma_cache_ready_reg <= '0';
			dma_fetch_destination_reg <= dma_fetch_null;
			
			playfield_display_active_reg <= '0';
			
			instruction_blank_reg <= '0';
			
			display_list_address_low_temp_reg <= (others=>'0');
			
			character_reg <= (others=>'0');
			displayed_character_reg <= (others=>'0');
			
			refresh_pending_reg <= '0';
			refresh_fetch_reg <= '0';
			
			--nmi_pending_reg <= '0';
			
			dli_nmi_reg <= '0';
			vbi_nmi_reg <= '0';
			nmien_raw_reg <= (others=>'0');
			
			delay_display_shift_reg <= (others=>'0');
			
			penh_reg <= (others=>'0');
			penv_reg <= (others=>'0');
			
			colour_clock_shift0_reg <= (others=>'0');
			colour_clock_shift2_reg <= (others=>'0');
			colour_clock_shift4_reg <= (others=>'0');
			colour_clock_shift8_reg <= (others=>'0');

			playfield_dma_start_reg <= (others=>'0');
			playfield_dma_end_reg <= (others=>'0');
			
		elsif (clk'event and clk='1') then			
			nmi_reg <= nmi_next;
			wsync_reg <= wsync_next;
			vcount_reg <= vcount_next;
			hcount_reg <= hcount_next;
			nmist_reg <= nmist_next;
			dmactl_raw_reg <= dmactl_raw_next;
			chactl_reg <= chactl_next;
			vblank_reg <= vblank_next;
			vsync_reg <= vsync_next;
			pmbase_reg <= pmbase_next;
			allow_real_dma_reg <= allow_real_dma_next;
			display_shift_reg <= display_shift_next;
			chbase_raw_reg <= chbase_raw_next;
			
			instruction_reg <= instruction_next;
			first_line_of_instruction_reg <= first_line_of_instruction_next;
			last_line_of_instruction_reg <= last_line_of_instruction_next;
			dma_speed_reg <= dma_speed_next;
			instruction_type_reg <= instruction_type_next;
			instruction_final_row_reg <= instruction_final_row_next;
			shift_rate_reg <= shift_rate_next;
			shift_twobit_reg <= shift_twobit_next;
			twopixel_reg <= twopixel_next;
			single_colour_character_reg <= single_colour_character_next;
			multi_colour_character_reg <= multi_colour_character_next;
			twoline_character_reg <= twoline_character_next;
			map_background_reg <= map_background_next;
			dli_enabled_reg <= dli_enabled_next;
			two_part_instruction_reg <= two_part_instruction_next;
			descenders_reg <= descenders_next;
			
			hscrol_reg <= hscrol_next;
			vscrol_raw_reg <= vscrol_raw_next;	
			vscrol_enabled_reg <= vscrol_enabled_next;
			vscrol_last_enabled_reg <= vscrol_last_enabled_next;
			hscrol_enabled_reg <= hscrol_enabled_next;
			
			shiftclock_reg <= shiftclock_next;
			
			hblank_reg <= hblank_next;
			
			an_reg <= an_next;
			an_current_reg <= an_current_next;
			
			dma_fetch_reg <= dma_fetch_next;
			dma_address_reg <= dma_address_next;
			dma_cache_reg <= dma_cache_next;
			dma_cache_ready_reg <= dma_cache_ready_next;
			dma_fetch_destination_reg <= dma_fetch_destination_next;
			
			playfield_display_active_reg <= playfield_display_active_next;
			
			instruction_blank_reg <= instruction_blank_next;
			
			display_list_address_low_temp_reg <= display_list_address_low_temp_next;
			
			character_reg <= character_next;
			displayed_character_reg <= displayed_character_next;
			
			refresh_pending_reg <= refresh_pending_next;
			refresh_fetch_reg <= refresh_fetch_next;
						
			dli_nmi_reg <= dli_nmi_next;
			vbi_nmi_reg <= vbi_nmi_next;
			nmien_raw_reg <= nmien_raw_next;
			
			delay_display_shift_reg <= delay_display_shift_next;
			
			penh_reg <= penh_next;
			penv_reg <= penv_next;
			
			colour_clock_shift0_reg <= colour_clock_shift0_next;
			colour_clock_shift2_reg <= colour_clock_shift2_next;
			colour_clock_shift4_reg <= colour_clock_shift4_next;
			colour_clock_shift8_reg <= colour_clock_shift8_next;

			playfield_dma_start_reg <= playfield_dma_start_next;
			playfield_dma_end_reg <= playfield_dma_end_next;

		end if;
	end process;
	
	-- Colour clock (3.57MHz for PAL)
	-- TODO - allow double for 640 pixel width and quadruple for 1280 pixel width)
	-- TODO - allow other clocks for driving VGA (mostly higher dot clock + line doubling (buffer between antic and gtia??))

	process(colour_clock_shift0_reg, colour_clock_shift2_reg, colour_clock_shift4_reg, colour_clock_shift8_reg, ANTIC_ENABLE_179 )		
	begin
		colour_clock_shift0_next(cycle_length-1 downto 0) <= colour_clock_shift0_reg(cycle_length-2 downto 0)&(ANTIC_ENABLE_179 or colour_clock_shift0_reg(cycle_length-1));
		colour_clock_shift2_next(cycle_length/4-1 downto 0) <= colour_clock_shift2_reg(cycle_length/4-2 downto 0)&(ANTIC_ENABLE_179 or colour_clock_shift2_reg(cycle_length/4-1));
		colour_clock_shift4_next(cycle_length/8-1 downto 0) <= colour_clock_shift4_reg(cycle_length/8-2 downto 0)&(ANTIC_ENABLE_179 or colour_clock_shift4_reg(cycle_length/8-1));
		colour_clock_shift8_next(cycle_length/16-1 downto 0) <= colour_clock_shift8_reg(cycle_length/16-2 downto 0)&(ANTIC_ENABLE_179 or colour_clock_shift8_reg(cycle_length/16-1));
		
		colour_clock_half_x <= colour_clock_shift0_reg(cycle_length-1);
		colour_clock_1x <= colour_clock_shift0_reg(cycle_length-1) or colour_clock_shift0_reg(cycle_length/2-1);
		colour_clock_2x <= colour_clock_shift2_reg(cycle_length/4-1);
		colour_clock_4x <= colour_clock_shift4_reg(cycle_length/8-1);
		colour_clock_8x <= colour_clock_shift8_reg(cycle_length/16-1);
	end process;

	process(playfield_dma_end_raw, playfield_dma_end_reg, playfield_dma_start_raw, playfield_dma_start_reg, colour_clock_4x)
	begin
		playfield_dma_start_next <= playfield_dma_start_reg;
		playfield_dma_end_next <= playfield_dma_end_reg;
		if (colour_clock_4x='1') then
			playfield_dma_start_next <= playfield_dma_start_reg(62 downto 0)&playfield_dma_start_raw;
			playfield_dma_end_next <= playfield_dma_end_reg(62 downto 0)&playfield_dma_end_raw;
		end if;
	end process;
	
	process(colour_clock_half_x,colour_clock_1x,colour_clock_2x, colour_clock_4x, colour_clock_8x, dmactl_delayed_reg, playfield_dma_start_reg, playfield_dma_start_raw, playfield_dma_end_reg, playfield_dma_end_raw, hcount_reg, hscrol_reg, an_current_next)
	begin
		enable_dma <= colour_clock_half_x;
		colour_clock_selected <= colour_clock_1x;
		colour_clock_selected_highres <= colour_clock_2x;		
		dmactl_delayed_enabled <= '0';
		playfield_dma_start <= playfield_dma_start_raw;
		playfield_dma_end <= playfield_dma_end_raw;
		cycle_latter <= not(hcount_reg(2));
		hscrol_adj <= hscrol_reg(3 downto 1)&"00";

		an_current <= an_current_next(0);
		an_prev <= an_current_next(1);
		
		case dmactl_delayed_reg(6 downto 5) is
		when "01" =>
			dmactl_delayed_enabled <= '1';
		when "10" =>
			enable_dma <= colour_clock_1x;
			colour_clock_selected <= colour_clock_2x;		
			colour_clock_selected_highres <= colour_clock_4x;
			dmactl_delayed_enabled <= '1';
			playfield_dma_start <= playfield_dma_start_reg(3+24);
			playfield_dma_end <= playfield_dma_end_reg(7+24);
			cycle_latter <= hcount_reg(1);
			hscrol_adj <= "0"&hscrol_reg(3 downto 1)&"0";
		when "11" =>
			enable_dma <= colour_clock_2x;
			colour_clock_selected <= colour_clock_4x;
			colour_clock_selected_highres <= colour_clock_8x;
			dmactl_delayed_enabled <= '1';
			playfield_dma_start <= playfield_dma_start_reg(5+36);
			playfield_dma_end <= playfield_dma_end_reg(11+36);
			cycle_latter <= hcount_reg(0);
			hscrol_adj <= "00"&hscrol_reg(3 downto 1);
		when others =>
			--nop
		end case;		
	end process;	

	-- Counters (memory address for data, memory address for display list)
	antic_counter_memory_scan : antic_counter
		generic map (STORE_WIDTH=>16, COUNT_WIDTH=>12)
		port map (clk=>clk, reset_n=>reset_n, increment=>increment_memory_scan_address, load=>load_memory_scan_address, load_value=>memory_scan_address_next, current_value=>memory_scan_address_reg);
		
	load_display_list_address <= load_display_list_address_cpu or load_display_list_address_dma;
	display_list_address_next <= display_list_address_next_cpu when load_display_list_address_cpu='1' else display_list_address_next_dma;
	antic_counter_display_list : antic_counter
		generic map (STORE_WIDTH=>16, COUNT_WIDTH=>10)
		port map (clk=>clk, reset_n=>reset_n, increment=>increment_display_list_address, load=>load_display_list_address, load_value=>display_list_address_next, current_value=>display_list_address_reg);
	antic_counter_line_buffer : simple_counter
		generic map (COUNT_WIDTH=>8)
		port map (clk=>clk, reset_n=>reset_n, increment=>increment_line_buffer_address, load=>load_line_buffer_address, load_value=>line_buffer_address_next, current_value=>line_buffer_address_reg);
	antic_counter_row_count : simple_counter
		generic map (COUNT_WIDTH=>4)
		port map (clk=>clk, reset_n=>reset_n, increment=>increment_row_count, load=>load_row_count, load_value=>row_count_next, current_value=>row_count_reg);
	antic_counter_refresh_count : simple_counter
		generic map (COUNT_WIDTH=>4)
		port map (clk=>clk, reset_n=>reset_n, increment=>increment_refresh_count, load=>load_refresh_count, load_value=>refresh_count_next, current_value=>refresh_count_reg);
	
	-- Count position on screen
	-- horizontal
	process(hcount_reg, colour_clock_4x, colour_clock_half_x, hcount_reset)
	begin
		hcount_next <= hcount_reg;		
		if (colour_clock_4x = '1') then
			hcount_next <= std_logic_vector(unsigned(hcount_reg)+1);
			
			if (colour_clock_half_x = '1') then
				hcount_next(2 downto 0) <= "100";
			end if;
		end if;
		
		if (hcount_reset = '1') then
			hcount_next <= (others=>'0');
		end if;
	end process;
	
	-- vertical
	process(vcount_reg, vcount_increment, vcount_reset, antic_enable_179)
	begin
		vcount_next <= vcount_reg;
		
		if (antic_enable_179 = '1') then		
			if (vcount_increment = '1') then
				vcount_next <= std_logic_vector(unsigned(vcount_reg)+1);
			end if;
			
			if (vcount_reset = '1') then
				vcount_next <= (others=>'0');
			end if;
		end if;
	end process;	
	
	-- Actions done based on vertical position		
	process(vcount_reg, vblank_reg, vsync_reg, colour_clock_1x,vcount_increment,pal)
	begin
		vblank_next <= vblank_reg;
		vsync_next <= vsync_reg;
		vcount_reset <= '0';
	
		if (colour_clock_1x='1') then
			case vcount_reg is
				when '0'&X"08" => 
					vblank_next <= '0';
				when '0'&X"F8" =>
					vblank_next <= '1';
				--when '1'&X"05" => (changed for testing galaxian!)
				--	vblank_next <= '1';					
-- PAL
				when '1'&X"13" =>
					vsync_next <= pal;
				when '1'&X"16" =>
					vsync_next <= '0';
				when '1'&X"38" =>
					vcount_reset <= '1'; -- Blip at 9c..., then wrap
-- NTSC
				when '0'&X"FF" =>
					vsync_next <= not(pal);
				when '1'&X"02" =>
					vsync_next <= '0';
				when '1'&X"06" =>
					vcount_reset <= not(pal); -- Blip at 9c..., then wrap
				when others =>
					-- nothing
			end case;
		end if;
	end process;
	
	-- Calculate playfield start/end
	process(hscrol_enabled_reg, dmactl_delayed_reg, hscrol_adj, hscrol_reg)
		variable width : std_logic_vector(1 downto 0);
		variable hscrol_adj_en : std_logic_vector(5 downto 0);
	begin		
		playfield_dma_start_cycle <= x"ff"&"00";
		playfield_dma_end_cycle <= x"ff"&"00";
		playfield_display_start_cycle <= (others=>'1');
		playfield_display_end_cycle <= (others=>'1');

		playfield_dma_enabled <= dmactl_delayed_reg(1) or dmactl_delayed_reg(0); -- TODO, more work needed here
		
		-- DMA clock start/end
		-- wide=3, normal=2, narrow=1
		-- Playfield start is at (in colour clocks):
		-- 68 + hscrol&FE - width*16
		-- i.e. for width=3 and hscrol=0 -> 68+0-48 = 20 (10 in cycles)
		-- i.e. for width=2 and hscrol=0 -> 68+0-32 = 36 (18 in cycles)
		-- i.e. for width=1 and hscrol=0 -> 68+0-16 = 52 (26 in cycles)
		-- MUST BE A NICE EASY WAY TO GET THIS - expect offset is wrong... 
		-- e.g. if its 64 then we may be able to do something like base&width&
		-- Playfield end is at (in colour clocks):
		-- 164 + hscrol&FE + width*16
		-- i.e. for width=3 and hscrol=0 -> 164+0+48 = 212 (106 in cycles)
		-- i.e. for width=2 and hscrol=0 -> 164+0+32 = 192 (96 in cycles)
		-- i.e. for width=1 and hscrol=0 -> 164+0+16 = 180 (92 in cycles)
		
		-- hscrol interfers with playfield dma width (for dma purposes only!)
		width := dmactl_delayed_reg(1 downto 0);
		if (hscrol_enabled_reg='1' and not(width="11")) then
			width:= std_logic_vector(unsigned(width) + 1);
		end if;

		hscrol_adj_en := "000000";
		if (hscrol_enabled_reg='1') then
			hscrol_adj_en := hscrol_adj&"0";
		end if;

		-- subsequent delay by hscrol_reg(3 downto 1) if hscrol_enabled_reg
		case width is
			when "11" => -- wide
				playfield_dma_start_cycle <= std_logic_vector(unsigned(std_logic_vector'(X"12"&"11")) + unsigned(hscrol_adj_en));
				playfield_dma_end_cycle   <= std_logic_vector(unsigned(std_logic_vector'(X"D0"&"11")) + unsigned(hscrol_adj_en));
			when "10" => -- normal
				playfield_dma_start_cycle <= std_logic_vector(unsigned(std_logic_vector'(X"22"&"11")) + unsigned(hscrol_adj_en));
				playfield_dma_end_cycle   <= std_logic_vector(unsigned(std_logic_vector'(X"C0"&"11")) + unsigned(hscrol_adj_en));
			when "01" => -- narrow
				playfield_dma_start_cycle <= std_logic_vector(unsigned(std_logic_vector'(X"32"&"11")) + unsigned(hscrol_adj_en));
				playfield_dma_end_cycle <=   std_logic_vector(unsigned(std_logic_vector'(X"B0"&"11")) + unsigned(hscrol_adj_en));
			when others =>
				-- nothing
		end case;		

		-- background colour outside this area...
		-- TODO - review these locations - should be clear due to garbage!
		case dmactl_delayed_reg(1 downto 0) is
			when "11" => -- wide
				playfield_display_start_cycle <= X"2C"; -- TODO work out correct noise on left for large hscrol
				if (hscrol_reg > X"C") then
					playfield_display_start_cycle <= X"30"; -- TODO work out correct noise on left for large hscrol				
				end if;
				playfield_display_end_cycle   <= X"DE"; -- last two colour clocks are corrupt (ie dc to dd), then there are two missing...
			when "10" => -- normal
				playfield_display_start_cycle <= X"30";
				playfield_display_end_cycle   <= X"d0";
			when "01" => -- narrow
				playfield_display_start_cycle <= X"40";
				playfield_display_end_cycle <=   X"c0";
			when others =>
				-- nothing
		end case;				
	end process;

	-- Actions done based on horizontal position - notably dma!
	process (dmactl_delayed_enabled, hcount_reg, vcount_reg, vblank_reg, hblank_reg, dmactl_delayed_reg, playfield_dma_start_cycle, playfield_dma_end_cycle, playfield_display_start_cycle, playfield_display_end_cycle, instruction_final_row_reg, display_list_address_reg, pmbase_reg, first_line_of_instruction_reg, last_line_of_instruction_live, last_line_of_instruction_reg, instruction_type_reg, dma_clock_character_name, dma_clock_character_data, dma_clock_bitmap_data, allow_real_dma_reg, row_count_reg, dma_address_reg, memory_scan_address_reg, chbase_delayed_reg, line_buffer_data_out, enable_dma, colour_clock_1x, colour_clock_selected, two_part_instruction_reg, dma_fetch_destination_reg, playfield_display_active_reg, character_reg, dma_clock_character_inc, single_colour_character_reg, twoline_character_reg, instruction_reg, dli_enabled_reg, refresh_fetch_next, chactl_reg, vscrol_enabled_reg, vscrol_last_enabled_reg,twopixel_reg,dli_nmi_reg,vbi_nmi_reg,displayed_character_reg, playfield_dma_enabled)
	begin
		allow_real_dma_next <= allow_real_dma_reg;

		playfield_dma_start_raw <= '0';
		playfield_dma_end_raw <= '0';
		playfield_display_active_next <= playfield_display_active_reg;
		
		dma_fetch_request <= '0';
		dma_address_next <= dma_address_reg;
		dma_fetch_destination_next <= dma_fetch_destination_reg;
		
		first_line_of_instruction_next <= first_line_of_instruction_reg;
		last_line_of_instruction_next <= last_line_of_instruction_reg;
		
		load_display_shift_from_line_buffer <= '0';
				
		increment_memory_scan_address <= '0';
		
		line_buffer_address_next <= (others=>'0');
		load_line_buffer_address <= '0';
		increment_line_buffer_address <= '0';
		
		hblank_next <= hblank_reg;
		hcount_reset <= '0';
		
		vcount_increment <= '0';
		
		character_next <= character_reg;
		displayed_character_next <= displayed_character_reg;
		
		dli_nmi_next <= dli_nmi_reg;
		vbi_nmi_next <= vbi_nmi_reg;
		wsync_reset <= '0';
		
		load_refresh_count <= '0';
		refresh_count_next <= (others=>'0');
		
		update_row_count <= '0'; 
		vscrol_last_enabled_next <= vscrol_last_enabled_reg;

		if (colour_clock_selected='1') then
			if (dma_clock_character_data = '1') then -- Final cycle of this is cycle 114 (0 based) - aka cycle 0... Which clashes with pmg dma.
				if (dmactl_delayed_enabled='1' and instruction_type_reg = mode_character) then -- Sooo only enable, never disable
					dma_fetch_request <= '1';
				end if;				

				if (twoline_character_reg='1') then
					if (single_colour_character_reg='1') then
						dma_address_next <= chbase_delayed_reg(7 downto 1)&character_reg(5 downto 0)&(row_count_reg(3 downto 1)xor chactl_reg(2)&chactl_reg(2)&chactl_reg(2));
					else
						dma_address_next <= chbase_delayed_reg(7 downto 2)&character_reg(6 downto 0)&(row_count_reg(3 downto 1)xor chactl_reg(2)&chactl_reg(2)&chactl_reg(2));
					end if;
				else
					if (single_colour_character_reg='1') then
						dma_address_next <= chbase_delayed_reg(7 downto 1)&character_reg(5 downto 0)&(row_count_reg(2 downto 0)xor chactl_reg(2)&chactl_reg(2)&chactl_reg(2));
					else
						dma_address_next <= chbase_delayed_reg(7 downto 2)&character_reg(6 downto 0)&(row_count_reg(2 downto 0)xor chactl_reg(2)&chactl_reg(2)&chactl_reg(2));
					end if;
				end if;

				displayed_character_next <= character_reg;
				
				-- TODO
				-- Logic depends on mode - e.g. some 128 char, some 64 char etc. Line count is complex, depends on vscrol etc.				
				dma_fetch_destination_next <= dma_fetch_shiftreg;
				
				load_display_shift_from_line_buffer <= to_std_logic(instruction_type_reg = mode_bitmap);								
				increment_line_buffer_address <= '1';
			end if;						

			-- Playfield start/end
			if (hcount_reg = playfield_dma_start_cycle) then
				playfield_dma_start_raw <= '1';				
				load_line_buffer_address <= '1';
			end if;
			
			if (hcount_reg = playfield_dma_end_cycle) then
				playfield_dma_end_raw <= '1';
			end if;	
				
			if (colour_clock_1x='1') then
				if (hcount_reg(9 downto 2) = playfield_display_start_cycle) then
					playfield_display_active_next <= '1';				
				end if;
				
				if (hcount_reg(9 downto 2) = playfield_display_end_cycle) then
					playfield_display_active_next <= '0';
				end if;	

				case hcount_reg(9 downto 2) is 		
					when X"00" => -- missile DMA, if missile or player DMA enabled					
						dma_fetch_request <= dmactl_delayed_reg(2) or dmactl_delayed_reg(3);
						dma_fetch_destination_next <= dma_fetch_null;									
						if (dmactl_delayed_reg(4) = '1') then -- single line resolution
							dma_address_next <= pmbase_reg(7 downto 3)&"011"&vcount_reg(7 downto 0);
						else
							dma_address_next <= pmbase_reg(7 downto 2)&"011"&vcount_reg(7 downto 1);
						end if;
						
					when X"02" => -- display list dma if enabled
						first_line_of_instruction_next <= '0';
						
						if (instruction_type_reg = mode_jvb) then
							-- suppress when waiting for vblank
							first_line_of_instruction_next <= first_line_of_instruction_reg or vblank_reg;
						else				
							if (last_line_of_instruction_reg = '1') then -- set on previous line at cycle 108
								dma_fetch_request <= dmactl_delayed_enabled;
								dma_address_next <= display_list_address_reg;
								dma_fetch_destination_next <= dma_fetch_instruction;									
								
								first_line_of_instruction_next <= '1';						
								
								vscrol_last_enabled_next <= vscrol_enabled_reg;
							end if;
						end if;					
					
					when X"05" =>				
						update_row_count <= '1'; -- done after instruction fetch...
						
					when X"04"|X"06"|X"08"|X"0A" =>  -- player DMA, if enabled
						dma_fetch_request <= dmactl_delayed_reg(3);
						dma_fetch_destination_next <= dma_fetch_null;	
						if (dmactl_delayed_reg(4) = '1') then -- single line resolution
							dma_address_next <= pmbase_reg(7 downto 3)&std_logic_vector(unsigned(hcount_reg(5 downto 3))+2)&vcount_reg(7 downto 0);
						else
							dma_address_next <= pmbase_reg(7 downto 2)&std_logic_vector(unsigned(hcount_reg(5 downto 3))+2)&vcount_reg(7 downto 1);
						end if;
						
					when X"0C" => -- lms lower byte dma if display list dma enabled?;
						dma_fetch_request <= dmactl_delayed_enabled and first_line_of_instruction_reg and two_part_instruction_reg;
						dma_address_next <= display_list_address_reg;				
						dma_fetch_destination_next <= dma_fetch_list_low;
					
					when X"0E" => -- lms upper byte dma if display list dma enabled?
						dma_fetch_request <= dmactl_delayed_enabled and first_line_of_instruction_reg and two_part_instruction_reg;
						dma_address_next <= display_list_address_reg;				
						dma_fetch_destination_next <= dma_fetch_list_high;
						
						if (instruction_type_reg = mode_jvb) then
							-- turn off this extra dma for jvb mode, re-enabled by vblank_reg
							first_line_of_instruction_next <= '0';
						end if;
						
						dli_nmi_next <= dli_enabled_reg and last_line_of_instruction_live and not vblank_reg;
						if (vcount_reg = '0'&X"F8") then
							vbi_nmi_next <= '1';
						end if;
						
					when X"12" =>
						dli_nmi_next <= '0';
						vbi_nmi_next <= '0';

					when X"22" =>
						hblank_next <= '0';					
						
					when X"31" => -- start refresh					
						load_refresh_count <= '1';
						refresh_count_next <= (others=>'0');
					
					when X"D2" => -- cycle 105 - reset wsync so we process from 105 on
						wsync_reset <= '1';				
				
					when X"D4" => -- Force playfield DMA into virtual mode (cycle 105)
						allow_real_dma_next <= '0';				
						load_refresh_count <= '1';
						refresh_count_next <= "1001";
						
					when X"D8" => -- vscrol value checked at cycle 108
						last_line_of_instruction_next <= last_line_of_instruction_live;
					
					when X"DE" => -- Increment vcount immediately before cycle 111 (again the 4 offset as seen in hscrol...)
						vcount_increment <= '1';
						hblank_next <= '1';					
						
					when X"E3" => -- Wrap hcount after 227 (i.e. 0 to 227)
						hcount_reset <= '1';
						allow_real_dma_next <= not(vblank_reg);
					when others =>
						-- nothing
				end case;	
			end if;
			
			-- Playfield DMA
			if (instruction_type_reg = mode_character and dma_clock_character_name = '1') then -- for character name
				dma_fetch_request <= dmactl_delayed_enabled and first_line_of_instruction_reg and playfield_dma_enabled;
				dma_address_next <= memory_scan_address_reg;
				dma_fetch_destination_next <= dma_fetch_line_buffer;
				increment_memory_scan_address <= first_line_of_instruction_reg;
			end if;					
			
			if (instruction_type_reg = mode_character and dma_clock_character_inc = '1') then -- next character
				character_next <= line_buffer_data_out;
				increment_line_buffer_address <= '1';
			end if;
			
			if (instruction_type_reg = mode_bitmap and dma_clock_bitmap_data = '1' and first_line_of_instruction_reg='1') then -- bitmap data			
				dma_fetch_request <= dmactl_delayed_enabled and playfield_dma_enabled;
				dma_address_next <= memory_scan_address_reg;
				dma_fetch_destination_next <= dma_fetch_line_buffer;
				increment_memory_scan_address <= '1';		
			end if;
			
			if (vblank_reg = '1') then
				dma_fetch_request <= '0';
			end if;
			
			if (refresh_fetch_next = '1') then
				dma_address_next <= (others=>'0');
			end if;
		
		end if;
	end process;
	
	-- refresh handling
	process(cycle_latter,hcount_reg,refresh_count_reg,colour_clock_selected,dma_fetch_next,refresh_pending_reg, refresh_fetch_reg, allow_real_dma_next)
	begin
		increment_refresh_count <= '0';
		refresh_pending_next <= refresh_pending_reg;
		refresh_fetch_next <= refresh_fetch_reg;
		
		if (colour_clock_selected = '1' and cycle_latter= '1') then
			refresh_fetch_next <= '0';
		
			-- do pending refresh once we have a spare cycle
			if (refresh_pending_reg='1' and (dma_fetch_next='0' or allow_real_dma_next='0')) then
				refresh_fetch_next <= '1';		
				refresh_pending_next <= '0';
			end if;
		
			-- do scheduled refresh - if block, enable pending one
			if (hcount_reg(4 downto 3) = "01" and unsigned(refresh_count_reg)<9) then
				increment_refresh_count <= '1';
				refresh_fetch_next <= not(dma_fetch_next);
				refresh_pending_next <= dma_fetch_next;
			end if;
		end if;
	end process;
	
	process(refresh_fetch_next)
	begin
	end process;
	
	-- nmi handling
	-- edge senstive, single cycle is enough (unless cpu disabled or  clashes)
	-- antic asserts for 2 old cycles - if we stick to that then in turbo mode it fixes most nmi bugs, in normal mode they still exist...	which is the goal.	

	nmien_delay : entity work.wide_delay_line
		generic map (COUNT=>1,WIDTH=>2)
		port map (clk=>clk,sync_reset=>'0',data_in=>nmien_raw_reg(7 downto 6),enable=>antic_enable_179,reset_n=>reset_n,data_out=>nmien_delayed_reg(7 downto 6));
		
	process(antic_enable_179,nmi_reg,dli_nmi_reg,vbi_nmi_reg,nmien_delayed_reg,rnmi_n) --delay_line/latch
	begin
		nmi_next <= nmi_reg;
		if (antic_enable_179 = '1') then
			nmi_next <= not((dli_nmi_reg and nmien_delayed_reg(7)) or (vbi_nmi_reg and nmien_delayed_reg(6))) and rnmi_n;
		end if;
	end process;
	
	process(nmist_reg, vbi_nmi_reg, dli_nmi_reg, vbi_nmi_next, dli_nmi_next, nmist_reset, rnmi_n)
	begin	
		nmist_next(5) <= ((nmist_reg(5) and not(nmist_reset))) or not(rnmi_n);
		nmist_next(6) <= ((nmist_reg(6) and not(nmist_reset)) or vbi_nmi_reg or vbi_nmi_next) and not(dli_nmi_reg or dli_nmi_next); -- auto clear vbi flat on dli!
		nmist_next(7) <= ((nmist_reg(7) and not(nmist_reset))or dli_nmi_reg or dli_nmi_next) and not(vbi_nmi_reg or vbi_nmi_next); -- auto clear dli flag on vbi!
	end process;
	
	-- dma clock	
	process(dma_speed_reg) -- XXX TODO - remove this process!
	begin
		slow_dma_s <= '0';
		medium_dma_s <= '0';
		fast_dma_s <= '0';
		
		case dma_speed_reg is
			when no_dma =>
				-- nothing
			when slow_dma =>
				slow_dma_s <= '1';
			when medium_dma =>
				medium_dma_s <= '1';
			when fast_dma =>
				fast_dma_s <= '1';
			when others =>
				-- nothing
		end case;
	end process;
	
	antic_dma_clock1 : antic_dma_clock_del
		port map (clk=>clk, reset_n=>reset_n,enable_dma=>enable_dma, playfield_start=>playfield_dma_start,playfield_end=>playfield_dma_end,vblank=>vblank_reg,slow_dma=>slow_dma_s,medium_dma=>medium_dma_s,fast_dma=>fast_dma_s,dma_clock_out_0=>dma_clock_character_name,dma_clock_out_1=>dma_clock_character_inc,dma_clock_out_2=>dma_clock_bitmap_data,dma_clock_out_3=>dma_clock_character_data);

	-- line buffer
	reg_file1 : entity work.generic_ram_infer
		--generic map (BYTES=>48, WIDTH=>6) -- TODO:reset after 63, not 64?
		--port map (clk=>clk,addr=>line_buffer_address_reg(5 downto 0),data_in=>line_buffer_data_in,wr_en=>line_buffer_write, data_out=>line_buffer_data_out);		
		--generic map (BYTES=>192, WIDTH=>8) -- TODO:reset after 63, not 64?
		--port map (clk=>clk,addr=>line_buffer_address_reg,data_in=>line_buffer_data_in,wr_en=>line_buffer_write, data_out=>line_buffer_data_out);
		generic map (ADDRESS_WIDTH=>8, SPACE=>192) -- TODO:reset after 63, not 64?
		port map (clock=>clk,reset_n=>reset_n,data=>line_buffer_data_in,address=>line_buffer_address_reg,we=>line_buffer_write,q=>line_buffer_data_out);

	-- vertical scrolling
	-- load row count from vscrol must be done at time of instruction load
	-- vscrol adjustment to affect dli should be done by cycle 5 - i.e. dli 'last line'
	-- vscrol adjustment to affect actual last line should be done by cycle 108 - because...
	vscrol_delay : entity work.wide_delay_line
		generic map (COUNT=>1,WIDTH=>4)
		port map (clk=>clk,sync_reset=>'0',data_in=>vscrol_raw_reg(3 downto 0),enable=>antic_enable_179,reset_n=>reset_n,data_out=>vscrol_delayed_reg(3 downto 0));		
	
	process(vblank_reg, vscrol_delayed_reg, vscrol_enabled_reg, vscrol_last_enabled_reg, first_line_of_instruction_reg, row_count_reg, instruction_final_row_reg, update_row_count, force_final_row)
	begin								
		load_row_count <= '0';
		row_count_next <= (others=>'0');
		increment_row_count <= '0';
		
		last_line_of_instruction_live <= '0';		
		
		if (update_row_count = '1') then							
			if (vscrol_enabled_reg='1' and vscrol_last_enabled_reg='0') then -- vscrol - first line
				row_count_next <= vscrol_delayed_reg;
			end if;
		
			if (first_line_of_instruction_reg = '1') then
				load_row_count <= '1';
			else
				increment_row_count <= '1';
			end if;
		end if;
		
		if (vscrol_enabled_reg='0' and vscrol_last_enabled_reg='1') then -- vscrol - last line
			if (row_count_reg = vscrol_delayed_reg) then -- TODO, review
				last_line_of_instruction_live <= '1';
			end if;
		else -- normal
			if (row_count_reg = instruction_final_row_reg) then
				last_line_of_instruction_live <= '1';
			end if;
		end if;
		
		if (vblank_reg = '1' or force_final_row = '1') then
			last_line_of_instruction_live <= '1';
		end if;
						
	end process;
	
	-- chbase 2 cycle delay
	chbase_delay : entity work.wide_delay_line
		generic map (COUNT=>2,WIDTH=>7)
		port map (clk=>clk,sync_reset=>'0',data_in=>chbase_raw_reg(7 downto 1),enable=>antic_enable_179,reset_n=>reset_n,data_out=>chbase_delayed_reg(7 downto 1));
		
	-- decode instruction	
	process(instruction_reg)
	begin
		dma_speed_next <= no_dma;
		instruction_type_next <= mode_blank;
		shift_rate_next <= slow_shift;
		shift_twobit_next <= '0';
		twopixel_next <= '0';
		single_colour_character_next <= '0';		
		multi_colour_character_next <= '0';		
		twoline_character_next <= '0';
		map_background_next <= '0';
		instruction_final_row_next <= (others=>'0');
		two_part_instruction_next <= instruction_reg(6);
		instruction_blank_next <= '0';
		vscrol_enabled_next <= instruction_reg(5);
		hscrol_enabled_next <= instruction_reg(4);
		dli_enabled_next <= instruction_reg(7);
		descenders_next <= '0';		
		force_final_row <= '0';
		
		case instruction_reg(3 downto 0) is 			
			when X"0" =>
				instruction_type_next <= mode_blank;
				instruction_final_row_next <= '0'&instruction_reg(6 downto 4);
				two_part_instruction_next <= '0';
				instruction_blank_next <= '1';
				vscrol_enabled_next <= '0';
				hscrol_enabled_next <= '0';
				
			when X"1" =>
				instruction_type_next <= mode_jump;
				instruction_final_row_next <= (others=>'0');
				instruction_blank_next <= '1';
				vscrol_enabled_next <= '0';
				hscrol_enabled_next <= '0';
				two_part_instruction_next <= '1';
				
				if (instruction_reg(6) = '1') then
					instruction_type_next <= mode_jvb;
					force_final_row <= '1';
				end if;
				
			when X"2" =>
				instruction_type_next <= mode_character;
				instruction_final_row_next <= X"7";
				
				dma_speed_next <= fast_dma;
				shift_rate_next <= fast_shift;
				shift_twobit_next <= '1';
				twopixel_next <= '1';
				
			when X"3" =>
				instruction_type_next <= mode_character;
				instruction_final_row_next <= X"9";
				
				dma_speed_next <= fast_dma;
				shift_rate_next <= fast_shift;
				shift_twobit_next <= '1';
				twopixel_next <= '1';
				descenders_next <= '1';
				
			when X"4" =>
				instruction_type_next <= mode_character;
				instruction_final_row_next <= X"7";
				
				dma_speed_next <= fast_dma;
				shift_rate_next <= fast_shift;
				shift_twobit_next <= '1';
				twopixel_next <= '0';
				multi_colour_character_next <= '1';
				
			when X"5" =>
				instruction_type_next <= mode_character;
				instruction_final_row_next <= X"F";
				
				dma_speed_next <= fast_dma;
				shift_rate_next <= fast_shift;
				shift_twobit_next <= '1';
				twopixel_next <= '0';	
				twoline_character_next <= '1';		
				multi_colour_character_next <= '1';
				
			when X"6" =>
				instruction_type_next <= mode_character;
				instruction_final_row_next <= X"7";
				
				dma_speed_next <= medium_dma;
				shift_rate_next <= fast_shift;
				shift_twobit_next <= '0';
				twopixel_next <= '0';
				single_colour_character_next <= '1';
				
			when X"7" =>
				instruction_type_next <= mode_character;
				instruction_final_row_next <= X"F";
				
				dma_speed_next <= medium_dma;
				shift_rate_next <= fast_shift;
				shift_twobit_next <= '0';
				twopixel_next <= '0';
				single_colour_character_next <= '1';
				twoline_character_next <= '1';
				
			when X"8" =>					
				instruction_type_next <= mode_bitmap;
				instruction_final_row_next <= X"7";
				
				dma_speed_next <= slow_dma;
				shift_rate_next <= slow_shift;
				shift_twobit_next <= '1';
				twopixel_next <= '0';
				map_background_next <= '1';
				
			when X"9" =>					
				instruction_type_next <= mode_bitmap;
				instruction_final_row_next <= X"3";
				
				dma_speed_next <= slow_dma;
				shift_rate_next <= medium_shift;
				shift_twobit_next <= '0';
				twopixel_next <= '0';
				map_background_next <= '1';
				
			when X"A" =>
				instruction_type_next <= mode_bitmap;
				instruction_final_row_next <= X"3";
				
				dma_speed_next <= medium_dma;
				shift_rate_next <= medium_shift;
				shift_twobit_next <= '1';
				twopixel_next <= '0';
				map_background_next <= '1';
				
			when X"B" =>					
				instruction_type_next <= mode_bitmap;
				instruction_final_row_next <= X"1";
				
				dma_speed_next <= medium_dma;
				shift_rate_next <= fast_shift;
				shift_twobit_next <= '0';
				twopixel_next <= '0';
				map_background_next <= '1';
				
			when X"C" =>					
				instruction_type_next <= mode_bitmap;
				instruction_final_row_next <= X"0";
				
				dma_speed_next <= medium_dma;
				shift_rate_next <= fast_shift;
				shift_twobit_next <= '0';
				twopixel_next <= '0';
				map_background_next <= '1';
				
			when X"D" =>
				instruction_type_next <= mode_bitmap;
				instruction_final_row_next <= X"1";
				
				dma_speed_next <= fast_dma;
				shift_rate_next <= fast_shift;
				shift_twobit_next <= '1';
				twopixel_next <= '0';
				map_background_next <= '1';
				
			when X"E" =>
				instruction_type_next <= mode_bitmap;
				instruction_final_row_next <= X"0";
				
				dma_speed_next <= fast_dma;
				shift_rate_next <= fast_shift;
				shift_twobit_next <= '1';
				twopixel_next <= '0';
				map_background_next <= '1';
				
			when X"F" =>
				instruction_type_next <= mode_bitmap;
				instruction_final_row_next <= X"0";
				
				dma_speed_next <= fast_dma;
				shift_rate_next <= fast_shift;
				shift_twobit_next <= '1';
				twopixel_next <= '1';
			when others =>
				-- nothing
				
		end case;
	end process;

	-- dma fetching
	-- dma fetch - cache response until needed
	-- we allow two colour clocks for each fetch...
	process(memory_data_in,memory_ready_both,cycle_latter,dma_fetch_reg,dma_address_reg,dma_fetch_destination_reg,dma_cache_ready_reg,dma_cache_reg,dma_fetch_request,vblank_reg, instruction_type_reg, instruction_reg, display_list_address_reg, memory_scan_address_reg, enable_dma, display_list_address_low_temp_reg,allow_real_dma_reg,allow_real_dma_next)
	begin	
		instruction_next <= instruction_reg;
		
		display_list_address_next_dma <= display_list_address_reg;
		load_display_list_address_dma <= '0';
		memory_scan_address_next <= memory_scan_address_reg;
		load_memory_scan_address <= '0';
		increment_display_list_address <= '0';
		
		load_display_shift_from_memory <= '0';
		display_list_address_low_temp_next <= display_list_address_low_temp_reg;		
		
		line_buffer_data_in <= (others=>'0');
		line_buffer_write <= '0';

		dma_cache_next <= dma_cache_reg;
		dma_cache_ready_next <= dma_cache_ready_reg;
		dma_fetch_next <= dma_fetch_request or dma_fetch_reg;

		if (dma_fetch_reg = '1' and memory_ready_both = '1') then
			dma_cache_next <= memory_data_in;
			dma_cache_ready_next <= '1';
			dma_fetch_next <= '0';
		end if;

		if (allow_real_dma_reg='0' and allow_real_dma_next='1') then
			dma_fetch_next <= '0';
		end if;
		
		if (vblank_reg = '1' and instruction_type_reg = mode_jvb) then
			instruction_next <= (others=>'0');
		end if;
	
		if (dma_cache_ready_reg='1' and cycle_latter='1') then
		--if (dma_cache_ready_reg='1') then
			case dma_fetch_destination_reg is 
				when dma_fetch_line_buffer =>
					line_buffer_data_in <= dma_cache_reg;					
					line_buffer_write <= '1';
				when dma_fetch_shiftreg =>
					load_display_shift_from_memory <= '1';
				when dma_fetch_null =>
					-- nothing (C/G/MTIA listens to bus)
				when dma_fetch_instruction =>
					instruction_next <= dma_cache_reg;
					
					increment_display_list_address <= '1';
					
				when dma_fetch_list_low =>
					if (instruction_type_reg = mode_jump or instruction_type_reg = mode_jvb) then
						--display_list_address_next_dma(7 downto 0) <= dma_cache_reg; Changing this so soon messes up next dma cycle
						display_list_address_low_temp_next <= dma_cache_reg;
						increment_display_list_address <= '1';
					else
						increment_display_list_address <= '1';
						memory_scan_address_next(7 downto 0) <= dma_cache_reg;
						load_memory_scan_address <= '1';
					end if;
				when dma_fetch_list_high =>
					if (instruction_type_reg = mode_jump or instruction_type_reg = mode_jvb) then
						 display_list_address_next_dma <= dma_cache_reg&display_list_address_low_temp_reg;
						 load_display_list_address_dma <= '1';
					else
						increment_display_list_address <= '1';
						memory_scan_address_next(15 downto 8) <= dma_cache_reg;
						load_memory_scan_address <= '1';
					end if;
				
				when others =>
					-- nothing
				
			end case;

			dma_cache_ready_next <= '0';
		end if;
	end process;
	
	-- shift reg clock
	playfield_reset <= hblank_reg;
	
	playfield_load <= dma_clock_character_name;
	process(colour_clock_selected, shift_rate_reg, shiftclock_reg, playfield_reset, playfield_load, hscrol_reg, hscrol_enabled_reg)
	begin
		shiftclock_next <= shiftclock_reg;
		enable_shift <= '0';
	
		if (colour_clock_selected = '1') then
		
			shiftclock_next <= shiftclock_reg(2 downto 0)&shiftclock_reg(3);
			
			if (playfield_load='1') then
				shiftclock_next <= "1000";
			end if;
			
			if (playfield_reset='1') then
				shiftclock_next <= "0000";
			end if;			
			
			--shiftclock_next(0) <= shiftclock_reg(1);
			--shiftclock_next(1) <= shiftclock_reg(2);
			--shiftclock_next(2) <= shiftclock_reg(3) nor playfield_load;
			--shiftclock_next(3) <= shiftclock_reg(0) nor playfield_reset;						
			case shift_rate_reg is
				when slow_shift =>
					enable_shift <= (shiftclock_reg(0) and not(hscrol_reg(1) and hscrol_enabled_reg)) or (shiftclock_reg(2) and hscrol_reg(1) and hscrol_enabled_reg);
				when medium_shift =>
					enable_shift <= shiftclock_reg(2) or shiftclock_reg(0);
				when fast_shift =>			
					enable_shift <= (shiftclock_reg(3) or shiftclock_reg(2)) or (shiftclock_reg(1) or shiftclock_reg(0));
				when others =>
					-- nothing
			end case;			
		end if;
	end process;

	-- shift reg
	process (enable_shift, shift_twobit_reg, display_shift_reg, load_display_shift_from_memory, load_display_shift_from_line_buffer, dma_cache_reg, line_buffer_data_out)
	begin
		display_shift_next <= display_shift_reg;
		
		if (enable_shift = '1') then
			if (shift_twobit_reg = '1') then
				display_shift_next <= display_shift_reg(5 downto 0)&"00";
			else
				display_shift_next <= display_shift_reg(6 downto 0)&"0";
			end if;			
		end if;
		
		if (load_display_shift_from_memory = '1') then
			display_shift_next(7 downto 0) <= dma_cache_reg;
		end if;

		if (load_display_shift_from_line_buffer = '1') then
			display_shift_next(7 downto 0) <= line_buffer_data_out;
		end if;
		
	end process;
	
	-- delay shift reg output for n cycles, so we can match AN with antic output
	process(colour_clock_selected, display_shift_reg, delay_display_shift_reg, displayed_character_reg, instruction_type_reg)
	begin
		delay_display_shift_next <= delay_display_shift_reg;
		
		if (colour_clock_selected = '1') then
			-- TODO - RAM accesses are now processed in the 2nd colour clock
			-- This is too late for character modes, so delay needs adjusting...
			if (instruction_type_reg=mode_character) then	
				delay_display_shift_next <= displayed_character_reg(7 downto 5)&"00"&delay_display_shift_reg(24 downto 22)&display_shift_reg(7 downto 6)&delay_display_shift_reg(19 downto 5);
			else
				delay_display_shift_next <= displayed_character_reg(7 downto 5)&display_shift_reg(7 downto 6)&delay_display_shift_reg(24 downto 5);
			end if;
		end if;
		
	end process;
	
	-- ANO-2
	-- XXX - clean up!	
	-- first process - AN with no blanking	
	process(data_live,delay_display_shift_reg, shift_twobit_reg, twopixel_reg, instruction_blank_reg, playfield_display_active_reg, single_colour_character_reg, multi_colour_character_reg, chactl_reg, instruction_type_reg, map_background_reg, descenders_reg, row_count_reg)
	begin
		an_current_raw <= (others=>'0');
		data_live <= (others=>'0');
		if (shift_twobit_reg = '1') then				
			an_current_raw(0) <= delay_display_shift_reg(0);
			an_current_raw(1) <= delay_display_shift_reg(1);
			an_current_raw(2) <= '1';
			
			if (instruction_type_reg = mode_character) then							
				data_live(0) <= delay_display_shift_reg(0);
				data_live(1) <= delay_display_shift_reg(1);
								
				if (descenders_reg = '1') then					
					if (delay_display_shift_reg(3 downto 2) = "11") then
						if (unsigned(row_count_reg)<2) then
							data_live(1 downto 0) <= "00";
						end if;
					else
						if (unsigned(row_count_reg)>=8) then
							data_live(1 downto 0) <= "00";
						end if;
					end if;
				end if;	
			
				if (delay_display_shift_reg(4)='1') then -- inverse/hidden
					if (chactl_reg(1)='1') then
						an_current_raw(0) <= not(data_live(0) and not(chactl_reg(0)));
						an_current_raw(1) <= not(data_live(1) and not(chactl_reg(0)));
					else
						an_current_raw(0) <= data_live(0) and not(chactl_reg(0));
						an_current_raw(1) <= data_live(1) and not(chactl_reg(0));					
					end if;
				else
					an_current_raw(0) <= data_live(0);
					an_current_raw(1) <= data_live(1);				
				end if;
			end if;		

			if (multi_colour_character_reg = '1') then
				case delay_display_shift_reg(1 downto 0) is
					when "00" =>
						an_current_raw <= "000";
					when "01" =>
						an_current_raw <= "100";			
					when "10" =>
						an_current_raw <= "101";			
					when "11" =>
						an_current_raw <= "11"&delay_display_shift_reg(4);										
					when others =>
						-- nop
				end case;				
			end if;
			
			if (map_background_reg='1') then
				case delay_display_shift_reg(1 downto 0) is
					when "00" =>
						an_current_raw <= "000";
					when "01" =>
						an_current_raw <= "100";			
					when "10" =>
						an_current_raw <= "101";			
					when "11" =>
						an_current_raw <= "110";										
					when others =>
						-- nop
				end case;
			end if;
		else
			if (single_colour_character_reg = '1') then
				-- i.e. antic 6,7
				if (delay_display_shift_reg(1) = '1') then
					an_current_raw(0) <= delay_display_shift_reg(3);
					an_current_raw(1) <= delay_display_shift_reg(4);
					an_current_raw(2) <= '1';					
				else
					an_current_raw(0) <= '0';
					an_current_raw(1) <= '0';
					an_current_raw(2) <= '0';
				end if;			
			end if;
			
			if (map_background_reg='1') then
				if (delay_display_shift_reg(1)='1') then
					an_current_raw <= "100";
				else
					an_current_raw <= "000";										
				end if;
			end if;				
		end if;		
	end process;
	
	process(colour_clock_selected, an_current_raw, an_current_reg)
	begin
		an_current_next <= an_current_reg;
		
		if (colour_clock_selected = '1') then
			an_current_next(3 downto 1) <= an_current_reg(2 downto 0);
			an_current_next(0) <= an_current_raw;
		end if;
	end process;

	process(colour_clock_selected, an_current, an_prev, hscrol_reg, hscrol_enabled_reg, vsync_reg, vblank_reg, hblank_reg, playfield_display_active_reg, instruction_blank_reg, twopixel_reg, playfield_dma_enabled)
	begin
		an_next <= an_current;
		
		if (hscrol_reg(0)='1' and hscrol_enabled_reg='1') then
			an_next <= an_prev;
		end if;
		
		if ((not(playfield_display_active_reg) or instruction_blank_reg or vblank_reg or not(playfield_dma_enabled)) = '1') then
			an_next <= "000";
		end if;
		
		if (vblank_reg = '1' or hblank_reg = '1') then				
			an_next(0) <= vsync_reg or twopixel_reg;
			an_next(1) <= not(vsync_reg);
			an_next(2) <= not(hblank_reg) and twopixel_reg and playfield_dma_enabled;
		end if;			
	end process;

	-- decode address
	decode_addr1 : complete_address_decoder
		generic map(width=>4)
		port map (addr_in=>addr, addr_decoded=>addr_decoded);

	-- wsync write takes 1.5 cycles to assert rdy - i.e. next cycle runs as normal then it pauses
	wsync_delay : entity work.latch_delay_line
		generic map (COUNT=>1) 
		port map (clk=>clk,sync_reset=>'0',data_in=>wsync_write,enable=>antic_enable_179,reset_n=>reset_n,data_out=>wsync_delayed_write);

	-- dmactl takes 1 cycle to be applied - NO IT DOES NOT - TODO FIXME
	--dmactl_delay : entity work.wide_delay_line
	--	generic map (COUNT=>cycle_length,WIDTH=>6)
	--	port map (clk=>clk,sync_reset=>'0',data_in=>dmactl_raw_reg(5 downto 0),enable=>'1',reset_n=>reset_n,data_out=>dmactl_delayed_reg(5 downto 0));
	dmactl_delayed_reg <= dmactl_raw_next;
	--dmactl_delayed_reg <= dmactl_raw_reg;
		
	-- Writes to registers
	process(cpu_data_in,wr_en,addr_decoded,nmien_raw_reg,dmactl_raw_reg,chactl_reg,hscrol_reg,display_list_address_reg,chbase_raw_reg,pmbase_reg,vscrol_raw_reg, wsync_reg, wsync_delayed_write, wsync_reset)
	begin		
		nmien_raw_next <= nmien_raw_reg;
		dmactl_raw_next <= dmactl_raw_reg;
		chactl_next <= chactl_reg;
		hscrol_next <= hscrol_reg;
		vscrol_raw_next <= vscrol_raw_reg;
		chbase_raw_next <= chbase_raw_reg;
		pmbase_next <= pmbase_reg;
		wsync_next <= (wsync_delayed_write or wsync_reg) and not(wsync_reset);
		nmist_reset <= '0';
		wsync_write <= '0';
		
		load_display_list_address_cpu <= '0';
		display_list_address_next_cpu <= display_list_address_reg;
	
		if (wr_en = '1') then
			if(addr_decoded(0) = '1') then
				dmactl_raw_next <= cpu_data_in(6 downto 0);
			end if;	

			if(addr_decoded(1) = '1') then
				chactl_next <= cpu_data_in(2 downto 0);
			end if;	
			
			if(addr_decoded(2) = '1') then
				display_list_address_next_cpu(7 downto 0) <= cpu_data_in;
				load_display_list_address_cpu <= '1';
			end if;		
			
			if(addr_decoded(3) = '1') then
				display_list_address_next_cpu(15 downto 8) <= cpu_data_in;
				load_display_list_address_cpu <= '1';
			end if;

			if(addr_decoded(4) = '1') then
				hscrol_next <= cpu_data_in(3 downto 0);
			end if;	

			if(addr_decoded(5) = '1') then
				vscrol_raw_next <= cpu_data_in(3 downto 0);
			end if;
			
			if(addr_decoded(7) = '1') then
				pmbase_next <= cpu_data_in(7 downto 2);
			end if;		
			
			if(addr_decoded(9) = '1') then
				chbase_raw_next <= cpu_data_in(7 downto 1);
			end if;		

			if(addr_decoded(10) = '1') then
				wsync_write <= '1';
			end if;		
	
			if(addr_decoded(14) = '1') then
				nmien_raw_next <= cpu_data_in(7 downto 6);
			end if;
		
			if(addr_decoded(15) = '1') then
				nmist_reset <= '1';
			end if;		
		end if;
	end process;
	
	-- Read from registers
	process(addr_decoded,hcount_reg,vcount_reg,nmist_reg,penv_reg,penh_reg)
	begin
		data_out <= X"FF";

		if (addr_decoded(8) = '1') then -- HCOUNT :-)
			data_out <= hcount_reg(9 downto 2); -- bonus points for the one who spots this in code:-)
		end if;
		
		if(addr_decoded(11) = '1') then --VCOUNT
			data_out <= vcount_reg(8 downto 1);
		end if;
		
		if (addr_decoded(12) = '1') then -- PENH
			data_out <= penh_reg;
		end if;
		
		if (addr_decoded(13) = '1') then -- PENV
			data_out <= penv_reg;
		end if;

		if(addr_decoded(15) = '1') then --NMIST
			data_out <= nmist_reg&"00000";
		end if;
		
	end process;
	
	-- light pen
	process(lightpen,hcount_reg,vcount_reg,penv_reg,penh_reg)
	begin
		penv_next <= penv_reg;
		penh_next <= penh_reg;
		
		if (lightpen = '0') then
			penv_next <= vcount_reg(8 downto 1);
			penh_next <= hcount_reg(9 downto 2);
		end if;
	end process;
	
	-- Use CPU data if virtual dma
	MEMORY_READY_both <= MEMORY_READY_ANTIC when allow_real_dma_reg='1' else MEMORY_READY_CPU;
	
	-- output
	nmi_n_out <= nmi_reg;
	
	shift_out <= display_shift_reg;
	dma_clock_out(3)<=dma_clock_character_name;
	dma_clock_out(2)<=dma_clock_character_inc;
	dma_clock_out(1)<=dma_clock_bitmap_data;
	dma_clock_out(0)<=dma_clock_character_data;
	
	AN <= an_reg;
	
	antic_ready <= not(wsync_reg);
	
	dma_fetch_out <= allow_real_dma_reg and dma_fetch_reg;
	dma_address_out <= dma_address_reg;
	
	refresh_out <= refresh_fetch_reg;
	
	COLOUR_CLOCK_ORIGINAL_OUT <= colour_clock_1x;
	COLOUR_CLOCK_OUT <= colour_clock_selected;
	HIGHRES_COLOUR_CLOCK_OUT <= colour_clock_selected_highres;

	vcount_out <= vcount_reg;
	hcount_out <= hcount_reg(9 downto 2);

	turbo_out <= dmactl_raw_reg(6);

	next_cycle_type <= (others=>'X'); -- TODO! Need to know after prior colour clock, if next one will be dma...
	
END vhdl;

