1635 lines
97 KiB
VHDL
1635 lines
97 KiB
VHDL
---------------------------------------------------------------------------------------------------------
|
|
--
|
|
-- Name: sharpmz.vhd
|
|
-- Created: June 2018
|
|
-- Author(s): Philip Smart
|
|
-- Description: Sharp MZ series compatible logic.
|
|
--
|
|
-- This module is the main (top level) container for the Emulation.
|
|
--
|
|
-- The design tries to work from top-down, where components which are common
|
|
-- to the Business and Personal MZ series are at the top (ie. main memory,
|
|
-- ROM, CPU), drilling down two trees, MZ-80B (Business), MZ-80C (Personal)
|
|
-- to the machine specific modules and components. Some components are common
|
|
-- by their nature (ie. 8255 PIO) but these are instantiated within the lower
|
|
-- tree branch as their design use is less generic.
|
|
--
|
|
-- The tree is as follows;-
|
|
--
|
|
-- (emu) sharpmz.vhd (mz80c) -> mz80c.vhd
|
|
-- |
|
|
-- |
|
|
-- | -> cmt.vhd (common)
|
|
-- | -> keymatrix.vhd (common)
|
|
-- | -> pll.v (common)
|
|
-- | -> clkgen.vhd (common)
|
|
-- | -> T80 (common)
|
|
-- | -> i8255 (common)
|
|
-- sys_top.sv (emu) -> (emu) sharpmz.vhd (hps_io) -> hps_io.sv
|
|
-- | -> i8253 (common)
|
|
-- | -> dpram.vhd (common)
|
|
-- | -> dprom.vhd (common)
|
|
-- | -> mctrl.vhd (common)
|
|
-- | -> video.vhd (common)
|
|
-- |
|
|
-- |
|
|
-- (emu) sharpmz.vhd (mz80b) -> mz80b.vhd
|
|
--
|
|
-- The idea of the design is to keep the emulation as independent of the HPS
|
|
-- as possible (so it works standalone), only needing the HPS to set control registers,
|
|
-- load tape ram and overlay the menu system. This in theory should allow easier
|
|
-- porting if someone wants to port this emulator to another platform or even
|
|
-- target an non-HPS Cyclone chip and instantiate another CPU as the menu control.
|
|
--
|
|
-- As the Cyclone V SE on the Terasic DE10 has 5.5Mbits of memory, nearly all the RAM used
|
|
-- by the emulation is on the FPGA. The Floppy Disk Controller may use HPS memory (or the
|
|
-- external SDRAM) depending on wether I decide to cache entire Floppy Disks as per the CMT
|
|
-- unit.
|
|
--
|
|
-- Credits: Credit to Nibbles Lab. 2012-2016, as I was originally going to port his mz80c_de0 emulator
|
|
-- based on a Terasic DE0 board. He used external memory and an instantiated NIOSII CPU
|
|
-- to provide a menu/control system. Some snippets of his code, such as the keyboard matrix
|
|
-- have been re-used in this emulation.
|
|
-- Copyright: (c) 2018 Philip Smart <philip.smart@net2net.org>
|
|
--
|
|
-- History: June 2018 - Initial creation.
|
|
--
|
|
---------------------------------------------------------------------------------------------------------
|
|
-- This source file 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
|
|
-- (at your option) any later version.
|
|
--
|
|
-- This source file 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 this program. If not, see <http:--www.gnu.org-licenses->.
|
|
---------------------------------------------------------------------------------------------------------
|
|
|
|
library ieee;
|
|
library pkgs;
|
|
use ieee.std_logic_1164.all;
|
|
use ieee.std_logic_unsigned.all;
|
|
use pkgs.config_pkg.all;
|
|
use pkgs.clkgen_pkg.all;
|
|
use pkgs.mctrl_pkg.all;
|
|
|
|
entity sharpmz is
|
|
port(
|
|
-------------------- Clock Input ----------------------------
|
|
CLKMASTER : in std_logic; -- Master Clock(50MHz)
|
|
CLKSYS : out std_logic; -- System clock.
|
|
CLKVID : out std_logic; -- Pixel base clock of video.
|
|
-------------------- Reset ----------------------------
|
|
COLD_RESET : in std_logic;
|
|
WARM_RESET : in std_logic;
|
|
-------------------- main_leds ----------------------------
|
|
MAIN_LEDS : out std_logic_vector(7 downto 0); -- main_leds Green[7:0]
|
|
-------------------- PS2 ----------------------------
|
|
PS2_KEY : in std_logic_vector(10 downto 0); -- PS2 Key data.
|
|
-------------------- VGA ----------------------------
|
|
VGA_HB_O : out std_logic; -- VGA Horizontal Blank
|
|
VGA_VB_O : out std_logic; -- VGA Vertical Blank
|
|
VGA_HS_O : out std_logic; -- VGA H_SYNC
|
|
VGA_VS_O : out std_logic; -- VGA V_SYNC
|
|
VGA_R_O : out std_logic_vector(7 downto 0); -- VGA Red[3:0], [7:4] = 0
|
|
VGA_G_O : out std_logic_vector(7 downto 0); -- VGA Green[3:0]
|
|
VGA_B_O : out std_logic_vector(7 downto 0); -- VGA Blue[3:0]
|
|
-------------------- AUDIO ------------------------------
|
|
AUDIO_L_O : out std_logic;
|
|
AUDIO_R_O : out std_logic;
|
|
-------------------- HPS Interface ------------------------------
|
|
IOCTL_DOWNLOAD : in std_logic; -- Downloading to FPGA.
|
|
IOCTL_UPLOAD : in std_logic; -- Uploading from FPGA.
|
|
IOCTL_CLK : in std_logic; -- I/O Clock.
|
|
IOCTL_WR : in std_logic; -- Write Enable to FPGA.
|
|
IOCTL_RD : in std_logic; -- Read Enable from FPGA.
|
|
IOCTL_ADDR : in std_logic_vector(24 downto 0); -- Address in FPGA to write into.
|
|
IOCTL_DOUT : in std_logic_vector(31 downto 0); -- Data to be written into FPGA.
|
|
IOCTL_DIN : out std_logic_vector(31 downto 0) -- Data to be read into HPS.
|
|
);
|
|
end sharpmz;
|
|
|
|
architecture rtl of sharpmz is
|
|
|
|
-- Parent signals brought out onto wires.
|
|
--
|
|
signal MZ_PS2_KEY : std_logic_vector(10 downto 0);
|
|
--
|
|
-- Keyboard
|
|
--
|
|
signal MZ_KEYB_SCAN : std_logic_vector(3 downto 0);
|
|
signal MZ_KEYB_DATA : std_logic_vector(7 downto 0);
|
|
signal MZ_KEYB_STALL : std_logic;
|
|
signal MZ_KEYB_BREAKDETECT : std_logic;
|
|
--
|
|
-- Master Control signals and configuration.
|
|
--
|
|
signal MZ_SYSTEM_RESET : std_logic;
|
|
signal MZ_MEMWR : std_logic;
|
|
--
|
|
-- Signal BUS's
|
|
--
|
|
signal CLKBUS : std_logic_vector(CLKBUS_WIDTH);
|
|
signal CONFIG : std_logic_vector(CONFIG_WIDTH);
|
|
signal DEBUG : std_logic_vector(DEBUG_WIDTH);
|
|
signal MZ_CMT_BUS_OUT : std_logic_vector(CMT_BUS_OUT_WIDTH);
|
|
--
|
|
-- HPS Control.
|
|
--
|
|
signal MZ_IOCTL_DOWNLOAD : std_logic;
|
|
signal MZ_IOCTL_UPLOAD : std_logic;
|
|
signal MZ_IOCTL_CLK : std_logic;
|
|
signal MZ_IOCTL_WR : std_logic;
|
|
signal MZ_IOCTL_RD : std_logic;
|
|
signal MZ_IOCTL_ADDR : std_logic_vector(24 downto 0);
|
|
signal MZ_IOCTL_DOUT : std_logic_vector(31 downto 0);
|
|
signal MZ_IOCTL_DIN_SYSROM : std_logic_vector(7 downto 0);
|
|
signal MZ_IOCTL_DIN_SYSRAM : std_logic_vector(7 downto 0);
|
|
signal MZ_IOCTL_DIN_VIDEO : std_logic_vector(31 downto 0);
|
|
signal MZ_IOCTL_DIN_MZ80C : std_logic_vector(31 downto 0);
|
|
signal MZ_IOCTL_DIN_MZ80B : std_logic_vector(31 downto 0);
|
|
signal MZ_IOCTL_DIN_MCTRL : std_logic_vector(31 downto 0);
|
|
signal MZ_IOCTL_DIN_CMT : std_logic_vector(31 downto 0);
|
|
signal MZ_IOCTL_DIN_KEY : std_logic_vector(31 downto 0);
|
|
signal MZ_IOCTL_WENROM : std_logic;
|
|
signal MZ_IOCTL_WENRAM : std_logic;
|
|
signal MZ_IOCTL_RENROM : std_logic;
|
|
signal MZ_IOCTL_RENRAM : std_logic;
|
|
--
|
|
-- T80 for MZ80C
|
|
--
|
|
signal MZ80C_BUSRQ_n : std_logic;
|
|
signal MZ80C_MWR_n : std_logic;
|
|
signal MZ80C_MRD_n : std_logic;
|
|
signal MZ80C_IWR_n : std_logic;
|
|
signal MZ80C_WAIT_n : std_logic;
|
|
signal MZ80C_INT_n : std_logic;
|
|
signal MZ80C_DI : std_logic_vector(7 downto 0);
|
|
signal MZ80C_NMI_n : std_logic;
|
|
--
|
|
-- Tape Control
|
|
--
|
|
signal MZ80C_CMT_BUS_IN : std_logic_vector(CMT_BUS_IN_WIDTH);
|
|
--
|
|
-- Keyboard
|
|
--
|
|
signal MZ80C_KEYB_SCAN : std_logic_vector(3 downto 0);
|
|
signal MZ80C_KEYB_STALL : std_logic;
|
|
--
|
|
-- Video
|
|
--
|
|
signal MZ_R : std_logic_vector(7 downto 0);
|
|
signal MZ_B : std_logic_vector(7 downto 0);
|
|
signal MZ_G : std_logic_vector(7 downto 0);
|
|
signal MZ_VGATE_n : std_logic;
|
|
signal MZ_DISPLAY_INVERT_n : std_logic;
|
|
signal MZ_DISPLAY_CHAR80 : std_logic;
|
|
signal MZ_HSYNC_n : std_logic;
|
|
signal MZ_VSYNC_n : std_logic;
|
|
signal MZ_HBLANK : std_logic;
|
|
signal MZ_VBLANK : std_logic;
|
|
--
|
|
-- Selects for MZ80C.
|
|
--
|
|
signal MZ80C_CS_ROM_n : std_logic;
|
|
signal MZ80C_CS_RAM_n : std_logic;
|
|
signal MZ80C_CS_VRAM_n : std_logic;
|
|
signal MZ80C_CS_MEM_G_n : std_logic;
|
|
signal MZ80C_CS_GRAM_n : std_logic;
|
|
signal MZ80C_CS_GRAM_80B_n : std_logic;
|
|
signal MZ80C_CS_IO_GFB_n : std_logic;
|
|
--
|
|
-- Audio for MZ80C
|
|
--
|
|
signal MZ80C_AUDIO_L : std_logic;
|
|
signal MZ80C_AUDIO_R : std_logic;
|
|
--
|
|
-- Video signals for MZ80C
|
|
--
|
|
signal MZ80C_VGATE_n : std_logic;
|
|
--
|
|
-- Debug for MZ80C
|
|
--
|
|
signal MZ80C_DEBUG_LEDS : std_logic_vector(111 downto 0);
|
|
--
|
|
-- T80 for MZ80B
|
|
--
|
|
signal MZ80B_BUSRQ_n : std_logic;
|
|
signal MZ80B_MWR_n : std_logic;
|
|
signal MZ80B_MRD_n : std_logic;
|
|
signal MZ80B_IWR_n : std_logic;
|
|
signal MZ80B_WAIT_n : std_logic;
|
|
signal MZ80B_INT_n : std_logic;
|
|
signal MZ80B_DI : std_logic_vector(7 downto 0);
|
|
signal MZ80B_NMI_n : std_logic;
|
|
--
|
|
-- Selects for MZ80B.
|
|
--
|
|
signal MZ80B_CS_ROM_n : std_logic;
|
|
signal MZ80B_CS_RAM_n : std_logic;
|
|
signal MZ80B_CS_VRAM_n : std_logic;
|
|
signal MZ80B_CS_GRAM_n : std_logic;
|
|
signal MZ80B_CS_IO_GFB_n : std_logic;
|
|
signal MZ80B_CS_IO_G_n : std_logic;
|
|
--
|
|
-- Audio for MZ80B
|
|
--
|
|
signal MZ80B_AUDIO_L : std_logic;
|
|
signal MZ80B_AUDIO_R : std_logic;
|
|
--
|
|
-- Video signals for MZ80B
|
|
--
|
|
signal MZ80B_VGATE_n : std_logic;
|
|
--
|
|
-- Tape Control
|
|
--
|
|
signal MZ80B_CMT_BUS_IN : std_logic_vector(CMT_BUS_IN_WIDTH);
|
|
--
|
|
-- Keyboard
|
|
--
|
|
signal MZ80B_KEYB_SCAN : std_logic_vector(3 downto 0);
|
|
signal MZ80B_KEYB_STALL : std_logic;
|
|
--
|
|
-- Debug for MZ80B
|
|
--
|
|
signal MZ80B_DEBUG_LEDS : std_logic_vector(111 downto 0);
|
|
--
|
|
-- T80
|
|
--
|
|
signal T80_RST_n : std_logic;
|
|
signal T80_MREQ_n : std_logic;
|
|
signal T80_BUSRQ_n : std_logic;
|
|
signal T80_IORQ_n : std_logic;
|
|
signal T80_WR_n : std_logic;
|
|
signal T80_RD_n : std_logic;
|
|
signal T80_WAIT_n : std_logic;
|
|
signal T80_M1_n : std_logic;
|
|
signal T80_RFSH_n : std_logic;
|
|
signal T80_A16 : std_logic_vector(15 downto 0);
|
|
signal T80_INT_n : std_logic;
|
|
signal T80_DO : std_logic_vector(7 downto 0);
|
|
signal T80_DI : std_logic_vector(7 downto 0);
|
|
signal T80_BUSAK_n : std_logic;
|
|
signal T80_NMI_n : std_logic;
|
|
signal T80_HALT_n : std_logic;
|
|
--
|
|
-- Decodes, control, misc
|
|
--
|
|
signal WENSYSRAM : std_logic;
|
|
--
|
|
-- Monitor ROM
|
|
--
|
|
signal SYSROM_DO : std_logic_vector(7 downto 0);
|
|
signal MZ_CS_ROM_n : std_logic;
|
|
signal MROM_BANK : std_logic_vector(5 downto 0);
|
|
--
|
|
-- Static RAM
|
|
--
|
|
signal SYSRAM_DO : std_logic_vector(7 downto 0);
|
|
signal MZ_CS_RAM_n : std_logic;
|
|
signal MZ_SYSMEM_A16 : std_logic_vector(15 downto 0);
|
|
signal MZ_SWP_MEM_BANK_n : std_logic;
|
|
--
|
|
-- Graphics RAM control signals.
|
|
--
|
|
signal VRAM_DO : std_logic_vector(7 downto 0);
|
|
signal MZ_CS_VRAM_n : std_logic;
|
|
signal MZ_CS_MEM_G_n : std_logic;
|
|
signal MZ_CS_GRAM_n : std_logic;
|
|
signal MZ_CS_GRAM_80B_n : std_logic;
|
|
signal MZ_CS_IO_GFB_n : std_logic;
|
|
signal MZ_CS_IO_G_n : std_logic;
|
|
signal VIDEO_WAIT_n : std_logic;
|
|
--
|
|
-- Tape Control
|
|
--
|
|
signal MZ_CMT_BUS_IN : std_logic_vector(CMT_BUS_IN_WIDTH);
|
|
signal MZ_CMT_DEBUG_LEDS : std_logic_vector(31 downto 0);
|
|
--
|
|
-- Debug and internal process signals.
|
|
--
|
|
signal debug_counter : integer range 0 to 13 := 0;
|
|
signal flip_counter : integer range 0 to 10000000 := 0;
|
|
signal block_flip : integer range 0 to 800000 := 0;
|
|
signal bank_flip : integer range 0 to 10000000 := 0;
|
|
|
|
--
|
|
-- Components
|
|
--
|
|
component clkgen
|
|
Port (
|
|
RST : in std_logic; -- Reset
|
|
|
|
-- Clocks
|
|
CKBASE : in std_logic; -- Base system main clock.
|
|
CLKBUS : out std_logic_vector(CLKBUS_WIDTH); -- Clock signals created by this module.
|
|
|
|
-- Different operations modes.
|
|
CONFIG : in std_logic_vector(CONFIG_WIDTH);
|
|
|
|
-- Debug modes.
|
|
DEBUG : in std_logic_vector(DEBUG_WIDTH)
|
|
);
|
|
end component;
|
|
|
|
component T80se
|
|
generic (
|
|
Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
|
|
T2Write : integer := 1; -- 0 => WR_n active in T3, /=0 => WR_n active in T2
|
|
IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle
|
|
);
|
|
Port (
|
|
RESET_n : in std_logic;
|
|
CLK_n : in std_logic; -- NB. Clock is high active.
|
|
CLKEN : in std_logic;
|
|
WAIT_n : in std_logic;
|
|
INT_n : in std_logic;
|
|
NMI_n : in std_logic;
|
|
BUSRQ_n : in std_logic;
|
|
M1_n : out std_logic;
|
|
MREQ_n : out std_logic;
|
|
IORQ_n : out std_logic;
|
|
RD_n : out std_logic;
|
|
WR_n : out std_logic;
|
|
RFSH_n : out std_logic;
|
|
HALT_n : out std_logic;
|
|
BUSAK_n : out std_logic;
|
|
A : out std_logic_vector(15 downto 0);
|
|
DI : in std_logic_vector(7 downto 0);
|
|
DO : out std_logic_vector(7 downto 0)
|
|
);
|
|
end component;
|
|
|
|
component dpram
|
|
generic (
|
|
init_file : string;
|
|
widthad_a : natural;
|
|
width_a : natural;
|
|
widthad_b : natural;
|
|
width_b : natural;
|
|
outdata_reg_a : string := "UNREGISTERED";
|
|
outdata_reg_b : string := "UNREGISTERED"
|
|
);
|
|
Port (
|
|
clock_a : in std_logic := '1';
|
|
clocken_a : in std_logic := '1';
|
|
address_a : in std_logic_vector (widthad_a-1 downto 0);
|
|
data_a : in std_logic_vector (width_a-1 downto 0);
|
|
wren_a : in std_logic := '0';
|
|
q_a : out std_logic_vector (width_a-1 downto 0);
|
|
|
|
clock_b : in std_logic;
|
|
clocken_b : in std_logic := '1';
|
|
address_b : in std_logic_vector (widthad_b-1 downto 0);
|
|
data_b : in std_logic_vector (width_b-1 downto 0);
|
|
wren_b : in std_logic := '0';
|
|
q_b : out std_logic_vector (width_b-1 downto 0)
|
|
);
|
|
end component;
|
|
|
|
component mctrl
|
|
Port (
|
|
-- Clock signals used by this module.
|
|
CLKBUS : in std_logic_vector(CLKBUS_WIDTH);
|
|
|
|
-- Reset's
|
|
COLD_RESET : in std_logic;
|
|
WARM_RESET : in std_logic;
|
|
SYSTEM_RESET : out std_logic;
|
|
|
|
-- HPS Interface
|
|
IOCTL_CLK : in std_logic; -- HPS I/O Clock
|
|
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(31 downto 0); -- HPS Data to be written into FPGA.
|
|
IOCTL_DIN : out std_logic_vector(31 downto 0); -- HPS Data to be read into HPS.
|
|
|
|
-- Different operations modes.
|
|
CONFIG : out std_logic_vector(CONFIG_WIDTH);
|
|
|
|
-- Cassette magnetic tape signals.
|
|
CMT_BUS_OUT : in std_logic_vector(CMT_BUS_OUT_WIDTH);
|
|
CMT_BUS_IN : in std_logic_vector(CMT_BUS_IN_WIDTH);
|
|
|
|
-- MZ80B series can dynamically change the video frequency to attain 40/80 character display.
|
|
CONFIG_CHAR80 : in std_logic;
|
|
|
|
-- Debug modes.
|
|
DEBUG : out std_logic_vector(DEBUG_WIDTH)
|
|
);
|
|
end component;
|
|
|
|
component video is
|
|
Port (
|
|
RST_n : in std_logic; -- Reset
|
|
|
|
-- Different operations modes.
|
|
CONFIG : in std_logic_vector(CONFIG_WIDTH);
|
|
|
|
-- Clocks
|
|
CLKBUS : in std_logic_vector(CLKBUS_WIDTH); -- Clock signals created by clkgen module.
|
|
|
|
-- CPU Signals
|
|
T80_A : in std_logic_vector(13 downto 0); -- CPU Address Bus
|
|
T80_RD_n : in std_logic; -- CPU Read Signal
|
|
T80_WR_n : in std_logic; -- CPU Write Signal
|
|
T80_MREQ_n : in std_logic; -- CPU Memory Request
|
|
T80_BUSACK_n : in std_logic; -- CPU Bus Acknowledge
|
|
T80_WAIT_n : out std_logic; -- CPU Wait Request
|
|
T80_DI : in std_logic_vector(7 downto 0); -- CPU Data Bus in
|
|
T80_DO : out std_logic_vector(7 downto 0); -- CPU Data Bus out
|
|
|
|
-- Selects.
|
|
CS_VRAM_n : in std_logic; -- VRAM Select
|
|
CS_MEM_G_n : in std_logic; -- Peripherals Select
|
|
CS_GRAM_n : in std_logic; -- Colour GRAM Select
|
|
CS_GRAM_80B_n : in std_logic; -- MZ80B GRAM Select
|
|
CS_IO_GFB_n : in std_logic; -- Graphics FB IO Select range
|
|
CS_IO_G_n : in std_logic; -- Graphics Options IO Select range
|
|
|
|
-- Video Signals
|
|
VGATE_n : in std_logic; -- Video Output Control
|
|
INVERSE_n : in std_logic; -- Invert video display.
|
|
CONFIG_CHAR80 : in std_logic; -- 40 Char = 0, 80 Char = 1 select.
|
|
HBLANK : out std_logic; -- Horizontal Blanking
|
|
VBLANK : out std_logic; -- Vertical Blanking
|
|
HSYNC_n : out std_logic; -- Horizontal Sync
|
|
VSYNC_n : out std_logic; -- Vertical Sync
|
|
ROUT : out std_logic_vector(7 downto 0); -- Red Output
|
|
GOUT : out std_logic_vector(7 downto 0); -- Green Output
|
|
BOUT : out std_logic_vector(7 downto 0); -- Green Output
|
|
|
|
-- HPS Interface
|
|
IOCTL_DOWNLOAD : in std_logic; -- HPS Downloading to FPGA.
|
|
IOCTL_UPLOAD : in std_logic; -- HPS Uploading from FPGA.
|
|
IOCTL_CLK : in std_logic; -- HPS I/O Clock.
|
|
IOCTL_WR : in std_logic; -- HPS Write Enable to FPGA.
|
|
IOCTL_RD : in std_logic; -- HPS Read Enable to FPGA.
|
|
IOCTL_ADDR : in std_logic_vector(24 downto 0); -- HPS Address in FPGA to write into.
|
|
IOCTL_DOUT : in std_logic_vector(31 downto 0); -- HPS Data to be written into FPGA.
|
|
IOCTL_DIN : out std_logic_vector(31 downto 0) -- HPS Data to be read into HPS.
|
|
);
|
|
end component;
|
|
|
|
component keymatrix
|
|
Port (
|
|
RST_n : in std_logic;
|
|
|
|
-- i8255
|
|
PA : in std_logic_vector(3 downto 0);
|
|
PB : out std_logic_vector(7 downto 0);
|
|
STALL : in std_logic;
|
|
BREAKDETECT : out std_logic;
|
|
|
|
-- PS/2 Keyboard Data
|
|
PS2_KEY : in std_logic_vector(10 downto 0); -- PS2 Key data.
|
|
|
|
-- Different operations modes.
|
|
CONFIG : in std_logic_vector(CONFIG_WIDTH);
|
|
|
|
-- Clock signals created by this module.
|
|
CLKBUS : in std_logic_vector(CLKBUS_WIDTH);
|
|
|
|
-- HPS Interface
|
|
IOCTL_DOWNLOAD : in std_logic; -- HPS Downloading to FPGA.
|
|
IOCTL_UPLOAD : in std_logic; -- HPS Uploading from FPGA.
|
|
IOCTL_CLK : in std_logic; -- HPS I/O Clock.
|
|
IOCTL_WR : in std_logic; -- HPS Write Enable to FPGA.
|
|
IOCTL_RD : in std_logic; -- HPS Read Enable to FPGA.
|
|
IOCTL_ADDR : in std_logic_vector(24 downto 0); -- HPS Address in FPGA to write into.
|
|
IOCTL_DOUT : in std_logic_vector(31 downto 0); -- HPS Data to be written into FPGA.
|
|
IOCTL_DIN : out std_logic_vector(31 downto 0) -- HPS Data to be read into HPS.
|
|
);
|
|
end component;
|
|
|
|
component cmt
|
|
Port (
|
|
-- HPS Bus
|
|
RST : in std_logic;
|
|
|
|
-- Clock signals created by this module.
|
|
CLKBUS : in std_logic_vector(CLKBUS_WIDTH);
|
|
|
|
-- Different operations modes.
|
|
CONFIG : in std_logic_vector(CONFIG_WIDTH);
|
|
|
|
-- Cassette magnetic tape signals.
|
|
CMT_BUS_OUT : out std_logic_vector(CMT_BUS_OUT_WIDTH);
|
|
CMT_BUS_IN : in std_logic_vector(CMT_BUS_IN_WIDTH);
|
|
|
|
-- HPS Interface
|
|
IOCTL_DOWNLOAD : in std_logic; -- HPS Downloading to FPGA.
|
|
IOCTL_UPLOAD : in std_logic; -- HPS Uploading from FPGA.
|
|
IOCTL_CLK : in std_logic; -- HPS I/O Clock.
|
|
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(31 downto 0); -- HPS Data to be written into FPGA.
|
|
IOCTL_DIN : out std_logic_vector(31 downto 0); -- HPS Data to be read into HPS.
|
|
|
|
-- Debug Status Leds
|
|
DEBUG_STATUS_LEDS : out std_logic_vector(31 downto 0) -- 24 leds to display cmt internal status.
|
|
);
|
|
end component;
|
|
|
|
component mz80c
|
|
PORT (
|
|
-- Clocks
|
|
CLKBUS : in std_logic_vector(CLKBUS_WIDTH); -- Clock signals created by this module.
|
|
|
|
-- Resets.
|
|
COLD_RESET : in std_logic;
|
|
SYSTEM_RESET : in std_logic;
|
|
|
|
-- Z80 CPU
|
|
T80_RST_n : in std_logic;
|
|
T80_WAIT_n : out std_logic;
|
|
T80_INT_n : out std_logic;
|
|
T80_NMI_n : out std_logic;
|
|
T80_BUSRQ_n : out std_logic;
|
|
T80_M1_n : in std_logic;
|
|
T80_MREQ_n : in std_logic;
|
|
T80_IORQ_n : in std_logic;
|
|
T80_RD_n : in std_logic;
|
|
T80_WR_n : in std_logic;
|
|
T80_RFSH_n : in std_logic;
|
|
T80_HALT_n : in std_logic;
|
|
T80_BUSAK_n : in std_logic;
|
|
T80_A16 : in std_logic_vector(15 downto 0);
|
|
T80_DI : out std_logic_vector(7 downto 0);
|
|
T80_DO : in std_logic_vector(7 downto 0);
|
|
|
|
-- Chip selects to common resources.
|
|
CS_ROM_n : out std_logic;
|
|
CS_RAM_n : out std_logic;
|
|
CS_VRAM_n : out std_logic; -- VRAM Select
|
|
CS_MEM_G_n : out std_logic; -- Memory mapped Peripherals Select
|
|
CS_GRAM_n : out std_logic; -- Colour GRAM Select
|
|
CS_IO_GFB_n : out std_logic; -- Graphics FB IO Select range
|
|
|
|
-- Audio.
|
|
AUDIO_L : out std_logic;
|
|
AUDIO_R : out std_logic;
|
|
|
|
-- Different operations modes.
|
|
CONFIG : in std_logic_vector(CONFIG_WIDTH);
|
|
|
|
-- I/O -- I/O down to the core.
|
|
KEYB_SCAN : out std_logic_vector(3 downto 0); -- Keyboard scan lines out.
|
|
KEYB_DATA : in std_logic_vector(7 downto 0); -- Keyboard scan data in.
|
|
KEYB_STALL : out std_logic; -- Keyboard Stall out.
|
|
|
|
-- Cassette magnetic tape signals.
|
|
CMT_BUS_OUT : in std_logic_vector(CMT_BUS_OUT_WIDTH);
|
|
CMT_BUS_IN : out std_logic_vector(CMT_BUS_IN_WIDTH);
|
|
|
|
-- Video
|
|
VGATE_n : out std_logic;
|
|
HBLANK : in std_logic; -- Horizontal Blanking Signal
|
|
VBLANK : in std_logic; -- Vertical Blanking Signal
|
|
|
|
-- HPS Interface
|
|
IOCTL_DOWNLOAD : in std_logic; -- HPS Downloading to FPGA.
|
|
IOCTL_UPLOAD : in std_logic; -- HPS Uploading from FPGA.
|
|
IOCTL_CLK : in std_logic; -- HPS I/O Clock
|
|
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(31 downto 0); -- HPS Data to be written into FPGA.
|
|
IOCTL_DIN : out std_logic_vector(31 downto 0); -- HPS Data to be read into HPS.
|
|
|
|
-- Debug Status Leds
|
|
DEBUG_STATUS_LEDS : out std_logic_vector(111 downto 0) -- 112 leds to display status.
|
|
);
|
|
end component;
|
|
|
|
component mz80b
|
|
PORT (
|
|
-- Clocks
|
|
CLKBUS : in std_logic_vector(CLKBUS_WIDTH); -- Clock signals created by this module.
|
|
|
|
-- Resets.
|
|
COLD_RESET : in std_logic;
|
|
SYSTEM_RESET : in std_logic;
|
|
|
|
-- Z80 CPU
|
|
T80_RST_n : in std_logic;
|
|
T80_WAIT_n : out std_logic;
|
|
T80_INT_n : out std_logic;
|
|
T80_NMI_n : out std_logic;
|
|
T80_BUSRQ_n : out std_logic;
|
|
T80_M1_n : in std_logic;
|
|
T80_MREQ_n : in std_logic;
|
|
T80_IORQ_n : in std_logic;
|
|
T80_RD_n : in std_logic;
|
|
T80_WR_n : in std_logic;
|
|
T80_RFSH_n : in std_logic;
|
|
T80_HALT_n : in std_logic;
|
|
T80_BUSAK_n : in std_logic;
|
|
T80_A16 : in std_logic_vector(15 downto 0);
|
|
T80_DI : out std_logic_vector(7 downto 0);
|
|
T80_DO : in std_logic_vector(7 downto 0);
|
|
|
|
-- Chip selects to common resources.
|
|
CS_ROM_n : out std_logic;
|
|
CS_RAM_n : out std_logic;
|
|
CS_VRAM_n : out std_logic; -- VRAM Select
|
|
CS_GRAM_n : out std_logic; -- Colour GRAM Select
|
|
CS_GRAM_80B_n : out std_logic; -- MZ80B GRAM Select
|
|
CS_IO_GFB_n : out std_logic; -- Graphics FB IO Select range
|
|
CS_IO_G_n : out std_logic; -- Graphics Options IO Select range
|
|
CS_SWP_MEMBANK_n : out std_logic; -- Move lower 32K into upper block.
|
|
|
|
-- Audio.
|
|
AUDIO_L : out std_logic;
|
|
AUDIO_R : out std_logic;
|
|
|
|
-- Different operations modes.
|
|
CONFIG : in std_logic_vector(CONFIG_WIDTH);
|
|
|
|
-- I/O -- I/O down to the core.
|
|
KEYB_SCAN : out std_logic_vector(3 downto 0); -- Keyboard scan lines out.
|
|
KEYB_DATA : in std_logic_vector(7 downto 0); -- Keyboard scan data in.
|
|
KEYB_STALL : out std_logic; -- Keyboard Stall out.
|
|
KEYB_BREAKDETECT : in std_logic; -- Keyboard break detect.
|
|
|
|
-- Cassette magnetic tape signals.
|
|
CMT_BUS_OUT : in std_logic_vector(CMT_BUS_OUT_WIDTH);
|
|
CMT_BUS_IN : out std_logic_vector(CMT_BUS_IN_WIDTH);
|
|
|
|
-- Video
|
|
VGATE_n : out std_logic;
|
|
INVERSE_n : out std_logic; -- Invert video display.
|
|
CONFIG_CHAR80 : out std_logic; -- 40 Char = 0, 80 Char = 1 select.
|
|
HBLANK : in std_logic; -- Horizontal Blanking Signal
|
|
VBLANK : in std_logic; -- Vertical Blanking Signal
|
|
|
|
-- HPS Interface
|
|
IOCTL_DOWNLOAD : in std_logic; -- HPS Downloading to FPGA.
|
|
IOCTL_UPLOAD : in std_logic; -- HPS Uploading from FPGA.
|
|
IOCTL_CLK : in std_logic; -- HPS I/O Clock
|
|
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(31 downto 0); -- HPS Data to be written into FPGA.
|
|
IOCTL_DIN : out std_logic_vector(31 downto 0); -- HPS Data to be read into HPS.
|
|
|
|
-- Debug Status Leds
|
|
DEBUG_STATUS_LEDS : out std_logic_vector(111 downto 0) -- 112 leds to display status.
|
|
);
|
|
end component;
|
|
|
|
begin
|
|
|
|
--
|
|
-- Instantiation
|
|
--
|
|
CLKGEN0 : clkgen port map (
|
|
RST => cold_reset, -- Reset
|
|
|
|
-- Clocks
|
|
CKBASE => CLKMASTER, -- Input clocks from top level.
|
|
CLKBUS => CLKBUS, -- Clock signals created by this module.
|
|
|
|
-- Different operations modes.
|
|
CONFIG => CONFIG,
|
|
|
|
-- Debug modes.
|
|
DEBUG => DEBUG
|
|
);
|
|
|
|
CPU0 : T80se
|
|
generic map (
|
|
Mode => 0, -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
|
|
T2Write => 1, -- 0 => WR_n active in T3, /=0 => WR_n active in T2
|
|
IOWait => 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle
|
|
)
|
|
port map (
|
|
RESET_n => T80_RST_n, -- Reset signal.
|
|
CLK_n => CLKBUS(CKMASTER), -- T80se uses positive level clock.
|
|
CLKEN => CLKBUS(CKENCPU), -- Pulse the master clock at the required CPU frequency.
|
|
WAIT_n => T80_WAIT_n, -- WAIT_n signal into the CPU to prolong a memory cycle.
|
|
INT_n => T80_INT_n, -- INT_n signal for maskable interrupts.
|
|
NMI_n => T80_NMI_n, -- NMI_n non maskable interrupt input.
|
|
BUSRQ_n => T80_BUSRQ_n, -- BUSRQ_n signal to request CPU go into tristate and relinquish bus.
|
|
M1_n => T80_M1_n, -- M1_n Machine Cycle 1 signal. M1 and MREQ active = opcode fetch, M1 and IORQ active = interrupt, vector can be read from D0-D7.
|
|
MREQ_n => T80_MREQ_n, -- MREQ_n signal indicates that the address bus holds a valid address for reading or writing memory.
|
|
IORQ_n => T80_IORQ_n, -- IORQ_n signal indicates that the address bus (A0-A7) holds a valid address for reading or writing and I/O device.
|
|
RD_n => T80_RD_n, -- RD_n signal indicates that data is ready to be read from a memory or I/O device to the CPU.
|
|
WR_n => T80_WR_n, -- WR_n signal indicates that data is going to be written from the CPU data bus to a memory or I/O device.
|
|
RFSH_n => T80_RFSH_n, -- RFSH_n signal to indicate dynamic memory refresh can take place.
|
|
HALT_n => T80_HALT_n, -- HALT_n signal indicates that the CPU has executed a "HALT" instruction.
|
|
BUSAK_n => T80_BUSAK_n, -- BUSAK_n signal indicates that the CPU address bus, data bus, and control signals have entered their HI-Z states, and that the external circuitry can now control these lines.
|
|
A => T80_A16, -- 16 bit address lines.
|
|
DI => T80_DI, -- 8 bit data input bus.
|
|
DO => T80_DO -- 8 bit data output bus.
|
|
);
|
|
|
|
-- MZ80 System RAM
|
|
--
|
|
SYSRAM : dpram
|
|
generic map (
|
|
init_file => "./software/mif/combined_mainmemory.mif",
|
|
widthad_a => 16,
|
|
width_a => 8,
|
|
widthad_b => 16,
|
|
width_b => 8,
|
|
outdata_reg_a => "UNREGISTERED",
|
|
outdata_reg_b => "UNREGISTERED"
|
|
)
|
|
port map (
|
|
clock_a => CLKBUS(CKMASTER), --CLKBUS(CKMEM),
|
|
clocken_a => CLKBUS(CKENCPU), --'1',
|
|
address_a => MZ_SYSMEM_A16,
|
|
data_a => T80_DO,
|
|
wren_a => WENSYSRAM, -- Pulse width controlled according to Master Clock.
|
|
q_a => SYSRAM_DO,
|
|
|
|
clock_b => MZ_IOCTL_CLK,
|
|
clocken_b => '1',
|
|
address_b => MZ_IOCTL_ADDR(15 downto 0),
|
|
data_b => MZ_IOCTL_DOUT(7 downto 0),
|
|
wren_b => MZ_IOCTL_WENRAM,
|
|
q_b => MZ_IOCTL_DIN_SYSRAM
|
|
);
|
|
|
|
-- MZ Monitor ROM
|
|
-- 0 = 80K MROM 4KBytes -> 0000:0fff 0000 bytes padding
|
|
-- 1 = 80x25 80K MROM 4KBytes -> 1000:1fff 0000 bytes padding
|
|
-- 2 = 80C MROM 4KBytes -> 2000:2fff 0000 bytes padding
|
|
-- 3 = 80x25 80C MROM 4KBytes -> 3000:3fff 0000 bytes padding
|
|
-- 4 = 1200 MROM 4KBytes -> 4000:4fff 0000 bytes padding
|
|
-- 5 = 80x25 1200 MROM 4KBytes -> 5000:5fff 0000 bytes padding
|
|
-- 6 = 80A MROM 4KBytes -> 6000:6fff 0000 bytes padding
|
|
-- 7 = 80x25 80A MROM 4KBytes -> 7000:7fff 0000 bytes padding
|
|
-- 8 = 700 MROM 4KBytes -> 8000:8fff 0000 bytes padding
|
|
-- 9 = 80x25 700 MROM 4KBytes -> 9000:9fff 0000 bytes padding
|
|
-- 10 = 80B MROM 2KBytes -> a000:afff 0800 bytes padding
|
|
-- 11 = 80x25 80B MROM 2KBytes -> b000:bfff 0800 bytes padding
|
|
--
|
|
--SYSROM : dprom
|
|
SYSROM : dpram
|
|
generic map (
|
|
init_file => "./software/mif/combined_mrom.mif",
|
|
widthad_a => 17,
|
|
width_a => 8,
|
|
widthad_b => 17,
|
|
width_b => 8,
|
|
outdata_reg_a => "UNREGISTERED",
|
|
outdata_reg_b => "UNREGISTERED"
|
|
)
|
|
port map (
|
|
clock_a => CLKBUS(CKMASTER), -- CLKBUS(CKMEM),
|
|
clocken_a => CLKBUS(CKENCPU), --'1',
|
|
address_a => MROM_BANK & T80_A16(10 downto 0),
|
|
data_a => T80_DO,
|
|
wren_a => '0', -- Block writes from Z80 to ROM.
|
|
q_a => SYSROM_DO,
|
|
|
|
clock_b => MZ_IOCTL_CLK,
|
|
clocken_b => '1',
|
|
address_b => MZ_IOCTL_ADDR(16 downto 0),
|
|
data_b => MZ_IOCTL_DOUT(7 downto 0),
|
|
wren_b => MZ_IOCTL_WENROM,
|
|
q_b => MZ_IOCTL_DIN_SYSROM
|
|
);
|
|
|
|
CTRL0 : mctrl
|
|
port map (
|
|
-- Clock
|
|
CLKBUS => CLKBUS,
|
|
|
|
-- Reset's
|
|
COLD_RESET => cold_reset,
|
|
WARM_RESET => warm_reset,
|
|
SYSTEM_RESET => MZ_SYSTEM_RESET,
|
|
|
|
-- HPS Interface
|
|
IOCTL_CLK => MZ_IOCTL_CLK, -- HPS I/O Clock
|
|
IOCTL_WR => MZ_IOCTL_WR,
|
|
IOCTL_RD => MZ_IOCTL_RD,
|
|
IOCTL_ADDR => MZ_IOCTL_ADDR,
|
|
IOCTL_DOUT => MZ_IOCTL_DOUT,
|
|
IOCTL_DIN => MZ_IOCTL_DIN_MCTRL,
|
|
|
|
-- Different operations modes.
|
|
CONFIG => CONFIG,
|
|
|
|
-- Cassette magnetic tape signals.
|
|
CMT_BUS_OUT => MZ_CMT_BUS_OUT,
|
|
CMT_BUS_IN => MZ_CMT_BUS_IN,
|
|
|
|
-- MZ80B series can dynamically change the video frequency to attain 40/80 character display.
|
|
CONFIG_CHAR80 => MZ_DISPLAY_CHAR80,
|
|
|
|
-- Debug modes.
|
|
DEBUG => DEBUG
|
|
);
|
|
|
|
VIDEO0 : video
|
|
port map (
|
|
RST_n => T80_RST_n, -- Reset
|
|
|
|
-- Different operations modes.
|
|
CONFIG => CONFIG,
|
|
|
|
-- Clocks
|
|
CLKBUS => CLKBUS, -- Clock signals created by clkgen module.
|
|
|
|
-- CPU Signals
|
|
T80_A => T80_A16(13 downto 0), -- CPU Address Bus
|
|
T80_RD_n => T80_RD_n, -- CPU Read Signal
|
|
T80_WR_n => T80_WR_n, -- CPU Write Signal
|
|
T80_MREQ_n => T80_MREQ_n, -- CPU Memory Request
|
|
T80_BUSACK_n => T80_BUSAK_n, -- CPU Bus Acknowledge
|
|
T80_WAIT_n => VIDEO_WAIT_n, -- Wait Request to CPU from Video circuitry.
|
|
T80_DI => T80_DO, -- CPU Data Bus(in)
|
|
T80_DO => VRAM_DO, -- CPU Data Bus(out)
|
|
|
|
-- Selects.
|
|
CS_VRAM_n => MZ_CS_VRAM_n, -- VRAM Select
|
|
CS_MEM_G_n => MZ_CS_MEM_G_n, -- Peripherals Select
|
|
CS_GRAM_n => MZ_CS_GRAM_n, -- Colour GRAM Select
|
|
CS_GRAM_80B_n => MZ_CS_GRAM_80B_n, -- MZ80B GRAM Select
|
|
CS_IO_GFB_n => MZ_CS_IO_GFB_n, -- Graphics FB IO Select range
|
|
CS_IO_G_n => MZ_CS_IO_G_n, -- Graphics Options IO Select range
|
|
|
|
-- Video Signals
|
|
VGATE_n => MZ_VGATE_n, -- Video Output Control
|
|
INVERSE_n => MZ_DISPLAY_INVERT_n, -- Invert video output.
|
|
CONFIG_CHAR80 => MZ_DISPLAY_CHAR80, -- 40 Char = 0, 80 Char = 1 select.
|
|
HBLANK => MZ_HBLANK, -- Horizontal Blanking
|
|
VBLANK => MZ_VBLANK, -- Vertical Blanking
|
|
HSYNC_n => MZ_HSYNC_n, -- Horizontal Sync
|
|
VSYNC_n => MZ_VSYNC_n, -- Vertical Sync
|
|
ROUT => MZ_R, -- Red Output
|
|
GOUT => MZ_G, -- Green Output
|
|
BOUT => MZ_B, -- Blue Output
|
|
|
|
-- HPS Interface
|
|
IOCTL_DOWNLOAD => MZ_IOCTL_DOWNLOAD,
|
|
IOCTL_UPLOAD => MZ_IOCTL_UPLOAD,
|
|
IOCTL_CLK => MZ_IOCTL_CLK, -- HPS I/O Clock.
|
|
IOCTL_WR => MZ_IOCTL_WR, -- HPS Write Enable to FPGA.
|
|
IOCTL_RD => MZ_IOCTL_RD, -- HPS Read Enable to FPGA.
|
|
IOCTL_ADDR => MZ_IOCTL_ADDR, -- HPS Address in FPGA to write into.
|
|
IOCTL_DOUT => MZ_IOCTL_DOUT, -- HPS Data to be written into FPGA.
|
|
IOCTL_DIN => MZ_IOCTL_DIN_VIDEO -- HPS Data to be sent to HPS.
|
|
);
|
|
|
|
TAPE0 : cmt
|
|
port map (
|
|
RST => MZ_SYSTEM_RESET,
|
|
|
|
-- Clock signals needed by this module.
|
|
CLKBUS => CLKBUS,
|
|
|
|
-- Different operations modes.
|
|
CONFIG => CONFIG,
|
|
|
|
-- Cassette magnetic tape signals.
|
|
CMT_BUS_OUT => MZ_CMT_BUS_OUT, -- Output is fed from CMT into MCTRL and MZ..
|
|
CMT_BUS_IN => MZ_CMT_BUS_IN, -- Input is fed from MCTRL/MZ into CMT.
|
|
|
|
-- HPS Interface
|
|
IOCTL_DOWNLOAD => MZ_IOCTL_DOWNLOAD, -- HPS Downloading to FPGA.
|
|
IOCTL_UPLOAD => MZ_IOCTL_UPLOAD, -- HPS Uploading from FPGA.
|
|
IOCTL_CLK => MZ_IOCTL_CLK, -- HPS I/O Clock.
|
|
IOCTL_WR => MZ_IOCTL_WR, -- HPS Write Enable to FPGA.
|
|
IOCTL_RD => MZ_IOCTL_RD, -- HPS Read Enable from FPGA.
|
|
IOCTL_ADDR => MZ_IOCTL_ADDR, -- HPS Address in FPGA to write into.
|
|
IOCTL_DOUT => MZ_IOCTL_DOUT, -- HPS Data to be written into FPGA.
|
|
IOCTL_DIN => MZ_IOCTL_DIN_CMT, -- HPS Data to be sent to HPS.
|
|
|
|
-- Debug Status Leds
|
|
DEBUG_STATUS_LEDS=> MZ_CMT_DEBUG_LEDS(31 downto 0) -- 24 leds to display cmt internal status.
|
|
);
|
|
|
|
KEYS : keymatrix
|
|
port map (
|
|
RST_n => T80_RST_n,
|
|
|
|
-- i8255
|
|
PA => MZ_KEYB_SCAN,
|
|
PB => MZ_KEYB_DATA,
|
|
STALL => MZ_KEYB_STALL,
|
|
BREAKDETECT => MZ_KEYB_BREAKDETECT,
|
|
|
|
-- PS/2 Keyboard Data
|
|
PS2_KEY => MZ_PS2_KEY, -- PS2 Key data.
|
|
|
|
-- Different operations modes.
|
|
CONFIG => CONFIG,
|
|
|
|
-- Clock signals created by this module.
|
|
CLKBUS => CLKBUS,
|
|
|
|
-- HPS Interface
|
|
IOCTL_DOWNLOAD => MZ_IOCTL_DOWNLOAD, -- HPS Downloading to FPGA.
|
|
IOCTL_UPLOAD => MZ_IOCTL_UPLOAD, -- HPS Uploading from FPGA.
|
|
IOCTL_CLK => MZ_IOCTL_CLK, -- HPS I/O Clock.
|
|
IOCTL_WR => MZ_IOCTL_WR, -- HPS Write Enable to FPGA.
|
|
IOCTL_RD => MZ_IOCTL_RD, -- HPS Read Enable from FPGA.
|
|
IOCTL_ADDR => MZ_IOCTL_ADDR, -- HPS Address in FPGA to write into.
|
|
IOCTL_DOUT => MZ_IOCTL_DOUT, -- HPS Data to be written into FPGA.
|
|
IOCTL_DIN => MZ_IOCTL_DIN_KEY -- HPS Data to be sent to HPS.
|
|
);
|
|
|
|
MZ80HW : mz80c
|
|
port map (
|
|
-- Clocks
|
|
CLKBUS => CLKBUS, -- Clock signals created by this module.
|
|
|
|
-- Resets.
|
|
COLD_RESET => cold_reset, -- Cold reset, one time reset on power up.
|
|
SYSTEM_RESET => MZ_SYSTEM_RESET, -- Reset generated by system based on Cold/Warm or trigger.
|
|
|
|
-- Z80 CPU
|
|
T80_RST_n => T80_RST_n,
|
|
T80_WAIT_n => MZ80C_WAIT_n,
|
|
T80_INT_n => MZ80C_INT_n,
|
|
T80_NMI_n => MZ80C_NMI_n,
|
|
T80_BUSRQ_n => MZ80C_BUSRQ_n,
|
|
T80_M1_n => T80_M1_n,
|
|
T80_MREQ_n => T80_MREQ_n,
|
|
T80_IORQ_n => T80_IORQ_n,
|
|
T80_RD_n => T80_RD_n,
|
|
T80_WR_n => T80_WR_n,
|
|
T80_RFSH_n => T80_RFSH_n, --RFSH_n
|
|
T80_HALT_n => T80_HALT_n,
|
|
T80_BUSAK_n => T80_BUSAK_n,
|
|
T80_A16 => T80_A16,
|
|
T80_DI => MZ80C_DI,
|
|
T80_DO => T80_DO,
|
|
|
|
-- Chip selects to common resources.
|
|
CS_ROM_n => MZ80C_CS_ROM_n,
|
|
CS_RAM_n => MZ80C_CS_RAM_n,
|
|
CS_VRAM_n => MZ80C_CS_VRAM_n, -- VRAM Select
|
|
CS_MEM_G_n => MZ80C_CS_MEM_G_n, -- Memory mapped Peripherals Select
|
|
CS_GRAM_n => MZ80C_CS_GRAM_n, -- Colour GRAM Select
|
|
CS_IO_GFB_n => MZ80C_CS_IO_GFB_n, -- Graphics FB IO Select range
|
|
|
|
-- Audio.
|
|
AUDIO_L => MZ80C_AUDIO_L,
|
|
AUDIO_R => MZ80C_AUDIO_R,
|
|
|
|
-- Different operations modes.
|
|
CONFIG => CONFIG,
|
|
|
|
-- Keyboard.
|
|
KEYB_SCAN => MZ80C_KEYB_SCAN, -- Keyboard scan lines out.
|
|
KEYB_DATA => MZ_KEYB_DATA, -- Keyboard scan data in.
|
|
KEYB_STALL => MZ80C_KEYB_STALL, -- Keyboard Stall out.
|
|
|
|
-- CMT status signals.
|
|
CMT_BUS_OUT => MZ_CMT_BUS_OUT,
|
|
CMT_BUS_IN => MZ80C_CMT_BUS_IN,
|
|
|
|
-- Video signals.
|
|
VGATE_n => MZ80C_VGATE_n,
|
|
HBLANK => MZ_HBLANK,
|
|
VBLANK => MZ_VBLANK,
|
|
|
|
-- HPS Interface
|
|
IOCTL_DOWNLOAD => MZ_IOCTL_DOWNLOAD,
|
|
IOCTL_UPLOAD => MZ_IOCTL_UPLOAD,
|
|
IOCTL_CLK => MZ_IOCTL_CLK, -- HPS I/O Clock
|
|
IOCTL_WR => MZ_IOCTL_WR,
|
|
IOCTL_RD => MZ_IOCTL_RD,
|
|
IOCTL_ADDR => MZ_IOCTL_ADDR,
|
|
IOCTL_DOUT => MZ_IOCTL_DOUT,
|
|
IOCTL_DIN => MZ_IOCTL_DIN_MZ80C,
|
|
|
|
-- Debug Status Leds
|
|
DEBUG_STATUS_LEDS=> MZ80C_DEBUG_LEDS
|
|
);
|
|
|
|
MZ80BHW : mz80b
|
|
port map (
|
|
-- Clocks
|
|
CLKBUS => CLKBUS, -- Clock signals created by this module.
|
|
|
|
-- Resets.
|
|
COLD_RESET => cold_reset, -- Cold reset, one time reset on power up.
|
|
SYSTEM_RESET => MZ_SYSTEM_RESET, -- Reset generated by system based on Cold/Warm or trigger.
|
|
|
|
-- Z80 CPU
|
|
T80_RST_n => T80_RST_n,
|
|
T80_WAIT_n => MZ80B_WAIT_n,
|
|
T80_INT_n => MZ80B_INT_n,
|
|
T80_NMI_n => MZ80B_NMI_n,
|
|
T80_BUSRQ_n => MZ80B_BUSRQ_n,
|
|
T80_M1_n => T80_M1_n,
|
|
T80_MREQ_n => T80_MREQ_n,
|
|
T80_IORQ_n => T80_IORQ_n,
|
|
T80_RD_n => T80_RD_n,
|
|
T80_WR_n => T80_WR_n,
|
|
T80_RFSH_n => T80_RFSH_n, --RFSH_n
|
|
T80_HALT_n => T80_HALT_n,
|
|
T80_BUSAK_n => T80_BUSAK_n,
|
|
T80_A16 => T80_A16,
|
|
T80_DI => MZ80B_DI,
|
|
T80_DO => T80_DO,
|
|
|
|
-- Chip selects to common resources.
|
|
CS_ROM_n => MZ80B_CS_ROM_n,
|
|
CS_RAM_n => MZ80B_CS_RAM_n,
|
|
CS_VRAM_n => MZ80B_CS_VRAM_n, -- VRAM Select
|
|
CS_GRAM_n => MZ80B_CS_GRAM_n, -- Colour GRAM Select
|
|
CS_GRAM_80B_n => MZ_CS_GRAM_80B_n, -- MZ80B GRAM Select
|
|
CS_IO_GFB_n => MZ80B_CS_IO_GFB_n, -- Graphics FB IO Select range
|
|
CS_IO_G_n => MZ80B_CS_IO_G_n, -- Graphics Options IO Select range
|
|
CS_SWP_MEMBANK_n => MZ_SWP_MEM_BANK_n, -- Swap lower 32K memory bank into upper 32k block.
|
|
|
|
-- Audio.
|
|
AUDIO_L => MZ80B_AUDIO_L,
|
|
AUDIO_R => MZ80B_AUDIO_R,
|
|
|
|
-- Different operations modes.
|
|
CONFIG => CONFIG,
|
|
|
|
-- Keyboard.
|
|
KEYB_SCAN => MZ80B_KEYB_SCAN, -- Keyboard scan lines out.
|
|
KEYB_DATA => MZ_KEYB_DATA, -- Keyboard scan data in.
|
|
KEYB_STALL => MZ80B_KEYB_STALL, -- Keyboard Stall out.
|
|
KEYB_BREAKDETECT => MZ_KEYB_BREAKDETECT, -- Keyboard detects a break.
|
|
|
|
-- CMT status signals.
|
|
CMT_BUS_OUT => MZ_CMT_BUS_OUT,
|
|
CMT_BUS_IN => MZ80B_CMT_BUS_IN,
|
|
|
|
-- Video signals.
|
|
VGATE_n => MZ80B_VGATE_n,
|
|
INVERSE_n => MZ_DISPLAY_INVERT_n, -- Invert video output.
|
|
CONFIG_CHAR80 => MZ_DISPLAY_CHAR80, -- 40 Char = 0, 80 Char = 1 select.
|
|
HBLANK => MZ_HBLANK,
|
|
VBLANK => MZ_VBLANK,
|
|
|
|
-- HPS Interface
|
|
IOCTL_DOWNLOAD => MZ_IOCTL_DOWNLOAD,
|
|
IOCTL_UPLOAD => MZ_IOCTL_UPLOAD,
|
|
IOCTL_CLK => MZ_IOCTL_CLK, -- HPS I/O Clock
|
|
IOCTL_WR => MZ_IOCTL_WR,
|
|
IOCTL_RD => MZ_IOCTL_RD,
|
|
IOCTL_ADDR => MZ_IOCTL_ADDR,
|
|
IOCTL_DOUT => MZ_IOCTL_DOUT,
|
|
IOCTL_DIN => MZ_IOCTL_DIN_MZ80B,
|
|
|
|
-- Debug Status Leds
|
|
DEBUG_STATUS_LEDS=> MZ80B_DEBUG_LEDS
|
|
);
|
|
|
|
-- Clocks.
|
|
--
|
|
CLKSYS <= CLKBUS(CKMASTER); -- HPS clock.
|
|
CLKVID <= CLKBUS(CKVIDEO); -- Video pixel clock output.
|
|
|
|
-- Multiplexer -> Signals to enabled hardware.
|
|
--
|
|
T80_WAIT_n <= VIDEO_WAIT_n when VIDEO_WAIT_n = '0' else MZ80C_WAIT_n when CONFIG(MZ_80C) = '1' else MZ80B_WAIT_n;
|
|
T80_INT_n <= MZ80C_INT_n when CONFIG(MZ_80C) = '1' else MZ80B_INT_n;
|
|
T80_NMI_n <= MZ80C_NMI_n when CONFIG(MZ_80C) = '1' else MZ80B_NMI_n;
|
|
T80_BUSRQ_n <= MZ80C_BUSRQ_n when CONFIG(MZ_80C) = '1' else MZ80B_BUSRQ_n;
|
|
T80_DI <= SYSRAM_DO when MZ_CS_RAM_n ='0' and T80_RD_n = '0' -- Read from System RAM
|
|
else
|
|
SYSROM_DO when MZ_CS_ROM_n ='0' and T80_RD_n = '0' -- Read from System ROM
|
|
else
|
|
VRAM_DO when (MZ_CS_VRAM_n ='0' or MZ_CS_GRAM_n = '0' or MZ_CS_GRAM_80B_n = '0') and T80_RD_n = '0' -- Read from Graphics/Video RAM.
|
|
else
|
|
MZ80C_DI when CONFIG(MZ_80C) = '1'
|
|
else
|
|
MZ80B_DI when CONFIG(MZ_80B) = '1'
|
|
else
|
|
(others=>'1'); -- Float the bus as high when not driven.
|
|
MZ_SYSMEM_A16 <= T80_A16 when CONFIG(MZ_80C) = '1' else T80_A16 when CONFIG(MZ_80B) = '1' and MZ_SWP_MEM_BANK_n = '1' else '0' & T80_A16(14 downto 0);
|
|
MZ_CS_ROM_n <= MZ80C_CS_ROM_n when CONFIG(MZ_80C) = '1' else MZ80B_CS_ROM_n;
|
|
MZ_CS_RAM_n <= MZ80C_CS_RAM_n when CONFIG(MZ_80C) = '1' else MZ80B_CS_RAM_n;
|
|
MZ_CS_VRAM_n <= MZ80C_CS_VRAM_n when CONFIG(MZ_80C) = '1' else MZ80B_CS_VRAM_n;
|
|
MZ_CS_MEM_G_n <= MZ80C_CS_MEM_G_n when CONFIG(MZ_80C) = '1' else '1';
|
|
MZ_CS_GRAM_n <= MZ80C_CS_GRAM_n when CONFIG(MZ_80C) = '1' else MZ80B_CS_GRAM_n;
|
|
MZ_CS_IO_GFB_n <= MZ80C_CS_IO_GFB_n when CONFIG(MZ_80C) = '1' else MZ80B_CS_IO_GFB_n;
|
|
MZ_CS_IO_G_n <= '1' when CONFIG(MZ_80C) = '1' else MZ80B_CS_IO_G_n;
|
|
audio_l_o <= MZ80C_AUDIO_L when CONFIG(MZ_80C) = '1' else MZ80B_AUDIO_L;
|
|
audio_r_o <= MZ80C_AUDIO_R when CONFIG(MZ_80C) = '1' else MZ80B_AUDIO_R;
|
|
MZ_VGATE_n <= MZ80C_VGATE_n when CONFIG(MZ_80C) = '1' else MZ80B_VGATE_n;
|
|
MZ_CMT_BUS_IN <= MZ80C_CMT_BUS_IN when CONFIG(MZ_80C) = '1' else MZ80B_CMT_BUS_IN;
|
|
|
|
MZ_KEYB_SCAN <= MZ80C_KEYB_SCAN when CONFIG(MZ_80C) = '1' else MZ80B_KEYB_SCAN;
|
|
MZ_KEYB_STALL <= MZ80C_KEYB_STALL when CONFIG(MZ_80C) = '1' else MZ80B_KEYB_STALL;
|
|
|
|
-- VGA output in original format or upscaled.
|
|
--
|
|
VGA_HS_O <= not MZ_HSYNC_n;
|
|
VGA_VS_O <= not MZ_VSYNC_n;
|
|
VGA_R_O <= MZ_R;
|
|
VGA_G_O <= MZ_G;
|
|
VGA_B_O <= MZ_B;
|
|
VGA_VB_O <= MZ_VBLANK;
|
|
VGA_HB_O <= MZ_HBLANK;
|
|
|
|
-- Parent signals onto local wires.
|
|
--
|
|
MZ_PS2_KEY <= ps2_key;
|
|
MZ_IOCTL_DOWNLOAD <= ioctl_download;
|
|
MZ_IOCTL_UPLOAD <= ioctl_upload;
|
|
MZ_IOCTL_CLK <= ioctl_clk;
|
|
MZ_IOCTL_WR <= ioctl_wr;
|
|
MZ_IOCTL_RD <= ioctl_rd;
|
|
MZ_IOCTL_ADDR <= ioctl_addr;
|
|
MZ_IOCTL_DOUT <= ioctl_dout;
|
|
IOCTL_DIN <= X"000000" & MZ_IOCTL_DIN_SYSROM when MZ_IOCTL_RENROM = '1' -- System ROM
|
|
else
|
|
X"000000" & MZ_IOCTL_DIN_SYSRAM when MZ_IOCTL_RENRAM = '1' -- System RAM
|
|
else
|
|
MZ_IOCTL_DIN_VIDEO when IOCTL_ADDR(24 downto 20) = "00011" -- Video RAM
|
|
else
|
|
MZ_IOCTL_DIN_VIDEO when IOCTL_ADDR(24 downto 20) = "00110" -- PCG
|
|
else
|
|
MZ_IOCTL_DIN_VIDEO when IOCTL_ADDR(24 downto 20) = "00101" -- CGROM
|
|
else
|
|
MZ_IOCTL_DIN_MCTRL when IOCTL_ADDR(24) = '1' -- MCTRL Registers
|
|
else
|
|
MZ_IOCTL_DIN_CMT when IOCTL_ADDR(24 downto 20) = "00100" -- CMT
|
|
else
|
|
MZ_IOCTL_DIN_KEY when IOCTL_ADDR(24 downto 20) = "00010" -- Key Matrix
|
|
else
|
|
MZ_IOCTL_DIN_MZ80C when CONFIG(MZ_80C) = '1' -- MZ80C memory.
|
|
else
|
|
MZ_IOCTL_DIN_MZ80B when CONFIG(MZ_80B) = '1' -- MZ80B memory.
|
|
else
|
|
(others=>'0');
|
|
|
|
--
|
|
-- Control Signals
|
|
--
|
|
T80_RST_n <= not MZ_SYSTEM_RESET;
|
|
--
|
|
MZ_MEMWR <= not T80_WR_n;
|
|
WENSYSRAM <= MZ_MEMWR when MZ_CS_RAM_n = '0' -- Write enable to System RAM
|
|
else '0';
|
|
MZ_IOCTL_WENROM <= '1' when MZ_IOCTL_ADDR(24 downto 20) = "00000" and MZ_IOCTL_WR = '1' -- Write enable from HPS to ROM.
|
|
else '0';
|
|
MZ_IOCTL_WENRAM <= '1' when MZ_IOCTL_ADDR(24 downto 20) = "00001" and MZ_IOCTL_WR = '1' -- Write enable from HPS to RAM.
|
|
else '0';
|
|
MZ_IOCTL_RENROM <= '1' when MZ_IOCTL_ADDR(24 downto 20) = "00000" and MZ_IOCTL_RD = '1' -- Read enable from ROM to HPS.
|
|
else '0';
|
|
MZ_IOCTL_RENRAM <= '1' when MZ_IOCTL_ADDR(24 downto 20) = "00001" and MZ_IOCTL_RD = '1' -- Read enable from RAM to HPS.
|
|
else '0';
|
|
|
|
-- System ROM. 128K split up into chunks which are enabled according to the running machine. The ROM can be accessed by the
|
|
-- HPS via the IOCTL bus and updated as necessary.
|
|
--
|
|
-- 16 15 14 13 12 11 16 15 14 13 12 11
|
|
-- K 4096 0 4095 0000000 0 0 0 0 0 0 0000FFF 0 0 0 0 0 1
|
|
-- 4096 4096 8191 0001000 0 0 0 0 1 0 0001FFF 0 0 0 0 1 1
|
|
-- 2048 8192 10239 0002000 0 0 0 1 0 0 00027FF 0 0 0 1 0 0
|
|
-- 2048 10240 12287 0002800 0 0 0 1 0 1 0002FFF 0 0 0 1 0 1
|
|
-- 2048 12288 14335 0003000 0 0 0 1 1 0 00037FF 0 0 0 1 1 0
|
|
-- C 4096 14336 18431 0003800 0 0 0 1 1 1 00047FF 0 0 1 0 0 0
|
|
-- 4096 18432 22527 0004800 0 0 1 0 0 1 00057FF 0 0 1 0 1 0
|
|
-- 2048 22528 22527 0005800 0 0 1 0 1 1 0005FFF 0 0 1 0 1 1
|
|
-- 2048 22528 24575 0006000 0 0 1 1 0 0 00067FF 0 0 1 1 0 0
|
|
-- 2048 24576 26623 0006800 0 0 1 1 0 1 0006FFF 0 0 1 1 0 1
|
|
-- 12 4096 18432 22527 0007000 0 0 1 1 1 0 0007FFF 0 0 1 1 1 1
|
|
-- 4096 22528 26623 0008000 0 1 0 0 0 0 0008FFF 0 1 0 0 0 1
|
|
-- 2048 26624 28671 0009000 0 1 0 0 1 0 00097FF 0 1 0 0 1 0
|
|
-- 2048 28672 30719 0009800 0 1 0 0 1 1 0009FFF 0 1 0 0 1 1
|
|
-- 2048 30720 32767 000A000 0 1 0 1 0 0 000A7FF 0 1 0 1 0 0
|
|
-- A 4096 22528 26623 000A800 0 1 0 1 0 1 000B7FF 0 1 0 1 1 0
|
|
-- 4096 26624 30719 000B800 0 1 0 1 1 1 000C7FF 0 1 1 0 0 0
|
|
-- 2048 30720 32767 000C800 0 1 1 0 0 1 000CFFF 0 1 1 0 0 1
|
|
-- 2048 32768 34815 000D000 0 1 1 0 1 0 000D7FF 0 1 1 0 1 0
|
|
-- 2048 34816 36863 000D800 0 1 1 0 1 1 000DFFF 0 1 1 0 1 1
|
|
-- 7 4096 26624 30719 000E000 0 1 1 1 0 0 000EFFF 0 1 1 1 0 1
|
|
-- 4096 30720 34815 000F000 0 1 1 1 1 0 000FFFF 0 1 1 1 1 1
|
|
-- 2048 34816 36863 0010000 1 0 0 0 0 0 00107FF 1 0 0 0 0 0
|
|
-- 2048 36864 38911 0010800 1 0 0 0 0 1 0010FFF 1 0 0 0 0 1
|
|
-- 2048 38912 40959 0011000 1 0 0 0 1 0 00117FF 1 0 0 0 1 0
|
|
-- 8 4096 30720 34815 0011800 1 0 0 0 1 1 00127FF 1 0 0 1 0 0
|
|
-- 4096 34816 38911 0012800 1 0 0 1 0 1 00137FF 1 0 0 1 1 0
|
|
-- 2048 38912 40959 0013800 1 0 0 1 1 1 0013FFF 1 0 0 1 1 1
|
|
-- 2048 40960 43007 0014000 1 0 1 0 0 0 00147FF 1 0 1 0 0 0
|
|
-- 2048 43008 45055 0014800 1 0 1 0 0 1 0014FFF 1 0 1 0 0 1
|
|
-- B 2048 34816 36863 0015000 1 0 1 0 1 0 00157FF 1 0 1 0 1 0
|
|
-- 2048 36864 38911 0015800 1 0 1 0 1 1 0015FFF 1 0 1 0 1 1
|
|
-- 2048 38912 40959 0016000 1 0 1 1 0 0 00167FF 1 0 1 1 0 0
|
|
-- 2048 40960 43007 0016800 1 0 1 1 0 1 0016FFF 1 0 1 1 0 1
|
|
-- 2048 43008 45055 0017000 1 0 1 1 1 0 00177FF 1 0 1 1 1 0
|
|
-- 20 2048 36864 38911 0017800 1 0 1 1 1 1 0017FFF 1 0 1 1 1 1
|
|
-- 2048 38912 40959 0018000 1 1 0 0 0 0 00187FF 1 1 0 0 0 0
|
|
-- 2048 40960 43007 0018800 1 1 0 0 0 1 0018FFF 1 1 0 0 0 1
|
|
-- 2048 43008 45055 0019000 1 1 0 0 1 0 00197FF 1 1 0 0 1 0
|
|
-- 2048 45056 47103 0019800 1 1 0 0 1 1 0019FFF 1 1 0 0 1 1
|
|
--
|
|
MROM_BANK <= "00000" & T80_A16(11) when CONFIG(MZ80K) = '1' and (CONFIG(NORMAL80) = '0' and CONFIG(COLOUR80) = '0')
|
|
else
|
|
"00001" & T80_A16(11) when CONFIG(MZ80K) = '1' and (CONFIG(NORMAL80) = '1' or CONFIG(COLOUR80) = '1')
|
|
else
|
|
"000100" when CONFIG(MZ80K) = '1' and T80_A16(15 downto 11) = "11101"
|
|
else
|
|
"000101" when CONFIG(MZ80K) = '1' and T80_A16(15 downto 11) = "11110"
|
|
else
|
|
"000110" when CONFIG(MZ80K) = '1' and T80_A16(15 downto 11) = "11111"
|
|
else
|
|
"000111" when CONFIG(pkgs.mctrl_pkg.MZ80C) = '1' and T80_A16(11) = '0' and (CONFIG(NORMAL80) = '0' and CONFIG(COLOUR80) = '0')
|
|
else
|
|
"001000" when CONFIG(pkgs.mctrl_pkg.MZ80C) = '1' and T80_A16(11) = '1' and (CONFIG(NORMAL80) = '0' and CONFIG(COLOUR80) = '0')
|
|
else
|
|
"001001" when CONFIG(pkgs.mctrl_pkg.MZ80C) = '1' and T80_A16(11) = '0' and (CONFIG(NORMAL80) = '1' or CONFIG(COLOUR80) = '1')
|
|
else
|
|
"001010" when CONFIG(pkgs.mctrl_pkg.MZ80C) = '1' and T80_A16(11) = '1' and (CONFIG(NORMAL80) = '1' or CONFIG(COLOUR80) = '1')
|
|
else
|
|
"001011" when CONFIG(pkgs.mctrl_pkg.MZ80C) = '1' and T80_A16(15 downto 11) = "11101"
|
|
else
|
|
"001100" when CONFIG(pkgs.mctrl_pkg.MZ80C) = '1' and T80_A16(15 downto 11) = "11110"
|
|
else
|
|
"001101" when CONFIG(pkgs.mctrl_pkg.MZ80C) = '1' and T80_A16(15 downto 11) = "11111"
|
|
else
|
|
"00111" & T80_A16(11) when CONFIG(MZ1200) = '1' and (CONFIG(NORMAL80) = '0' and CONFIG(COLOUR80) = '0')
|
|
else
|
|
"01000" & T80_A16(11) when CONFIG(MZ1200) = '1' and (CONFIG(NORMAL80) = '1' or CONFIG(COLOUR80) = '1')
|
|
else
|
|
"010010" when CONFIG(MZ1200) = '1' and T80_A16(15 downto 11) = "11101"
|
|
else
|
|
"010011" when CONFIG(MZ1200) = '1' and T80_A16(15 downto 11) = "11110"
|
|
else
|
|
"010100" when CONFIG(MZ1200) = '1' and T80_A16(15 downto 11) = "11111"
|
|
else
|
|
"010101" when CONFIG(MZ80A) = '1' and T80_A16(11) = '0' and (CONFIG(NORMAL80) = '0' and CONFIG(COLOUR80) = '0')
|
|
else
|
|
"010110" when CONFIG(MZ80A) = '1' and T80_A16(11) = '1' and (CONFIG(NORMAL80) = '0' and CONFIG(COLOUR80) = '0')
|
|
else
|
|
"010111" when CONFIG(MZ80A) = '1' and T80_A16(11) = '0' and (CONFIG(NORMAL80) = '1' or CONFIG(COLOUR80) = '1')
|
|
else
|
|
"011000" when CONFIG(MZ80A) = '1' and T80_A16(11) = '1' and (CONFIG(NORMAL80) = '1' or CONFIG(COLOUR80) = '1')
|
|
else
|
|
"011001" when CONFIG(MZ80A) = '1' and T80_A16(15 downto 11) = "11101"
|
|
else
|
|
"011010" when CONFIG(MZ80A) = '1' and T80_A16(15 downto 11) = "11110"
|
|
else
|
|
"011011" when CONFIG(MZ80A) = '1' and T80_A16(15 downto 11) = "11111"
|
|
else
|
|
"01110" & T80_A16(11) when CONFIG(MZ700) = '1' and (CONFIG(NORMAL80) = '0' and CONFIG(COLOUR80) = '0')
|
|
else
|
|
"01111" & T80_A16(11) when CONFIG(MZ700) = '1' and (CONFIG(NORMAL80) = '1' or CONFIG(COLOUR80) = '1')
|
|
else
|
|
"100000" when CONFIG(MZ700) = '1' and T80_A16(15 downto 11) = "11101"
|
|
else
|
|
"100001" when CONFIG(MZ700) = '1' and T80_A16(15 downto 11) = "11110"
|
|
else
|
|
"100010" when CONFIG(MZ700) = '1' and T80_A16(15 downto 11) = "11111"
|
|
else
|
|
"100011" when CONFIG(MZ800) = '1' and T80_A16(11) = '0' and (CONFIG(NORMAL80) = '0' and CONFIG(COLOUR80) = '0')
|
|
else
|
|
"100100" when CONFIG(MZ800) = '1' and T80_A16(11) = '1' and (CONFIG(NORMAL80) = '0' and CONFIG(COLOUR80) = '0')
|
|
else
|
|
"100101" when CONFIG(MZ800) = '1' and T80_A16(11) = '0' and (CONFIG(NORMAL80) = '1' or CONFIG(COLOUR80) = '1')
|
|
else
|
|
"100110" when CONFIG(MZ800) = '1' and T80_A16(11) = '1' and (CONFIG(NORMAL80) = '1' or CONFIG(COLOUR80) = '1')
|
|
else
|
|
"100111" when CONFIG(MZ800) = '1' and T80_A16(15 downto 11) = "11101"
|
|
else
|
|
"101000" when CONFIG(MZ800) = '1' and T80_A16(15 downto 11) = "11110"
|
|
else
|
|
"101001" when CONFIG(MZ800) = '1' and T80_A16(15 downto 11) = "11111"
|
|
else
|
|
-- MZ80/2000 Series have different rom requirements.
|
|
"101010" when CONFIG(pkgs.mctrl_pkg.MZ80B) = '1' and (CONFIG(NORMAL80) = '0' and CONFIG(COLOUR80) = '0')
|
|
else
|
|
"101011" when CONFIG(pkgs.mctrl_pkg.MZ80B) = '1' and (CONFIG(NORMAL80) = '1' or CONFIG(COLOUR80) = '1')
|
|
else
|
|
"101100" when CONFIG(pkgs.mctrl_pkg.MZ80B) = '1' and T80_A16(15 downto 11) = "11101"
|
|
else
|
|
"101101" when CONFIG(pkgs.mctrl_pkg.MZ80B) = '1' and T80_A16(15 downto 11) = "11110"
|
|
else
|
|
"101110" when CONFIG(pkgs.mctrl_pkg.MZ80B) = '1' and T80_A16(15 downto 11) = "11111"
|
|
else
|
|
"101111" when CONFIG(pkgs.mctrl_pkg.MZ80B) = '1' and (CONFIG(NORMAL80) = '0' and CONFIG(COLOUR80) = '0')
|
|
else
|
|
"110000" when CONFIG(pkgs.mctrl_pkg.MZ80B) = '1' and (CONFIG(NORMAL80) = '1' or CONFIG(COLOUR80) = '1')
|
|
else
|
|
"110001" when CONFIG(pkgs.mctrl_pkg.MZ80B) = '1' and T80_A16(15 downto 11) = "11101"
|
|
else
|
|
"110010" when CONFIG(pkgs.mctrl_pkg.MZ80B) = '1' and T80_A16(15 downto 11) = "11110"
|
|
else
|
|
"110011" when CONFIG(pkgs.mctrl_pkg.MZ80B) = '1' and T80_A16(15 downto 11) = "11111"
|
|
else
|
|
"000000"; -- Default to K ROM.
|
|
|
|
-- Debug: Every 5 seconds, change the mb led bank to show a set of values (0 -> 7), bank indicated by 1 second of a bank number.
|
|
--
|
|
DEBUG0: if DEBUG_ENABLE = 1 generate
|
|
process( MZ_SYSTEM_RESET, CLKBUS(CKMASTER), DEBUG) begin
|
|
if MZ_SYSTEM_RESET = '1' then
|
|
debug_counter <= 0;
|
|
flip_counter <= 0;
|
|
|
|
elsif rising_edge(CLKBUS(CKMASTER)) then
|
|
|
|
if CLKBUS(CKENLEDS) = '1' then
|
|
|
|
-- If debug mode is enabled, enable use of sequencer.
|
|
--
|
|
if DEBUG(ENABLED) = '1' then
|
|
|
|
-- If LEDS are switched on, run the sample sequencer.
|
|
--
|
|
if DEBUG(LEDS_ON) = '1' then
|
|
|
|
-- The changing of the values displayed depends on the sample frequency as this drives the process.
|
|
case DEBUG(SMPFREQ) is
|
|
when "0000" => -- CMT/CPU frequency - default to 1s/5s @ 2MHz.
|
|
block_flip <= 250000;
|
|
bank_flip <= 10000000;
|
|
when "0001" => -- 1MHz
|
|
block_flip <= 800000;
|
|
bank_flip <= 5000000;
|
|
when "0010" => -- 100KHz
|
|
block_flip <= 80000;
|
|
bank_flip <= 500000;
|
|
when "0011" => -- 10KHz
|
|
block_flip <= 8000;
|
|
bank_flip <= 50000;
|
|
when "0100" => -- 5KHz
|
|
block_flip <= 4000;
|
|
bank_flip <= 25000;
|
|
when "0101" => -- 1KHz
|
|
block_flip <= 800;
|
|
bank_flip <= 5000;
|
|
when "0110" => -- 500Hz
|
|
block_flip <= 400;
|
|
bank_flip <= 2500;
|
|
when "0111" => -- 100Hz
|
|
block_flip <= 80;
|
|
bank_flip <= 500;
|
|
when "1000" => -- 50Hz
|
|
block_flip <= 40;
|
|
bank_flip <= 250;
|
|
when "1001" => -- 10Hz
|
|
block_flip <= 8;
|
|
bank_flip <= 50;
|
|
when "1010" => -- 5Hz
|
|
block_flip <= 4;
|
|
bank_flip <= 25;
|
|
when "1011" => -- 2Hz
|
|
block_flip <= 1;
|
|
bank_flip <= 10;
|
|
when "1100" => -- 1Hz
|
|
block_flip <= 1;
|
|
bank_flip <= 5;
|
|
when "1101" => -- 0.5Hz
|
|
block_flip <= 1;
|
|
bank_flip <= 5;
|
|
when "1110" => -- 0.2Hz
|
|
block_flip <= 1;
|
|
bank_flip <= 2;
|
|
when "1111" => -- 0.1Hz
|
|
block_flip <= 1;
|
|
bank_flip <= 1;
|
|
end case;
|
|
|
|
-- If a subbank has been provided, we dont cycle through the blocks in the bank,
|
|
-- just fix on the given subbank.
|
|
--
|
|
case DEBUG(LEDS_SUBBANK) is
|
|
when "001" => debug_counter <= 1;
|
|
when "010" => debug_counter <= 3;
|
|
when "011" => debug_counter <= 5;
|
|
when "100" => debug_counter <= 7;
|
|
when "101" => debug_counter <= 9;
|
|
when "110" => debug_counter <= 11;
|
|
when "111" => debug_counter <= 13;
|
|
when "000" =>
|
|
flip_counter <= flip_counter + 1;
|
|
if(flip_counter = block_flip-1 and (debug_counter mod 2) = 0) then
|
|
flip_counter <= 0;
|
|
debug_counter <= debug_counter + 1;
|
|
elsif(flip_counter = bank_flip-1) then
|
|
flip_counter <= 0;
|
|
debug_counter <= debug_counter + 1;
|
|
end if;
|
|
end case;
|
|
|
|
-- Bank 0 : T80 Signals
|
|
if( DEBUG(LEDS_BANK) = "000") then
|
|
case debug_counter is
|
|
when 0 => main_leds(7 downto 0) <= "00010000";
|
|
when 1 => main_leds(7 downto 0) <= T80_A16(7 downto 0); -- Address Bus A0->A7
|
|
when 2 => main_leds(7 downto 0) <= "00010001";
|
|
when 3 => main_leds(7 downto 0) <= T80_A16(15 downto 8); -- Address Bus A8->A15
|
|
when 4 => main_leds(7 downto 0) <= "00010010";
|
|
when 5 => main_leds(7 downto 0) <= T80_DI(7 downto 0); -- Data Bus D0->D7
|
|
when 6 => main_leds(7 downto 0) <= "00010011";
|
|
when 7 => main_leds(0) <= T80_RST_n; -- T80 signals
|
|
main_leds(1) <= T80_WAIT_n;
|
|
main_leds(2) <= T80_INT_n;
|
|
main_leds(3) <= T80_BUSRQ_n;
|
|
main_leds(4) <= T80_M1_n;
|
|
main_leds(5) <= T80_IORQ_n;
|
|
main_leds(6) <= T80_RD_n;
|
|
main_leds(7) <= T80_WR_n;
|
|
when 8 => main_leds(7 downto 0) <= "00010100";
|
|
when 10=> main_leds(7 downto 0) <= "00010101";
|
|
when 12=> main_leds(7 downto 0) <= "00010110";
|
|
when others => main_leds <= "00010111";
|
|
end case;
|
|
|
|
-- Bank 1 : Video, Keyboard and CMT
|
|
elsif( DEBUG(LEDS_BANK) = "001") then
|
|
case debug_counter is
|
|
when 0 => main_leds(7 downto 0) <= "00110000";
|
|
when 1 => main_leds(0) <= MZ_VBLANK; -- Video signals
|
|
main_leds(1) <= MZ_HBLANK; -- Video signals
|
|
main_leds(2) <= '0';
|
|
main_leds(3) <= MZ_HSYNC_n;
|
|
main_leds(4) <= MZ_VSYNC_n;
|
|
main_leds(5) <= MZ_R(7);
|
|
main_leds(6) <= MZ_G(7);
|
|
main_leds(7) <= MZ_B(7);
|
|
when 2 => main_leds(7 downto 0) <= "00110001";
|
|
when 3 => main_leds(0) <= MZ_PS2_KEY(0); -- PS2 Keyboard Data
|
|
main_leds(1) <= MZ_PS2_KEY(1);
|
|
main_leds(2) <= MZ_PS2_KEY(2);
|
|
main_leds(3) <= MZ_PS2_KEY(3);
|
|
main_leds(4) <= MZ_PS2_KEY(4);
|
|
main_leds(5) <= MZ_PS2_KEY(5);
|
|
main_leds(6) <= MZ_PS2_KEY(6);
|
|
main_leds(7) <= MZ_PS2_KEY(7);
|
|
when 4 => main_leds(7 downto 0) <= "00110010";
|
|
when 5 => main_leds(0) <= MZ_PS2_KEY(9);
|
|
main_leds(1) <= MZ_PS2_KEY(10);
|
|
main_leds(2) <= MZ_CS_ROM_n;
|
|
main_leds(3) <= MZ_CS_RAM_n;
|
|
main_leds(4) <= WENSYSRAM;
|
|
main_leds(7 downto 5) <= CONFIG(TURBO);
|
|
when 6 => main_leds(7 downto 0) <= "00111011";
|
|
when 7 => main_leds <= MZ_CMT_DEBUG_LEDS(7 downto 0);
|
|
when 8 => main_leds(7 downto 0) <= "00111100";
|
|
when 9 => main_leds <= MZ_CMT_DEBUG_LEDS(15 downto 8);
|
|
when 10=> main_leds(7 downto 0) <= "00111101";
|
|
when 11=> main_leds <= MZ_CMT_DEBUG_LEDS(23 downto 16);
|
|
when 12=> main_leds(7 downto 0) <= "00111110";
|
|
when 13=> main_leds <= MZ_CMT_DEBUG_LEDS(31 downto 24);
|
|
when others => main_leds <= "00110111";
|
|
end case;
|
|
|
|
-- Bank 2: IOCTL
|
|
elsif( DEBUG(LEDS_BANK) = "010") then
|
|
case debug_counter is
|
|
when 0 => main_leds(7 downto 0) <= "01010000";
|
|
when 1 => main_leds <= MZ_IOCTL_ADDR(23 downto 16);
|
|
when 2 => main_leds(7 downto 0) <= "01010001";
|
|
when 3 => main_leds <= MZ_IOCTL_ADDR(15 downto 8);
|
|
when 4 => main_leds(7 downto 0) <= "01010010";
|
|
when 5 => main_leds <= MZ_IOCTL_ADDR(7 downto 0);
|
|
when 6 => main_leds(7 downto 0) <= "01010011";
|
|
when 7 => main_leds(0) <= MZ_IOCTL_RD;
|
|
main_leds(1) <= MZ_IOCTL_WR;
|
|
main_leds(2) <= MZ_IOCTL_DOWNLOAD;
|
|
main_leds(3) <= MZ_IOCTL_UPLOAD;
|
|
main_leds(4) <= MZ_IOCTL_WENROM;
|
|
main_leds(5) <= MZ_IOCTL_WENRAM;
|
|
main_leds(6) <= MZ_IOCTL_RENROM;
|
|
main_leds(7) <= MZ_IOCTL_RENRAM;
|
|
when 8 => main_leds(7 downto 0) <= "01010100";
|
|
when 10=> main_leds(7 downto 0) <= "01010101";
|
|
when 12=> main_leds(7 downto 0) <= "01010110";
|
|
when others => main_leds <= "01010111";
|
|
end case;
|
|
|
|
-- Bank 3 : Config
|
|
elsif( DEBUG(LEDS_BANK) = "011") then
|
|
case debug_counter is
|
|
when 0 => main_leds(7 downto 0) <= "01110000";
|
|
when 1 => main_leds(0) <= CONFIG(MZ80K); -- Mode of operation.
|
|
main_leds(1) <= CONFIG(pkgs.mctrl_pkg.MZ80C);
|
|
main_leds(2) <= CONFIG(MZ1200);
|
|
main_leds(3) <= CONFIG(MZ80A);
|
|
main_leds(4) <= CONFIG(pkgs.mctrl_pkg.MZ80B);
|
|
main_leds(5) <= CONFIG(MZ2000);
|
|
main_leds(6) <= CONFIG(MZ700);
|
|
main_leds(7) <= CONFIG(MZ800);
|
|
when 2 => main_leds(7 downto 0) <= "01110001";
|
|
when 3 => main_leds(0) <= CONFIG(MZ_KC);
|
|
main_leds(1) <= CONFIG(MZ_A);
|
|
main_leds(2) <= CONFIG(pkgs.mctrl_pkg.MZ_B);
|
|
main_leds(3) <= CONFIG(MZ_80B);
|
|
main_leds(4) <= CONFIG(MZ_80C);
|
|
main_leds(5) <= CONFIG(NORMAL);
|
|
main_leds(6) <= CONFIG(NORMAL80);
|
|
main_leds(7) <= CONFIG(COLOUR);
|
|
when 4 => main_leds(7 downto 0) <= "01110010";
|
|
when 5 => main_leds(0) <= CONFIG(AUDIOSRC);
|
|
main_leds(3 downto 1) <= CONFIG(TURBO);
|
|
main_leds(6 downto 4) <= CONFIG(FASTTAPE);
|
|
main_leds(7) <= CONFIG(PCGRAM);
|
|
when 6 => main_leds(7 downto 0) <= "01110011";
|
|
when 7 => main_leds(3 downto 0) <= CONFIG(CPUSPEED);
|
|
main_leds(6 downto 4) <= CONFIG(VIDSPEED);
|
|
main_leds(7) <= '0';
|
|
when 8 => main_leds(7 downto 0) <= "01110100";
|
|
when 9 => main_leds(1 downto 0) <= CONFIG(PERSPEED);
|
|
main_leds(3 downto 2) <= CONFIG(RTCSPEED);
|
|
main_leds(5 downto 4) <= CONFIG(SNDSPEED);
|
|
main_leds(7 downto 6) <= CONFIG(BUTTONS);
|
|
when 10=> main_leds(7 downto 0) <= "01110101";
|
|
when 11=> main_leds <= "00000000";
|
|
when 12=> main_leds(7 downto 0) <= "01110110";
|
|
when 13=> main_leds <= "00000000";
|
|
when others => main_leds <= "01110111";
|
|
end case;
|
|
|
|
|
|
-- Bank 4 & 5: MZ80C Debug Leds
|
|
elsif( DEBUG(LEDS_BANK) = "100") then
|
|
case debug_counter is
|
|
when 0 => main_leds(7 downto 0) <= "10010000";
|
|
when 1 => main_leds <= MZ80C_DEBUG_LEDS(7 downto 0);
|
|
when 2 => main_leds(7 downto 0) <= "10010001";
|
|
when 3 => main_leds <= MZ80C_DEBUG_LEDS(15 downto 8);
|
|
when 4 => main_leds(7 downto 0) <= "10010010";
|
|
when 5 => main_leds <= MZ80C_DEBUG_LEDS(23 downto 16);
|
|
when 6 => main_leds(7 downto 0) <= "10010011";
|
|
when 7 => main_leds <= MZ80C_DEBUG_LEDS(31 downto 24);
|
|
when 8 => main_leds(7 downto 0) <= "10010100";
|
|
when 9 => main_leds <= MZ80C_DEBUG_LEDS(39 downto 32);
|
|
when 10=> main_leds(7 downto 0) <= "10010101";
|
|
when 11=> main_leds <= MZ80C_DEBUG_LEDS(47 downto 40);
|
|
when 12=> main_leds(7 downto 0) <= "10010110";
|
|
when 13=> main_leds <= MZ80C_DEBUG_LEDS(55 downto 48);
|
|
when others => main_leds <= "10010111";
|
|
end case;
|
|
elsif( DEBUG(LEDS_BANK) = "101") then
|
|
case debug_counter is
|
|
when 0 => main_leds(7 downto 0) <= "10110000";
|
|
when 1 => main_leds <= MZ80C_DEBUG_LEDS(63 downto 56);
|
|
when 2 => main_leds(7 downto 0) <= "10110001";
|
|
when 3 => main_leds <= MZ80C_DEBUG_LEDS(71 downto 64);
|
|
when 4 => main_leds(7 downto 0) <= "10110010";
|
|
when 5 => main_leds <= MZ80C_DEBUG_LEDS(79 downto 72);
|
|
when 6 => main_leds(7 downto 0) <= "10110011";
|
|
when 7 => main_leds <= MZ80C_DEBUG_LEDS(87 downto 80);
|
|
when 8 => main_leds(7 downto 0) <= "10110100";
|
|
when 9 => main_leds <= MZ80C_DEBUG_LEDS(95 downto 88);
|
|
when 10=> main_leds(7 downto 0) <= "10110101";
|
|
when 11=> main_leds <= MZ80C_DEBUG_LEDS(103 downto 96);
|
|
when 12=> main_leds(7 downto 0) <= "10110110";
|
|
when 13=> main_leds <= MZ80C_DEBUG_LEDS(111 downto 104);
|
|
when others => main_leds <= "10110111";
|
|
end case;
|
|
|
|
-- Bank 6 & 7 : MZ80B Debug Leds
|
|
elsif( DEBUG(LEDS_BANK) = "110") then
|
|
case debug_counter is
|
|
when 0 => main_leds(7 downto 0) <= "11010000";
|
|
when 1 => main_leds <= MZ80B_DEBUG_LEDS(7 downto 0);
|
|
when 2 => main_leds(7 downto 0) <= "11010001";
|
|
when 3 => main_leds <= MZ80B_DEBUG_LEDS(15 downto 8);
|
|
when 4 => main_leds(7 downto 0) <= "11010010";
|
|
when 5 => main_leds <= MZ80B_DEBUG_LEDS(23 downto 16);
|
|
when 6 => main_leds(7 downto 0) <= "11010011";
|
|
when 7 => main_leds <= MZ80B_DEBUG_LEDS(31 downto 24);
|
|
when 8 => main_leds(7 downto 0) <= "11010100";
|
|
when 9 => main_leds <= MZ80B_DEBUG_LEDS(39 downto 32);
|
|
when 10=> main_leds(7 downto 0) <= "11010101";
|
|
when 11=> main_leds <= MZ80B_DEBUG_LEDS(47 downto 40);
|
|
when 12=> main_leds(7 downto 0) <= "11010110";
|
|
when 13=> main_leds <= MZ80B_DEBUG_LEDS(55 downto 48);
|
|
when others => main_leds <= "11010111";
|
|
end case;
|
|
elsif( DEBUG(LEDS_BANK) = "111") then
|
|
case debug_counter is
|
|
when 0 => main_leds(7 downto 0) <= "11110000";
|
|
when 1 => main_leds <= MZ80B_DEBUG_LEDS(63 downto 56);
|
|
when 2 => main_leds(7 downto 0) <= "11110001";
|
|
when 3 => main_leds <= MZ80B_DEBUG_LEDS(71 downto 64);
|
|
when 4 => main_leds(7 downto 0) <= "11110010";
|
|
when 5 => main_leds <= MZ80B_DEBUG_LEDS(79 downto 72);
|
|
when 6 => main_leds(7 downto 0) <= "11110011";
|
|
when 7 => main_leds <= MZ80B_DEBUG_LEDS(87 downto 80);
|
|
when 8 => main_leds(7 downto 0) <= "11110100";
|
|
when 9 => main_leds <= MZ80B_DEBUG_LEDS(95 downto 88);
|
|
when 10=> main_leds(7 downto 0) <= "11110101";
|
|
when 11=> main_leds <= MZ80B_DEBUG_LEDS(103 downto 96);
|
|
when 12=> main_leds(7 downto 0) <= "11110110";
|
|
when 13=> main_leds <= MZ80B_DEBUG_LEDS(111 downto 104);
|
|
when others => main_leds <= "11110111";
|
|
end case;
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
end generate;
|
|
DEBUG1: if DEBUG_ENABLE = 0 generate
|
|
main_leds <= (others => '0');
|
|
end generate;
|
|
end rtl;
|