--
-- Text Screen Video Controller.
-- Pixel resolution is 640x480/60Hz, 8 colors (3-bit DAC).
--
-- 2007 Javier Valcarce García, javier.valcarce@gmail.com
-- angepasst für Acorn Atom T65 Core mit 6867 VDU von C. Meyer, cm@ctmagazin.de
-- $Id$

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;


entity qvga_txt is port (
	RST    : in  std_logic;
	SYSCLK50 : in  std_logic;
	RAMWR : in  std_logic;
	RAMDASCII: in  std_logic_vector(07 downto 0);
	RAMADR: in std_logic_vector(11 downto 0);
	CURSX: in  std_logic_vector(07 downto 0);
	CURSY: in  std_logic_vector(07 downto 0);
	COLOR: in  std_logic_vector(3 downto 0); 	-- Invert (3), R(2), G(1), B(0)
	R        : out std_logic;
	G        : out std_logic;
	B        : out std_logic;
   FRAME       : out std_logic;
	hsync    : out std_logic;
	vsync    : out std_logic
	);
end qvga_txt;


architecture behavioral of qvga_txt is

	component qvga40x24
    port (
      reset       : in  std_logic;
      clk12MHz    : in  std_logic;
      R           : out std_logic;
      G           : out std_logic;
      B           : out std_logic;
      FRAME       : out std_logic;
      TEXT_A      : out std_logic_vector(11 downto 0);
      TEXT_D      : in  std_logic_vector(07 downto 0);
		FONT_A      : out std_logic_vector(11 downto 0);
		FONT_D      : in  std_logic_vector(07 downto 0);
		hsync       : out std_logic;
		vsync       : out std_logic;
		ocrx    : in  std_logic_vector(7 downto 0);
		ocry    : in  std_logic_vector(7 downto 0);
		octl    : in  std_logic_vector(7 downto 0)
      );   
  end component;
	
	component mem_color
		port (
		clka: IN std_logic;
		dina: IN std_logic_VECTOR(3 downto 0);
		addra: IN std_logic_VECTOR(11 downto 0);
		wea: IN std_logic;
		douta: OUT std_logic_VECTOR(3 downto 0);
		clkb: IN std_logic;
		dinb: IN std_logic_VECTOR(3 downto 0);
		addrb: IN std_logic_VECTOR(11 downto 0);
		web: IN std_logic;
		doutb: OUT std_logic_VECTOR(3 downto 0));
	end component;
  
  component mem_text
    port (
      clka  : in  std_logic;
      dina  : in  std_logic_vector(07 downto 0);
      addra : in  std_logic_vector(11 downto 0);
      wea   : in  std_logic_vector(00 downto 0);
      douta : out std_logic_vector(07 downto 0);
      clkb  : in  std_logic;
      dinb  : in  std_logic_vector(07 downto 0);
      addrb : in  std_logic_vector(11 downto 0);
      web   : in  std_logic_vector(00 downto 0);
      doutb : out std_logic_vector(07 downto 0));
  end component;
	
	component mem_font
    port (
    clka: IN std_logic;
    addra: IN std_logic_VECTOR(11 downto 0);
    douta: OUT std_logic_VECTOR(7 downto 0));
	end component;

  signal clk25MHz    : std_logic;
  signal clk12MHz    : std_logic;
  signal crx_oreg_ce : std_logic;
  signal cry_oreg_ce : std_logic;
  signal ctl_oreg_ce : std_logic;
  signal crx_oreg    : std_logic_vector(7 downto 0);
  signal cry_oreg    : std_logic_vector(7 downto 0);
  signal ctl_oreg    : std_logic_vector(7 downto 0);


  -- Color Buffer RAM Memory Signals, Port B (to CPU core)
  signal ram_rgb : std_logic_vector(03 downto 0);
  signal color_i : std_logic_vector(03 downto 0);
  signal ram_doA : std_logic_vector(07 downto 0);
  signal ram_adA : std_logic_vector(11 downto 0);

  -- Text Buffer RAM Memory Signals, Port B (to VGA core)
  signal ram_diB : std_logic_vector(07 downto 0);
  signal ram_doB : std_logic_vector(07 downto 0);
  signal ram_adB : std_logic_vector(11 downto 0);
  signal ram_weB : std_logic_vector(00 downto 0);
  
  
  -- Font Buffer RAM Memory Signals
  signal rom_adB : std_logic_vector(11 downto 0);
  signal rom_doB : std_logic_vector(07 downto 0);

  
begin

  --Clock divider /2. Pixel clock is 25MHz
	clk25MHz <= '0' when RST = '1' else (not clk25MHz) when rising_edge(SYSCLK50);
	clk12MHz <= '0' when RST = '1' else (not clk12MHz) when rising_edge(clk25MHz);
--	ascii_data <= RAMDASCII or "01000000"; 
	
  U_VGA : qvga40x24 port map (
    reset       => RST,
    clk12MHz    => clk12MHz,
    R           => R,
    G           => G,
    B           => B,
    FRAME       => FRAME,
    hsync       => hsync,
    vsync       => vsync,
    TEXT_A      => ram_adB,
    TEXT_D      => ram_doB,
    FONT_A      => rom_adB,
    FONT_D      => rom_doB,
    ocrx    => crx_oreg,
    ocry    => cry_oreg,
    octl    => ctl_oreg);

  U_TEXT: mem_text port map (			-- Text RAM 4K x 8
    clka  => clk12MHz,
    dina  => RAMDASCII,
    addra => RAMADR,
    wea(0)   => RAMWR,
    douta => ram_doA,
    clkb  => clk12MHz,
    dinb  => ram_diB,
    addrb => ram_adB,
    web   => ram_weB,
    doutb => ram_doB
    );
  U_COLOR: mem_color port map (		-- COLOR RAM 4K x 4
    clka  => clk12MHz,
    dina  => color_i,
    addra => RAMADR,
    wea   => RAMWR,
    douta => open,
    clkb  => clk12MHz,
    dinb  => "0000",
    addrb => ram_adB,
    web   => '0',
    doutb => ram_rgb
    );
  U_FONT: mem_font port map (
    clka => CLK12Mhz,
    addra => rom_adB,
    douta => rom_doB);
	 
  ram_weB <= "0";
  ram_diB <= (others => '0');

--  ram_weA(0) <= RAMWR;
	
--  ram_diA <= RAMDASCII;
--  ram_adA <= RAMADR;

  crx_oreg    <= CURSX;
  cry_oreg    <= CURSY;
  ctl_oreg(7)   <= ram_rgb(3);
  ctl_oreg(6 downto 3)   <= "1110";
  ctl_oreg(2 downto 0)   <= ram_rgb(2 downto 0);	-- R(2), G(1), B(0)
	color_i <= COLOR;
end behavioral;
