------------------------------------------------------------------------------- -- th9958_graphic.vhd -- graphic for TH9958 -- -- Copyright (C) 2008 Takayuki Hara -- All rights reserved. ------------------------------------------------------------------------------- -- -- Redistribution and use of this software or any derivative works, -- 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 binary 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. -- 3. Redistributions may not be sold, nor may they be used in a -- commercial product or activity without specific prior written -- permission. -- -- 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 OWNER 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. -- ------------------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY TH9958_GRAPHIC IS PORT( CLK : IN STD_LOGIC; RESET_N : IN STD_LOGIC; ENABLE : IN STD_LOGIC; -- INPUT SIGNAL SCR_X : IN STD_LOGIC_VECTOR( 9 DOWNTO 0 ); SCR_Y : IN STD_LOGIC_VECTOR( 7 DOWNTO 0 ); ACT_X : IN STD_LOGIC; -- OUTPUT SIGNAL PALETTE : OUT STD_LOGIC_VECTOR( 7 DOWNTO 0 ); -- VRAM IL_MODE : OUT STD_LOGIC; VRAM_A : OUT STD_LOGIC_VECTOR( 16 DOWNTO 0 ); VRAM_REQ : OUT STD_LOGIC; VRAM_Q : IN STD_LOGIC_VECTOR( 15 DOWNTO 0 ); -- MODE SP_MODE : OUT STD_LOGIC; -- REGISTER REG_M543 : IN STD_LOGIC_VECTOR( 2 DOWNTO 0 ); REG_M12 : IN STD_LOGIC_VECTOR( 1 DOWNTO 0 ); REG_PAT : IN STD_LOGIC_VECTOR( 6 DOWNTO 0 ); REG_COL_L : IN STD_LOGIC_VECTOR( 7 DOWNTO 0 ); REG_GEN : IN STD_LOGIC_VECTOR( 5 DOWNTO 0 ); REG_COL_H : IN STD_LOGIC_VECTOR( 2 DOWNTO 0 ) ); END TH9958_GRAPHIC; ARCHITECTURE RTL OF TH9958_GRAPHIC IS -- MODE DECODE SIGNAL W_MODE : STD_LOGIC_VECTOR( 4 DOWNTO 0 ); SIGNAL W_TEXT1 : STD_LOGIC; SIGNAL W_TEXT2 : STD_LOGIC; SIGNAL W_MULTI : STD_LOGIC; SIGNAL W_GRAPHIC1 : STD_LOGIC; SIGNAL W_GRAPHIC2 : STD_LOGIC; SIGNAL W_GRAPHIC3 : STD_LOGIC; SIGNAL W_GRAPHIC4 : STD_LOGIC; SIGNAL W_GRAPHIC5 : STD_LOGIC; SIGNAL W_GRAPHIC6 : STD_LOGIC; SIGNAL W_GRAPHIC7 : STD_LOGIC; SIGNAL W_INVALID : STD_LOGIC; SIGNAL W_PN_ADR : STD_LOGIC_VECTOR( 16 DOWNTO 0 ); SIGNAL W_CL_ADR : STD_LOGIC_VECTOR( 16 DOWNTO 0 ); SIGNAL W_PG_ADR : STD_LOGIC_VECTOR( 16 DOWNTO 0 ); SIGNAL W_PN_ADR_G1 : STD_LOGIC_VECTOR( 16 DOWNTO 0 ); SIGNAL W_PN_ADR_G4 : STD_LOGIC_VECTOR( 16 DOWNTO 0 ); SIGNAL W_PN_ADR_G6 : STD_LOGIC_VECTOR( 16 DOWNTO 0 ); SIGNAL W_CL_ADR_G1 : STD_LOGIC_VECTOR( 16 DOWNTO 0 ); SIGNAL W_PG_ADR_G1 : STD_LOGIC_VECTOR( 16 DOWNTO 0 ); SIGNAL W_CL_ADR_G2 : STD_LOGIC_VECTOR( 16 DOWNTO 0 ); SIGNAL W_PG_ADR_G2 : STD_LOGIC_VECTOR( 16 DOWNTO 0 ); SIGNAL W_OUT_G1 : STD_LOGIC_VECTOR( 3 DOWNTO 0 ); SIGNAL W_OUT_G4 : STD_LOGIC_VECTOR( 3 DOWNTO 0 ); SIGNAL W_OUT_G5 : STD_LOGIC_VECTOR( 1 DOWNTO 0 ); SIGNAL W_OUT_G6 : STD_LOGIC_VECTOR( 3 DOWNTO 0 ); SIGNAL W_OUT_G7 : STD_LOGIC_VECTOR( 7 DOWNTO 0 ); SIGNAL W_PALETTE : STD_LOGIC_VECTOR( 7 DOWNTO 0 ); -- FF SIGNAL FF_TEXT1 : STD_LOGIC; SIGNAL FF_TEXT2 : STD_LOGIC; SIGNAL FF_MULTI : STD_LOGIC; SIGNAL FF_GRAPHIC1 : STD_LOGIC; SIGNAL FF_GRAPHIC2 : STD_LOGIC; SIGNAL FF_GRAPHIC3 : STD_LOGIC; SIGNAL FF_GRAPHIC4 : STD_LOGIC; SIGNAL FF_GRAPHIC5 : STD_LOGIC; SIGNAL FF_GRAPHIC6 : STD_LOGIC; SIGNAL FF_GRAPHIC7 : STD_LOGIC; SIGNAL FF_INVALID : STD_LOGIC; SIGNAL FF_VRAM_A : STD_LOGIC_VECTOR( 16 DOWNTO 0 ); SIGNAL FF_VRAM_REQ : STD_LOGIC; SIGNAL FF_PN : STD_LOGIC_VECTOR( 15 DOWNTO 0 ); SIGNAL FF_PN2 : STD_LOGIC_VECTOR( 15 DOWNTO 0 ); SIGNAL FF_PN3 : STD_LOGIC_VECTOR( 15 DOWNTO 0 ); SIGNAL FF_CL : STD_LOGIC_VECTOR( 7 DOWNTO 0 ); SIGNAL FF_CLO : STD_LOGIC_VECTOR( 7 DOWNTO 0 ); SIGNAL FF_PGO : STD_LOGIC_VECTOR( 7 DOWNTO 0 ); BEGIN VRAM_A <= FF_VRAM_A; VRAM_REQ <= FF_VRAM_REQ; -------------------------------------------------------------------------- -- MODE DECODER -------------------------------------------------------------------------- W_MODE <= REG_M543 & REG_M12; W_TEXT1 <= '1' WHEN( W_MODE = "00010" )ELSE '0'; W_TEXT2 <= '1' WHEN( W_MODE = "01010" )ELSE '0'; W_MULTI <= '1' WHEN( W_MODE = "00001" )ELSE '0'; W_GRAPHIC1 <= '1' WHEN( W_MODE = "00000" )ELSE '0'; W_GRAPHIC2 <= '1' WHEN( W_MODE = "00100" )ELSE '0'; W_GRAPHIC3 <= '1' WHEN( W_MODE = "01000" )ELSE '0'; W_GRAPHIC4 <= '1' WHEN( W_MODE = "01100" )ELSE '0'; W_GRAPHIC5 <= '1' WHEN( W_MODE = "10000" )ELSE '0'; W_GRAPHIC6 <= '1' WHEN( W_MODE = "10100" )ELSE '0'; W_GRAPHIC7 <= '1' WHEN( W_MODE = "11100" )ELSE '0'; W_INVALID <= NOT (W_TEXT1 OR W_TEXT2 OR W_MULTI OR W_GRAPHIC1 OR W_GRAPHIC2 OR W_GRAPHIC3 OR W_GRAPHIC4 OR W_GRAPHIC5 OR W_GRAPHIC6 OR W_GRAPHIC7); PROCESS( RESET_N, CLK ) BEGIN IF( RESET_N = '0' )THEN FF_TEXT1 <= '0'; FF_TEXT2 <= '0'; FF_MULTI <= '0'; FF_GRAPHIC1 <= '0'; FF_GRAPHIC2 <= '0'; FF_GRAPHIC3 <= '0'; FF_GRAPHIC4 <= '0'; FF_GRAPHIC5 <= '0'; FF_GRAPHIC6 <= '0'; FF_GRAPHIC7 <= '0'; FF_INVALID <= '0'; ELSIF( CLK'EVENT AND CLK = '1' )THEN IF( ENABLE = '1' )THEN FF_TEXT1 <= W_TEXT1; FF_TEXT2 <= W_TEXT2; FF_MULTI <= W_MULTI; FF_GRAPHIC1 <= W_GRAPHIC1; FF_GRAPHIC2 <= W_GRAPHIC2; FF_GRAPHIC3 <= W_GRAPHIC3; FF_GRAPHIC4 <= W_GRAPHIC4; FF_GRAPHIC5 <= W_GRAPHIC5; FF_GRAPHIC6 <= W_GRAPHIC6; FF_GRAPHIC7 <= W_GRAPHIC7; FF_INVALID <= W_INVALID; END IF; END IF; END PROCESS; IL_MODE <= FF_GRAPHIC6 OR FF_GRAPHIC7; SP_MODE <= FF_GRAPHIC3 OR FF_GRAPHIC4 OR FF_GRAPHIC5 OR FF_GRAPHIC6 OR FF_GRAPHIC7; -------------------------------------------------------------------------- -- PIXEL GENERATOR -------------------------------------------------------------------------- W_PN_ADR <= W_PN_ADR_G1 WHEN((FF_GRAPHIC1 OR FF_GRAPHIC2 OR FF_GRAPHIC3) = '1' )ELSE W_PN_ADR_G4 WHEN((FF_GRAPHIC4 OR FF_GRAPHIC5) = '1' )ELSE W_PN_ADR_G6 WHEN((FF_GRAPHIC6 OR FF_GRAPHIC7) = '1' )ELSE (OTHERS => '0'); W_CL_ADR <= W_CL_ADR_G1 WHEN( FF_GRAPHIC1 = '1' )ELSE W_CL_ADR_G2 WHEN( FF_GRAPHIC2 = '1' )ELSE W_CL_ADR_G2 WHEN( FF_GRAPHIC3 = '1' )ELSE (OTHERS => '0'); W_PG_ADR <= W_PG_ADR_G1 WHEN( FF_GRAPHIC1 = '1' )ELSE W_PG_ADR_G2 WHEN( FF_GRAPHIC2 = '1' )ELSE W_PG_ADR_G2 WHEN( FF_GRAPHIC3 = '1' )ELSE (OTHERS => '0'); W_PN_ADR_G1 <= REG_PAT & SCR_Y( 7 DOWNTO 3 ) & SCR_X( 9 DOWNTO 5 ); -- GRAPHIC1,2,3 W_PN_ADR_G4 <= REG_PAT( 6 DOWNTO 5 ) & SCR_Y( 7 DOWNTO 0 ) & SCR_X( 9 DOWNTO 3 ); -- GRAPHIC4,5 W_PN_ADR_G6 <= REG_PAT(5) & SCR_Y( 7 DOWNTO 0 ) & SCR_X( 9 DOWNTO 3 ) & '0'; -- GRAPHIC6,7 W_CL_ADR_G1 <= REG_COL_H & REG_COL_L & '0' & FF_PN( 7 DOWNTO 3 ); -- GRAPHIC1 W_CL_ADR_G2 <= REG_COL_H & REG_COL_L(7) & SCR_Y( 7 DOWNTO 6 ) & FF_PN( 7 DOWNTO 0 ) & SCR_Y( 2 DOWNTO 0 ); -- GRAPHIC2,3 W_PG_ADR_G1 <= REG_GEN & FF_PN( 7 DOWNTO 0 ) & SCR_Y( 2 DOWNTO 0 ); -- GRAPHIC1 W_PG_ADR_G2 <= REG_GEN( 5 DOWNTO 2 ) & SCR_Y( 7 DOWNTO 6 ) & FF_PN( 7 DOWNTO 0 ) & SCR_Y( 2 DOWNTO 0 ); -- GRAPHIC2,3 PROCESS( RESET_N, CLK ) BEGIN IF( RESET_N = '0' )THEN FF_VRAM_A <= (OTHERS => '0'); ELSIF( CLK'EVENT AND CLK = '1' )THEN IF( ENABLE = '1' )THEN IF( (FF_GRAPHIC1 OR FF_GRAPHIC2 OR FF_GRAPHIC3) = '1' AND SCR_X( 4 DOWNTO 0 ) = "01000" )THEN FF_VRAM_A <= W_CL_ADR; ELSIF( (FF_GRAPHIC1 OR FF_GRAPHIC2 OR FF_GRAPHIC3) = '1' AND SCR_X( 4 DOWNTO 0 ) = "10000" )THEN FF_VRAM_A <= W_PG_ADR; ELSIF( SCR_X( 2 DOWNTO 0 ) = "000" )THEN FF_VRAM_A <= W_PN_ADR; END IF; END IF; END IF; END PROCESS; PROCESS( RESET_N, CLK ) BEGIN IF( RESET_N = '0' )THEN FF_VRAM_REQ <= '0'; ELSIF( CLK'EVENT AND CLK = '1' )THEN IF( ENABLE = '1' )THEN IF( (FF_GRAPHIC1 OR FF_GRAPHIC2 OR FF_GRAPHIC3) = '1' AND (SCR_X( 4 DOWNTO 0 ) = "00000" OR SCR_X( 4 DOWNTO 0 ) = "01000" OR SCR_X( 4 DOWNTO 0 ) = "10000") )THEN FF_VRAM_REQ <= ACT_X; ELSIF( (FF_GRAPHIC4 OR FF_GRAPHIC5 OR FF_GRAPHIC6 OR FF_GRAPHIC7) = '1' AND (SCR_X( 2 DOWNTO 0 ) = "000") )THEN FF_VRAM_REQ <= ACT_X; ELSE FF_VRAM_REQ <= '0'; END IF; END IF; END IF; END PROCESS; PROCESS( RESET_N, CLK ) BEGIN IF( RESET_N = '0' )THEN FF_PN <= (OTHERS => '0'); FF_PN2 <= (OTHERS => '0'); ELSIF( CLK'EVENT AND CLK = '1' )THEN IF( ENABLE = '1' )THEN IF( SCR_X( 2 DOWNTO 0 ) = "100" )THEN FF_PN <= VRAM_Q; FF_PN2 <= FF_PN; END IF; END IF; END IF; END PROCESS; PROCESS( RESET_N, CLK ) BEGIN IF( RESET_N = '0' )THEN FF_PN3 <= (OTHERS => '0'); ELSIF( CLK'EVENT AND CLK = '1' )THEN IF( ENABLE = '1' )THEN IF( SCR_X( 2 DOWNTO 0 ) = "011" )THEN FF_PN3 <= FF_PN2; END IF; END IF; END IF; END PROCESS; PROCESS( RESET_N, CLK ) BEGIN IF( RESET_N = '0' )THEN FF_CL <= (OTHERS => '0'); ELSIF( CLK'EVENT AND CLK = '1' )THEN IF( ENABLE = '1' )THEN IF( SCR_X( 4 DOWNTO 0 ) = "01100" )THEN FF_CL <= VRAM_Q( 7 DOWNTO 0 ); END IF; END IF; END IF; END PROCESS; PROCESS( RESET_N, CLK ) BEGIN IF( RESET_N = '0' )THEN FF_CLO <= (OTHERS => '0'); ELSIF( CLK'EVENT AND CLK = '1' )THEN IF( ENABLE = '1' )THEN IF( SCR_X( 4 DOWNTO 0 ) = "10011" )THEN FF_CLO <= FF_CL; END IF; END IF; END IF; END PROCESS; PROCESS( RESET_N, CLK ) BEGIN IF( RESET_N = '0' )THEN FF_PGO <= (OTHERS => '0'); ELSIF( CLK'EVENT AND CLK = '1' )THEN IF( ENABLE = '1' )THEN IF( SCR_X( 4 DOWNTO 0 ) = "10100" )THEN FF_PGO <= VRAM_Q( 7 DOWNTO 0 ); ELSIF( SCR_X( 1 DOWNTO 0 ) = "11" )THEN FF_PGO <= FF_PGO( 6 DOWNTO 0 ) & '0'; END IF; END IF; END IF; END PROCESS; -- GRAPHIC1,2,3 W_OUT_G1 <= FF_CLO( 7 DOWNTO 4 ) WHEN( FF_PGO(7) = '1' )ELSE FF_CLO( 3 DOWNTO 0 ); -- GRAPHIC4 W_OUT_G4 <= FF_PN3( 7 DOWNTO 4 ) WHEN( SCR_X(2) = '1' )ELSE FF_PN3( 3 DOWNTO 0 ); -- GRAPHIC5 WITH SCR_X( 2 DOWNTO 1 ) SELECT W_OUT_G5 <= FF_PN3( 7 DOWNTO 6 ) WHEN "00", FF_PN3( 5 DOWNTO 4 ) WHEN "01", FF_PN3( 3 DOWNTO 2 ) WHEN "10", FF_PN3( 1 DOWNTO 0 ) WHEN "11", "XX" WHEN OTHERS; -- GRAPHIC6 WITH SCR_X( 2 DOWNTO 1 ) SELECT W_OUT_G6 <= FF_PN3( 15 DOWNTO 12 ) WHEN "00", FF_PN3( 11 DOWNTO 8 ) WHEN "01", FF_PN3( 7 DOWNTO 4 ) WHEN "10", FF_PN3( 3 DOWNTO 0 ) WHEN "11", "XXXX" WHEN OTHERS; -- GRAPHIC7 W_OUT_G7 <= FF_PN3( 15 DOWNTO 8 ) WHEN( SCR_X(2) = '1' )ELSE FF_PN3( 7 DOWNTO 0 ); W_PALETTE <= ("0000" & W_OUT_G1) WHEN((FF_GRAPHIC1 OR FF_GRAPHIC2 OR FF_GRAPHIC3) = '1')ELSE ("0000" & W_OUT_G4) WHEN( FF_GRAPHIC4 = '1' )ELSE ("000000" & W_OUT_G5) WHEN( FF_GRAPHIC5 = '1' )ELSE ("0000" & W_OUT_G6) WHEN( FF_GRAPHIC6 = '1' )ELSE ( W_OUT_G7) WHEN( FF_GRAPHIC7 = '1' )ELSE "00001111"; PROCESS( RESET_N, CLK ) BEGIN IF( RESET_N = '0' )THEN PALETTE <= (OTHERS => '0'); ELSIF( CLK'EVENT AND CLK = '1' )THEN IF( ENABLE = '1' )THEN PALETTE <= W_PALETTE; END IF; END IF; END PROCESS; END RTL;