diff --git a/Arcade_MiST/Midway MCR 3/rtl/MCR3_MiST.sv b/Arcade_MiST/Midway MCR 3/rtl/MCR3_MiST.sv index e7b7061d..3a42f733 100644 --- a/Arcade_MiST/Midway MCR 3/rtl/MCR3_MiST.sv +++ b/Arcade_MiST/Midway MCR 3/rtl/MCR3_MiST.sv @@ -183,10 +183,10 @@ pll_mist pll( wire [31:0] status; wire [1:0] buttons; wire [1:0] switches; -wire [15:0] joystick_0; -wire [15:0] joystick_1; -wire [15:0] joystick_2; -wire [15:0] joystick_3; +wire [31:0] joystick_0; +wire [31:0] joystick_1; +wire [31:0] joystick_2; +wire [31:0] joystick_3; wire scandoublerD; wire ypbpr; wire no_csync; @@ -464,13 +464,13 @@ wire sarge_fire1A, sarge_fire1B, sarge_fire2A, sarge_fire2B; always @(*) begin if (~onestick) begin sarge_up1 = m_up; - sarge_up2 = m_up2; + sarge_up2 = m_up2 | m_upB; sarge_up3 = m_up3; - sarge_up4 = m_up4; + sarge_up4 = m_up4 | m_up3B; sarge_down1 = m_down; - sarge_down2 = m_down2; + sarge_down2 = m_down2 | m_downB; sarge_down3 = m_down3; - sarge_down4 = m_down4; + sarge_down4 = m_down4 | m_down3B; sarge_fire1A = m_fireA | m_fire2A; sarge_fire1B = m_fireB | m_fire2B; sarge_fire2A = m_fire3A | m_fire4A; @@ -597,10 +597,10 @@ wire [5:0] dotron_spinner; spinner #(15) dotron_spn (clk_sys, reset, m_fireE | m_fireG, m_fireF | m_fireH, 1'b0, vs, dotron_spinner); // Common inputs -wire m_up, m_down, m_left, m_right, m_fireA, m_fireB, m_fireC, m_fireD, m_fireE, m_fireF, m_fireG, m_fireH; -wire m_up2, m_down2, m_left2, m_right2, m_fire2A, m_fire2B, m_fire2C, m_fire2D; -wire m_up3, m_down3, m_left3, m_right3, m_fire3A, m_fire3B, m_fire3C, m_fire3D; -wire m_up4, m_down4, m_left4, m_right4, m_fire4A, m_fire4B, m_fire4C, m_fire4D; +wire m_up, m_down, m_left, m_right, m_fireA, m_fireB, m_fireC, m_fireD, m_fireE, m_fireF, m_upB, m_downB, m_leftB, m_rightB; +wire m_up2, m_down2, m_left2, m_right2, m_fire2A, m_fire2B, m_fire2C, m_fire2D, m_fire2E, m_fire2F, m_up2B, m_down2B, m_left2B, m_right2B; +wire m_up3, m_down3, m_left3, m_right3, m_fire3A, m_fire3B, m_fire3C, m_fire3D, m_fire3E, m_fire3F, m_up3B, m_down3B, m_left3B, m_right3B; +wire m_up4, m_down4, m_left4, m_right4, m_fire4A, m_fire4B, m_fire4C, m_fire4D, m_fire4E, m_fire4F, m_up4B, m_down4B, m_left4B, m_right4B; wire m_tilt, m_coin1, m_coin2, m_coin3, m_coin4, m_one_player, m_two_players, m_three_players, m_four_players; arcade_inputs inputs ( @@ -617,10 +617,10 @@ arcade_inputs inputs ( .joyswap ( joyswap ), .oneplayer ( 1'b0 ), .controls ( {m_tilt, m_coin4, m_coin3, m_coin2, m_coin1, m_four_players, m_three_players, m_two_players, m_one_player} ), - .player1 ( {m_fireH, m_fireG, m_fireF, m_fireE, m_fireD, m_fireC, m_fireB, m_fireA, m_up, m_down, m_left, m_right} ), - .player2 ( {m_fire2D, m_fire2C, m_fire2B, m_fire2A, m_up2, m_down2, m_left2, m_right2} ), - .player3 ( {m_fire3D, m_fire3C, m_fire3B, m_fire3A, m_up3, m_down3, m_left3, m_right3} ), - .player4 ( {m_fire4D, m_fire4C, m_fire4B, m_fire4A, m_up4, m_down4, m_left4, m_right4} ) + .player1 ( {m_upB, m_downB, m_leftB, m_rightB, 6'd0, m_fireF, m_fireE, m_fireD, m_fireC, m_fireB, m_fireA, m_up, m_down, m_left, m_right} ), + .player2 ( {m_up2B, m_down2B, m_left2B, m_right2B, 6'd0, m_fire2F, m_fire2E, m_fire2D, m_fire2C, m_fire2B, m_fire2A, m_up2, m_down2, m_left2, m_right2} ), + .player3 ( {m_up3B, m_down3B, m_left3B, m_right3B, 6'd0, m_fire3F, m_fire3E, m_fire3D, m_fire3C, m_fire3B, m_fire3A, m_up3, m_down3, m_left3, m_right3} ), + .player4 ( {m_up4B, m_down4B, m_left4B, m_right4B, 6'd0, m_fire4F, m_fire4E, m_fire4D, m_fire4C, m_fire4B, m_fire4A, m_up4, m_down4, m_left4, m_right4} ) ); endmodule diff --git a/common/CPU/T80/T80.vhd b/common/CPU/T80/T80.vhd index 4779f50b..641ed7ab 100644 --- a/common/CPU/T80/T80.vhd +++ b/common/CPU/T80/T80.vhd @@ -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; diff --git a/common/CPU/T80/T80_MCode.vhd b/common/CPU/T80/T80_MCode.vhd index 22820539..554ec9b5 100644 --- a/common/CPU/T80/T80_MCode.vhd +++ b/common/CPU/T80/T80_MCode.vhd @@ -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; diff --git a/common/CPU/T80/T80_Pack.vhd b/common/CPU/T80/T80_Pack.vhd index fc1407a1..3ac15221 100644 --- a/common/CPU/T80/T80_Pack.vhd +++ b/common/CPU/T80/T80_Pack.vhd @@ -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; diff --git a/common/CPU/T80/T80a.vhd b/common/CPU/T80/T80a.vhd index 2103a5c9..fdd84d11 100644 --- a/common/CPU/T80/T80a.vhd +++ b/common/CPU/T80/T80a.vhd @@ -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;