mirror of
https://github.com/MiSTer-devel/BBCMicro_MiSTer.git
synced 2026-04-19 03:04:13 +00:00
192 lines
5.9 KiB
VHDL
192 lines
5.9 KiB
VHDL
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
use ieee.std_logic_unsigned.all;
|
|
use ieee.numeric_std.all;
|
|
|
|
use work.tube_comp_pack.all;
|
|
|
|
entity CoPro6502 is
|
|
port (
|
|
|
|
-- Host
|
|
h_clk : in std_logic;
|
|
h_cs_b : in std_logic;
|
|
h_rdnw : in std_logic;
|
|
h_addr : in std_logic_vector(2 downto 0);
|
|
h_data_in : in std_logic_vector(7 downto 0);
|
|
h_data_out : out std_logic_vector(7 downto 0);
|
|
h_rst_b : in std_logic;
|
|
h_irq_b : out std_logic;
|
|
|
|
-- Parasite Clock (32 MHz)
|
|
clk_cpu : in std_logic;
|
|
cpu_clken : in std_logic;
|
|
|
|
-- External RAM
|
|
ram_addr : out std_logic_vector(15 downto 0);
|
|
ram_data_in : out std_logic_vector(7 downto 0);
|
|
ram_data_out : in std_logic_vector(7 downto 0);
|
|
ram_wr : out std_logic;
|
|
|
|
-- Test signals for debugging
|
|
test : out std_logic_vector(7 downto 0)
|
|
);
|
|
end;
|
|
|
|
architecture BEHAVIORAL of CoPro6502 is
|
|
|
|
-------------------------------------------------
|
|
-- clock and reset signals
|
|
-------------------------------------------------
|
|
|
|
signal bootmode : std_logic;
|
|
signal RSTn : std_logic;
|
|
signal RSTn_sync : std_logic;
|
|
signal reset_counter : std_logic_vector (8 downto 0);
|
|
|
|
-------------------------------------------------
|
|
-- parasite signals
|
|
-------------------------------------------------
|
|
|
|
signal p_cs_b : std_logic;
|
|
signal p_data_out : std_logic_vector (7 downto 0);
|
|
|
|
-------------------------------------------------
|
|
-- ram/rom signals
|
|
-------------------------------------------------
|
|
|
|
signal ram_cs_b : std_logic;
|
|
signal rom_cs_b : std_logic;
|
|
signal rom_data_out : std_logic_vector (7 downto 0);
|
|
|
|
-------------------------------------------------
|
|
-- cpu signals
|
|
-------------------------------------------------
|
|
|
|
signal cpu_R_W_n : std_logic;
|
|
signal cpu_addr : std_logic_vector (23 downto 0);
|
|
signal cpu_addr_us: unsigned (23 downto 0);
|
|
signal cpu_din : std_logic_vector (7 downto 0);
|
|
signal cpu_dout : std_logic_vector (7 downto 0);
|
|
signal cpu_dout_us: unsigned (7 downto 0);
|
|
signal cpu_IRQ_n : std_logic;
|
|
signal cpu_NMI_n : std_logic;
|
|
signal cpu_IRQ_n_sync : std_logic;
|
|
signal cpu_NMI_n_sync : std_logic;
|
|
|
|
begin
|
|
|
|
---------------------------------------------------------------------
|
|
-- instantiated components
|
|
---------------------------------------------------------------------
|
|
|
|
inst_tuberom : entity work.tuberom_65c102 port map (
|
|
CLK => clk_cpu,
|
|
ADDR => cpu_addr(10 downto 0),
|
|
DATA => rom_data_out
|
|
);
|
|
|
|
inst_r65c02: entity work.r65c02 port map(
|
|
reset => RSTn_sync,
|
|
clk => clk_cpu,
|
|
enable => cpu_clken,
|
|
nmi_n => cpu_NMI_n_sync,
|
|
irq_n => cpu_IRQ_n_sync,
|
|
di => unsigned(cpu_din),
|
|
do => cpu_dout_us,
|
|
addr => cpu_addr_us(15 downto 0),
|
|
nwe => cpu_R_W_n,
|
|
sync => open,
|
|
sync_irq => open
|
|
);
|
|
cpu_dout <= std_logic_vector(cpu_dout_us);
|
|
cpu_addr <= std_logic_vector(cpu_addr_us);
|
|
|
|
inst_tube: tube port map (
|
|
h_addr => h_addr,
|
|
h_cs_b => h_cs_b,
|
|
h_data_in => h_data_in,
|
|
h_data_out => h_data_out,
|
|
h_phi2 => not h_clk,
|
|
h_rdnw => h_rdnw,
|
|
h_rst_b => h_rst_b,
|
|
h_irq_b => h_irq_b,
|
|
p_addr => cpu_addr(2 downto 0),
|
|
p_cs_b => not((not p_cs_b) and cpu_clken),
|
|
p_data_in => cpu_dout,
|
|
p_data_out => p_data_out,
|
|
p_rdnw => cpu_R_W_n,
|
|
p_phi2 => clk_cpu,
|
|
p_rst_b => RSTn,
|
|
p_nmi_b => cpu_NMI_n,
|
|
p_irq_b => cpu_IRQ_n
|
|
);
|
|
|
|
|
|
p_cs_b <= '0' when cpu_addr(15 downto 3) = "1111111011111" else '1';
|
|
|
|
rom_cs_b <= '0' when cpu_addr(15 downto 11) = "11111" and cpu_R_W_n = '1' and bootmode = '1' else '1';
|
|
|
|
ram_cs_b <= '0' when p_cs_b = '1' and rom_cs_b = '1' else '1';
|
|
|
|
ram_wr <= (not ram_cs_b) and (not cpu_R_W_n);
|
|
|
|
ram_data_in <= cpu_dout;
|
|
|
|
ram_addr <= cpu_addr(15 downto 0);
|
|
|
|
cpu_din <=
|
|
p_data_out when p_cs_b = '0' else
|
|
rom_data_out when rom_cs_b = '0' else
|
|
ram_data_out when ram_cs_b = '0' else
|
|
x"f1";
|
|
|
|
--------------------------------------------------------
|
|
-- boot mode generator
|
|
--------------------------------------------------------
|
|
boot_gen : process(clk_cpu, RSTn_sync)
|
|
begin
|
|
if RSTn_sync = '0' then
|
|
bootmode <= '1';
|
|
elsif rising_edge(clk_cpu) then
|
|
if p_cs_b = '0' then
|
|
bootmode <= '0';
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
--------------------------------------------------------
|
|
-- power up reset
|
|
--------------------------------------------------------
|
|
reset_gen : process(clk_cpu)
|
|
begin
|
|
if rising_edge(clk_cpu) then
|
|
if (reset_counter(8) = '0') then
|
|
reset_counter <= reset_counter + 1;
|
|
end if;
|
|
RSTn_sync <= RSTn AND reset_counter(8);
|
|
end if;
|
|
end process;
|
|
|
|
--------------------------------------------------------
|
|
-- interrupt synchronization
|
|
--------------------------------------------------------
|
|
sync_gen : process(clk_cpu, RSTn_sync)
|
|
begin
|
|
if RSTn_sync = '0' then
|
|
cpu_NMI_n_sync <= '1';
|
|
cpu_IRQ_n_sync <= '1';
|
|
elsif rising_edge(clk_cpu) then
|
|
if (cpu_clken = '1') then
|
|
cpu_NMI_n_sync <= cpu_NMI_n;
|
|
cpu_IRQ_n_sync <= cpu_IRQ_n;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
test <= RSTn & RSTn_sync & h_rst_b & cpu_NMI_n_sync & cpu_IRQ_n_sync & bootmode & "00";
|
|
|
|
end BEHAVIORAL;
|
|
|
|
|