mirror of
https://github.com/Gehstock/Mist_FPGA.git
synced 2026-02-02 14:50:52 +00:00
Moon Patrol Cleanup
This commit is contained in:
225
common/IO/A6532.vhd
Normal file
225
common/IO/A6532.vhd
Normal file
@@ -0,0 +1,225 @@
|
||||
-- A6532 RAM-I/O-Timer (RIOT)
|
||||
-- Copyright 2006, 2010 Retromaster
|
||||
--
|
||||
-- This file is part of A2601.
|
||||
--
|
||||
-- A2601 is free software: you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation, either version 3 of the License,
|
||||
-- or any later version.
|
||||
--
|
||||
-- A2601 is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with A2601. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity ramx8 is
|
||||
generic(addr_width : integer := 7);
|
||||
port(clk: in std_logic;
|
||||
r: in std_logic;
|
||||
d_in: in std_logic_vector(7 downto 0);
|
||||
d_out: out std_logic_vector(7 downto 0);
|
||||
a: in std_logic_vector(addr_width - 1 downto 0));
|
||||
end ramx8;
|
||||
|
||||
architecture arch of ramx8 is
|
||||
type ram_type is array (0 to 2**addr_width - 1) of
|
||||
std_logic_vector(7 downto 0);
|
||||
signal ram: ram_type;
|
||||
begin
|
||||
|
||||
process (clk, r, a)
|
||||
begin
|
||||
if (clk'event and clk = '1') then
|
||||
if (r = '1') then
|
||||
d_out <= ram(to_integer(unsigned(a)));
|
||||
else
|
||||
ram(to_integer(unsigned(a))) <= d_in;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end arch;
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_arith.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
entity A6532 is
|
||||
port(clk: in std_logic;
|
||||
ph2_en: in std_logic;
|
||||
r: in std_logic;
|
||||
rs: in std_logic;
|
||||
cs: in std_logic;
|
||||
irq: out std_logic;
|
||||
d: inout std_logic_vector(7 downto 0) := "ZZZZZZZZ";
|
||||
pa: inout std_logic_vector(7 downto 0);
|
||||
pb: inout std_logic_vector(7 downto 0);
|
||||
pa7: in std_logic;
|
||||
a: in std_logic_vector(6 downto 0));
|
||||
end A6532;
|
||||
|
||||
architecture arch of A6532 is
|
||||
|
||||
signal pa_reg: std_logic_vector(7 downto 0) := "00000000";
|
||||
signal pb_reg: std_logic_vector(7 downto 0) := "00000000";
|
||||
signal pa_ddr: std_logic_vector(7 downto 0) := "00000000";
|
||||
signal pb_ddr: std_logic_vector(7 downto 0) := "00000000";
|
||||
signal pa_in: std_logic_vector(7 downto 0);
|
||||
signal pb_in: std_logic_vector(7 downto 0);
|
||||
|
||||
signal timer: std_logic_vector(7 downto 0) := "00000000";
|
||||
signal timer_write: std_logic;
|
||||
signal timer_read: std_logic;
|
||||
signal timer_intr: std_logic := '0';
|
||||
signal timer_intvl: std_logic_vector(1 downto 0) := "11";
|
||||
signal timer_dvdr: std_logic_vector(10 downto 0) := "00000000001";
|
||||
signal timer_inc: std_logic;
|
||||
signal timer_irq_en: std_logic := '0';
|
||||
|
||||
signal edge_pol: std_logic := '0';
|
||||
signal edge_irq_en: std_logic := '0';
|
||||
signal edge_intr_lo: std_logic := '0';
|
||||
signal edge_intr_hi: std_logic := '0';
|
||||
signal edge_intr: std_logic;
|
||||
|
||||
signal intr_read: std_logic;
|
||||
|
||||
signal ram_d_out: std_logic_vector(7 downto 0);
|
||||
signal ram_r: std_logic;
|
||||
|
||||
begin
|
||||
|
||||
io: for i in 0 to 7 generate
|
||||
-- TEMPORARY FIX
|
||||
pa(i) <= pa_reg(i) when pa_ddr(i) = '1' else 'Z';
|
||||
pb(i) <= pb_reg(i) when pb_ddr(i) = '1' else 'Z';
|
||||
--pa(i) <= 'Z';
|
||||
--pb(i) <= 'Z';
|
||||
pa_in(i) <= pa(i);
|
||||
pb_in(i) <= pb(i) when pb_ddr(i) = '0' else pb_reg(i);
|
||||
end generate;
|
||||
|
||||
ram: work.ramx8 port map(clk, ram_r, d, ram_d_out, a);
|
||||
|
||||
ram_r <= (not rs and r) or rs or not cs;
|
||||
|
||||
timer_write <= (not r) and rs and a(2) and a(4) and cs;
|
||||
timer_read <= r and rs and a(2) and (not a(0)) and cs;
|
||||
intr_read <= r and rs and a(0) and a(2) and cs;
|
||||
|
||||
irq <= not ((timer_intr and timer_irq_en) or (edge_intr and edge_irq_en));
|
||||
edge_intr <= edge_intr_lo when edge_pol = '0' else edge_intr_hi;
|
||||
|
||||
process(clk, ph2_en, cs, r, rs, a, ram_d_out, pa_in, pa_ddr, pb_in, pb_ddr, timer, timer_intr, edge_intr)
|
||||
begin
|
||||
if r = '1' then
|
||||
if (cs = '0') then
|
||||
d <= "ZZZZZZZZ";
|
||||
elsif rs = '0' then
|
||||
d <= ram_d_out;
|
||||
elsif a(2) = '0' then
|
||||
case a(1 downto 0) is
|
||||
when "00" =>
|
||||
d <= pa_in;
|
||||
when "01" =>
|
||||
d <= pa_ddr;
|
||||
when "10" =>
|
||||
d <= pb_in;
|
||||
when "11" =>
|
||||
d <= pb_ddr;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
elsif a(0) = '0' then
|
||||
d <= timer;
|
||||
elsif a(0) = '1' then
|
||||
d <= timer_intr & edge_intr & "000000";
|
||||
else
|
||||
d <= "--------";
|
||||
end if;
|
||||
else
|
||||
d <= "ZZZZZZZZ";
|
||||
if (clk'event and clk = '1' and cs = '1' and ph2_en = '1') then
|
||||
if (rs = '1') then
|
||||
if a(2) = '0' then
|
||||
case a(1 downto 0) is
|
||||
when "00" =>
|
||||
--pa_reg <= d;
|
||||
when "01" =>
|
||||
pa_ddr <= d;
|
||||
when "10" =>
|
||||
pb_reg <= d;
|
||||
when "11" =>
|
||||
pb_ddr <= d;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
elsif a(4) = '0' then
|
||||
edge_pol <= a(0);
|
||||
edge_irq_en <= a(1);
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process(pa7, intr_read)
|
||||
begin
|
||||
if (intr_read = '1') then
|
||||
edge_intr_lo <= '0';
|
||||
elsif (pa7'event and pa7 = '1') then
|
||||
edge_intr_lo <= '1';
|
||||
end if;
|
||||
|
||||
if (intr_read = '1') then
|
||||
edge_intr_hi <= '0';
|
||||
elsif (pa7'event and pa7 = '0') then
|
||||
edge_intr_hi <= '1';
|
||||
end if;
|
||||
end process;
|
||||
|
||||
with timer_intvl select timer_inc <=
|
||||
timer_dvdr(0) when "00",
|
||||
timer_dvdr(3) when "01",
|
||||
timer_dvdr(6) when "10",
|
||||
timer_dvdr(10) when "11",
|
||||
'-' when others;
|
||||
|
||||
process(clk, ph2_en)
|
||||
begin
|
||||
if (clk'event and clk = '1' and ph2_en = '1') then
|
||||
if (timer_inc = '1') then
|
||||
timer_dvdr <= "00000000001";
|
||||
else
|
||||
timer_dvdr <= timer_dvdr + 1;
|
||||
end if;
|
||||
|
||||
if (timer_write = '1') then
|
||||
timer <= d - 1;
|
||||
timer_intvl <= a(1 downto 0);
|
||||
timer_irq_en <= a(3);
|
||||
timer_dvdr <= "00000000001";
|
||||
elsif (timer_intr = '0') then
|
||||
timer <= timer - timer_inc;
|
||||
elsif (not (timer = X"00")) then
|
||||
timer <= timer - 1;
|
||||
end if;
|
||||
|
||||
if (timer = X"00" and timer_inc = '1' and timer_intr = '0' and timer_write = '0') then
|
||||
timer_intr <= '1';
|
||||
elsif (timer_read = '1' or timer_write = '1') then
|
||||
timer_intr <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end arch;
|
||||
Reference in New Issue
Block a user