------------------------------------------------------------------------------- -- th9958_sprite.vhd -- sprite 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; USE IEEE.STD_LOGIC_ARITH.ALL; ENTITY TH9958_SPRITE IS PORT( CLK : IN STD_LOGIC; RESET_N : IN STD_LOGIC; ENABLE : IN STD_LOGIC; SCR_X : IN STD_LOGIC_VECTOR( 9 DOWNTO 0 ); SCR_Y : IN STD_LOGIC_VECTOR( 7 DOWNTO 0 ); ACT_X : IN STD_LOGIC; ACT_Y : IN STD_LOGIC; SPR_ADR : OUT STD_LOGIC_VECTOR( 16 DOWNTO 0 ); SPR_REQ : OUT STD_LOGIC; SPR_ACK : IN STD_LOGIC; SPR_LATCH : IN STD_LOGIC; SPR_Q : IN STD_LOGIC_VECTOR( 7 DOWNTO 0 ); CLR_5S : IN STD_LOGIC; S_5S : OUT STD_LOGIC; S_5TH_SP : OUT STD_LOGIC_VECTOR( 4 DOWNTO 0 ); REG_MAG : IN STD_LOGIC; REG_SI : IN STD_LOGIC; REG_LN : IN STD_LOGIC; REG_SPA_L : IN STD_LOGIC_VECTOR( 5 DOWNTO 0 ); REG_SPA_H : IN STD_LOGIC_VECTOR( 1 DOWNTO 0 ); SP_MODE : IN STD_LOGIC ); END TH9958_SPRITE; ARCHITECTURE RTL OF TH9958_SPRITE IS TYPE INFO_ARRAY IS ARRAY( 0 TO 7 ) OF STD_LOGIC_VECTOR( 8 DOWNTO 0 ); SIGNAL RAM_INFO : INFO_ARRAY; SIGNAL FF_VRAM_Q : STD_LOGIC_VECTOR( 7 DOWNTO 0 ); SIGNAL FF_STATE : STD_LOGIC; SIGNAL FF_DISP_CNT : STD_LOGIC_VECTOR( 3 DOWNTO 0 ); SIGNAL FF_WE : STD_LOGIC; SIGNAL FF_D : STD_LOGIC_VECTOR( 8 DOWNTO 0 ); SIGNAL FF_UNDISP : STD_LOGIC; SIGNAL FF_5S : STD_LOGIC; SIGNAL FF_5TH_SP : STD_LOGIC_VECTOR( 4 DOWNTO 0 ); SIGNAL W_SP_REQ_S1 : STD_LOGIC; SIGNAL W_SP_REQ_S2 : STD_LOGIC; SIGNAL W_SPA_S1 : STD_LOGIC_VECTOR( 16 DOWNTO 0 ); SIGNAL W_REL_Y : STD_LOGIC_VECTOR( 8 DOWNTO 0 ); SIGNAL W_REL_MASK : STD_LOGIC_VECTOR( 1 DOWNTO 0 ); SIGNAL W_MODE : STD_LOGIC_VECTOR( 1 DOWNTO 0 ); SIGNAL W_CMP : STD_LOGIC_VECTOR( 8 DOWNTO 3 ); SIGNAL W_ACT : STD_LOGIC; SIGNAL W_WE : STD_LOGIC; SIGNAL W_FULL : STD_LOGIC; SIGNAL W_REL_SEL : STD_LOGIC_VECTOR( 3 DOWNTO 0 ); SIGNAL W_UNDISP_LINE : STD_LOGIC_VECTOR( 7 DOWNTO 0 ); SIGNAL W_UNDISP_SP : STD_LOGIC; BEGIN S_5S <= FF_5S; W_SP_REQ_S1 <= '1' WHEN( SCR_X( 4 DOWNTO 0 ) = "10101" )ELSE '0'; W_SP_REQ_S2 <= '1' WHEN( SCR_X( 2 DOWNTO 0 ) = "001" )ELSE '0'; SPR_REQ <= W_SP_REQ_S1 WHEN( FF_STATE = '0' )ELSE W_SP_REQ_S2; W_SPA_S1 <= REG_SPA_H & REG_SPA_L & "00" & SCR_X( 9 DOWNTO 5 ) & "00"; SPR_ADR <= W_SPA_S1; -- šŽb’è W_REL_Y <= ('0' & FF_VRAM_Q) - ('0' & SCR_Y); W_MODE <= REG_MAG & REG_SI; WITH W_MODE SELECT W_REL_MASK <= "00" WHEN "11", "10" WHEN "10", "10" WHEN "01", "11" WHEN "00", "XX" WHEN OTHERS; W_UNDISP_LINE <= CONV_STD_LOGIC_VECTOR( 216, 8 ) WHEN( REG_LN = '1' )ELSE CONV_STD_LOGIC_VECTOR( 208, 8 ); W_UNDISP_SP <= '1' WHEN( FF_VRAM_Q = W_UNDISP_LINE )ELSE '0'; PROCESS( RESET_N, CLK ) BEGIN IF( RESET_N = '0' )THEN FF_UNDISP <= '0'; ELSIF( CLK'EVENT AND CLK = '1' )THEN IF( ENABLE = '1' )THEN IF( FF_STATE = '1' )THEN FF_UNDISP <= '0'; ELSIF( W_UNDISP_SP = '1' )THEN FF_UNDISP <= '1'; END IF; END IF; END IF; END PROCESS; W_CMP( 4 DOWNTO 3 ) <= W_REL_MASK AND W_REL_Y( 4 DOWNTO 3 ); W_CMP( 8 DOWNTO 5 ) <= W_REL_Y( 8 DOWNTO 5 ); W_ACT <= (NOT (W_UNDISP_SP OR FF_UNDISP)) WHEN( W_CMP = 0 )ELSE '0'; W_FULL <= ((NOT SP_MODE) AND FF_DISP_CNT(2)) OR FF_DISP_CNT(3); W_WE <= W_ACT AND (NOT W_FULL); W_REL_SEL <= W_REL_Y( 3 DOWNTO 0 ) WHEN( REG_MAG = '0' )ELSE W_REL_Y( 4 DOWNTO 1 ); PROCESS( RESET_N, CLK ) BEGIN IF( RESET_N = '0' )THEN FF_VRAM_Q <= (OTHERS => '0'); ELSIF( CLK'EVENT AND CLK = '1' )THEN IF( ENABLE = '1' )THEN IF( SPR_LATCH = '1' )THEN FF_VRAM_Q <= SPR_Q; END IF; END IF; END IF; END PROCESS; PROCESS( RESET_N, CLK ) BEGIN IF( RESET_N = '0' )THEN FF_STATE <= '0'; ELSIF( CLK'EVENT AND CLK = '1' )THEN IF( ENABLE = '1' )THEN IF( SCR_X = "0000000000" )THEN FF_STATE <= '0'; ELSIF( SCR_X = "1111111111" )THEN FF_STATE <= '1'; END IF; END IF; END IF; END PROCESS; PROCESS( RESET_N, CLK ) BEGIN IF( RESET_N = '0' )THEN FF_DISP_CNT <= (OTHERS => '0'); ELSIF( CLK'EVENT AND CLK = '1' )THEN IF( ENABLE = '1' )THEN IF( SCR_X = 0 )THEN FF_DISP_CNT <= (OTHERS => '0'); ELSIF( FF_WE = '1' )THEN FF_DISP_CNT <= FF_DISP_CNT + 1; END IF; END IF; END IF; END PROCESS; PROCESS( RESET_N, CLK ) BEGIN IF( RESET_N = '0' )THEN FF_WE <= '0'; FF_D <= (OTHERS => '0'); ELSIF( CLK'EVENT AND CLK = '1' )THEN IF( ENABLE = '1' )THEN IF( SCR_X( 4 DOWNTO 0 ) = "11001" )THEN FF_WE <= W_WE; FF_D <= W_REL_SEL & SCR_X( 9 DOWNTO 5 ); ELSE FF_WE <= '0'; FF_D <= (OTHERS => '0'); END IF; END IF; END IF; END PROCESS; PROCESS( RESET_N, CLK ) BEGIN IF( RESET_N = '0' )THEN FF_5S <= '0'; ELSIF( CLK'EVENT AND CLK = '1' )THEN IF( ENABLE = '1' )THEN IF( CLR_5S = '1' )THEN FF_5S <= '0'; ELSIF( (W_ACT AND W_FULL) = '1' )THEN FF_5S <= '1'; END IF; END IF; END IF; END PROCESS; PROCESS( RESET_N, CLK ) BEGIN IF( RESET_N = '0' )THEN FF_5TH_SP <= "00000"; ELSIF( CLK'EVENT AND CLK = '1' )THEN IF( ENABLE = '1' )THEN IF( CLR_5S = '1' )THEN FF_5TH_SP <= "00000"; ELSIF( ((NOT FF_5S) AND W_ACT AND W_FULL) = '1' )THEN FF_5TH_SP <= SCR_X( 9 DOWNTO 5 ); END IF; END IF; END IF; END PROCESS; END RTL;