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

📄 cpu65xx_fast.vhd

📁 FPGA64的VHDL源代码
💻 VHD
📖 第 1 页 / 共 4 页
字号:
			end if;
		end if;
	end process;

-- -----------------------------------------------------------------------
-- C flag
-- -----------------------------------------------------------------------
	process(clk)
	begin
		if rising_edge(clk) then
			if updateRegisters then
				if opcInfo(opcUpdateC) = '1' then
					C <= aluC;
				end if;
			end if;
		end if;
	end process;

-- -----------------------------------------------------------------------
-- Z flag
-- -----------------------------------------------------------------------
	process(clk)
	begin
		if rising_edge(clk) then
			if updateRegisters then
				if opcInfo(opcUpdateZ) = '1' then
					Z <= aluZ;
				end if;
			end if;
		end if;
	end process;

-- -----------------------------------------------------------------------
-- I flag
-- -----------------------------------------------------------------------
	process(clk)
	begin
		if rising_edge(clk) then
			if updateRegisters then
				if opcInfo(opcUpdateI) = '1' then
					I <= aluInput(2);
				end if;
			end if;
		end if;
	end process;

-- -----------------------------------------------------------------------
-- D flag
-- -----------------------------------------------------------------------
	process(clk)
	begin
		if rising_edge(clk) then
			if updateRegisters then
				if opcInfo(opcUpdateD) = '1' then
					D <= aluInput(3);
				end if;
			end if;
		end if;
	end process;

-- -----------------------------------------------------------------------
-- V flag
-- -----------------------------------------------------------------------
	process(clk)
	begin
		if rising_edge(clk) then
			if updateRegisters then
				if opcInfo(opcUpdateV) = '1' then
					V <= aluV;
				end if;
			end if;
			if enable = '1' then
				if soReg = '1' and so_n = '0' then
					V <= '1';
				end if;
				soReg <= so_n;
			end if;
		end if;
	end process;

-- -----------------------------------------------------------------------
-- N flag
-- -----------------------------------------------------------------------
	process(clk)
	begin
		if rising_edge(clk) then
			if updateRegisters then
				if opcInfo(opcUpdateN) = '1' then
					N <= aluN;
				end if;
			end if;
		end if;
	end process;

-- -----------------------------------------------------------------------
-- Stack pointer
-- -----------------------------------------------------------------------
	process(clk)
		variable sIncDec : unsigned(7 downto 0);
		variable updateFlag : boolean;
	begin
		if rising_edge(clk) then

			if opcInfo(opcStackUp) = '1' then
				sIncDec := S + 1;
			else
				sIncDec := S - 1;
			end if;	
			
			if enable = '1' then
				updateFlag := false;			
				case nextCpuCycle is
				when cycleStack1 =>
					if (opcInfo(opcStackUp) = '1')
					or (opcInfo(opcStackData) = '1') then
						updateFlag := true;			
					end if;
				when cycleStack2 =>
					updateFlag := true;
				when cycleStack3 =>
					updateFlag := true;			
				when cycleStack4 =>
					updateFlag := true;
				when cycleRead =>
					if opcInfo(opcRti) = '1' then							
						updateFlag := true;
					end if;						
				when cycleWrite =>
					if opcInfo(opcStackData) = '1' then
						updateFlag := true;
					end if;						
				when others =>
					null;					
				end case;
				if updateFlag then
					S <= sIncDec;
				end if;					
			end if;
			if updateRegisters then
				if opcInfo(opcUpdateS) = '1' then
					S <= aluRegisterOut;
				end if;					
			end if;
		end if;
	end process;

-- -----------------------------------------------------------------------
-- Data out
-- -----------------------------------------------------------------------
--calcDo: process(cpuNo, theCpuCycle, aluOut, PC, T)
calcDo: process(clk)
	begin
		if rising_edge(clk) then
			if enable = '1' then
				doReg <= aluRmwOut;
				if opcInfo(opcInH) = '1' then
					-- For illegal opcodes SHA, SHX, SHY, SHS
					doReg <= aluRmwOut and myAddrIncrH;
				end if;

				case nextCpuCycle is
				when cycleStack2 =>
					if opcInfo(opcIRQ) = '1'
					and irqActive = '0' then
						doReg <= myAddrIncr(15 downto 8);
					else
						doReg <= PC(15 downto 8);
					end if;
				when cycleStack3 =>
					doReg <= PC(7 downto 0);
				when cycleRmw =>
--					do <= T; -- Read-modify-write write old value first.
					doReg <= di; -- Read-modify-write write old value first.
				when others => null;
				end case;
			end if;			
		end if;
	end process;
	do <= doReg;
	


-- -----------------------------------------------------------------------
-- Write enable
-- -----------------------------------------------------------------------
calcWe: process(clk)
	begin
		if rising_edge(clk) then
			if enable = '1' then
				theWe <= '0';
				case nextCpuCycle is
				when cycleStack1 =>
					if opcInfo(opcStackUp) = '0'
					and ((opcInfo(opcStackAddr) = '0')
					or (opcInfo(opcStackData) = '1')) then
						theWe <= '1';
					end if;						
				when cycleStack2 | cycleStack3 | cycleStack4 =>
					if opcInfo(opcStackUp) = '0' then
						theWe <= '1';
					end if;						
				when cycleRmw =>
					theWe <= '1';
				when cycleWrite =>
					theWe <= '1';
				when others =>
					null;
				end case;				
			end if;
		end if;							
	end process;
	we <= theWe;

-- -----------------------------------------------------------------------
-- Program counter
-- -----------------------------------------------------------------------
calcPC: process(clk)
	begin
		if rising_edge(clk) then
			if enable = '1' then
				case theCpuCycle is
				when opcodeFetch =>
					PC <= myAddr;
				when cycle2 =>
					if irqActive = '0' then
						if opcInfo(opcSecondByte) = '1' then
							PC <= myAddrIncr;
						else							
							PC <= myAddr;
						end if;							
					end if;						
				when cycle3 =>
					if opcInfo(opcAbsolute) = '1' then
						PC <= myAddrIncr;					
					end if;
				when others =>
					null;
				end case;
			end if;
		end if;
	end process;
	debugPc <= PC;

-- -----------------------------------------------------------------------
-- Address generation
-- -----------------------------------------------------------------------
calcNextAddr: process(theCpuCycle, opcInfo, indexOut, T, reset)
	begin
		nextAddr <= nextAddrIncr;
		case theCpuCycle is
		when cycle2 =>
			if opcInfo(opcStackAddr) = '1' 
			or opcInfo(opcStackData) = '1' then
				nextAddr <= nextAddrStack;
			elsif opcInfo(opcAbsolute) = '1' then
				nextAddr <= nextAddrIncr;
			elsif opcInfo(opcZeroPage) = '1' then
				nextAddr <= nextAddrZeroPage;
			elsif opcInfo(opcIndirect) = '1' then
				nextAddr <= nextAddrZeroPage;
			elsif opcInfo(opcSecondByte) = '1' then
				nextAddr <= nextAddrIncr;
			else
				nextAddr <= nextAddrHold;
			end if;
		when cycle3 =>
			if (opcInfo(opcIndirect) = '1')
			and (opcInfo(indexX) = '1') then
				nextAddr <= nextAddrAbs;
			else							
				nextAddr <= nextAddrAbsIndexed;
			end if;				
		when cyclePreIndirect =>
			nextAddr <= nextAddrZPIndexed;
		when cycleIndirect =>
			nextAddr <= nextAddrIncrL;
		when cycleBranchTaken =>
			nextAddr <= nextAddrRelative;
		when cycleBranchPage =>
			if T(7) = '0' then
				nextAddr <= nextAddrIncrH;
			else				
				nextAddr <= nextAddrDecrH;
			end if;
		when cyclePreRead =>
			nextAddr <= nextAddrZPIndexed;
		when cycleRead =>
			nextAddr <= nextAddrPc;
			if opcInfo(opcJump) = '1' then
				-- Emulate 6510 bug, jmp(xxFF) fetches from same page.
				-- Replace with nextAddrIncr if emulating 65C02 or later cpu.
				nextAddr <= nextAddrIncrL; 
			elsif indexOut(8) = '1' then
				nextAddr <= nextAddrIncrH;
			elsif opcInfo(opcRmw) = '1' then
				nextAddr <= nextAddrHold;
			end if;
		when cycleRead2 =>
			nextAddr <= nextAddrPc;
			if opcInfo(opcRmw) = '1' then
				nextAddr <= nextAddrHold;
			end if;
		when cycleRmw =>
			nextAddr <= nextAddrHold;			
		when cyclePreWrite =>
			nextAddr <= nextAddrHold;			
			if opcInfo(opcZeroPage) = '1' then
				nextAddr <= nextAddrZPIndexed;
			elsif indexOut(8) = '1' then
				nextAddr <= nextAddrIncrH;
			end if;							
		when cycleWrite =>
			nextAddr <= nextAddrPc;			
		when cycleStack1 =>
			nextAddr <= nextAddrStack;
		when cycleStack2 =>
			nextAddr <= nextAddrStack;
		when cycleStack3 =>
			nextAddr <= nextAddrStack;
			if opcInfo(opcStackData) = '0' then
				nextAddr <= nextAddrPc;
			end if;				
		when cycleStack4 =>
			nextAddr <= nextAddrIrq;
		when cycleJump =>
			nextAddr <= nextAddrAbs;
		when others =>
			null;
		end case;										
		if reset = '1' then
			nextAddr <= nextAddrReset;
		end if;			
	end process;
	
indexAlu: process(opcInfo, myAddr, T, X, Y)
	begin
		if opcInfo(indexX) = '1' then
			indexOut <= (B"0" & T) + (B"0" & X);
		elsif opcInfo(indexY) = '1' then
			indexOut <= (B"0" & T) + (B"0" & Y);
		elsif opcInfo(opcBranch) = '1' then			
			indexOut <= (B"0" & T) + (B"0" & myAddr(7 downto 0));
		else
			indexOut <= B"0" & T;
		end if;
	end process;

calcAddr: process(clk)
	begin
		if rising_edge(clk) then
			if enable = '1' then
				case nextAddr is
				when nextAddrIncr => myAddr <= myAddrIncr;
				when nextAddrIncrL => myAddr(7 downto 0) <= myAddrIncr(7 downto 0);
				when nextAddrIncrH => myAddr(15 downto 8) <= myAddrIncrH;
				when nextAddrDecrH => myAddr(15 downto 8) <= myAddrDecrH;
				when nextAddrPc => myAddr <= PC;
				when nextAddrIrq =>
					myAddr <= X"FFFE";
					if nmiReg = '0' then
						myAddr <= X"FFFA";
					end if;
				when nextAddrReset => myAddr <= X"FFFC";
				when nextAddrAbs => myAddr <= di & T;
				when nextAddrAbsIndexed => myAddr <= di & indexOut(7 downto 0);
				when nextAddrZeroPage => myAddr <= "00000000" & di;
				when nextAddrZPIndexed => myAddr <= "00000000" & indexOut(7 downto 0);
				when nextAddrStack => myAddr <= "00000001" & S;
				when nextAddrRelative => myAddr(7 downto 0) <= indexOut(7 downto 0);
				when others => null;
				end case;
			end if;
		end if;							
	end process;	

	myAddrIncr <= myAddr + 1;
	myAddrIncrH <= myAddr(15 downto 8) + 1;
	myAddrDecrH <= myAddr(15 downto 8) - 1;

	addr <= myAddr;

	debugA <= A;
	debugX <= X;
	debugY <= Y;
	debugS <= S;
	
end architecture;


⌨️ 快捷键说明

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