1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-01-26 03:51:07 +00:00

Update T80

This commit is contained in:
Gyorgy Szombathelyi
2022-06-23 18:23:42 +02:00
parent 05b27e6ef8
commit 51cd6eb1ec
5 changed files with 202 additions and 140 deletions

View File

@@ -238,6 +238,7 @@ architecture rtl of T80 is
signal ExchangeRp : std_logic;
signal ExchangeAF : std_logic;
signal ExchangeRS : std_logic;
signal ExchangeWH : std_logic;
signal I_DJNZ : std_logic;
signal I_CPL : std_logic;
signal I_CCF : std_logic;
@@ -318,6 +319,7 @@ begin
ExchangeRp => ExchangeRp,
ExchangeAF => ExchangeAF,
ExchangeRS => ExchangeRS,
ExchangeWH => ExchangeWH,
I_DJNZ => I_DJNZ,
I_CPL => I_CPL,
I_CCF => I_CCF,
@@ -497,6 +499,11 @@ begin
IR <= DInst;
end if;
if Mode <= 1 and IntCycle = '1' and IStatus = "10" then
-- IM2 vector address low byte from bus
WZ(7 downto 0) <= DInst;
end if;
ISet <= "00";
if Prefix /= "00" then
if Prefix = "11" then
@@ -677,7 +684,7 @@ begin
F(Flag_N) <= DI_Reg(7);
F(Flag_C) <= ioq(8);
F(Flag_H) <= ioq(8);
ioq := (ioq and x"7") xor ('0'&BusA);
ioq := (ioq and "000000111") xor ('0'&BusA);
F(Flag_P) <= not (ioq(0) xor ioq(1) xor ioq(2) xor ioq(3) xor ioq(4) xor ioq(5) xor ioq(6) xor ioq(7));
end if;
@@ -979,8 +986,12 @@ begin
-- EX HL,DL
Alternate & "10" when ExchangeDH = '1' and TState = 3 else
Alternate & "01" when (ExchangeDH = '1' or I_MULU = '1') and TState = 4 else
-- EX (SP),HL (HL(IX,IY) <= WZ)
Alternate & "10" when ExchangeWH = '1' and XY_State = "00" and TState = 4 else
XY_State(1) & "11" when ExchangeWH = '1' and TState = 4 else
-- LDHLSP
"010" when LDHLSP = '1' and TState = 4 else
-- Bus A / Write
RegAddrA_r;
@@ -994,7 +1005,7 @@ begin
signed(RegBusA) + 1;
process (Save_ALU_r, Auto_Wait_t1, ALU_OP_r, Read_To_Reg_r, I_MULU, T_Res,
ExchangeDH, IncDec_16, MCycle, TState, Wait_n, LDHLSP)
ExchangeDH, ExchangeWH, IncDec_16, MCycle, TState, Wait_n, LDHLSP)
begin
RegWEH <= '0';
RegWEL <= '0';
@@ -1018,7 +1029,7 @@ begin
RegWEL <= '1';
end if;
if LDHLSP = '1' and MCycle = "010" and TState = 4 then
if ((LDHLSP = '1' and MCycle = "010") or ExchangeWH = '1') and TState = 4 then
RegWEH <= '1';
RegWEL <= '1';
end if;
@@ -1036,7 +1047,7 @@ begin
TmpAddr2 <= std_logic_vector(unsigned(signed(SP) + signed(Save_Mux)));
process (Save_Mux, RegBusB, RegBusA_r, ID16, I_MULU, MULU_Prod32, MULU_tmp, T_Res,
ExchangeDH, IncDec_16, MCycle, TState, Wait_n, LDHLSP, TmpAddr2)
ExchangeDH, ExchangeWH, IncDec_16, MCycle, TState, Wait_n, LDHLSP, TmpAddr2, WZ)
begin
RegDIH <= Save_Mux;
RegDIL <= Save_Mux;
@@ -1064,7 +1075,10 @@ begin
RegDIH <= RegBusA_r(15 downto 8);
RegDIL <= RegBusA_r(7 downto 0);
end if;
if ExchangeWH = '1' and TState = 4 then
RegDIH <= WZ(15 downto 8);
RegDIL <= WZ(7 downto 0);
end if;
if IncDec_16(2) = '1' and ((TState = 2 and MCycle /= "001") or (TState = 3 and MCycle = "001")) then
RegDIH <= std_logic_vector(ID16(15 downto 8));
RegDIL <= std_logic_vector(ID16(7 downto 0));
@@ -1320,5 +1334,5 @@ begin
end if;
end process;
Auto_Wait <= '1' when (IntCycle = '1' or NMICycle = '1') and MCycle = "001" else '0';
Auto_Wait <= '1' when IntCycle = '1' and MCycle = "001" else '0';
end;

View File

@@ -130,6 +130,7 @@ entity T80_MCode is
ExchangeRp : out std_logic;
ExchangeAF : out std_logic;
ExchangeRS : out std_logic;
ExchangeWH : out std_logic;
I_DJNZ : out std_logic;
I_CPL : out std_logic;
I_CCF : out std_logic;
@@ -237,6 +238,7 @@ begin
ExchangeRp <= '0';
ExchangeAF <= '0';
ExchangeRS <= '0';
ExchangeWH <= '0';
I_DJNZ <= '0';
I_CPL <= '0';
I_CCF <= '0';
@@ -687,24 +689,21 @@ begin
when 1 =>
Set_Addr_To <= aSP;
when 2 =>
Read_To_Reg <= '1';
Set_BusA_To <= "0101";
Set_BusB_To <= "0101";
Set_Addr_To <= aSP;
LDZ <= '1';
IncDec_16 <= "0111"; -- SP <= SP+1
when 3 =>
IncDec_16 <= "0111";
Set_Addr_To <= aSP;
TStates <= "100";
Write <= '1';
when 4 =>
Read_To_Reg <= '1';
Set_BusA_To <= "0100";
Set_BusB_To <= "0100";
Set_Addr_To <= aSP;
LDW <= '1';
when 4 =>
Set_BusB_To <= "0101";
Write <= '1';
IncDec_16 <= "1111"; -- SP <= SP-1
Set_Addr_To <= aSP;
when 5 =>
IncDec_16 <= "1111";
ExchangeWH <= '1'; -- save WZ to HL
TStates <= "101";
Write <= '1';
when others => null;
@@ -884,7 +883,6 @@ begin
MCycles <= "101";
case to_integer(unsigned(MCycle)) is
when 1 =>
LDZ <= '1';
TStates <= "101";
IncDec_16 <= "1111";
Set_Addr_To <= aSP;

View File

@@ -189,6 +189,7 @@ package T80_Pack is
ExchangeRp : out std_logic;
ExchangeAF : out std_logic;
ExchangeRS : out std_logic;
ExchangeWH : out std_logic;
I_DJNZ : out std_logic;
I_CPL : out std_logic;
I_CCF : out std_logic;

View File

@@ -67,11 +67,12 @@
--
-- 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
--
-- 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
--
library IEEE;
use IEEE.std_logic_1164.all;
@@ -113,15 +114,20 @@ architecture rtl of T80a is
signal NoRead : std_logic;
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 IORQ_n_i : std_logic;
signal RD_n_i : std_logic;
signal WR_n_i : std_logic;
signal WR_n_j : std_logic; -- 0247a
signal MReq_Inhibit : std_logic;
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 RFSH_n_i : std_logic;
signal BUSAK_n_i : std_logic;
signal A_i : std_logic_vector(15 downto 0);
@@ -135,15 +141,18 @@ begin
CEN <= '1';
BUSAK_n <= BUSAK_n_i;
MREQ_n_i <= not MREQ or (Req_Inhibit and MReq_Inhibit);
RD_n_i <= not RD or Req_Inhibit;
WR_n_j <= WR_n_i; -- 0247a
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
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
IORQ_n <= IORQ_n_i when BUSAK_n_i = '1' else 'Z';
RD_n <= RD_n_i when BUSAK_n_i = '1' else 'Z';
WR_n <= WR_n_j when BUSAK_n_i = '1' else 'Z'; -- 0247a
WR_n <= WR_n_i when BUSAK_n_i = '1' else 'Z';
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');
@@ -195,99 +204,139 @@ begin
end if;
end process;
process (CLK_n) -- 0247a
begin
if CLK_n'event and CLK_n = '1' then
IReq_Inhibit <= not IORQ;
end if;
end process;
-- 30/10/19 Charlie Ingley - Generate WR_t2 to correct MREQ/WR timing
process (Reset_s,CLK_n)
begin
if Reset_s = '0' then
WR_t2 <= '0';
elsif CLK_n'event and CLK_n = '0' then
if MCycle /= "001" then
if TState = "010" then -- WR starts on falling edge of T2 for MREQ
WR_t2 <= Write;
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
WR_n_i <= '1';
elsif CLK_n'event and CLK_n = '0' then
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" and IORQ_n_i = '0' then
WR_n_i <= not Write;
elsif Tstate = "011" then
WR_n_i <= '1';
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 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 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 MCycle = "001" and TState = "010" and wait_s = '1' then
Req_Inhibit <= '1';
else
Req_Inhibit <= '0';
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
elsif CLK_n'event and CLK_n = '0' then
if MCycle = "001" and TState = "010" and WAIT_n = '1' then -- by Fabio Belavenuto - fix behavior of Wait_n
MReq_Inhibit <= '0';
else
MReq_Inhibit <= '1';
end if;
end if;
end process;
process (Reset_s,CLK_n)
begin
if Reset_s = '0' then
MReq_Inhibit <= '0';
elsif CLK_n'event and CLK_n = '0' then
if MCycle = "001" and TState = "010" then
MReq_Inhibit <= '1';
else
MReq_Inhibit <= '0';
end if;
end if;
end process;
-- Generate RD for MREQ
process(Reset_s,CLK_n)
begin
if Reset_s = '0' then
RD <= '0';
MREQ <= '0';
elsif CLK_n'event and CLK_n = '0' then
if MCycle = "001" then
if TState = "001" then
RD <= IntCycle_n;
MREQ <= IntCycle_n;
end if;
if TState = "011" then
RD <= '0';
MREQ <= '1';
end if;
if TState = "100" then
MREQ <= '0';
end if;
else
if TState = "001" and NoRead = '0' then
RD <= not Write;
MREQ <= not IORQ;
end if;
if TState = "011" then
RD <= '0';
MREQ <= '0';
end if;
end if;
end if;
end process;
process(Reset_s,CLK_n)
begin
if Reset_s = '0' then
RD <= '0';
IORQ_n_i <= '1';
MREQ <= '0';
elsif CLK_n'event and CLK_n = '0' then
-- 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 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 process;
if MCycle = "001" then
if TState = "001" then
RD <= IntCycle_n;
MREQ <= IntCycle_n;
IORQ_n_i <= IntCycle_n;
end if;
if TState = "011" then
RD <= '0';
IORQ_n_i <= '1';
MREQ <= '1';
end if;
if TState = "100" then
MREQ <= '0';
end if;
else
if TState = "001" and NoRead = '0' then
IORQ_n_i <= not IORQ;
MREQ <= not IORQ;
if IORQ = '0' then
RD <= not Write;
elsif IORQ_n_i = '0' then
RD <= not Write;
end if;
end if;
if TState = "011" then
RD <= '0';
IORQ_n_i <= '1';
MREQ <= '0';
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 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 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 TState = "001" then
IORQ_t1 <= not IntCycle_n;
end if;
if TState = "011" then
IORQ_t1 <= '1';
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
IORQ_t2 <= IORQ_t1;
end if;
end process;
end;