⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 video_vicii_656x_a.vhd

📁 FPGA64的VHDL源代码
💻 VHD
📖 第 1 页 / 共 3 页
字号:
-- Which sprites are active?
-- -----------------------------------------------------------------------
	process(MCnt)
	begin
		for i in 0 to 7 loop
			MActive(i) <= false;
			if MCnt(i) /= 63 then
				MActive(i) <= true;
			end if;
		end loop;
	end process;

-- -----------------------------------------------------------------------
-- Sprite byte counter
-- Y expansion flipflop
-- -----------------------------------------------------------------------
	process(clk)
	begin
		if rising_edge(clk) then
			if phi = '0'
			and enaData = '1' then
				case vicCycle is
				when cycleRefresh5 =>
					for i in 0 to 7 loop
						MYE_ff(i) <= not MYE_ff(i);
						if MActive(i) then
							if MYE_ff(i) = MYE(i) then
								MCnt(i) <= MCnt(i) + 1;
							else
								MCnt(i) <= MCnt(i) - 2;
							end if;
						end if;
					end loop;
				when others =>
					null;
				end case;
			end if;
			for i in 0 to 7 loop
				if MYE(i) = '0'
				or not MActive(i) then
					MYE_ff(i) <= '0';
				end if;
			end loop;
			
			--
			-- On cycleCalcSprite check for each inactive sprite if
			-- there is a Y match. Reset MCnt if this is so.
			--
			-- The RasterX counter is used here to multiplex the compare logic.
			-- This saves a few logic cells in the FPGA.
			if vicCycle = cycleCalcSprites then
				if (not MActive(to_integer(RasterX(2 downto 0))))
				and (ME(to_integer(RasterX(2 downto 0))) = '1')
				and (rasterY(7 downto 0) = MY(to_integer(RasterX(2 downto 0)))) then
					MCnt(to_integer(RasterX(2 downto 0))) <= (others => '0');
				end if;
			end if;
			--
			-- Original non-multiplexed version
--				if vicCycle = cycleCalcSprites then
--					for i in 0 to 7 loop
--						if (not MActive(i))
--						and (ME(i) = '1')
--						and (rasterY(7 downto 0) = MY(i)) then
--							MCnt(i) <= (others => '0');
--						end if;
--					end loop;						
--				end if;
			
			--
			-- Increment MCnt after fetching data.
			if enaData = '1' then
				if (vicCycle = cycleSpriteA and phi = '1')
				or (vicCycle = cycleSpriteB and phi = '0') then
					if MActive(to_integer(sprite)) then
						MCnt(to_integer(sprite)) <= MCnt(to_integer(sprite)) + 1;
					end if;
				end if;
			end if;
		end if;
	end process;

-- -----------------------------------------------------------------------
-- Sprite pixel Shift register
-- -----------------------------------------------------------------------
	process(clk)
	begin
		if rising_edge(clk) then
			if enaPixel = '1' then
				-- Enable sprites on the correct X position
				for i in 0 to 7 loop
					if rasterX = MX(i) then
						MShift(i) <= true;
					end if;
				end loop;

				-- Shift one pixel of the sprite from the shift register.
				for i in 0 to 7 loop
					if MShift(i) then
						MXE_ff(i) <= (not MXE_ff(i)) and MXE(i);
						if MXE_ff(i) = '0' then
							MC_ff(i) <= (not MC_ff(i)) and MC(i);
							if MC_ff(i) = '0' then
								MCurrentPixel(i) <= MPixels(i)(23 downto 22);
							end if;
							MPixels(i) <= MPixels(i)(22 downto 0) & '0';
						end if;
					else
						MXE_ff(i) <= '0';
						MC_ff(i) <= '0';
						MCurrentPixel(i) <= "00";
					end if;
				end loop;
			end if;

			--
			-- Fill Sprite shift-register with new data.
			if enaData = '1' then
				if phi = '0'
				and vicCycle = cycleSpriteA then
					MShift(to_integer(sprite)) <= false;
				end if;

				if Mactive(to_integer(sprite)) then
					if phi = '0' then
						case vicCycle is
						when cycleSpriteB =>
							MPixels(to_integer(sprite)) <= MPixels(to_integer(sprite))(15 downto 0) & di;
						when others => null;
						end case;
					else
						case vicCycle is
						when cycleSpriteA | cycleSpriteB =>
							MPixels(to_integer(sprite)) <= MPixels(to_integer(sprite))(15 downto 0) & di;
						when others => null;
						end case;
					end if;
				end if;
			end if;
		end if;
	end process;

-- -----------------------------------------------------------------------
-- Video output
-- -----------------------------------------------------------------------
	process(clk)
		variable myColor: unsigned(3 downto 0);
		variable muxSprite : unsigned(2 downto 0);
		variable muxColor : unsigned(1 downto 0);
		-- 00 = pixels
		-- 01 = MM0
		-- 10 = Sprite
		-- 11 = MM1
	begin
		if rising_edge(clk) then
			muxColor := "00";
			muxSprite := (others => '-');
			for i in 7 downto 0 loop
				if (MPRIO(i) = '0') or (pixelBgFlag = '0') then
					if MC(i) = '1' then
						if MCurrentPixel(i) /= "00" then
							muxColor := MCurrentPixel(i);
							muxSprite := to_unsigned(i, 3);
						end if;
					elsif MCurrentPixel(i)(1) = '1' then
						muxColor := "10";
						muxSprite := to_unsigned(i, 3);
					end if;
				end if;
			end loop;

			myColor := pixelColor;
			case muxColor is
			when "01" => myColor := MM0;
			when "10" => myColor := spriteColors(to_integer(muxSprite));
			when "11" => myColor := MM1;
			when others =>
				null;
			end case;
		
		
--			myColor := pixelColor;
--			for i in 7 downto 0 loop
--				if (MPRIO(i) = '0') or (pixelBgFlag = '0') then
--					if MC(i) = '1' then
--						case MCurrentPixel(i) is
--						when "01" => myColor := MM0;
--						when "10" => myColor := spriteColors(i);
--						when "11" => myColor := MM1;
--						when others => null;
--						end case;
--					elsif MCurrentPixel(i)(1) = '1' then
--						myColor := spriteColors(i);
--					end if;
--				end if;
--			end loop;
			
			if enaPixel = '1' then
				colorIndex <= myColor;

-- Krestage 3 debugging routine
--				if (cs = '1' and aRegisters = "011100") then
--					colorIndex <= "1111";
--				end if;
				if (LRBorder = '1') or (TBBorder = '1') then
					colorIndex <= EC;
				end if;
				if (hBlack = '1') then
					colorIndex <= (others => '0');
				end if;
			end if;
		end if;
	end process;

-- -----------------------------------------------------------------------
-- Sprite to sprite collision
-- -----------------------------------------------------------------------
spriteSpriteCollision: process(clk)
		variable collision : unsigned(7 downto 0);
	begin
		if rising_edge(clk) then			
			if resetIMMC = '1' then
				IMMC <= '0';
			end if;

			if (myRd = '1')
			and	(aRegisters = "011110") then
				M2M <= (others => '0');
				M2Mhit <= '0';
			end if;

			for i in 0 to 7 loop
				collision(i) := MCurrentPixel(i)(1);
			end loop;
			if (collision /= "00000000")
			and (collision /= "00000001")
			and (collision /= "00000010")
			and (collision /= "00000100")
			and (collision /= "00001000")
			and (collision /= "00010000")
			and (collision /= "00100000")
			and (collision /= "01000000")
			and (collision /= "10000000")
			and (TBBorder = '0') then
				M2M <= M2M or collision;
				
				-- Give collision interrupt but only once until clear of register
				if M2Mhit = '0' then
					IMMC <= '1';
					M2Mhit <= '1';
				end if;
			end if;
		end if;
	end process;

-- -----------------------------------------------------------------------
-- Sprite to background collision
-- -----------------------------------------------------------------------
spriteBackgroundCollision: process(clk)
	begin
		if rising_edge(clk) then			
			if resetIMBC = '1' then
				IMBC <= '0';
			end if;

			if (myRd = '1')
			and	(aRegisters = "011111") then
				M2D <= (others => '0');
				M2Dhit <= '0';
			end if;

			for i in 0 to 7 loop
				if MCurrentPixel(i)(1) = '1'
				and pixelBgFlag = '1'
				and (TBBorder = '0') then
					M2D(i) <= '1';
					
					-- Give collision interrupt but only once until clear of register
					if M2Dhit = '0' then
						IMBC <= '1';
						M2Dhit <= '1';
					end if;
				end if;
			end loop;
		end if;
	end process;

-- -----------------------------------------------------------------------
-- Generate IRQ signal
-- -----------------------------------------------------------------------
	IRQ <= (ILP and ELP) or (IMMC and EMMC) or (IMBC and EMBC) or (IRST and ERST);

-- -----------------------------------------------------------------------
-- Krestage 3 hack
-- -----------------------------------------------------------------------
	process(clk)
	begin
		if rising_edge(clk) then
			if phi = '1'
			and enaData = '1' then
				MC <= MCDelay;
			end if;
		end if;
	end process;

-- -----------------------------------------------------------------------
-- Write registers
-- -----------------------------------------------------------------------
writeRegisters: process(clk)
	begin
		if rising_edge(clk) then
			resetLightPenIrq <= '0';
			resetIMMC <= '0';
			resetIMBC <= '0';
			resetRasterIrq <= '0';
		
			--
			-- write to registers
			if (myWr = '1') then
				case aRegisters is
				when "000000" => MX(0)(7 downto 0) <= diRegisters;
				when "000001" => MY(0) <= diRegisters;
				when "000010" => MX(1)(7 downto 0) <= diRegisters;
				when "000011" => MY(1) <= diRegisters;
				when "000100" => MX(2)(7 downto 0) <= diRegisters;
				when "000101" => MY(2) <= diRegisters;
				when "000110" => MX(3)(7 downto 0) <= diRegisters;
				when "000111" => MY(3) <= diRegisters;
				when "001000" => MX(4)(7 downto 0) <= diRegisters;
				when "001001" => MY(4) <= diRegisters;
				when "001010" => MX(5)(7 downto 0) <= diRegisters;
				when "001011" => MY(5) <= diRegisters;
				when "001100" => MX(6)(7 downto 0) <= diRegisters;
				when "001101" => MY(6) <= diRegisters;
				when "001110" => MX(7)(7 downto 0) <= diRegisters;
				when "001111" => MY(7) <= diRegisters;
				when "010000" =>
					MX(0)(8) <= diRegisters(0);
					MX(1)(8) <= diRegisters(1);
					MX(2)(8) <= diRegisters(2);
					MX(3)(8) <= diRegisters(3);
					MX(4)(8) <= diRegisters(4);
					MX(5)(8) <= diRegisters(5);
					MX(6)(8) <= diRegisters(6);
					MX(7)(8) <= diRegisters(7);
				when "010001" =>
					rasterCmp(8) <= diRegisters(7);
					ECM <= diRegisters(6);
					BMM <= diRegisters(5);
					DEN <= diRegisters(4);
					RSEL <= diRegisters(3);
					yscroll <= diRegisters(2 downto 0);
				when "010010" =>
					rasterCmp(7 downto 0) <= diRegisters;
				when "010101" =>
					ME <= diRegisters;
				when "010110" =>
					RES <= diRegisters(5);
					MCM <= diRegisters(4);
					CSEL <= diRegisters(3);
					xscroll <= diRegisters(2 downto 0);

				when "010111" => MYE <= diRegisters;
				when "011000" =>
					VM <= diRegisters(7 downto 4);
					CB <= diRegisters(3 downto 1);
				when "011001" =>
					resetLightPenIrq <= diRegisters(3);
					resetIMMC <= diRegisters(2);
					resetIMBC <= diRegisters(1);
					resetRasterIrq <= diRegisters(0);
				when "011010" =>
					ELP <= diRegisters(3);
					EMMC <= diRegisters(2);
					EMBC <= diRegisters(1);
					ERST <= diRegisters(0);
				when "011011" => MPRIO <= diRegisters;
				when "011100" =>
					-- MC <= diRegisters;
					MCDelay <= diRegisters; -- !!! Krestage 3 hack
				when "011101" => MXE <= diRegisters;
				when "100000" => EC <= diRegisters(3 downto 0);
				when "100001" => B0C <= diRegisters(3 downto 0);
				when "100010" => B1C <= diRegisters(3 downto 0);
				when "100011" => B2C <= diRegisters(3 downto 0);
				when "100100" => B3C <= diRegisters(3 downto 0);
				when "100101" => MM0 <= diRegisters(3 downto 0);
				when "100110" => MM1 <= diRegisters(3 downto 0);
				when "100111" => spriteColors(0) <= diRegisters(3 downto 0);
				when "101000" => spriteColors(1) <= diRegisters(3 downto 0);
				when "101001" => spriteColors(2) <= diRegisters(3 downto 0);
				when "101010" => spriteColors(3) <= diRegisters(3 downto 0);
				when "101011" => spriteColors(4) <= diRegisters(3 downto 0);
				when "101100" => spriteColors(5) <= diRegisters(3 downto 0);
				when "101101" => spriteColors(6) <= diRegisters(3 downto 0);
				when "101110" => spriteColors(7) <= diRegisters(3 downto 0);
				when others => null;
				end case;
			end if;
		end if;
	end process;

-- -----------------------------------------------------------------------
-- Read registers
-- -----------------------------------------------------------------------
readRegisters: process(clk)
	begin
		if rising_edge(clk) then
			case aRegisters is
			when "000000" => do <= MX(0)(7 downto 0);
			when "000001" => do <= MY(0);
			when "000010" => do <= MX(1)(7 downto 0);
			when "000011" => do <= MY(1);
			when "000100" => do <= MX(2)(7 downto 0);
			when "000101" => do <= MY(2);
			when "000110" => do <= MX(3)(7 downto 0);
			when "000111" => do <= MY(3);
			when "001000" => do <= MX(4)(7 downto 0);
			when "001001" => do <= MY(4);
			when "001010" => do <= MX(5)(7 downto 0);
			when "001011" => do <= MY(5);
			when "001100" => do <= MX(6)(7 downto 0);
			when "001101" => do <= MY(6);
			when "001110" => do <= MX(7)(7 downto 0);
			when "001111" => do <= MY(7);
			when "010000" =>
				do <= MX(7)(8) & MX(6)(8) & MX(5)(8) & MX(4)(8)
				& MX(3)(8) & MX(2)(8) & MX(1)(8) & MX(0)(8);
			when "010001" => do <= rasterY(8) & ECM & BMM & DEN & RSEL & yscroll;
			when "010010" => do <= rasterY(7 downto 0);
			when "010011" => do <= lpX;
			when "010100" => do <= lpY;
			when "010101" => do <= ME;
			when "010110" => do <= "11" & RES & MCM & CSEL & xscroll;
			when "010111" => do <= MYE;
			when "011000" => do <= VM & CB & '1';
			when "011001" => do <= IRQ & "111" & ILP & IMMC & IMBC & IRST;
			when "011010" => do <= "1111" & ELP & EMMC & EMBC & ERST;
			when "011011" => do <= MPRIO;
			when "011100" => do <= MC;
			when "011101" => do <= MXE;
			when "011110" => do <= M2M;
			when "011111" => do <= M2D;
			when "100000" => do <= "1111" & EC;
			when "100001" => do <= "1111" & B0C;
			when "100010" => do <= "1111" & B1C;
			when "100011" => do <= "1111" & B2C;
			when "100100" => do <= "1111" & B3C;
			when "100101" => do <= "1111" & MM0;
			when "100110" => do <= "1111" & MM1;
			when "100111" => do <= "1111" & spriteColors(0);
			when "101000" => do <= "1111" & spriteColors(1);
			when "101001" => do <= "1111" & spriteColors(2);
			when "101010" => do <= "1111" & spriteColors(3);
			when "101011" => do <= "1111" & spriteColors(4);
			when "101100" => do <= "1111" & spriteColors(5);
			when "101101" => do <= "1111" & spriteColors(6);
			when "101110" => do <= "1111" & spriteColors(7);
			when others => do <= (others => '1');
			end case;
		end if;
	end process;
end architecture;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -