Files
SharpMZ_MiSTer/rtl/mz80b/sysctrl.vhd
birdybro b32c9615e4 Restructure folders
Proposal to restructure all the files and folders to keep things organized and similar to other cores.
2022-06-24 14:04:27 -06:00

196 lines
8.4 KiB
VHDL

--
-- sysctrl.vhd
--
-- SHARP MZ-80B/2000 series compatible logic, system control module
-- for Altera DE0
--
-- Nibbles Lab. 2014
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity sysctrl is
port(
RST_n : in std_logic; -- Reset
CLK : in std_logic; -- System Clock
-- Push Button
BUTTON : in std_logic_vector(2 downto 0); -- Pushbutton[2:0]
-- Switch
SW : in std_logic_vector(9 downto 0); -- Toggle Switch[9:0]
-- PS/2 Keyboard Data
KBEN : in std_logic; -- PS/2 Keyboard Data Valid
KBDT : in std_logic_vector(7 downto 0); -- PS/2 Keyboard Data
-- Interrupt
INTL : out std_logic; -- Interrupt Signal Output
I_CMT : in std_logic; -- from CMT
I_FDD : in std_logic; -- from FD unit
-- Others
URST_n : out std_logic; -- Universal Reset
ARST_n : out std_logic; -- All Reset
ZRST : out std_logic; -- Z80 Reset
CLK50 : in std_logic; -- 50MkHz
SCLK : in std_logic; -- 31.25kHz
ZBREQ : out std_logic; -- Z80 Bus Request
ZBACK : in std_logic; -- Z80 Bus Acknowridge
BST_n : in std_logic; -- BOOT start request from Z80
BOOTM : out std_logic; -- BOOT mode
F_BTN : out std_logic -- Function Button
-- HPS Interface
IOCTL_DOWNLOAD : in std_logic; -- HPS Downloading to FPGA.
IOCTL_INDEX : in std_logic_vector(7 downto 0); -- Menu index used to upload file.
IOCTL_WR : in std_logic; -- HPS Write Enable to FPGA.
IOCTL_RD : in std_logic; -- HPS Read Enable from FPGA.
IOCTL_ADDR : in std_logic_vector(24 downto 0); -- HPS Address in FPGA to write into.
IOCTL_DOUT : in std_logic_vector(15 downto 0) -- HPS Data to be written into FPGA.
IOCTL_DIN : out std_logic_vector(15 downto 0); -- HPS Data to be read into HPS.
IOCTL_INTERRUPT : out std_logic -- HPS Interrupt.
);
end sysctrl;
architecture rtl of sysctrl is
--
-- Reset & Filters
--
signal URSTi : std_logic; -- Universal Reset
signal BUF : std_logic_vector(7 downto 0) := "00000000";
signal CNT5 : std_logic_vector(4 downto 0);
signal SR_BTN : std_logic_vector(7 downto 0);
signal ZR_BTN : std_logic_vector(7 downto 0);
signal F_BTNi : std_logic;
--
-- Interrupt
--
signal IRQ_KB : std_logic;
signal IE_KB : std_logic;
signal IKBBUF : std_logic_vector(2 downto 0);
signal IRQ_FB : std_logic;
signal IE_FB : std_logic;
signal IFBBUF : std_logic_vector(2 downto 0);
signal IRQ_CT : std_logic;
signal IE_CT : std_logic;
signal ICTBUF : std_logic_vector(2 downto 0);
signal IRQ_FD : std_logic;
signal IE_FD : std_logic;
signal IFDBUF : std_logic_vector(2 downto 0);
--
-- Control for Z80
--
signal ZRSTi : std_logic;
signal BOOTMi : std_logic := '1';
begin
--
-- Avalon Bus
--
process( RST_n, CLK ) begin
if RST_n='0' then
IRQ_KB <= '0';
IRQ_FB <= '0';
IRQ_CT <= '0';
IRQ_FD <= '0';
IKBBUF <= (others=>'0');
IFBBUF <= (others=>'0');
ICTBUF <= (others=>'0');
IFDBUF <= (others=>'0');
IE_KB <= '0';
IE_FB <= '0';
IE_CT <= '0';
IE_FD <= '0';
ZBREQ <= '1';
BOOTMi <= '1';
ZRSTi <= '0';
elsif CLK'event and CLK='1' then
-- Edge Sense
IKBBUF<=IKBBUF(1 downto 0)&(KBEN and ((not ZBACK) or BOOTMi));
if IKBBUF(2 downto 1)="01" then
IRQ_KB <= IE_KB;
end if;
IFBBUF <= IFBBUF(1 downto 0)&F_BTNi;
if IFBBUF(2 downto 1)="01" then
IRQ_FB <= IE_FB;
end if;
ICTBUF <= ICTBUF(1 downto 0)&I_CMT;
if ICTBUF(2 downto 1)="01" then
IRQ_CT <= IE_CT;
end if;
IFDBUF <= IFDBUF(1 downto 0)&I_FDD;
if IFDBUF(2 downto 1)="01" then
IRQ_FD <= IE_FD;
end if;
-- Register
if IOCTL_RD='1' and IOCTL_WR='1' then
if IOCTL_ADDR=X"0005" then -- MZ_SYS_IREQ
IRQ_KB <= IRQ_KB and (not IOCTL_DOUT(0)); -- I_KBD 0x01
IRQ_FB <= IRQ_FB and (not IOCTL_DOUT(1)); -- I_FBTN 0x02
IRQ_CT <= IRQ_CT and (not IOCTL_DOUT(2)); -- I_CMT 0x04
IRQ_FD <= IRQ_FD and (not IOCTL_DOUT(3)); -- I_FDD 0x08
end if;
if IOCTL_ADDR=X"0006" then -- MZ_SYS_IENB
IE_KB <= IOCTL_DOUT(0); -- I_KBD 0x01
IE_FB <= IOCTL_DOUT(1); -- I_FBTN 0x02
IE_CT <= IOCTL_DOUT(2); -- I_CMT 0x04
IE_FD <= IOCTL_DOUT(3); -- I_FDD 0x08
end if;
if IOCTL_ADDR=X"0007" then -- MZ_SYS_CTRL (Control for Z80)
ZBREQ <= IOCTL_DOUT(0);
ZRSTi <= IOCTL_DOUT(1);
BOOTMi <= IOCTL_DOUT(2);
end if;
end if;
end if;
end process;
IOCTL_DIN <= "00000"&BUTTON when IOCTL_RD='1' and IOCTL_ADDR=X"0000" else -- MZ_SYS_BUTTON
SW(7 downto 0) when IOCTL_RD='1' and IOCTL_ADDR=X"0002" else -- MZ_SYS_SW70
"000000"&SW(9)&SW(8) when IOCTL_RD='1' and IOCTL_ADDR=X"0003" else -- MZ_SYS_SW98
KBDT when IOCTL_RD='1' and IOCTL_ADDR=X"0004" else -- MZ_SYS_KBDT
"0000"&IRQ_FD&IRQ_CT&IRQ_FB&IRQ_KB when IOCTL_RD='1' and IOCTL_ADDR=X"0005" else -- MZ_SYS_IREQ
"0000"&IE_FD&IE_CT&IE_FB&IE_KB when IOCTL_RD='1' and IOCTL_ADDR=X"0006" else -- MZ_SYS_IENB
"000000"&(not BST_n)&ZBACK when IOCTL_RD='1' and IOCTL_ADDR=X"0007" else -- MZ_SYS_STATUS
"00000000";
INTL <= IRQ_KB or IRQ_FB or IRQ_CT or IRQ_FD;
--
-- Filter and Asynchronous Reset with automatic
--
URST_n <= URSTi;
process( CLK50 ) begin
if( CLK50'event and CLK50='1' ) then
if BUF=X"80" then
URSTi <= '1';
else
BUF <= BUF+'1';
URSTi <= '0';
end if;
end if;
end process;
process( URSTi, SCLK ) begin
if URSTi='0' then
CNT5 <= (others=>'0');
SR_BTN <= (others=>'1');
ZR_BTN <= (others=>'1');
elsif SCLK'event and SCLK='1' then
if CNT5="11111" then
SR_BTN <= SR_BTN(6 downto 0)&(BUTTON(1) or (not BUTTON(0))); -- only BUTTON1
ZR_BTN <= ZR_BTN(6 downto 0)&((not BUTTON(1)) or BUTTON(0)); -- only BUTTON0
CNT5 <= (others=>'0');
else
CNT5<=CNT5+'1';
end if;
end if;
end process;
F_BTNi <= '1' when SR_BTN="00000000" else '0';
F_BTN <= F_BTNi;
ARST_n <= URSTi ;
ZRST <= '0' when (ZR_BTN="00000000" and ZBACK='1') or ZRSTi='0' or URSTi='0' else '1';
BOOTM <= BOOTMi;
end rtl;