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

📄 t65_mcode.vhd

📁 用FPGA制作的NES游戏主机(80后都知道的游戏主机)的VHDL代码
💻 VHD
📖 第 1 页 / 共 2 页
字号:
				LDAD <= '1';
				if IR(7 downto 5) = "100" then
					Write <= '1';
				end if;
				Set_Addr_To <= "10"; -- AD
			when 2 =>
			when others =>
			end case;
		--}}}

		when "00101" | "00110" | "00111" =>
		--{{{
			-- Zero Page
			if IR(7 downto 6) /= "10" and IR(1 downto 0) = "10" then
				-- Read-Modify-Write
				LCycle <= "100";
				case to_integer(unsigned(MCycle)) is
				when 1 =>
					Jump <= "01";
					LDAD <= '1';
					Set_Addr_To <= "10"; -- AD
				when 2 =>
					LDDI <= '1';
					Write <= '1';
					Set_Addr_To <= "10"; -- AD
				when 3 =>
					LDALU <= '1';
					SaveP <= '1';
					Write <= '1';
					Set_Addr_To <= "10"; -- AD
				when 4 =>
				when others =>
				end case;
			else
				LCycle <= "010";
				if IR(7 downto 6) /= "10" then
					LDA <= '1';
				end if;
				case to_integer(unsigned(MCycle)) is
				when 0 =>
				when 1 =>
					Jump <= "01";
					LDAD <= '1';
					if IR(7 downto 5) = "100" then
						Write <= '1';
					end if;
					Set_Addr_To <= "10"; -- AD
				when 2 =>
				when others =>
				end case;
			end if;
		--}}}

		when "01100" =>
		--{{{
			-- Absolute
			if IR(7 downto 6) = "01" and IR(4 downto 0) = "01100" then
				-- JMP
				if IR(5) = '0' then
					--LCycle <= "011";
					LCycle <= "010";
					case to_integer(unsigned(MCycle)) is
					when 1 =>
						Jump <= "01";
						LDDI <= '1';
					when 2 =>
						Jump <= "10"; -- DIDL
					when others =>
					end case;
				else
					LCycle <= "101";
					case to_integer(unsigned(MCycle)) is
					when 2 =>
						Jump <= "01";
						LDDI <= '1';
						LDBAL <= '1';
					when 3 =>
						LDBAH <= '1';
						if Mode /= "00" then
							Jump <= "10"; -- DIDL
						end if;
						if Mode = "00" then
							Set_Addr_To <= "11"; -- BA
						end if;
					when 4 =>
						LDDI <= '1';
						if Mode = "00" then
							Set_Addr_To <= "11"; -- BA
							BAAdd <= "01";      -- DB Inc
						else
							Jump <= "01";
						end if;
					when 5 =>
						Jump <= "10"; -- DIDL
					when others =>
					end case;
				end if;
			else
				LCycle <= "011";
				case to_integer(unsigned(MCycle)) is
				when 0 =>
					if IR(7 downto 5) = "001" then
						SaveP <= '1';
					end if;
				when 1 =>
					Jump <= "01";
					LDBAL <= '1';
				when 2 =>
					Jump <= "01";
					LDBAH <= '1';
					if IR(7 downto 5) = "100" then
						Write <= '1';
					end if;
					Set_Addr_To <= "11"; -- BA
				when 3 =>
				when others =>
				end case;
			end if;
		--}}}

		when "01101" | "01110" | "01111" =>
		--{{{
			-- Absolute
			if IR(7 downto 6) /= "10" and IR(1 downto 0) = "10" then
				-- Read-Modify-Write
				LCycle <= "101";
				case to_integer(unsigned(MCycle)) is
				when 1 =>
					Jump <= "01";
					LDBAL <= '1';
				when 2 =>
					Jump <= "01";
					LDBAH <= '1';
					Set_Addr_To <= "11"; -- BA
				when 3 =>
					LDDI <= '1';
					Write <= '1';
					Set_Addr_To <= "11"; -- BA
				when 4 =>
					Write <= '1';
					LDALU <= '1';
					SaveP <= '1';
					Set_Addr_To <= "11"; -- BA
				when 5 =>
					SaveP <= '0'; -- MIKEJ was 1
				when others =>
				end case;
			else
				LCycle <= "011";
				if IR(7 downto 6) /= "10" then
					LDA <= '1';
				end if;
				case to_integer(unsigned(MCycle)) is
				when 0 =>
				when 1 =>
					Jump <= "01";
					LDBAL <= '1';
				when 2 =>
					Jump <= "01";
					LDBAH <= '1';
					if IR(7 downto 5) = "100" then
						Write <= '1';
					end if;
					Set_Addr_To <= "11"; -- BA
				when 3 =>
				when others =>
				end case;
			end if;
		--}}}

		when "10000" =>
		--{{{
			-- Relative

						-- This circuit dictates when the last
						-- microcycle occurs for the branch depending on
						-- whether or not the branch is taken and if a page
						-- is crossed...
			if (Branch = '1') then

							 LCycle <= "011"; -- We're done @ T3 if branching...upper
											  -- level logic will stop at T2 if no page cross
											  -- (See the Break signal)
			else

							 LCycle <= "001";

			end if;

						-- This decodes the current microcycle and takes the
						-- proper course of action...
			case to_integer(unsigned(MCycle)) is

							-- On the T1 microcycle, increment the program counter
							-- and instruct the upper level logic to fetch the offset
							-- from the Din bus and store it in the data latches. This
							-- will be the last microcycle if the branch isn't taken.
				when 1 =>

					Jump <= "01"; -- Increments the PC by one (PC will now be PC+2)
											  -- from microcycle T0.

				LDDI <= '1';  -- Tells logic in top level (T65.vhd) to route
											  -- the Din bus to the memory data latch (DL)
											  -- so that the branch offset is fetched.

							-- In microcycle T2, tell the logic in the top level to
							-- add the offset.  If the most significant byte of the
							-- program counter (i.e. the current "page") does not need
							-- updating, we are done here...the Break signal at the
							-- T65.vhd level takes care of that...
				when 2 =>

				Jump    <= "11"; -- Tell the PC Jump logic to use relative mode.

				PCAdd   <= '1';  -- This tells the PC adder to update itself with
												 -- the current offset recently fetched from
												 -- memory.

							-- The following is microcycle T3 :
							-- The program counter should be completely updated
							-- on this cycle after the page cross is detected.
							-- We don't need to do anything here...
				when 3 =>


				when others => null; -- Do nothing.

			end case;
		--}}}

		when "10001" | "10011" =>
		--{{{
			-- Zero Page Indirect Indexed (d),y
			LCycle <= "101";
			if IR(7 downto 6) /= "10" then
				LDA <= '1';
			end if;
			case to_integer(unsigned(MCycle)) is
			when 0 =>
			when 1 =>
				Jump <= "01";
				LDAD <= '1';
				Set_Addr_To <= "10"; -- AD
			when 2 =>
				LDBAL <= '1';
				BAAdd <= "01";  -- DB Inc
				Set_Addr_To <= "10"; -- AD
			when 3 =>
				Set_BusA_To <= "011"; -- Y
				BAAdd <= "10";  -- BA Add
				LDBAH <= '1';
				Set_Addr_To <= "11"; -- BA
			when 4 =>
				BAAdd <= "11";  -- BA Adj
				if IR(7 downto 5) = "100" then
					Write <= '1';
				else
					BreakAtNA <= '1';
				end if;
				Set_Addr_To <= "11"; -- BA
			when 5 =>
			when others =>
			end case;
		--}}}

		when "10100" | "10101" | "10110" | "10111" =>
		--{{{
			-- Zero Page, X
			if IR(7 downto 6) /= "10" and IR(1 downto 0) = "10" then
				-- Read-Modify-Write
				LCycle <= "101";
				case to_integer(unsigned(MCycle)) is
				when 1 =>
					Jump <= "01";
					LDAD <= '1';
					Set_Addr_To <= "10"; -- AD
				when 2 =>
					ADAdd <= '1';
					Set_Addr_To <= "10"; -- AD
				when 3 =>
					LDDI <= '1';
					Write <= '1';
					Set_Addr_To <= "10"; -- AD
				when 4 =>
					LDALU <= '1';
					SaveP <= '1';
					Write <= '1';
					Set_Addr_To <= "10"; -- AD
				when 5 =>
				when others =>
				end case;
			else
				LCycle <= "011";
				if IR(7 downto 6) /= "10" then
					LDA <= '1';
				end if;
				case to_integer(unsigned(MCycle)) is
				when 0 =>
				when 1 =>
					Jump <= "01";
					LDAD <= '1';
					Set_Addr_To <= "10"; -- AD
				when 2 =>
					ADAdd <= '1';
					-- Added this check for Y reg. use...
					if (IR(3 downto 0) = "0110") then
					  AddY <= '1';
					end if;

					if IR(7 downto 5) = "100" then
						Write <= '1';
					end if;
					Set_Addr_To <= "10"; -- AD
				when 3 => null;
				when others =>
				end case;
			end if;
		--}}}

		when "11001" | "11011" =>
		--{{{
			-- Absolute Y
			LCycle <= "100";
			if IR(7 downto 6) /= "10" then
				LDA <= '1';
			end if;
			case to_integer(unsigned(MCycle)) is
			when 0 =>
			when 1 =>
				Jump <= "01";
				LDBAL <= '1';
			when 2 =>
				Jump <= "01";
				Set_BusA_To <= "011"; -- Y
				BAAdd <= "10";  -- BA Add
				LDBAH <= '1';
				Set_Addr_To <= "11"; -- BA
			when 3 =>
				BAAdd <= "11";  -- BA adj
				if IR(7 downto 5) = "100" then
					Write <= '1';
				else
					BreakAtNA <= '1';
				end if;
				Set_Addr_To <= "11"; -- BA
			when 4 =>
			when others =>
			end case;
		--}}}

		when "11100" | "11101" | "11110" | "11111" =>
		--{{{
			-- Absolute X

			if IR(7 downto 6) /= "10" and IR(1 downto 0) = "10" then
				-- Read-Modify-Write
				LCycle <= "110";
				case to_integer(unsigned(MCycle)) is
				when 1 =>
					Jump <= "01";
					LDBAL <= '1';
				when 2 =>
					Jump <= "01";
					Set_BusA_To <= "010"; -- X
					BAAdd <= "10";      -- BA Add
					LDBAH <= '1';
					Set_Addr_To <= "11"; -- BA
				when 3 =>
					BAAdd <= "11";      -- BA adj
					Set_Addr_To <= "11"; -- BA
				when 4 =>
					LDDI <= '1';
					Write <= '1';
					Set_Addr_To <= "11"; -- BA
				when 5 =>
					LDALU <= '1';
					SaveP <= '1';
					Write <= '1';
					Set_Addr_To <= "11"; -- BA
				when 6 =>
				when others =>
				end case;
			else
				LCycle <= "100";
				if IR(7 downto 6) /= "10" then
					LDA <= '1';
				end if;
				case to_integer(unsigned(MCycle)) is
				when 0 =>
				when 1 =>
					Jump <= "01";
					LDBAL <= '1';
				when 2 =>
					Jump <= "01";
					-- mikej
					-- special case 0xBE which uses Y reg as index!!
					if (IR = "10111110") then
					  Set_BusA_To <= "011"; -- Y
					else
					  Set_BusA_To <= "010"; -- X
					end if;
					BAAdd <= "10";      -- BA Add
					LDBAH <= '1';
					Set_Addr_To <= "11"; -- BA
				when 3 =>
					BAAdd <= "11";      -- BA adj
					if IR(7 downto 5) = "100" then
						Write <= '1';
					else
						BreakAtNA <= '1';
					end if;
					Set_Addr_To <= "11"; -- BA
				when 4 =>
				when others =>
				end case;
			end if;
		--}}}
		when others =>
		end case;
	end process;

	process (IR, MCycle)
	begin
		-- ORA, AND, EOR, ADC, NOP, LD, CMP, SBC
		-- ASL, ROL, LSR, ROR, BIT, LD, DEC, INC
		case IR(1 downto 0) is
		when "00" =>
		--{{{
			case IR(4 downto 2) is
			when "000" | "001" | "011" =>
				case IR(7 downto 5) is
				when "110" | "111" =>
					-- CP
					ALU_Op <= "0110";
				when "101" =>
					-- LD
					ALU_Op <= "0101";
				when "001" =>
					-- BIT
					ALU_Op <= "1100";
				when others =>
					-- NOP/ST
					ALU_Op <= "0100";
				end case;
			when "010" =>
				case IR(7 downto 5) is
				when "111" | "110" =>
					-- IN
					ALU_Op <= "1111";
				when "100" =>
					-- DEY
					ALU_Op <= "1110";
				when others =>
					-- LD
					ALU_Op <= "1101";
				end case;
			when "110" =>
				case IR(7 downto 5) is
				when "100" =>
					-- TYA
					ALU_Op <= "1101";
				when others =>
					ALU_Op <= "----";
				end case;
			when others =>
				case IR(7 downto 5) is
				when "101" =>
					-- LD
					ALU_Op <= "1101";
				when others =>
					ALU_Op <= "0100";
				end case;
			end case;
		--}}}
		when "01" => -- OR
		--{{{
			ALU_Op(3) <= '0';
			ALU_Op(2 downto 0) <= IR(7 downto 5);
		--}}}
		when "10" =>
		--{{{
			ALU_Op(3) <= '1';
			ALU_Op(2 downto 0) <= IR(7 downto 5);
			case IR(7 downto 5) is
			when "000" =>
				if IR(4 downto 2) = "110" then
					-- INC
					ALU_Op <= "1111";
				end if;
			when "001" =>
				if IR(4 downto 2) = "110" then
					-- DEC
					ALU_Op <= "1110";
				end if;
			when "100" =>
				if IR(4 downto 2) = "010" then
					-- TXA
					ALU_Op <= "0101";
				else
					ALU_Op <= "0100";
				end if;
			when others =>
			end case;
		--}}}
		when others =>
		--{{{
			case IR(7 downto 5) is
			when "100" =>
				ALU_Op <= "0100";
			when others =>
				if MCycle = "000" then
					ALU_Op(3) <= '0';
					ALU_Op(2 downto 0) <= IR(7 downto 5);
				else
					ALU_Op(3) <= '1';
					ALU_Op(2 downto 0) <= IR(7 downto 5);
				end if;
			end case;
		--}}}
		end case;
	end process;

end;

⌨️ 快捷键说明

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