-- Copyright (c) 2015, $ME -- All rights reserved. -- -- Redistribution and use in source and synthezised forms, with or without modification, are permitted -- provided that the following conditions are met: -- -- 1. Redistributions of source code must retain the above copyright notice, this list of conditions -- and the following disclaimer. -- -- 2. Redistributions in synthezised form must reproduce the above copyright notice, this list of conditions -- and the following disclaimer in the documentation and/or other materials provided with the distribution. -- -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED -- WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -- ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -- TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -- POSSIBILITY OF SUCH DAMAGE. -- -- -- kc87 video controller -- https://eewiki.net/pages/viewpage.action?pageId=15925278 library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; entity video is generic ( H_DISP : integer := 1024; H_SYNC_START : integer := 1024+24; H_SYNC_END : integer := 1024+24+136; H_VID_END : integer := 1024+24+136+160; H_SYNC_ACTIVE : std_logic := '0'; V_DISP : integer := 768; V_SYNC_START : integer := 768+3; V_SYNC_END : integer := 768+3+6; V_VID_END : integer := 768+3+6+29; --V_DISP : integer := 768; --V_SYNC_START : integer := 768+3; --V_SYNC_END : integer := 768+3+6; --V_VID_END : integer := 768+3+6+29; V_SYNC_ACTIVE : std_logic := '0'; CHAR_X_SIZE : integer := 16; CHAR_Y_SIZE : integer := 24; CHAR_PER_LINE : integer := 64; SYNC_DELAY : integer := 3 ); port ( clk : in std_logic; hsync : out std_logic; vsync : out std_logic; ramAddr : out std_logic_vector(10 downto 0); charData : in std_logic_vector(7 downto 0); pixel : out std_logic; scanLine : in std_logic ); end video; architecture rtl of video is signal countH : integer range 0 to H_VID_END-1 := 0; signal countV : integer range 0 to V_VID_END-1 := 0; signal display : boolean; signal cgAddr : std_logic_vector(10 downto 0); signal cgData : std_logic_vector(7 downto 0); signal output : std_logic_vector(7 downto 0); signal vSyncDelay : std_logic_vector(SYNC_DELAY-1 downto 0) := (others => not(V_SYNC_ACTIVE)); signal invers : std_logic; begin chargen : entity work.chargen port map ( clk => clk, addr => cgAddr, data => cgData ); vsync <= vSyncDelay(SYNC_DELAY-1); cgAddr <= charData & std_logic_vector(to_unsigned(countV / (CHAR_Y_SIZE/8), 3)); ramAddr <= std_logic_vector(to_unsigned(countH/CHAR_X_SIZE + countV/CHAR_Y_SIZE * CHAR_PER_LINE, 11)); process begin wait until rising_edge(clk); if (charData = x"11") then invers <= '1'; elsif (charData = x"10") then invers <= '0'; elsif (display = false) then invers <= '0'; end if; end process; --invers <= '0'; -- timing process begin wait until rising_edge(clk); if (countH < H_VID_END-1) then countH <= countH + 1; if ((countH mod CHAR_X_SIZE) = 2) then output <= cgData; elsif ((countH mod (CHAR_X_SIZE/8)) = 0) then output <= output(6 downto 0) & "0"; end if; else countH <= 0; if (countV < V_VID_END-1) then countV <= countV + 1; else countV <= 0; end if; end if; end process; -- sync+blanking process begin wait until rising_edge(clk); display <= false; if (countV < V_DISP) and (countH >= SYNC_DELAY-1) and (countH < H_DISP+SYNC_DELAY-1) then display <= true; end if; hsync <= not(H_SYNC_ACTIVE); if (countH >= H_SYNC_START+SYNC_DELAY-1) and (countH <= H_SYNC_END+SYNC_DELAY-1) then hsync <= H_SYNC_ACTIVE; end if; vSyncDelay(0) <= not(V_SYNC_ACTIVE); if (countV >= V_SYNC_START) and (countV <= V_SYNC_END) then vSyncDelay(0) <= V_SYNC_ACTIVE; end if; vSyncDelay(SYNC_DELAY-1 downto 1) <= vSyncDelay(SYNC_DELAY-2 downto 0); end process; -- color+output process (display, output, countV, scanLine) begin if (display and not(countV mod (CHAR_Y_SIZE/8) = 0 and scanLine='0')) then if (invers = '1') then if (output(7)='1') then pixel <= '0'; else pixel <= '1'; end if; else if (output(7)='1') then pixel <= '1'; else pixel <= '0'; end if; end if; else pixel <= '0'; end if; end process; end rtl;