Z80: Revert T80a wrapper to previous version

Change-Id: I856a39c51305e99c3d8b32efe5be1f8ed8b2583f
This commit is contained in:
David Banks 2021-06-30 19:44:01 +01:00
parent e65951cfbb
commit 4ecd60065e
1 changed files with 123 additions and 183 deletions

View File

@ -1,16 +1,7 @@
-- ****
-- T80(b) core. In an effort to merge and maintain bug fixes ....
--
--
-- Ver 300 started tidyup
-- MikeJ March 2005
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
--
-- ****
--
-- Z80 compatible microprocessor core, asynchronous top level
--
-- Version : 0250
-- Version : 0247a
--
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
--
@ -47,32 +38,28 @@
-- you have the latest version of this file.
--
-- The latest version of this file can be found at:
-- http://www.opencores.org/cvsweb.shtml/t80/
-- http://www.opencores.org/cvsweb.shtml/t80/
--
-- Limitations :
--
-- File history :
--
-- 0208 : First complete release
-- 0208 : First complete release
--
-- 0211 : Fixed interrupt cycle
-- 0211 : Fixed interrupt cycle
--
-- 0235 : Updated for T80 interface change
-- 0235 : Updated for T80 interface change
--
-- 0238 : Updated for T80 interface change
-- 0238 : Updated for T80 interface change
--
-- 0240 : Updated for T80 interface change
-- 0240 : Updated for T80 interface change
--
-- 0242 : Updated for T80 interface change
-- 0242 : Updated for T80 interface change
--
-- 0247 : Fixed bus req/ack cycle
--
-- 0250 : Added R800 Multiplier by TobiFlex 2017.10.15
--
-- Bus signal logic changes from the ZX Spectrum Next were made by:
--
-- Fabio Belavenuto, Charlie Ingley
-- 0247 : Fixed bus req/ack cycle
--
-- 0247a: 7th of September, 2003 by Kazuhiro Tsujikawa (tujikawa@hat.hi-ho.ne.jp)
-- Fixed IORQ_n, RD_n, WR_n bus timing
library IEEE;
use IEEE.std_logic_1164.all;
@ -81,37 +68,34 @@ use work.T80_Pack.all;
entity T80a is
generic(
Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
IOWait : integer := 1 -- 0 => Single I/O cycle, 1 => Std I/O cycle
);
Mode : integer := 0 -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
);
port(
-- DMB
TS : out std_logic_vector(2 downto 0);
Regs : out std_logic_vector(255 downto 0);
PdcData : out std_logic_vector(7 downto 0);
CEN : in std_logic;
Din : in std_logic_vector(7 downto 0);
Dout : out std_logic_vector(7 downto 0);
Den : out std_logic;
-- Additions
TS : out std_logic_vector(2 downto 0);
Regs : out std_logic_vector(255 downto 0);
PdcData : out std_logic_vector(7 downto 0);
-- Original Signals
RESET_n : in std_logic;
R800_mode : in std_logic := '0';
CLK_n : 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)
-- D : inout std_logic_vector(7 downto 0)
);
RESET_n : in std_logic;
CLK_n : in std_logic;
CEN : 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);
Din : in std_logic_vector(7 downto 0);
Dout : out std_logic_vector(7 downto 0);
Den : out std_logic
);
end T80a;
architecture rtl of T80a is
@ -124,55 +108,51 @@ architecture rtl of T80a is
signal Write : std_logic;
signal MREQ : std_logic;
signal MReq_Inhibit : std_logic;
signal IReq_Inhibit : std_logic; -- 0247a
signal Req_Inhibit : std_logic;
signal RD : std_logic;
signal MREQ_n_i : std_logic;
signal MREQ_rw : std_logic; -- 30/10/19 Charlie Ingley-- add MREQ control
signal IORQ_n_i : std_logic;
signal IORQ_t1 : std_logic; -- 30/10/19 Charlie Ingley-- add IORQ control
signal IORQ_t2 : std_logic; -- 30/10/19 Charlie Ingley-- add IORQ control
signal IORQ_rw : std_logic; -- 30/10/19 Charlie Ingley-- add IORQ control
signal IORQ_int : std_logic; -- 30/10/19 Charlie Ingley-- add IORQ interrupt control
signal IORQ_int_inhibit : std_logic_vector(2 downto 0);
signal RD_n_i : std_logic;
signal WR_n_i : std_logic;
signal WR_t2 : std_logic; -- 30/10/19 Charlie Ingley-- add WR control
signal WR_n_j : std_logic; -- 0247a
signal RFSH_n_i : std_logic;
signal BUSAK_n_i : std_logic;
signal A_i : std_logic_vector(15 downto 0);
signal DO : std_logic_vector(7 downto 0);
signal DI_Reg : std_logic_vector (7 downto 0); -- Input synchroniser
signal DI_Reg : std_logic_vector (7 downto 0); -- Input synchroniser
signal Wait_s : std_logic;
signal MCycle : std_logic_vector(2 downto 0);
signal TState : std_logic_vector(2 downto 0);
signal HALT_n_int : std_logic;
signal iack1 : std_logic;
signal iack2 : std_logic;
begin
BUSAK_n <= BUSAK_n_i; -- 30/10/19 Charlie Ingley - IORQ/RD/WR changes
MREQ_rw <= MREQ and (Req_Inhibit or MReq_Inhibit); -- added MREQ timing control
MREQ_n_i <= not MREQ_rw; -- changed MREQ generation
IORQ_rw <= IORQ and not (IORQ_t1 or IORQ_t2); -- added IORQ generation timing control
IORQ_n_i <= not ((IORQ_int and not IORQ_int_inhibit(2)) or IORQ_rw); -- changed IORQ generation
RD_n_i <= not (RD and (MREQ_rw or IORQ_rw)); -- changed RD/IORQ generation
WR_n_i <= not (Write and ((WR_t2 and MREQ_rw) or IORQ_rw)); -- added WR/IORQ timing control
BUSAK_n <= BUSAK_n_i;
MREQ_n_i <= not MREQ or (Req_Inhibit and MReq_Inhibit);
RD_n_i <= not RD or (IORQ and IReq_Inhibit) or Req_Inhibit; -- DMB
WR_n_j <= WR_n_i or (IORQ and IReq_Inhibit); -- DMB
HALT_n <= HALT_n_int;
--Remove tristate as in ICE-Z80 this is implmeneted in Z80CpuMon
--MREQ_n <= MREQ_n_i when BUSAK_n_i = '1' else 'Z';
--IORQ_n <= IORQ_n_i when BUSAK_n_i = '1' else 'Z';
--MREQ_n <= MREQ_n_i; when BUSAK_n_i = '1' else 'Z';
--IORQ_n <= IORQ_n_i or IReq_Inhibit when BUSAK_n_i = '1' else 'Z'; -- 0247a
--RD_n <= RD_n_i when BUSAK_n_i = '1' else 'Z';
--WR_n <= WR_n_i when BUSAK_n_i = '1' else 'Z';
--WR_n <= WR_n_j when BUSAK_n_i = '1' else 'Z'; -- 0247a
--RFSH_n <= RFSH_n_i when BUSAK_n_i = '1' else 'Z';
--A <= A_i when BUSAK_n_i = '1' else (others => 'Z');
--D <= DO when Write = '1' and BUSAK_n_i = '1' else (others => 'Z');
MREQ_n <= MREQ_n_i;
IORQ_n <= IORQ_n_i;
IORQ_n <= IORQ_n_i or IReq_Inhibit or Req_inhibit; --DMB
RD_n <= RD_n_i;
WR_n <= WR_n_i;
WR_n <= WR_n_j; -- 0247a
RFSH_n <= RFSH_n_i;
A <= A_i;
Dout <= DO;
Den <= Write and BUSAK_n_i;
@ -181,18 +161,15 @@ begin
if RESET_n = '0' then
Reset_s <= '0';
elsif CLK_n'event and CLK_n = '1' then
if CEN = '1' then
Reset_s <= '1';
end if;
Reset_s <= '1';
end if;
end process;
u0 : T80
generic map(
Mode => Mode,
IOWait => IOWait)
IOWait => 1)
port map(
R800_mode => R800_mode,
CEN => CEN,
M1_n => M1_n,
IORQ => IORQ,
@ -214,7 +191,6 @@ begin
MC => MCycle,
TS => TState,
IntCycle_n => IntCycle_n,
-- DMB
NMICycle_n => NMICycle_n,
REG => Regs(211 downto 0),
DIRSet => '0',
@ -235,72 +211,102 @@ begin
end if;
end process;
-- 30/10/19 Charlie Ingley - Generate WR_t2 to correct MREQ/WR timing
process (Reset_s,CLK_n)
process (CLK_n) -- 0247a
begin
if CLK_n'event and CLK_n = '1' then
IReq_Inhibit <= (not IORQ) and IntCycle_n;
end if;
end process;
process (Reset_s,CLK_n) -- 0247a
begin
if Reset_s = '0' then
WR_t2 <= '0';
WR_n_i <= '1';
elsif CLK_n'event and CLK_n = '0' then
if CEN = '1' then
if MCycle /= "001" then
if TState = "010" then -- WR starts on falling edge of T2 for MREQ
WR_t2 <= Write;
if (IORQ = '0') then
if TState = "010" then
WR_n_i <= not Write;
elsif Tstate = "011" then
WR_n_i <= '1';
end if;
else
if TState = "001" then -- DMB
WR_n_i <= not Write;
elsif Tstate = "011" then
WR_n_i <= '1';
end if;
end if;
if TState = "011" then -- end WR
WR_t2 <= '0';
end if;
end if;
end process;
process (Reset_s,CLK_n) -- 0247a
begin
if Reset_s = '0' then
Req_Inhibit <= '0';
elsif CLK_n'event and CLK_n = '1' then
if CEN = '1' then
if MCycle = "001" and TState = "010" and wait_s = '1' then
Req_Inhibit <= '1';
else
Req_Inhibit <= '0';
end if;
end if;
end if;
end process;
-- Generate Req_Inhibit
process (Reset_s,CLK_n)
begin
if Reset_s = '0' then
Req_Inhibit <= '1'; -- Charlie Ingley 30/10/19 - changed Req_Inhibit polarity
elsif CLK_n'event and CLK_n = '1' then
if CEN = '1' then
if MCycle = "001" and TState = "010" and WAIT_n = '1' then -- by Fabio Belavenuto - fix behavior of Wait_n
Req_Inhibit <= '0';
else
Req_Inhibit <= '1';
end if;
end if;
end if;
end process;
-- Generate MReq_Inhibit
process (Reset_s, CLK_n)
begin
if Reset_s = '0' then
MReq_Inhibit <= '1'; -- Charlie Ingley 30/10/19 - changed Req_Inhibit polarity
MReq_Inhibit <= '0';
elsif CLK_n'event and CLK_n = '0' then
if CEN = '1' then
if MCycle = "001" and TState = "010" and WAIT_n = '1' then -- by Fabio Belavenuto - fix behavior of Wait_n
MReq_Inhibit <= '0';
else
if MCycle = "001" and TState = "010" then
MReq_Inhibit <= '1';
else
MReq_Inhibit <= '0';
end if;
end if;
end if;
end process;
-- Generate RD for MREQ
process(Reset_s,CLK_n)
process(Reset_s,CLK_n) -- 0247a
begin
if Reset_s = '0' then
RD <= '0';
IORQ_n_i <= '1';
MREQ <= '0';
iack1 <= '0';
iack2 <= '0';
elsif CLK_n'event and CLK_n = '0' then
if CEN = '1' then
if MCycle = "001" then
if TState = "001" then
RD <= IntCycle_n;
MREQ <= IntCycle_n;
if IntCycle_n = '1' then
-- Normal M1 Cycle
if TState = "001" then
RD <= '1';
MREQ <= '1';
IORQ_n_i <= '1';
end if;
else
-- Interupt Ack Cycle
-- 5 T-states: T1 T1 (auto wait) T1 (auto wait) T2 T3
-- Assert IORQ in middle of third T1
if TState = "001" then
iack1 <= '1';
iack2 <= iack1;
else
iack1 <= '0';
iack2 <= '0';
end if;
if iack2 = '1' then
IORQ_n_i <= '0';
end if;
end if;
if TState = "011" then
RD <= '0';
IORQ_n_i <= '1';
MREQ <= '1';
end if;
if TState = "100" then
@ -308,11 +314,13 @@ begin
end if;
else
if TState = "001" and NoRead = '0' then
RD <= not Write;
IORQ_n_i <= not IORQ;
MREQ <= not IORQ;
RD <= not Write; -- DMB
end if;
if TState = "011" then
RD <= '0';
IORQ_n_i <= '1';
MREQ <= '0';
end if;
end if;
@ -320,74 +328,6 @@ begin
end if;
end process;
-- 30/10/19 Charlie Ingley - Generate IORQ_int for IORQ interrupt timing control
process(Reset_s,CLK_n)
begin
if Reset_s = '0' then
IORQ_int <= '0';
elsif CLK_n'event and CLK_n = '1' then
if CEN = '1' then
if MCycle = "001" then
if TState = "001" then
IORQ_int <= not IntCycle_n;
end if;
if TState = "010" then
IORQ_int <= '0';
end if;
end if;
end if;
end if;
end process;
process(Reset_s,CLK_n)
begin
if Reset_s = '0' then
IORQ_int_inhibit <= "111";
elsif CLK_n'event and CLK_n = '0' then
if CEN = '1' then
if IntCycle_n = '0' then
if MCycle = "001" then
IORQ_int_inhibit <= IORQ_int_inhibit(1 downto 0) & '0';
end if;
if MCycle = "010" then
IORQ_int_inhibit <= "111";
end if;
end if;
end if;
end if;
end process;
-- 30/10/19 Charlie Ingley - Generate IORQ_t1 for IORQ timing control
process(Reset_s, CLK_n)
begin
if Reset_s = '0' then
IORQ_t1 <= '1';
elsif CLK_n'event and CLK_n = '0' then
if CEN = '1' then
if TState = "001" then
IORQ_t1 <= not IntCycle_n;
end if;
if TState = "011" then
IORQ_t1 <= '1';
end if;
end if;
end if;
end process;
-- 30/10/19 Charlie Ingley - Generate IORQ_t2 for IORQ timing control
process (RESET_n, CLK_n)
begin
if RESET_n = '0' then
IORQ_t2 <= '1';
elsif CLK_n'event and CLK_n = '1' then
if CEN = '1' then
IORQ_t2 <= IORQ_t1;
end if;
end if;
end process;
-- DMB
TS <= TState;
PdcData <= (not HALT_n_int) & (not NMICycle_n) & (not IntCycle_n) & "00000";