------------------------------------------------------------------------------
-- Carte :		Cam-ass-ultra
-- Fonction : 	SAA signals decoder
-- Author :		crazyfred EIRBOT 2006
-- Date :		01.05.2006
------------------------------------------------------------------------------

library IEEE, work;
use IEEE.std_logic_1164.all;
use ieee.std_logic_unsigned.all; 
use ieee.numeric_std.all; 
use work.all;

entity saa_decode is
	port (
		LLC2       : in std_logic;
		RESETn     : in std_logic;

		HS         : in std_logic;	-- SAA: synchro trame
		VS         : in std_logic;	-- SAA: synchro ligne
		HREF       : in std_logic;	-- SAA: pixels actifs
		VREF       : in std_logic;

		pline_num  : out std_logic_vector(8 downto 0);
		ppixel_num : out std_logic_vector(9 downto 0);

		RTS0       : in std_logic;
		
		pblank     : out std_logic;
		psync      : out std_logic;
		--pimage     : out std_logic;
		resetphase : out std_logic;
		pburst     : out std_logic;

		--trame      : out std_logic_vector(2 downto 0)
		typeAB     : out std_logic
	);

end saa_decode;


architecture structure of saa_decode is

	signal new_line               : std_logic;
	signal reset_l, reset_x       : std_logic;
	signal line : std_logic_vector(17 downto 0);
	signal cpt : std_logic_vector(17 downto 0);
	signal cptsync : std_logic_vector(7 downto 0);

	signal linei : std_logic_vector(14 downto 0);
	signal cpti : std_logic_vector(14 downto 0);
	signal pixel_numi : std_logic_vector(9 downto 0);

	signal line_num  : std_logic_vector(8 downto 0);
	signal pixel_num : std_logic_vector(9 downto 0);
	signal blank     : std_logic;
	signal sync      : std_logic;
	signal burst     : std_logic;
	signal image     : std_logic;

	signal sigtrame : std_logic_vector(2 downto 0);
	signal sigtypeAB : std_logic;

	signal count_trame : std_logic;
	signal count_trame_reg : std_logic;

	component division720
		PORT
		(
			numer		: IN STD_LOGIC_VECTOR (17 DOWNTO 0);
			denom		: IN STD_LOGIC_VECTOR (9 DOWNTO 0);
			quotient		: OUT STD_LOGIC_VECTOR (17 DOWNTO 0);
			remain		: OUT STD_LOGIC_VECTOR (9 DOWNTO 0)
		);
	end component;
	component division864
		PORT
		(
			numer		: IN STD_LOGIC_VECTOR (14 DOWNTO 0);
			denom		: IN STD_LOGIC_VECTOR (9 DOWNTO 0);
			quotient		: OUT STD_LOGIC_VECTOR (14 DOWNTO 0);
			remain		: OUT STD_LOGIC_VECTOR (9 DOWNTO 0)
		);
	end component;

	begin



	registering : process(llc2, line_num, pixel_num, blank, sync, burst)
	begin
		if rising_edge(llc2) then
			pline_num <= line_num;
			ppixel_num <= pixel_num;
			pblank <= blank;
			psync <= sync;
			pburst <= burst;
			--pimage <= image;
		end if;
	end process;

-------------------------------------------------------------------------------

	sync_blank : process(cptsync, HREF, RTS0, VREF, pixel_numi, linei, sigtrame)
	begin
		if VREF = '0' then -- synchro verticale
		-- lignes: 623 à 625, 1 à 23, 310 à 336
			if linei(4 downto 0) > 8 then -- lignes: 7 à 23, 319 à 336
				if pixel_numi < 54 then
					sync <= '1';
					blank <= '0';
					burst <= '0';
					image <= '0';
				elsif pixel_numi > 76 and pixel_numi < 107 then
					sync <= '0';
					blank <= '1';
					if sigtrame = "011" or sigtrame = "111" then
						burst <= '0'; -- normalement pas de burst sur la 319 pour les trames 4 et 8
					else
						burst <= '1';
					end if;
					image <= '0';
				else
					sync <= '0';
					blank <= '1';
					burst <= '0';
					image <= '0';
				end if;


			elsif RTS0 = '0' then -- fin de 2eme trame, passage à la 1ere
			-- lignes: 623 à 625, 1 à 6
				if linei(4 downto 0) = 8 then -- ligne: 6
					if pixel_numi < 54 then
						sync <= '1';
						blank <= '0';
						burst <= '0';
						image <= '0';
					elsif pixel_numi > 76 and pixel_numi < 107 then
						sync <= '0';
						blank <= '1';
						if sigtrame = "010" or sigtrame = "110" then
							burst <= '1'; -- normalement il faut des burst sur les trames 3 et 7
						else
							burst <= '0';
						end if;
						image <= '0';
					else
						sync <= '0';
						blank <= '1';
						burst <= '0';
						image <= '0';
					end if;
				elsif linei(4 downto 0) = 0 then -- ligne 623
					if pixel_numi < 54 or ( pixel_numi > 432 and pixel_numi < 459 ) then
						sync <= '1';
						blank <= '0';
						burst <= '0';
						image <= '0';
					else
						sync <= '0';
						blank <= '1';
						burst <= '0';
						image <= '0';
					end if;				
				elsif linei(4 downto 0) < 3 or linei(4 downto 0) > 5 then -- lignes: 624 à 625 ou 4, 5
					if pixel_numi < 27 or ( pixel_numi > 432 and pixel_numi < 459 ) then
						sync <= '1';
						blank <= '0';
						burst <= '0';
						image <= '0';
					else
						sync <= '0';
						blank <= '1';
						burst <= '0';
						image <= '0';
					end if;
				elsif linei(4 downto 0) = 5 then -- ligne 3
					if ( pixel_numi < 432 and pixel_numi > 405 ) or pixel_numi > 459 then
						sync <= '0';
						blank <= '1';
						burst <= '0';
						image <= '0';
					else
						sync <= '1';
						blank <= '0';
						burst <= '0';
						image <= '0';
					end if;
				else -- lignes: 1, 2 (par déduction)
					if ( pixel_numi > 405 and pixel_numi < 432) or pixel_numi > 837 then
						sync <= '0';
						blank <= '1';
						burst <= '0';
						image <= '0';
					else
						sync <= '1';
						blank <= '0';
						burst <= '0';
						image <= '0';
					end if;
				end if;


			else -- fin de 1ere trame, passage à la 2eme
			-- lignes: 310 à 318
				if linei(4 downto 0) = 8 then -- ligne 318
					if pixel_numi < 27 then
						sync <= '1';
						blank <= '0';
						burst <= '0';
						image <= '0';
					else
						sync <= '0';
						blank <= '1';
						burst <= '0';
						image <= '0';
					end if;
				elsif linei(4 downto 0) = 0 then -- ligne 310
					if pixel_numi < 54 then
						sync <= '1';
						blank <= '0';
						if sigtrame = "011" or sigtrame = "111" then
							burst <= '1'; -- normalement il faut un burst sur les trames 4 et 8
						else
							burst <= '0';
						end if;
						burst <= '0';
						image <= '0';
					else
						sync <= '0';
						blank <= '1';
						burst <= '0';
						image <= '0';
					end if;
				elsif linei(4 downto 0) = 1 or linei(4 downto 0) = 2 or linei(4 downto 0) = 6 or linei(4 downto 0) = 7 then
				-- lignes: 311, 312 ou 316, 317
					if (pixel_numi < 27) or ( (pixel_numi > 432) and (pixel_numi < 459) ) then
						sync <= '1';
						blank <= '0';
						burst <= '0';
						image <= '0';
					else
						sync <= '0';
						blank <= '1';
						burst <= '0';
						image <= '0';
					end if;
				elsif linei(4 downto 0) = 3 then -- ligne 313
					if (pixel_numi < 432 and pixel_numi > 27 ) or pixel_numi > 837 then
						sync <= '0';
						blank <= '1';
						burst <= '0';
						image <= '0';
					else
						sync <= '1';
						blank <= '0';
						burst <= '0';
						image <= '0';
					end if;
				else -- lignes 314, 315
					if ( (pixel_numi > 405) and (pixel_numi < 432) ) or (pixel_numi > 837) then
						sync <= '0';
						blank <= '1';
						burst <= '0';
						image <= '0';
					else
						sync <= '1';
						blank <= '0';
						burst <= '0';
						image <= '0';
					end if;
				end if;
			end if;



		else -- image normale
			if HREF = '1' then -- image active (cptsync <= 138 a priori)
				burst <= '0';
				sync <= '0';
				blank <= '0';
				image <= '1';
				-- IMAGE !!
			elsif cptsync < 54 then -- synchro horizontale
				sync <= '1';
				blank <= '0';
				burst <= '0';
				image <= '0';
			elsif cptsync > 76 and cptsync < 107 then
				sync <= '0';
				blank <= '1';
				burst <= '1';
				image <= '0';
				-- COLORBURST (normalement pas de burst sur 622 pour 3 et 7)
			else -- blank/black apres la synchro et avant l'image
				sync <= '0';
				blank <= '1';
				burst <= '0';
				image <= '0';
			end if;
		end if;
	end process;

-------------------------------------------------------------------------------

	comptage_sync : process (llc2, HREF)
	begin
		if HREF = '1' then
			cptsync <= "11111111";
		elsif rising_edge(llc2) then
			cptsync <= cptsync + 1;
		end if;
	end process;
-------------------------------------------------------------------------------
	comptage_inactif : process (llc2, VREF)
	begin
		if VREF = '1' then
			cpti <= "000000000000000";
		elsif rising_edge(llc2) then
			cpti <= cpti + 1; -- comptage "pixels" inactifs pour synchro verticale
		end if;
	end process;
-------------------------------------------------------------------------------
	comptage : process (llc2, HREF, VREF)
	begin
		if VREF = '0' then
			cpt <= "000000000000000000";
		elsif rising_edge(llc2) then
			if HREF = '1' then
				cpt <= cpt + 1; -- comptage pixels actifs
			end if;
		end if;
	end process;

-------------------------------------------------------------------------------
-- le comptage de trame demande trop de ressources pour faire ca en 1 seul coup
-- de clock. donc on decoupe en plein d'etapes.
	cpt_trame : process(llc2, RTS0, count_trame_reg, sigtrame)
	begin
		if rising_edge(llc2) and count_trame_reg = '1' and (RTS0='1' xor sigtrame(0)='1') then
			sigtrame <= sigtrame + 1;
		end if;
	end process;
-------------------------------------------------------------------------------
	en_cpt_trame : process(cpti)
	begin
		if cpti = "000101000100000" then
			count_trame <= '1';
		else
			count_trame <= '0';
		end if;
	end process;
-------------------------------------------------------------------------------
	reg_en_cpt_trame : process(llc2, count_trame)
	begin
		if rising_edge(llc2) then
			count_trame_reg <= count_trame;
		end if;
	end process;
-------------------------------------------------------------------------------
	reg_type : process(llc2, sigtypeAB)
	begin
		if rising_edge(llc2) then
			typeAB <= sigtypeAB;
		end if;
	end process;
-------------------------------------------------------------------------------
	burst_type : process(sigtrame, line, linei, VREF)
	begin
		if VREF = '0' then -- lignes: 623 à 625, 1 à 23, 310 à 336
			if sigtrame(0) = '0' then -- trames 0 2 4 6
				if sigtrame(1) = '0' then -- trames 0 4
					sigtypeAB <= linei(0);
				else -- trames 2 6
					sigtypeAB <= not(linei(0));
				end if;
			else -- trames 1 3 5 7
				if sigtrame(1) = '0' then -- trames 1 5
					sigtypeAB <= linei(1);
				else -- trames 3 7
					sigtypeAB <= not(linei(1));
				end if;
			end if;
		else -- lignes 24 à 309, 337 à 622
			if sigtrame(1) = '0' then -- trames 0 1 4 5
				if sigtrame(0) = '0' then -- trames 0 4
					sigtypeAB <= line(0);
				else -- trames 1 5
					sigtypeAB <= not(line(0));
				end if;
			else -- trames 2 3 6 7
				if sigtrame(0) = '0' then -- trames 2 6
					sigtypeAB <= not(line(0));
				else -- trames 3 7
					sigtypeAB <= line(0);
				end if;
			end if;
		end if;
	end process;
-------------------------------------------------------------------------------
	reseteur : process(cpti, sigtrame)
	begin
		if sigtrame = "111" and cpti = "000101000100000" then
			resetphase <= '1';
		else
			resetphase <= '0';
		end if;
	end process;
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------

	line_num <= line(8 downto 0);

division720_inst : division720 PORT MAP (
		numer	 => cpt,
		denom	 => "1011010000",
		quotient	 => line,
		remain	 => pixel_num
	);

division864_inst : division864 PORT MAP (
		numer	 => cpti,
		denom	 => "1101100000",
		quotient	 => linei,
		remain	 => pixel_numi
	);

-------------------------------------------------------------------------------

	end structure;
