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

📄 fpga64_buslogic_roms.vhd

📁 FPGA64的VHDL源代码
💻 VHD
字号:
-- -----------------------------------------------------------------------
--
--                                 FPGA 64
--
--     A fully functional commodore 64 implementation in a single FPGA
--
-- -----------------------------------------------------------------------
-- Copyright 2005-2008 by Peter Wendrich (pwsoft@syntiac.com)
-- http://www.syntiac.com/fpga64.html
-- -----------------------------------------------------------------------

library IEEE;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;

-- -----------------------------------------------------------------------

entity fpga64_buslogic_roms is
	port (
		clk: in std_logic;
		reset: in std_logic;
		ena : in std_logic;
		busCycle: in unsigned(5 downto 0);
		cpuGetsBus : in std_logic;

		ramData: in unsigned(7 downto 0);

		-- 2 CHAREN
		-- 1 HIRAM
		-- 0 LORAM
		bankSwitch: in unsigned(2 downto 0);

		cpuWe: in std_logic;
		cpuAddr: in unsigned(15 downto 0);
		cpuData: in unsigned(7 downto 0);
		vicAddr: in unsigned(15 downto 0);
		vicData: in unsigned(7 downto 0);
		sidData: in unsigned(7 downto 0);
		colorData: in unsigned(3 downto 0);
		cia1Data: in unsigned(7 downto 0);
		cia2Data: in unsigned(7 downto 0);
		lastVicData : in unsigned(7 downto 0);

		systemWe: out std_logic;
		pulseWr: out std_logic;
		systemAddr: out unsigned(15 downto 0);
		dataToCpu : out unsigned(7 downto 0);
		dataToVic : out unsigned(7 downto 0);

		cs_vic: out std_logic;
		cs_sid: out std_logic;
		cs_color : out std_logic;
		cs_cia1: out std_logic;
		cs_cia2: out std_logic;
		cs_ram: out std_logic
	);
end fpga64_buslogic_roms;

-- -----------------------------------------------------------------------

architecture rtl of fpga64_buslogic_roms is
	component fpga64_colorram is
		port (
			clk: in std_logic;
			cs: in std_logic;
			we: in std_logic;

			addr: in unsigned(9 downto 0);
			di: in unsigned(3 downto 0);
			do: out unsigned(3 downto 0)
		);
	end component;

	signal charData: unsigned(7 downto 0);
	signal basicData: unsigned(7 downto 0);
	signal kernalData: unsigned(7 downto 0);

	signal cs_CharReg : std_logic;
	signal cs_BasicReg : std_logic;
	signal cs_KernalReg : std_logic;
	signal vicCharReg : std_logic;

	signal cs_ramReg : std_logic;
	signal cs_vicReg : std_logic;
	signal cs_sidReg : std_logic;
	signal cs_colorReg : std_logic;
	signal cs_cia1Reg : std_logic;
	signal cs_cia2Reg : std_logic;

	signal currentAddr: unsigned(15 downto 0);
	signal cpuHasBus : std_logic; -- Hacky hack
begin
	charrom: entity work.c64rom_chargen
		port map (
			clk => clk,
			addr => currentAddr(11 downto 0),
			do => charData
		);

	basicrom: entity work.c64rom_basic
		port map (
			clk => clk,
			addr => cpuAddr(12 downto 0),
			do => basicData
		);

	kernelrom: entity work.c64rom_kernal
		port map (
			clk => clk,
			addr => cpuAddr(12 downto 0),
			do => kernalData
		);
	
	--
	-- write pulse runs during subCycle xxx10. 
	generatePulseWe: process(clk, busCycle, cpuWe)
	begin
		if rising_edge(clk) then
			pulseWr <= '0';
-- !!! Need to go into toplevel not buslogic
			if (busCycle = "00101") and (cpuWe = '1') then
				-- Pulse WR halfway CPU access
				pulseWr <= '1';
			end if;
		end if;
	end process;
	
	process(ramData, vicData, sidData, colorData, cia1Data, cia2Data, cs_ramReg, cs_vicReg, cs_sidReg, cs_colorReg, cs_cia1Reg, cs_cia2Reg, lastVicData)
	begin
		-- If no hardware is addressed the bus is floating.
		-- It will contain the last data read by the VIC. (if a C64 is shielded correctly)
		dataToCpu <= lastVicData;
		if cs_CharReg = '1' then	
			dataToCpu <= charData;
		elsif cs_BasicReg = '1' then	
			dataToCpu <= basicData;
		elsif cs_KernalReg = '1' then	
			dataToCpu <= kernalData;	
		elsif cs_ramReg = '1' then
			dataToCpu <= ramData;
		elsif cs_vicReg = '1' then
			dataToCpu <= vicData;
		elsif cs_sidReg = '1' then
			dataToCpu <= sidData;
		elsif cs_colorReg = '1' then
			dataToCpu <= "1111" & colorData;
		elsif cs_cia1Reg = '1' then
			dataToCpu <= cia1Data;
		elsif cs_cia2Reg = '1' then
			dataToCpu <= cia2Data;
		end if;
	end process;

	-- !!! hacky hack
	process(clk)
	begin
		if rising_edge(clk) then
			if ena = '1' then
				cpuHasBus <= cpuGetsBus;
			end if;
		end if;
	end process;

	process(clk)
	begin
		if rising_edge(clk) then
			currentAddr <= (others => '1'); -- Prevent generation of a latch when neither vic or cpu is using the bus.
			systemWe <= '0';
			vicCharReg <= '0';
			cs_charReg <= '0';
			cs_basicReg <= '0';
			cs_kernalReg <= '0';
			cs_ramReg <= '0';
			cs_vicReg <= '0';
			cs_sidReg <= '0';
			cs_colorReg <= '0';
			cs_cia1Reg <= '0';
			cs_cia2Reg <= '0';

			if (cpuHasBus = '1') then
				-- The 6502 CPU has the bus.
				currentAddr <= cpuAddr;
				case cpuAddr(15 downto 12) is
				when X"E" | X"F" =>
					if (cpuWe = '0') and (bankSwitch(1) = '1') then
						-- Read kernal
						cs_kernalReg <= '1';
					else
						-- 64Kbyte RAM layout
						cs_ramReg <= '1';
					end if;
				when X"D" =>
					if (bankSwitch(1) = '0') and (bankSwitch(0) = '0') then
						-- 64Kbyte RAM layout
						cs_ramReg <= '1';
					elsif bankSwitch(2) = '1' then
						case cpuAddr(11 downto 8) is
							when X"0" | X"1" | X"2" | X"3" =>
								cs_vicReg <= '1';
							when X"4" | X"5" | X"6" | X"7" =>
								cs_sidReg <= '1';
							when X"8" | X"9" | X"A" | X"B" =>
								cs_colorReg <= '1';
							when X"C" =>
								cs_cia1Reg <= '1';
							when X"D" =>
								cs_cia2Reg <= '1';
							when others =>
								null;
						end case;						
					else
						-- I/O space turned off. Read from charrom or write to RAM.
						if cpuWe = '0' then
							cs_charReg <= '1';
						else
							cs_ramReg <= '1';
						end if;
					end if;
				when X"A" | X"B" =>
					if (cpuWe = '0') and (bankSwitch(1) = '1') and (bankSwitch(0) = '1') then
						cs_basicReg <= '1';
					else
						cs_ramReg <= '1';
					end if;
				when others =>
					cs_ramReg <= '1';
				end case;

				systemWe <= cpuWe;
			else
				-- The VIC-II has the bus.
				currentAddr <= vicAddr;
				if vicAddr(14 downto 12)="001" then
					vicCharReg <= '1';
				else
					cs_ramReg <= '1';
				end if;
			end if;
		end if;
	end process;
	
	cs_ram <= cs_ramReg;
	cs_vic <= cs_vicReg;
	cs_sid <= cs_sidReg;
	cs_color <= cs_colorReg;
	cs_cia1 <= cs_cia1Reg;
	cs_cia2 <= cs_cia2Reg;

	process(ramData, charData, vicCharReg)
	begin
		if vicCharReg = '1' then
			dataToVic <= charData;
		else
			dataToVic <= ramData;
		end if;
	end process;

	systemAddr <= currentAddr;
end architecture;

⌨️ 快捷键说明

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