From dd8051278d19a07165187ad1e0bf6a60bc1ea04e Mon Sep 17 00:00:00 2001 From: Gyorgy Szombathelyi Date: Mon, 14 Dec 2020 17:04:58 +0100 Subject: [PATCH] T80: update to latest --- common/CPU/T80/GBse.vhd | 202 ++++++++++++ common/CPU/T80/README | 7 +- common/CPU/T80/T80.qip | 2 + common/CPU/T80/T80.vhd | 287 ++++++++++++---- common/CPU/T80/T80_ALU.vhd | 85 +++-- common/CPU/T80/T80_MCode.vhd | 617 ++++++++++++++++++++++++----------- common/CPU/T80/T80_Pack.vhd | 12 +- common/CPU/T80/T80a.vhd | 61 +++- common/CPU/T80/T80pa.vhd | 9 +- 9 files changed, 974 insertions(+), 308 deletions(-) create mode 100644 common/CPU/T80/GBse.vhd diff --git a/common/CPU/T80/GBse.vhd b/common/CPU/T80/GBse.vhd new file mode 100644 index 00000000..efcb40b9 --- /dev/null +++ b/common/CPU/T80/GBse.vhd @@ -0,0 +1,202 @@ +-- **** +-- 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, synchronous top level with clock enable +-- Different timing than the original z80 +-- Inputs needs to be synchronous and outputs may glitch +-- +-- Version : 0240 +-- +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- 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/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0235 : First release +-- +-- 0236 : Added T2Write generic +-- +-- 0237 : Fixed T2Write with wait state +-- +-- 0238 : Updated for T80 interface change +-- +-- 0240 : Updated for T80 interface change +-- +-- 0242 : Updated for T80 interface change +-- +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use work.T80_Pack.all; + +entity GBse is + generic( + 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; + 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; + STOP : 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 GBse; + +architecture rtl of GBse is + + signal IntCycle_n : std_logic; + signal NoRead : std_logic; + signal Write : std_logic; + signal IORQ : std_logic; + signal DI_Reg : std_logic_vector(7 downto 0); + signal MCycle : std_logic_vector(2 downto 0); + signal TState : std_logic_vector(2 downto 0); + +begin + + u0 : T80 + generic map( + Mode => 3, + IOWait => IOWait, + Flag_S => 0, + Flag_P => 0, + Flag_X => 0, + Flag_Y => 0, + Flag_C => 4, + Flag_H => 5, + Flag_N => 6, + Flag_Z => 7 + ) + port map( + CEN => CLKEN, + M1_n => M1_n, + IORQ => IORQ, + NoRead => NoRead, + Write => Write, + RFSH_n => RFSH_n, + HALT_n => HALT_n, + Stop => STOP, + WAIT_n => Wait_n, + INT_n => INT_n, + NMI_n => NMI_n, + RESET_n => RESET_n, + BUSRQ_n => BUSRQ_n, + BUSAK_n => BUSAK_n, + CLK_n => CLK_n, + A => A, + DInst => DI, + DI => DI_Reg, + DO => DO, + MC => MCycle, + TS => TState, + IntCycle_n => IntCycle_n); + + process (RESET_n, CLK_n) + begin + if RESET_n = '0' then + RD_n <= '1'; + WR_n <= '1'; + IORQ_n <= '1'; + MREQ_n <= '1'; + DI_Reg <= "00000000"; + elsif CLK_n'event and CLK_n = '1' then + if CLKEN = '1' then + RD_n <= '1'; + WR_n <= '1'; + IORQ_n <= '1'; + MREQ_n <= '1'; + if MCycle = "001" then + if TState = "001" or (TState = "010" and Wait_n = '0') then + RD_n <= not IntCycle_n; + MREQ_n <= not IntCycle_n; + IORQ_n <= IntCycle_n; + end if; + if TState = "011" then + MREQ_n <= '0'; + end if; + else + if (TState = "001" or (TState = "010" and Wait_n = '0')) and NoRead = '0' and Write = '0' then + RD_n <= '0'; + IORQ_n <= not IORQ; + MREQ_n <= IORQ; + end if; + if T2Write = 0 then + if TState = "010" and Write = '1' then + WR_n <= '0'; + IORQ_n <= not IORQ; + MREQ_n <= IORQ; + end if; + else + if (TState = "001" or (TState = "010" and Wait_n = '0')) and Write = '1' then + WR_n <= '0'; + IORQ_n <= not IORQ; + MREQ_n <= IORQ; + end if; + end if; + end if; + if TState = "010" and Wait_n = '1' then + DI_Reg <= DI; + end if; + end if; + end if; + end process; + +end; diff --git a/common/CPU/T80/README b/common/CPU/T80/README index 16297f14..2fce7700 100644 --- a/common/CPU/T80/README +++ b/common/CPU/T80/README @@ -2,6 +2,11 @@ -- **** -- T80(c) core. Attempt to finish all undocumented features and provide -- accurate timings. +-- +-- Version 351. +-- Merged Gameboy fixes from Bruno Duarte Gouveia (brNX) +-- Passes Blargg's test ROMs +-- -- Version 350. -- Copyright (c) 2018 Sorgelig -- Test passed: ZEXDOC, ZEXALL, Z80Full(*), Z80memptr @@ -21,7 +26,7 @@ -- **** -- Z80 compatible microprocessor core -- --- Version : 0247 +-- Version : 0250 -- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) -- All rights reserved -- diff --git a/common/CPU/T80/T80.qip b/common/CPU/T80/T80.qip index ba96c065..e7a05b6b 100644 --- a/common/CPU/T80/T80.qip +++ b/common/CPU/T80/T80.qip @@ -1,6 +1,8 @@ +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) GBse.vhd ] set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80pa.vhd ] set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80s.vhd ] set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80se.vhd ] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80a.vhd ] set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80as.vhd ] set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80sed.vhd ] set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T8080se.vhd ] diff --git a/common/CPU/T80/T80.vhd b/common/CPU/T80/T80.vhd index d7745b16..89d618ea 100644 --- a/common/CPU/T80/T80.vhd +++ b/common/CPU/T80/T80.vhd @@ -21,7 +21,7 @@ -- **** -- Z80 compatible microprocessor core -- --- Version : 0247 +-- Version : 0250 -- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) -- All rights reserved -- @@ -73,6 +73,7 @@ -- 0240 : Added interrupt ack fix by Mike Johnson, changed (IX/IY+d) timing and changed flags in GB mode -- 0242 : Added I/O wait, fixed refresh address, moved some registers to RAM -- 0247 : Fixed bus req/ack cycle +-- 0250 : Added R800 Multiplier by TobiFlex 2017.10.15 -- library IEEE; @@ -118,6 +119,7 @@ entity T80 is IntCycle_n : out std_logic; IntE : out std_logic; Stop : out std_logic; + R800_mode : in std_logic := '0'; out0 : in std_logic := '0'; -- 0 => OUT(C),0, 1 => OUT(C),255 REG : out std_logic_vector(211 downto 0); -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A @@ -151,9 +153,13 @@ architecture rtl of T80 is -- Help Registers signal WZ : std_logic_vector(15 downto 0); -- MEMPTR register + signal TmpAddr2 : std_logic_vector(15 downto 0); -- Temporary address register signal IR : std_logic_vector(7 downto 0); -- Instruction register signal ISet : std_logic_vector(1 downto 0); -- Instruction set selector signal RegBusA_r : std_logic_vector(15 downto 0); + signal MULU_Prod32 : std_logic_vector(31 downto 0); + signal MULU_tmp : std_logic_vector(31 downto 0); + signal MULU_Fakt1 : std_logic_vector(15 downto 0); signal ID16 : signed(15 downto 0); signal Save_Mux : std_logic_vector(7 downto 0); @@ -212,6 +218,7 @@ architecture rtl of T80 is signal Set_BusA_To : std_logic_vector(3 downto 0); signal ALU_Op : std_logic_vector(3 downto 0); signal Save_ALU : std_logic; + signal Rot_Akku : std_logic; signal PreserveC : std_logic; signal Arith16 : std_logic; signal Set_Addr_To : std_logic_vector(2 downto 0); @@ -223,6 +230,8 @@ architecture rtl of T80 is signal LDZ : std_logic; signal LDW : std_logic; signal LDSPHL : std_logic; + signal LDHLSP : std_logic; + signal ADDSPdd : std_logic; signal IORQ_i : std_logic; signal Special_LD : std_logic_vector(2 downto 0); signal ExchangeDH : std_logic; @@ -241,6 +250,8 @@ architecture rtl of T80 is signal I_RRD : std_logic; signal I_RXDD : std_logic; signal I_INRC : std_logic; + signal I_MULUB : std_logic; + signal I_MULU : std_logic; signal SetWZ : std_logic_vector(1 downto 0); signal SetDI : std_logic; signal SetEI : std_logic; @@ -249,6 +260,11 @@ architecture rtl of T80 is signal XYbit_undoc : std_logic; signal DOR : std_logic_vector(127 downto 0); + signal ABus : std_logic_vector(15 downto 0); + signal ABus_last : std_logic_vector(15 downto 0); + signal NoRead_int : std_logic; + signal Write_int : std_logic; + begin REG <= IntE_FF2 & IntE_FF1 & IStatus & DOR & std_logic_vector(PC) & std_logic_vector(SP) & std_logic_vector(R) & I & Fp & Ap & F & ACC when Alternate = '0' @@ -286,6 +302,7 @@ begin Set_BusA_To => Set_BusA_To, ALU_Op => ALU_Op, Save_ALU => Save_ALU, + Rot_Akku => Rot_Akku, PreserveC => PreserveC, Arith16 => Arith16, Set_Addr_To => Set_Addr_To, @@ -298,6 +315,8 @@ begin LDZ => LDZ, LDW => LDW, LDSPHL => LDSPHL, + LDHLSP => LDHLSP, + ADDSPdd => ADDSPdd, Special_LD => Special_LD, ExchangeDH => ExchangeDH, ExchangeRp => ExchangeRp, @@ -314,14 +333,17 @@ begin I_RLD => I_RLD, I_RRD => I_RRD, I_INRC => I_INRC, + I_MULUB => I_MULUB, + I_MULU => I_MULU, SetWZ => SetWZ, SetDI => SetDI, SetEI => SetEI, IMode => IMode, Halt => Halt, - NoRead => NoRead, - Write => Write, - XYbit_undoc => XYbit_undoc); + NoRead => NoRead_int, + Write => Write_int, + XYbit_undoc => XYbit_undoc, + R800_mode => R800_mode); alu : T80_ALU generic map( @@ -340,6 +362,7 @@ begin WZ => WZ, XY_State=> XY_State, ALU_Op => ALU_Op_r, + Rot_Akku => Rot_Akku, IR => IR(5 downto 0), ISet => ISet, BusA => BusA, @@ -364,10 +387,12 @@ begin process (RESET_n, CLK_n) variable n : std_logic_vector(7 downto 0); variable ioq : std_logic_vector(8 downto 0); + variable temp_c : unsigned(8 downto 0); + variable temp_h : unsigned(4 downto 0); begin if RESET_n = '0' then PC <= (others => '0'); -- Program Counter - A <= (others => '0'); + ABus <= (others => '0'); WZ <= (others => '0'); IR <= "00000000"; ISet <= "00"; @@ -378,6 +403,11 @@ begin ACC <= (others => '1'); F <= (others => '1'); + if Mode = 3 then + ACC <= (others => '0'); + F <= "11110000"; + end if; + Ap <= (others => '1'); Fp <= (others => '1'); I <= (others => '0'); @@ -406,7 +436,7 @@ begin R <= unsigned(DIR(47 downto 40)); SP <= unsigned(DIR(63 downto 48)); PC <= unsigned(DIR(79 downto 64)); - A <= DIR(79 downto 64); + ABus <= DIR(79 downto 64); IStatus <= DIR(209 downto 208); elsif ClkEn = '1' then @@ -416,7 +446,27 @@ begin MCycles <= MCycles_d; - if IMode /= "11" then + if LDHLSP = '1' and MCycle = "011" and TState = 1 then + temp_c := unsigned('0'&SP(7 downto 0))+unsigned('0'&Save_Mux); + temp_h := unsigned('0'&SP(3 downto 0))+unsigned('0'&Save_Mux(3 downto 0)); + F(Flag_Z) <= '0'; + F(Flag_N) <= '0'; + F(Flag_H) <= temp_h(4); + F(Flag_C) <= temp_c(8); + end if; + + if ADDSPdd = '1' and TState = 1 then + temp_c := unsigned('0'&SP(7 downto 0))+unsigned('0'&Save_Mux); + temp_h := unsigned('0'&SP(3 downto 0))+unsigned('0'&Save_Mux(3 downto 0)); + F(Flag_Z) <= '0'; + F(Flag_N) <= '0'; + F(Flag_H) <= temp_h(4); + F(Flag_C) <= temp_c(8); + end if; + + if Mode = 3 then + IStatus <= "10"; + elsif IMode /= "11" then IStatus <= IMode; end if; @@ -433,8 +483,8 @@ begin if TState = 2 and Wait_n = '1' then if Mode < 2 then - A(7 downto 0) <= std_logic_vector(R); - A(15 downto 8) <= I; + ABus(7 downto 0) <= std_logic_vector(R); + ABus(15 downto 8) <= I; R(6 downto 0) <= R(6 downto 0) + 1; end if; @@ -484,57 +534,57 @@ begin if T_Res = '1' then BTR_r <= (I_BT or I_BC or I_BTR) and not No_BTR; if Jump = '1' then - A(15 downto 8) <= DI_Reg; - A(7 downto 0) <= WZ(7 downto 0); + ABus(15 downto 8) <= DI_Reg; + ABus(7 downto 0) <= WZ(7 downto 0); PC(15 downto 8) <= unsigned(DI_Reg); PC(7 downto 0) <= unsigned(WZ(7 downto 0)); elsif JumpXY = '1' then - A <= RegBusC; + ABus <= RegBusC; PC <= unsigned(RegBusC); elsif Call = '1' or RstP = '1' then - A <= WZ; + ABus <= WZ; PC <= unsigned(WZ); elsif MCycle = MCycles and NMICycle = '1' then - A <= "0000000001100110"; + ABus <= "0000000001100110"; PC <= "0000000001100110"; elsif MCycle = "011" and IntCycle = '1' and IStatus = "10" then - A(15 downto 8) <= I; - A(7 downto 0) <= WZ(7 downto 0); + ABus(15 downto 8) <= I; + ABus(7 downto 0) <= WZ(7 downto 0); PC(15 downto 8) <= unsigned(I); PC(7 downto 0) <= unsigned(WZ(7 downto 0)); else case Set_Addr_To is when aXY => if XY_State = "00" then - A <= RegBusC; + ABus <= RegBusC; else if NextIs_XY_Fetch = '1' then - A <= std_logic_vector(PC); + ABus <= std_logic_vector(PC); else - A <= WZ; + ABus <= WZ; end if; end if; when aIOA => if Mode = 3 then -- Memory map I/O on GBZ80 - A(15 downto 8) <= (others => '1'); + ABus(15 downto 8) <= (others => '1'); elsif Mode = 2 then -- Duplicate I/O address on 8080 - A(15 downto 8) <= DI_Reg; + ABus(15 downto 8) <= DI_Reg; else - A(15 downto 8) <= ACC; + ABus(15 downto 8) <= ACC; end if; - A(7 downto 0) <= DI_Reg; + ABus(7 downto 0) <= DI_Reg; WZ <= (ACC & DI_Reg) + "1"; when aSP => - A <= std_logic_vector(SP); + ABus <= std_logic_vector(SP); when aBC => if Mode = 3 and IORQ_i = '1' then -- Memory map I/O on GBZ80 - A(15 downto 8) <= (others => '1'); - A(7 downto 0) <= RegBusC(7 downto 0); + ABus(15 downto 8) <= (others => '1'); + ABus(7 downto 0) <= RegBusC(7 downto 0); else - A <= RegBusC; + ABus <= RegBusC; if SetWZ = "01" then WZ <= RegBusC + "1"; end if; @@ -544,24 +594,24 @@ begin end if; end if; when aDE => - A <= RegBusC; + ABus <= RegBusC; if SetWZ = "10" then WZ(7 downto 0) <= RegBusC(7 downto 0) + "1"; WZ(15 downto 8) <= ACC; end if; when aZI => if Inc_WZ = '1' then - A <= std_logic_vector(unsigned(WZ) + 1); + ABus <= std_logic_vector(unsigned(WZ) + 1); else - A(15 downto 8) <= DI_Reg; - A(7 downto 0) <= WZ(7 downto 0); + ABus(15 downto 8) <= DI_Reg; + ABus(7 downto 0) <= WZ(7 downto 0); if SetWZ = "10" then WZ(7 downto 0) <= WZ(7 downto 0) + "1"; WZ(15 downto 8) <= ACC; end if; end if; when others => - A <= std_logic_vector(PC); + ABus <= std_logic_vector(PC); end case; end if; @@ -572,33 +622,54 @@ begin Save_ALU_r <= Save_ALU; ALU_Op_r <= ALU_Op; - if I_CPL = '1' then - -- CPL - ACC <= not ACC; - F(Flag_Y) <= not ACC(5); - F(Flag_H) <= '1'; - F(Flag_X) <= not ACC(3); - F(Flag_N) <= '1'; - end if; - if I_CCF = '1' then - -- CCF - F(Flag_C) <= not F(Flag_C); - F(Flag_Y) <= ACC(5); - F(Flag_H) <= F(Flag_C); - F(Flag_X) <= ACC(3); - F(Flag_N) <= '0'; - end if; - if I_SCF = '1' then - -- SCF - F(Flag_C) <= '1'; - F(Flag_Y) <= ACC(5); - F(Flag_H) <= '0'; - F(Flag_X) <= ACC(3); - F(Flag_N) <= '0'; + if Mode = 3 then + if I_CPL = '1' then + -- CPL + ACC <= not ACC; + F(Flag_H) <= '1'; + F(Flag_N) <= '1'; + end if; + if I_CCF = '1' then + -- CCF + F(Flag_C) <= not F(Flag_C); + F(Flag_H) <= '0'; + F(Flag_N) <= '0'; + end if; + if I_SCF = '1' then + -- SCF + F(Flag_C) <= '1'; + F(Flag_H) <= '0'; + F(Flag_N) <= '0'; + end if; + else + if I_CPL = '1' then + -- CPL + ACC <= not ACC; + F(Flag_Y) <= not ACC(5); + F(Flag_H) <= '1'; + F(Flag_X) <= not ACC(3); + F(Flag_N) <= '1'; + end if; + if I_CCF = '1' then + -- CCF + F(Flag_C) <= not F(Flag_C); + F(Flag_Y) <= ACC(5); + F(Flag_H) <= F(Flag_C); + F(Flag_X) <= ACC(3); + F(Flag_N) <= '0'; + end if; + if I_SCF = '1' then + -- SCF + F(Flag_C) <= '1'; + F(Flag_Y) <= ACC(5); + F(Flag_H) <= '0'; + F(Flag_X) <= ACC(3); + F(Flag_N) <= '0'; + end if; end if; end if; - if (TState = 2 and I_BTR = '1' and IR(0) = '1') or (TState = 1 and I_BTR = '1' and IR(0) = '0') then + if (TState = 2 and I_BTR = '1' and IR(0) = '1' and Wait_n = '1') or (TState = 1 and I_BTR = '1' and IR(0) = '0') then ioq := ('0' & DI_Reg) + ('0' & std_logic_vector(ID16(7 downto 0))); F(Flag_N) <= DI_Reg(7); F(Flag_C) <= ioq(8); @@ -645,6 +716,11 @@ begin end if; end if; + if ADDSPdd = '1' and TState = 2 and Wait_n = '1' then + WZ <= std_logic_vector(SP); + SP <= unsigned(signed(SP)+signed(Save_Mux)); + end if; + if LDSPHL = '1' then SP <= unsigned(RegBusC); end if; @@ -792,7 +868,12 @@ begin when "11001" => SP(15 downto 8) <= unsigned(Save_Mux); when "11011" => - F <= Save_Mux; + if Mode = 3 then + F(7 downto 4) <= Save_Mux(7 downto 4); + F(3 downto 0) <= "0000"; -- bit 3 to 0 always return 0 + else + F <= Save_Mux; + end if; when others => end case; if XYbit_undoc='1' then @@ -803,6 +884,42 @@ begin end if; end process; +--------------------------------------------------------------------------- +-- +-- Multiply +-- +--------------------------------------------------------------------------- + process (CLK_n, ACC, RegBusB, MULU_tmp, MULU_Fakt1, MULU_Prod32) + begin + + MULU_tmp(31 downto 12) <= std_logic_vector((unsigned(MULU_Fakt1)*unsigned(MULU_Prod32(3 downto 0)))+unsigned("0000"&MULU_Prod32(31 downto 16))); + MULU_tmp(11 downto 0) <= MULU_Prod32(15 downto 4); + + if rising_edge(CLK_n) then + if ClkEn = '1' then + if T_Res='1' then + if I_MULUB='1' then + MULU_Prod32(7 downto 0) <= ACC; + MULU_Prod32(15 downto 8) <= "--------"; + MULU_Prod32(31 downto 16) <= X"0000"; + MULU_Fakt1(7 downto 0) <= "00000000"; + if Set_BusB_To(0) = '1' then + MULU_Fakt1(15 downto 8) <= RegBusB(7 downto 0); + else + MULU_Fakt1(15 downto 8) <= RegBusB(15 downto 8); + end if; + else + MULU_Prod32(15 downto 0) <= RegBusA; + MULU_Prod32(31 downto 16) <= X"0000"; + MULU_Fakt1 <= RegBusB; + end if; + else + MULU_Prod32 <= MULU_tmp; + end if; + end if; + end if; + end process; + --------------------------------------------------------------------------- -- -- BC('), DE('), HL('), IX and IY @@ -837,7 +954,7 @@ begin if I_DJNZ = '1' and Save_ALU_r = '1' and Mode < 2 then IncDecZ <= F_Out(Flag_Z); end if; - if (TState = 2 or (TState = 3 and MCycle = "001")) and IncDec_16(2 downto 0) = "100" then + if ((TState = 2 and Wait_n = '1') or (TState = 3 and MCycle = "001")) and IncDec_16(2 downto 0) = "100" then if ID16 = 0 then IncDecZ <= '0'; else @@ -858,7 +975,9 @@ begin (TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and IncDec_16(1 downto 0) = "10" else -- EX HL,DL Alternate & "10" when ExchangeDH = '1' and TState = 3 else - Alternate & "01" when ExchangeDH = '1' and TState = 4 else + Alternate & "01" when (ExchangeDH = '1' or I_MULU = '1') and TState = 4 else + -- LDHLSP + "010" when LDHLSP = '1' and TState = 4 else -- Bus A / Write RegAddrA_r; @@ -871,8 +990,8 @@ begin ID16 <= signed(RegBusA) - 1 when IncDec_16(3) = '1' else signed(RegBusA) + 1; - process (Save_ALU_r, Auto_Wait_t1, ALU_OP_r, Read_To_Reg_r, - ExchangeDH, IncDec_16, MCycle, TState, Wait_n) + 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) begin RegWEH <= '0'; RegWEL <= '0'; @@ -886,11 +1005,21 @@ begin end case; end if; + if I_MULU = '1' and (T_Res = '1' or TState = 4) then -- TState = 4 DE write + RegWEH <= '1'; + RegWEL <= '1'; + end if; + if ExchangeDH = '1' and (TState = 3 or TState = 4) then RegWEH <= '1'; RegWEL <= '1'; end if; + if LDHLSP = '1' and MCycle = "010" and TState = 4 then + RegWEH <= '1'; + RegWEL <= '1'; + end if; + if IncDec_16(2) = '1' and ((TState = 2 and Wait_n = '1' and MCycle /= "001") or (TState = 3 and MCycle = "001")) then case IncDec_16(1 downto 0) is when "00" | "01" | "10" => @@ -901,12 +1030,29 @@ begin end if; end process; - process (Save_Mux, RegBusB, RegBusA_r, ID16, - ExchangeDH, IncDec_16, MCycle, TState, Wait_n) + 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) begin RegDIH <= Save_Mux; RegDIL <= Save_Mux; + if I_MULU = '1' then + if T_Res = '1' then + RegDIH <= MULU_Prod32(31 downto 24); + RegDIL <= MULU_Prod32(23 downto 16); + else + RegDIH <= MULU_tmp(15 downto 8); -- TState = 4 DE write + RegDIL <= MULU_tmp(7 downto 0); + end if; + end if; + + if LDHLSP = '1' and MCycle = "010" and TState = 4 then + RegDIH <= TmpAddr2(15 downto 8); + RegDIL <= TmpAddr2(7 downto 0); + end if; + if ExchangeDH = '1' and TState = 3 then RegDIH <= RegBusB(15 downto 8); RegDIL <= RegBusB(7 downto 0); @@ -916,7 +1062,7 @@ begin RegDIL <= RegBusA_r(7 downto 0); end if; - if IncDec_16(2) = '1' and ((TState = 2 and MCycle /= "001") or (TState = 3 and MCycle = "001")) then + if IncDec_16(2) = '1' and ((TState = 2 and MCycle /= "001" and Wait_n = '1') or (TState = 3 and MCycle = "001")) then RegDIH <= std_logic_vector(ID16(15 downto 8)); RegDIL <= std_logic_vector(ID16(7 downto 0)); end if; @@ -1029,6 +1175,9 @@ begin else RFSH_n <= '1'; end if; + if (TState = 1 and (NoRead_int = '0' and IORQ_i = '0')) or (TState = 3 and MCycle = "001") then + ABus_last <= ABus; + end if; end if; end if; end process; @@ -1042,6 +1191,10 @@ begin IntE <= IntE_FF1; IORQ <= IORQ_i; Stop <= I_DJNZ; + NoRead <= NoRead_int; + Write <= Write_int; + A <= ABus when (Mode > 1) or (NoRead_int = '0' or Write_int = '1') else ABus_last; + ------------------------------------------------------------------------- -- @@ -1090,7 +1243,7 @@ begin No_BTR <= (I_BT and (not IR(4) or not F(Flag_P))) or (I_BC and (not IR(4) or F(Flag_Z) or not F(Flag_P))) or (I_BTR and (not IR(4) or F(Flag_Z))); - if TState = 2 then + if TState = 2 and Wait_n = '1' then if SetEI = '1' then IntE_FF1 <= '1'; IntE_FF2 <= '1'; @@ -1116,7 +1269,7 @@ begin BusAck <= '0'; if TState = 2 and Wait_n = '0' then elsif T_Res = '1' then - if Halt = '1' then + if Halt = '1' and ( not(Mode = 3 and INT_n = '0' and IntE_FF1 = '0')) then -- halt bug when Mode = 3 , INT_n = '0' and IME=0 Halt_FF <= '1'; end if; if BusReq_s = '1' then @@ -1144,6 +1297,8 @@ begin IntCycle <= '1'; IntE_FF1 <= '0'; IntE_FF2 <= '0'; + elsif (Halt_FF = '1' and INT_n = '0' and Mode = 3) then + Halt_FF <= '0'; end if; else MCycle <= std_logic_vector(unsigned(MCycle) + 1); diff --git a/common/CPU/T80/T80_ALU.vhd b/common/CPU/T80/T80_ALU.vhd index a9438aed..1192e0b9 100644 --- a/common/CPU/T80/T80_ALU.vhd +++ b/common/CPU/T80/T80_ALU.vhd @@ -89,6 +89,7 @@ entity T80_ALU is WZ : in std_logic_vector(15 downto 0); XY_State : in std_logic_vector(1 downto 0); ALU_Op : in std_logic_vector(3 downto 0); + Rot_Akku : in std_logic; IR : in std_logic_vector(5 downto 0); ISet : in std_logic_vector(1 downto 0); BusA : in std_logic_vector(7 downto 0); @@ -158,7 +159,7 @@ begin end if; end process; - process (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16, WZ, XY_State) + process (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16, Rot_Akku, WZ, XY_State) variable Q_t : std_logic_vector(7 downto 0); variable DAA_Q : unsigned(8 downto 0); begin @@ -220,35 +221,64 @@ begin end if; when "1100" => -- DAA - F_Out(Flag_H) <= F_In(Flag_H); - F_Out(Flag_C) <= F_In(Flag_C); - DAA_Q(7 downto 0) := unsigned(BusA); - DAA_Q(8) := '0'; - if F_In(Flag_N) = '0' then - -- After addition - -- Alow > 9 or H = 1 - if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then - if (DAA_Q(3 downto 0) > 9) then - F_Out(Flag_H) <= '1'; - else - F_Out(Flag_H) <= '0'; + if Mode = 3 then + F_Out(Flag_H) <= '0'; + F_Out(Flag_C) <= F_In(Flag_C); + DAA_Q(7 downto 0) := unsigned(BusA); + DAA_Q(8) := '0'; + if F_In(Flag_N) = '0' then + -- After addition + -- Alow > 9 or H = 1 + if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then + DAA_Q := DAA_Q + 6; + end if; + -- new Ahigh > 9 or C = 1 + if DAA_Q(8 downto 4) > 9 or F_In(Flag_C) = '1' then + DAA_Q := DAA_Q + 96; -- 0x60 + end if; + else + -- After subtraction + if F_In(Flag_H) = '1' then + DAA_Q := DAA_Q - 6; + if F_In(Flag_C) = '0' then + DAA_Q(8) := '0'; + end if; + end if; + if F_In(Flag_C) = '1' then + DAA_Q := DAA_Q - 96; -- 0x60 end if; - DAA_Q := DAA_Q + 6; - end if; - -- new Ahigh > 9 or C = 1 - if DAA_Q(8 downto 4) > 9 or F_In(Flag_C) = '1' then - DAA_Q := DAA_Q + 96; -- 0x60 end if; else - -- After subtraction - if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then - if DAA_Q(3 downto 0) > 5 then - F_Out(Flag_H) <= '0'; + F_Out(Flag_H) <= F_In(Flag_H); + F_Out(Flag_C) <= F_In(Flag_C); + DAA_Q(7 downto 0) := unsigned(BusA); + DAA_Q(8) := '0'; + if F_In(Flag_N) = '0' then + -- After addition + -- Alow > 9 or H = 1 + if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then + if (DAA_Q(3 downto 0) > 9) then + F_Out(Flag_H) <= '1'; + else + F_Out(Flag_H) <= '0'; + end if; + DAA_Q := DAA_Q + 6; + end if; + -- new Ahigh > 9 or C = 1 + if DAA_Q(8 downto 4) > 9 or F_In(Flag_C) = '1' then + DAA_Q := DAA_Q + 96; -- 0x60 + end if; + else + -- After subtraction + if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then + if DAA_Q(3 downto 0) > 5 then + F_Out(Flag_H) <= '0'; + end if; + DAA_Q(7 downto 0) := DAA_Q(7 downto 0) - 6; + end if; + if unsigned(BusA) > 153 or F_In(Flag_C) = '1' then + DAA_Q := DAA_Q - 352; -- 0x160 end if; - DAA_Q(7 downto 0) := DAA_Q(7 downto 0) - 6; - end if; - if unsigned(BusA) > 153 or F_In(Flag_C) = '1' then - DAA_Q := DAA_Q - 352; -- 0x160 end if; end if; F_Out(Flag_X) <= DAA_Q(3); @@ -368,6 +398,9 @@ begin F_Out(Flag_S) <= F_In(Flag_S); F_Out(Flag_Z) <= F_In(Flag_Z); end if; + if Mode = 3 and Rot_Akku = '1' then + F_Out(Flag_Z) <= '0'; + end if; when others => null; end case; diff --git a/common/CPU/T80/T80_MCode.vhd b/common/CPU/T80/T80_MCode.vhd index 9fc1af7b..bdd9b0ea 100644 --- a/common/CPU/T80/T80_MCode.vhd +++ b/common/CPU/T80/T80_MCode.vhd @@ -19,7 +19,7 @@ -- **** -- Z80 compatible microprocessor core -- --- Version : 0242 +-- Version : 0250 -- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) -- All rights reserved -- @@ -69,6 +69,7 @@ -- 0240 : Added (IX/IY+d) states, removed op-codes from mode 2 and added all remaining mode 3 op-codes -- 0240mj1 fix for HL inc/dec for INI, IND, INIR, INDR, OUTI, OUTD, OTIR, OTDR -- 0242 : Fixed I/O instruction timing, cleanup +-- 0250 : Added R800 Multiplier by TobiFlex 2017.10.15 -- library IEEE; @@ -109,6 +110,7 @@ entity T80_MCode is ALU_Op : out std_logic_vector(3 downto 0); -- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None Save_ALU : out std_logic; + Rot_Akku : out std_logic; PreserveC : out std_logic; Arith16 : out std_logic; Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI @@ -121,6 +123,8 @@ entity T80_MCode is LDZ : out std_logic; LDW : out std_logic; LDSPHL : out std_logic; + LDHLSP : out std_logic; + ADDSPdd : out std_logic; Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None ExchangeDH : out std_logic; ExchangeRp : out std_logic; @@ -137,6 +141,8 @@ entity T80_MCode is I_RLD : out std_logic; I_RRD : out std_logic; I_INRC : out std_logic; + I_MULUB : out std_logic; + I_MULU : out std_logic; SetWZ : out std_logic_vector(1 downto 0); SetDI : out std_logic; SetEI : out std_logic; @@ -144,7 +150,8 @@ entity T80_MCode is Halt : out std_logic; NoRead : out std_logic; Write : out std_logic; - XYbit_undoc : out std_logic + XYbit_undoc : out std_logic; + R800_mode : in std_logic ); end T80_MCode; @@ -157,10 +164,10 @@ architecture rtl of T80_MCode is begin if Mode = 3 then case cc is - when "000" => return F(Flag_S) = '0'; -- NZ - when "001" => return F(Flag_S) = '1'; -- Z - when "010" => return F(Flag_H) = '0'; -- NC - when "011" => return F(Flag_H) = '1'; -- C + when "000" => return F(Flag_Z) = '0'; -- NZ + when "001" => return F(Flag_Z) = '1'; -- Z + when "010" => return F(Flag_C) = '0'; -- NC + when "011" => return F(Flag_C) = '1'; -- C when "100" => return false; when "101" => return false; when "110" => return false; @@ -182,7 +189,7 @@ architecture rtl of T80_MCode is begin - process (IR, ISet, MCycle, F, NMICycle, IntCycle, XY_State) + process (IR, ISet, MCycle, F, NMICycle, IntCycle, XY_State, R800_mode) variable DDD : std_logic_vector(2 downto 0); variable SSS : std_logic_vector(2 downto 0); variable DPair : std_logic_vector(1 downto 0); @@ -209,6 +216,7 @@ begin Set_BusA_To <= "0000"; ALU_Op <= "0" & IR(5 downto 3); Save_ALU <= '0'; + Rot_Akku <= '0'; PreserveC <= '0'; Arith16 <= '0'; IORQ <= '0'; @@ -221,6 +229,8 @@ begin LDZ <= '0'; LDW <= '0'; LDSPHL <= '0'; + LDHLSP <= '0'; + ADDSPdd <= '0'; Special_LD <= "000"; ExchangeDH <= '0'; ExchangeRp <= '0'; @@ -237,6 +247,8 @@ begin I_RLD <= '0'; I_RRD <= '0'; I_INRC <= '0'; + I_MULUB <= '0'; + I_MULU <= '0'; SetDI <= '0'; SetEI <= '0'; IMode <= "11"; @@ -513,38 +525,76 @@ begin end if; when "11111001" => -- LD SP,HL - TStates <= "110"; - LDSPHL <= '1'; + if Mode = 3 then + MCycles <= "010"; + if MCycle = "010" then + LDSPHL <= '1'; + end if; + else + TStates <= "110"; + LDSPHL <= '1'; + end if; when "11000101"|"11010101"|"11100101"|"11110101" => -- PUSH qq - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - TStates <= "101"; - IncDec_16 <= "1111"; - Set_Addr_TO <= aSP; - if DPAIR = "11" then - Set_BusB_To <= "0111"; - else - Set_BusB_To(2 downto 1) <= DPAIR; - Set_BusB_To(0) <= '0'; - Set_BusB_To(3) <= '0'; - end if; - when 2 => - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - if DPAIR = "11" then - Set_BusB_To <= "1011"; - else - Set_BusB_To(2 downto 1) <= DPAIR; - Set_BusB_To(0) <= '1'; - Set_BusB_To(3) <= '0'; - end if; - Write <= '1'; - when 3 => - Write <= '1'; - when others => null; - end case; + if Mode = 3 then + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + TStates <= "101"; + IncDec_16 <= "1111"; + Set_Addr_TO <= aSP; + if DPAIR = "11" then + Set_BusB_To <= "0111"; + else + Set_BusB_To(2 downto 1) <= DPAIR; + Set_BusB_To(0) <= '0'; + Set_BusB_To(3) <= '0'; + end if; + when 3 => + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + if DPAIR = "11" then + Set_BusB_To <= "1011"; + else + Set_BusB_To(2 downto 1) <= DPAIR; + Set_BusB_To(0) <= '1'; + Set_BusB_To(3) <= '0'; + end if; + Write <= '1'; + when 4 => + Write <= '1'; + when others => null; + end case; + else + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + IncDec_16 <= "1111"; + Set_Addr_TO <= aSP; + if DPAIR = "11" then + Set_BusB_To <= "0111"; + else + Set_BusB_To(2 downto 1) <= DPAIR; + Set_BusB_To(0) <= '0'; + Set_BusB_To(3) <= '0'; + end if; + when 2 => + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + if DPAIR = "11" then + Set_BusB_To <= "1011"; + else + Set_BusB_To(2 downto 1) <= DPAIR; + Set_BusB_To(0) <= '1'; + Set_BusB_To(3) <= '0'; + end if; + Write <= '1'; + when 3 => + Write <= '1'; + when others => null; + end case; + end if; when "11000001"|"11010001"|"11100001"|"11110001" => -- POP qq MCycles <= "011"; @@ -608,7 +658,7 @@ begin when "11011001" => if Mode = 3 then -- RETI - MCycles <= "011"; + MCycles <= "100"; case to_integer(unsigned(MCycle)) is when 1 => Set_Addr_TO <= aSP; @@ -619,7 +669,7 @@ begin when 3 => Jump <= '1'; IncDec_16 <= "0111"; - I_RETN <= '1'; + --I_RETN <= '1'; SetEI <= '1'; when others => null; end case; @@ -809,30 +859,50 @@ begin end case; elsif IntCycle = '1' then -- INT (IM 2) - MCycles <= "101"; - case to_integer(unsigned(MCycle)) is - when 1 => - LDZ <= '1'; - TStates <= "101"; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1101"; - when 2 => - --TStates <= "100"; - Write <= '1'; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1100"; - when 3 => - --TStates <= "100"; - Write <= '1'; - when 4 => - Inc_PC <= '1'; - LDZ <= '1'; - when 5 => - Jump <= '1'; - when others => null; - end case; + if mode = 3 then + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 1 => + LDZ <= '1'; + TStates <= "110"; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1101"; + when 2 => + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 3 => + Write <= '1'; + when others => null; + end case; + else + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 1 => + LDZ <= '1'; + TStates <= "101"; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1101"; + when 2 => + --TStates <= "100"; + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 3 => + --TStates <= "100"; + Write <= '1'; + when 4 => + Inc_PC <= '1'; + LDZ <= '1'; + when 5 => + Jump <= '1'; + when others => null; + end case; + end if; else -- NOP end if; @@ -849,49 +919,105 @@ begin -- 16 BIT ARITHMETIC GROUP when "00001001"|"00011001"|"00101001"|"00111001" => -- ADD HL,ss - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - NoRead <= '1'; - ALU_Op <= "0000"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_BusA_To(2 downto 0) <= "101"; - case to_integer(unsigned(IR(5 downto 4))) is - when 0|1|2 => - Set_BusB_To(2 downto 1) <= IR(5 downto 4); - Set_BusB_To(0) <= '1'; + if Mode = 3 then + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + NoRead <= '1'; + ALU_Op <= "0000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusA_To(2 downto 0) <= "101"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '1'; + when others => + Set_BusB_To <= "1000"; + end case; + TStates <= "100"; + Arith16 <= '1'; + SetWZ <= "11"; + when 2 => + NoRead <= '1'; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0001"; + Set_BusA_To(2 downto 0) <= "100"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + when others => + Set_BusB_To <= "1001"; + end case; + Arith16 <= '1'; when others => - Set_BusB_To <= "1000"; end case; - TStates <= "100"; - Arith16 <= '1'; - SetWZ <= "11"; - when 3 => - NoRead <= '1'; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - ALU_Op <= "0001"; - Set_BusA_To(2 downto 0) <= "100"; - case to_integer(unsigned(IR(5 downto 4))) is - when 0|1|2 => - Set_BusB_To(2 downto 1) <= IR(5 downto 4); + else + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + NoRead <= '1'; + ALU_Op <= "0000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusA_To(2 downto 0) <= "101"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '1'; + when others => + Set_BusB_To <= "1000"; + end case; + TStates <= "100"; + Arith16 <= '1'; + SetWZ <= "11"; + when 3 => + NoRead <= '1'; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0001"; + Set_BusA_To(2 downto 0) <= "100"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + when others => + Set_BusB_To <= "1001"; + end case; + Arith16 <= '1'; when others => - Set_BusB_To <= "1001"; end case; - Arith16 <= '1'; - when others => - end case; + end if; when "00000011"|"00010011"|"00100011"|"00110011" => -- INC ss - TStates <= "110"; - IncDec_16(3 downto 2) <= "01"; - IncDec_16(1 downto 0) <= DPair; + if Mode = 3 then + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 2 => + IncDec_16(3 downto 2) <= "01"; + IncDec_16(1 downto 0) <= DPair; + when others => + end case; + else + TStates <= "110"; + IncDec_16(3 downto 2) <= "01"; + IncDec_16(1 downto 0) <= DPair; + end if; when "00001011"|"00011011"|"00101011"|"00111011" => -- DEC ss - TStates <= "110"; - IncDec_16(3 downto 2) <= "11"; - IncDec_16(1 downto 0) <= DPair; + if Mode = 3 then + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 2 => + IncDec_16(3 downto 2) <= "11"; + IncDec_16(1 downto 0) <= DPair; + when others => + end case; + else + TStates <= "110"; + IncDec_16(3 downto 2) <= "11"; + IncDec_16(1 downto 0) <= DPair; + end if; -- ROTATE AND SHIFT GROUP when "00000111" @@ -905,12 +1031,17 @@ begin Set_BusA_To(2 downto 0) <= "111"; ALU_Op <= "1000"; Read_To_Reg <= '1'; + Rot_Akku <= '1'; Save_ALU <= '1'; -- JUMP GROUP when "11000011" => -- JP nn - MCycles <= "011"; + if Mode = 3 then + MCycles <= "100"; + else + MCycles <= "011"; + end if; case to_integer(unsigned(MCycle)) is when 2 => Inc_PC <= '1'; @@ -918,7 +1049,9 @@ begin when 3 => Inc_PC <= '1'; Jump <= '1'; - LDW <= '1'; + if Mode /= 3 then + LDW <= '1'; + end if; when others => null; end case; when "11000010"|"11001010"|"11010010"|"11011010"|"11100010"|"11101010"|"11110010"|"11111010" => @@ -931,9 +1064,9 @@ begin when 1 => Set_Addr_To <= aBC; Set_BusB_To <= "0111"; + IORQ <= '1'; --TH must be earlier to be stable when address is generated when 2 => Write <= '1'; - IORQ <= '1'; when others => end case; when "01" => @@ -957,9 +1090,9 @@ begin case to_integer(unsigned(MCycle)) is when 1 => Set_Addr_To <= aBC; + IORQ <= '1'; --TH must be earlier to be stable when address is generated when 2 => Read_To_Acc <= '1'; - IORQ <= '1'; when others => end case; when "11" => @@ -979,16 +1112,24 @@ begin end case; else -- JP cc,nn - MCycles <= "011"; + if Mode = 3 then + MCycles <= "100"; + else + MCycles <= "011"; + end if; case to_integer(unsigned(MCycle)) is when 2 => Inc_PC <= '1'; LDZ <= '1'; when 3 => - LDW <= '1'; + if Mode /= 3 then + LDW <= '1'; + end if; Inc_PC <= '1'; if is_cc_true(F, to_bitvector(IR(5 downto 3))) then Jump <= '1'; + elsif Mode = 3 then + MCycles <= "011"; end if; when others => null; end case; @@ -1078,9 +1219,15 @@ begin when "11101001" => -- JP (HL) JumpXY <= '1'; - when "00010000" => - if Mode = 3 then + when "00010000" => + if Mode = 3 then -- STOP and skip next byte + MCycles <= "010"; I_DJNZ <= '1'; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + when others => null; + end case; elsif Mode < 2 then -- DJNZ,e MCycles <= "011"; @@ -1107,7 +1254,11 @@ begin -- CALL AND RETURN GROUP when "11001101" => -- CALL nn - MCycles <= "101"; + if Mode = 3 then + MCycles <= "110"; + else + MCycles <= "101"; + end if; case to_integer(unsigned(MCycle)) is when 2 => Inc_PC <= '1'; @@ -1132,7 +1283,11 @@ begin when "11000100"|"11001100"|"11010100"|"11011100"|"11100100"|"11101100"|"11110100"|"11111100" => if IR(5) = '0' or Mode /= 3 then -- CALL cc,nn - MCycles <= "101"; + if Mode = 3 then + MCycles <= "110"; + else + MCycles <= "101"; + end if; case to_integer(unsigned(MCycle)) is when 2 => Inc_PC <= '1'; @@ -1161,20 +1316,36 @@ begin end if; when "11001001" => -- RET - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - --TStates <= "101"; - Set_Addr_TO <= aSP; - when 2 => - IncDec_16 <= "0111"; - Set_Addr_To <= aSP; - LDZ <= '1'; - when 3 => - Jump <= '1'; - IncDec_16 <= "0111"; - when others => null; - end case; + if Mode = 3 then + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + Set_Addr_TO <= aSP; + when 3 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + LDZ <= '1'; + when 4 => + Jump <= '1'; + IncDec_16 <= "0111"; + when others => null; + end case; + else + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + --TStates <= "101"; + Set_Addr_TO <= aSP; + when 2 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + LDZ <= '1'; + when 3 => + Jump <= '1'; + IncDec_16 <= "0111"; + when others => null; + end case; + end if; when "11000000"|"11001000"|"11010000"|"11011000"|"11100000"|"11101000"|"11110000"|"11111000" => if IR(5) = '1' and Mode = 3 then case IRB(4 downto 3) is @@ -1192,22 +1363,11 @@ begin end case; when "01" => -- ADD SP,n - MCycles <= "011"; + MCycles <= "100"; case to_integer(unsigned(MCycle)) is - when 2 => - ALU_Op <= "0000"; - Inc_PC <= '1'; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_BusA_To <= "1000"; - Set_BusB_To <= "0110"; when 3 => - NoRead <= '1'; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - ALU_Op <= "0001"; - Set_BusA_To <= "1001"; - Set_BusB_To <= "1110"; -- Incorrect unsigned !!!!!!!!!!!!!!!!!!!!! + Inc_PC <= '1'; + ADDSPdd <= '1'; when others => end case; when "10" => @@ -1222,67 +1382,100 @@ begin when others => null; end case; when "11" => - -- LD HL,SP+n -- Not correct !!!!!!!!!!!!!!!!!!! - MCycles <= "101"; + -- LD HL,SP+n + MCycles <= "011"; case to_integer(unsigned(MCycle)) is + when 1 => + Inc_PC <= '1'; when 2 => + LDHLSP <= '1'; Inc_PC <= '1'; - LDZ <= '1'; when 3 => - Set_Addr_To <= aZI; - Inc_PC <= '1'; - LDW <= '1'; - when 4 => - Set_BusA_To(2 downto 0) <= "101"; -- L - Read_To_Reg <= '1'; - Inc_WZ <= '1'; - Set_Addr_To <= aZI; - when 5 => - Set_BusA_To(2 downto 0) <= "100"; -- H - Read_To_Reg <= '1'; + LDHLSP <= '1'; when others => null; end case; end case; else -- RET cc - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - if is_cc_true(F, to_bitvector(IR(5 downto 3))) then - Set_Addr_TO <= aSP; - else - MCycles <= "001"; - end if; - TStates <= "101"; - when 2 => - IncDec_16 <= "0111"; - Set_Addr_To <= aSP; - LDZ <= '1'; - when 3 => - Jump <= '1'; - IncDec_16 <= "0111"; - when others => null; - end case; + if Mode = 3 then + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + if is_cc_true(F, to_bitvector(IR(5 downto 3))) then + Set_Addr_TO <= aSP; + else + MCycles <= "010"; + end if; + TStates <= "101"; + when 3 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + LDZ <= '1'; + when 4 => + Jump <= '1'; + IncDec_16 <= "0111"; + when others => null; + end case; + else + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + if is_cc_true(F, to_bitvector(IR(5 downto 3))) then + Set_Addr_TO <= aSP; + else + MCycles <= "001"; + end if; + TStates <= "101"; + when 2 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + LDZ <= '1'; + when 3 => + Jump <= '1'; + IncDec_16 <= "0111"; + when others => null; + end case; + end if; end if; when "11000111"|"11001111"|"11010111"|"11011111"|"11100111"|"11101111"|"11110111"|"11111111" => -- RST p - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - TStates <= "101"; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1101"; - when 2 => - Write <= '1'; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1100"; - when 3 => - Write <= '1'; - RstP <= '1'; - when others => null; - end case; + if Mode = 3 then + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + TStates <= "101"; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1101"; + when 3 => + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 4 => + Write <= '1'; + RstP <= '1'; + when others => null; + end case; + else + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1101"; + when 2 => + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 3 => + Write <= '1'; + RstP <= '1'; + when others => null; + end case; + end if; -- INPUT AND OUTPUT GROUP when "11011011" => @@ -1582,16 +1775,16 @@ begin | "10101100"|"10101101"|"10101110"|"10101111" | "10110100"|"10110101"|"10110110"|"10110111" | "10111100"|"10111101"|"10111110"|"10111111" - |"11000000"|"11000001"|"11000010"|"11000011"|"11000100"|"11000101"|"11000110"|"11000111" - |"11001000"|"11001001"|"11001010"|"11001011"|"11001100"|"11001101"|"11001110"|"11001111" - |"11010000"|"11010001"|"11010010"|"11010011"|"11010100"|"11010101"|"11010110"|"11010111" - |"11011000"|"11011001"|"11011010"|"11011011"|"11011100"|"11011101"|"11011110"|"11011111" + |"11000000"| "11000010" |"11000100"|"11000101"|"11000110"|"11000111" + |"11001000"| "11001010"|"11001011"|"11001100"|"11001101"|"11001110"|"11001111" + |"11010000"| "11010010"|"11010011"|"11010100"|"11010101"|"11010110"|"11010111" + |"11011000"| "11011010"|"11011011"|"11011100"|"11011101"|"11011110"|"11011111" |"11100000"|"11100001"|"11100010"|"11100011"|"11100100"|"11100101"|"11100110"|"11100111" |"11101000"|"11101001"|"11101010"|"11101011"|"11101100"|"11101101"|"11101110"|"11101111" - |"11110000"|"11110001"|"11110010"|"11110011"|"11110100"|"11110101"|"11110110"|"11110111" + |"11110000"|"11110001"|"11110010" |"11110100"|"11110101"|"11110110"|"11110111" |"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111110"|"11111111" => null; -- NOP, undocumented - when "01111110"|"01111111" => + when "01110111"|"01111111" => -- NOP, undocumented null; -- 8 BIT LOAD GROUP @@ -1747,7 +1940,7 @@ begin when "01010110"|"01110110" => -- IM 1 IMode <= "01"; - when "01011110"|"01110111" => + when "01011110"|"01111110" => -- IM 2 IMode <= "10"; -- 16 bit arithmetic @@ -1972,6 +2165,46 @@ begin TStates <= "101"; when others => null; end case; + when "11000001"|"11001001"|"11010001"|"11011001" => + --R800 MULUB + if R800_mode = '1' then + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + NoRead <= '1'; + I_MULUB <= '1'; + Set_BusB_To(2 downto 0) <= IR(5 downto 3); + Set_BusB_To(3) <= '0'; + when 2 => + NoRead <= '1'; + I_MULU <= '1'; + Set_BusA_To(2 downto 0) <= "100"; + when others => null; + end case; + end if; + when "11000011"|"11110011" => + --R800 MULUW + if R800_mode = '1' then + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + NoRead <= '1'; + if DPAIR = "11" then + Set_BusB_To(3 downto 0) <= "1000"; + else + Set_BusB_To(2 downto 1) <= DPAIR; + Set_BusB_To(0) <= '0'; + Set_BusB_To(3) <= '0'; + end if; + Set_BusA_To(2 downto 0) <= "100"; + when 2 => + TStates <= "101"; + NoRead <= '1'; + I_MULU <= '1'; + Set_BusA_To(2 downto 0) <= "100"; + when others => null; + end case; + end if; end case; end case; diff --git a/common/CPU/T80/T80_Pack.vhd b/common/CPU/T80/T80_Pack.vhd index fc6a5a93..fd9eebb5 100644 --- a/common/CPU/T80/T80_Pack.vhd +++ b/common/CPU/T80/T80_Pack.vhd @@ -11,7 +11,7 @@ -- -- Z80 compatible microprocessor core -- --- Version : 0242 +-- Version : 0250 -- -- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) -- @@ -105,6 +105,7 @@ package T80_Pack is IntCycle_n : out std_logic; IntE : out std_logic; Stop : out std_logic; + R800_mode : in std_logic := '0'; out0 : in std_logic := '0'; -- 0 => OUT(C),0, 1 => OUT(C),255 REG : out std_logic_vector(211 downto 0); -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A DIRSet : in std_logic := '0'; @@ -168,6 +169,7 @@ package T80_Pack is ALU_Op : out std_logic_vector(3 downto 0); -- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None Save_ALU : out std_logic; + Rot_Akku : out std_logic; PreserveC : out std_logic; Arith16 : out std_logic; Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI @@ -180,6 +182,8 @@ package T80_Pack is LDZ : out std_logic; LDW : out std_logic; LDSPHL : out std_logic; + LDHLSP : out std_logic; + ADDSPdd : out std_logic; Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None ExchangeDH : out std_logic; ExchangeRp : out std_logic; @@ -196,6 +200,8 @@ package T80_Pack is I_RLD : out std_logic; I_RRD : out std_logic; I_INRC : out std_logic; + I_MULUB : out std_logic; + I_MULU : out std_logic; SetWZ : out std_logic_vector(1 downto 0); SetDI : out std_logic; SetEI : out std_logic; @@ -203,7 +209,8 @@ package T80_Pack is Halt : out std_logic; NoRead : out std_logic; Write : out std_logic; - XYbit_undoc : out std_logic + XYbit_undoc : out std_logic; + R800_mode : in std_logic ); end component; @@ -225,6 +232,7 @@ package T80_Pack is WZ : in std_logic_vector(15 downto 0); XY_State : in std_logic_vector(1 downto 0); ALU_Op : in std_logic_vector(3 downto 0); + Rot_Akku : in std_logic; IR : in std_logic_vector(5 downto 0); ISet : in std_logic_vector(1 downto 0); BusA : in std_logic_vector(7 downto 0); diff --git a/common/CPU/T80/T80a.vhd b/common/CPU/T80/T80a.vhd index 75636aa4..2103a5c9 100644 --- a/common/CPU/T80/T80a.vhd +++ b/common/CPU/T80/T80a.vhd @@ -10,7 +10,7 @@ -- -- Z80 compatible microprocessor core, asynchronous top level -- --- Version : 0247 +-- Version : 0250 -- -- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) -- @@ -67,6 +67,11 @@ -- -- 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 +-- library IEEE; use IEEE.std_logic_1164.all; @@ -75,10 +80,12 @@ use work.T80_Pack.all; entity T80a is generic( - Mode : integer := 0 -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + 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 ); port( RESET_n : in std_logic; + R800_mode : in std_logic; CLK_n : in std_logic; WAIT_n : in std_logic; INT_n : in std_logic; @@ -92,8 +99,8 @@ entity T80a is 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) + A : out std_logic_vector(15 downto 0); + D : inout std_logic_vector(7 downto 0) ); end T80a; @@ -107,12 +114,14 @@ 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 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 RFSH_n_i : std_logic; signal BUSAK_n_i : std_logic; signal A_i : std_logic_vector(15 downto 0); @@ -129,11 +138,12 @@ begin 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 MREQ_n <= MREQ_n_i when BUSAK_n_i = '1' else 'Z'; - IORQ_n <= IORQ_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'); @@ -150,8 +160,9 @@ begin u0 : T80 generic map( Mode => Mode, - IOWait => 1) + IOWait => IOWait) port map( + R800_mode => R800_mode, CEN => CEN, M1_n => M1_n, IORQ => IORQ, @@ -184,24 +195,40 @@ begin end if; end process; - process (Reset_s,CLK_n) + process (CLK_n) -- 0247a + begin + if CLK_n'event and CLK_n = '1' then + IReq_Inhibit <= not IORQ; + 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 = '1' then - WR_n_i <= '1'; - if TState = "001" then -- To short for IO writes !!!!!!!!!!!!!!!!!!! - WR_n_i <= not Write; + 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; - process (Reset_s,CLK_n) + 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" then + if MCycle = "001" and TState = "010" and wait_s = '1' then Req_Inhibit <= '1'; else Req_Inhibit <= '0'; @@ -246,9 +273,13 @@ begin end if; else if TState = "001" and NoRead = '0' then - RD <= not Write; 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'; diff --git a/common/CPU/T80/T80pa.vhd b/common/CPU/T80/T80pa.vhd index 98e5c3a1..315623be 100644 --- a/common/CPU/T80/T80pa.vhd +++ b/common/CPU/T80/T80pa.vhd @@ -83,6 +83,7 @@ entity T80pa is A : out std_logic_vector(15 downto 0); DI : in std_logic_vector(7 downto 0); DO : out std_logic_vector(7 downto 0); + R800_mode : in std_logic := '0'; REG : out std_logic_vector(211 downto 0); -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A DIRSet : in std_logic := '0'; DIR : in std_logic_vector(211 downto 0) := (others => '0') -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A @@ -101,12 +102,9 @@ architecture rtl of T80pa is signal MCycle : std_logic_vector(2 downto 0); signal TState : std_logic_vector(2 downto 0); signal CEN_pol : std_logic; - signal A_int : std_logic_vector(15 downto 0); - signal A_last : std_logic_vector(15 downto 0); signal CEN : std_logic; begin - A <= A_int when NoRead = '0' or Write = '1' else A_last; CEN <= CEN_p and not CEN_pol; BUSAK_n <= BUSAK; @@ -130,7 +128,7 @@ begin BUSRQ_n => BUSRQ_n, BUSAK_n => BUSAK, CLK_n => CLK, - A => A_int, + A => A, DInst => DI, -- valid at beginning of T3 DI => DI_Reg, -- latched at middle of T3 DO => DO, @@ -138,6 +136,7 @@ begin MC => MCycle, TS => TState, OUT0 => OUT0, + R800_mode => R800_mode, IntCycle_n => IntCycle_n, DIRSet => DIRSet, DIR => DIR @@ -183,7 +182,6 @@ begin RD_n <= not IntCycle_n; MREQ_n <= not IntCycle_n; IORQ_n <= IntCycleD_n(1); - A_last <= A_int; end if; if TState = "011" then IntCycleD_n <= "11"; @@ -198,7 +196,6 @@ begin if TState = "001" then RD_n <= Write; MREQ_n <= '0'; - A_last <= A_int; end if; end if; if TState = "010" then