mirror of
https://github.com/UzixLS/TSConf_MiST.git
synced 2025-07-19 07:11:22 +03:00
update T80
This commit is contained in:
205
rtl/T80/GBse.vhd
Normal file
205
rtl/T80/GBse.vhd
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
-- ****
|
||||||
|
-- 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;
|
||||||
|
end if;
|
||||||
|
if TState = "011" then
|
||||||
|
MREQ_n <= '0';
|
||||||
|
end if;
|
||||||
|
elsif MCycle = "011" and IntCycle_n = '0' then
|
||||||
|
if TState = "001" then
|
||||||
|
IORQ_n <= '0'; -- Acknowledge IRQ
|
||||||
|
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;
|
58
rtl/T80/README
Normal file
58
rtl/T80/README
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- ****
|
||||||
|
-- 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
|
||||||
|
-- (*) Currently only SCF and CCF instructions aren't passed X/Y flags check as
|
||||||
|
-- correct implementation is still unclear.
|
||||||
|
--
|
||||||
|
-- ****
|
||||||
|
-- T80(b) core. In an effort to merge and maintain bug fixes ....
|
||||||
|
--
|
||||||
|
-- Ver 303 add undocumented DDCB and FDCB opcodes by TobiFlex 20.04.2010
|
||||||
|
-- Ver 301 parity flag is just parity for 8080, also overflow for Z80, by Sean Riddle
|
||||||
|
-- Ver 300 started tidyup.
|
||||||
|
--
|
||||||
|
-- MikeJ March 2005
|
||||||
|
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
|
||||||
|
--
|
||||||
|
-- ****
|
||||||
|
-- Z80 compatible microprocessor core
|
||||||
|
--
|
||||||
|
-- Version : 0250
|
||||||
|
-- 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.
|
||||||
|
--
|
@ -1,6 +1,13 @@
|
|||||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80s.vhd ]
|
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) 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 ]
|
||||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80_Reg.vhd ]
|
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80_Reg.vhd ]
|
||||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80_MCode.vhd ]
|
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80_MCode.vhd ]
|
||||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80_ALU.vhd ]
|
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80_ALU.vhd ]
|
||||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80.vhd ]
|
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80.vhd ]
|
||||||
|
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80_Pack.vhd ]
|
287
rtl/T80/T80.vhd
287
rtl/T80/T80.vhd
@ -21,7 +21,7 @@
|
|||||||
-- ****
|
-- ****
|
||||||
-- Z80 compatible microprocessor core
|
-- Z80 compatible microprocessor core
|
||||||
--
|
--
|
||||||
-- Version : 0247
|
-- Version : 0250
|
||||||
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
||||||
-- All rights reserved
|
-- All rights reserved
|
||||||
--
|
--
|
||||||
@ -73,12 +73,14 @@
|
|||||||
-- 0240 : Added interrupt ack fix by Mike Johnson, changed (IX/IY+d) timing and changed flags in GB mode
|
-- 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
|
-- 0242 : Added I/O wait, fixed refresh address, moved some registers to RAM
|
||||||
-- 0247 : Fixed bus req/ack cycle
|
-- 0247 : Fixed bus req/ack cycle
|
||||||
|
-- 0250 : Added R800 Multiplier by TobiFlex 2017.10.15
|
||||||
--
|
--
|
||||||
|
|
||||||
library IEEE;
|
library IEEE;
|
||||||
use IEEE.std_logic_1164.all;
|
use IEEE.std_logic_1164.all;
|
||||||
use IEEE.numeric_std.all;
|
use IEEE.numeric_std.all;
|
||||||
use IEEE.STD_LOGIC_UNSIGNED.all;
|
use IEEE.STD_LOGIC_UNSIGNED.all;
|
||||||
|
use work.T80_Pack.all;
|
||||||
|
|
||||||
entity T80 is
|
entity T80 is
|
||||||
generic(
|
generic(
|
||||||
@ -117,21 +119,17 @@ entity T80 is
|
|||||||
IntCycle_n : out std_logic;
|
IntCycle_n : out std_logic;
|
||||||
IntE : out std_logic;
|
IntE : out std_logic;
|
||||||
Stop : 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
|
out0 : in std_logic := '0'; -- 0 => OUT(C),0, 1 => OUT(C),255
|
||||||
REG : out std_logic_vector(207 downto 0) -- IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A
|
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
|
||||||
);
|
);
|
||||||
end T80;
|
end T80;
|
||||||
|
|
||||||
architecture rtl of T80 is
|
architecture rtl of T80 is
|
||||||
|
|
||||||
constant aNone : std_logic_vector(2 downto 0) := "111";
|
|
||||||
constant aBC : std_logic_vector(2 downto 0) := "000";
|
|
||||||
constant aDE : std_logic_vector(2 downto 0) := "001";
|
|
||||||
constant aXY : std_logic_vector(2 downto 0) := "010";
|
|
||||||
constant aIOA : std_logic_vector(2 downto 0) := "100";
|
|
||||||
constant aSP : std_logic_vector(2 downto 0) := "101";
|
|
||||||
constant aZI : std_logic_vector(2 downto 0) := "110";
|
|
||||||
|
|
||||||
-- Registers
|
-- Registers
|
||||||
signal ACC, F : std_logic_vector(7 downto 0);
|
signal ACC, F : std_logic_vector(7 downto 0);
|
||||||
signal Ap, Fp : std_logic_vector(7 downto 0);
|
signal Ap, Fp : std_logic_vector(7 downto 0);
|
||||||
@ -155,9 +153,13 @@ architecture rtl of T80 is
|
|||||||
|
|
||||||
-- Help Registers
|
-- Help Registers
|
||||||
signal WZ : std_logic_vector(15 downto 0); -- MEMPTR register
|
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 IR : std_logic_vector(7 downto 0); -- Instruction register
|
||||||
signal ISet : std_logic_vector(1 downto 0); -- Instruction set selector
|
signal ISet : std_logic_vector(1 downto 0); -- Instruction set selector
|
||||||
signal RegBusA_r : std_logic_vector(15 downto 0);
|
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 ID16 : signed(15 downto 0);
|
||||||
signal Save_Mux : std_logic_vector(7 downto 0);
|
signal Save_Mux : std_logic_vector(7 downto 0);
|
||||||
@ -167,8 +169,8 @@ architecture rtl of T80 is
|
|||||||
signal IntE_FF1 : std_logic;
|
signal IntE_FF1 : std_logic;
|
||||||
signal IntE_FF2 : std_logic;
|
signal IntE_FF2 : std_logic;
|
||||||
signal Halt_FF : std_logic;
|
signal Halt_FF : std_logic;
|
||||||
signal BusReq_s : std_logic;
|
signal BusReq_s : std_logic := '0';
|
||||||
signal BusAck : std_logic;
|
signal BusAck : std_logic := '0';
|
||||||
signal ClkEn : std_logic;
|
signal ClkEn : std_logic;
|
||||||
signal NMI_s : std_logic;
|
signal NMI_s : std_logic;
|
||||||
signal IStatus : std_logic_vector(1 downto 0);
|
signal IStatus : std_logic_vector(1 downto 0);
|
||||||
@ -216,6 +218,7 @@ architecture rtl of T80 is
|
|||||||
signal Set_BusA_To : std_logic_vector(3 downto 0);
|
signal Set_BusA_To : std_logic_vector(3 downto 0);
|
||||||
signal ALU_Op : std_logic_vector(3 downto 0);
|
signal ALU_Op : std_logic_vector(3 downto 0);
|
||||||
signal Save_ALU : std_logic;
|
signal Save_ALU : std_logic;
|
||||||
|
signal Rot_Akku : std_logic;
|
||||||
signal PreserveC : std_logic;
|
signal PreserveC : std_logic;
|
||||||
signal Arith16 : std_logic;
|
signal Arith16 : std_logic;
|
||||||
signal Set_Addr_To : std_logic_vector(2 downto 0);
|
signal Set_Addr_To : std_logic_vector(2 downto 0);
|
||||||
@ -227,12 +230,17 @@ architecture rtl of T80 is
|
|||||||
signal LDZ : std_logic;
|
signal LDZ : std_logic;
|
||||||
signal LDW : std_logic;
|
signal LDW : std_logic;
|
||||||
signal LDSPHL : std_logic;
|
signal LDSPHL : std_logic;
|
||||||
|
signal LDHLSP : std_logic;
|
||||||
|
signal ADDSPdd : std_logic;
|
||||||
signal IORQ_i : std_logic;
|
signal IORQ_i : std_logic;
|
||||||
|
signal Write_i : std_logic;
|
||||||
|
signal NoRead_i : std_logic;
|
||||||
signal Special_LD : std_logic_vector(2 downto 0);
|
signal Special_LD : std_logic_vector(2 downto 0);
|
||||||
signal ExchangeDH : std_logic;
|
signal ExchangeDH : std_logic;
|
||||||
signal ExchangeRp : std_logic;
|
signal ExchangeRp : std_logic;
|
||||||
signal ExchangeAF : std_logic;
|
signal ExchangeAF : std_logic;
|
||||||
signal ExchangeRS : std_logic;
|
signal ExchangeRS : std_logic;
|
||||||
|
signal ExchangeWH : std_logic;
|
||||||
signal I_DJNZ : std_logic;
|
signal I_DJNZ : std_logic;
|
||||||
signal I_CPL : std_logic;
|
signal I_CPL : std_logic;
|
||||||
signal I_CCF : std_logic;
|
signal I_CCF : std_logic;
|
||||||
@ -245,21 +253,26 @@ architecture rtl of T80 is
|
|||||||
signal I_RRD : std_logic;
|
signal I_RRD : std_logic;
|
||||||
signal I_RXDD : std_logic;
|
signal I_RXDD : std_logic;
|
||||||
signal I_INRC : 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 SetWZ : std_logic_vector(1 downto 0);
|
||||||
signal SetDI : std_logic;
|
signal SetDI : std_logic;
|
||||||
signal SetEI : std_logic;
|
signal SetEI : std_logic;
|
||||||
signal IMode : std_logic_vector(1 downto 0);
|
signal IMode : std_logic_vector(1 downto 0);
|
||||||
signal Halt : std_logic;
|
signal Halt : std_logic;
|
||||||
signal XYbit_undoc : std_logic;
|
signal XYbit_undoc : std_logic;
|
||||||
|
signal No_PC : std_logic;
|
||||||
signal DOR : std_logic_vector(127 downto 0);
|
signal DOR : std_logic_vector(127 downto 0);
|
||||||
|
|
||||||
|
signal Really_Wait : std_logic;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
REG <= DOR & std_logic_vector(PC) & std_logic_vector(SP) & std_logic_vector(R) & I & Fp & Ap & F & ACC when Alternate = '0'
|
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'
|
||||||
else DOR(127 downto 112) & DOR(47 downto 0) & DOR(63 downto 48) & DOR(111 downto 64) &
|
else IntE_FF2 & IntE_FF1 & IStatus & DOR(127 downto 112) & DOR(47 downto 0) & DOR(63 downto 48) & DOR(111 downto 64) &
|
||||||
std_logic_vector(PC) & std_logic_vector(SP) & std_logic_vector(R) & I & Fp & Ap & F & ACC;
|
std_logic_vector(PC) & std_logic_vector(SP) & std_logic_vector(R) & I & Fp & Ap & F & ACC;
|
||||||
|
|
||||||
mcode : work.T80_MCode
|
mcode : T80_MCode
|
||||||
generic map(
|
generic map(
|
||||||
Mode => Mode,
|
Mode => Mode,
|
||||||
Flag_C => Flag_C,
|
Flag_C => Flag_C,
|
||||||
@ -290,6 +303,7 @@ begin
|
|||||||
Set_BusA_To => Set_BusA_To,
|
Set_BusA_To => Set_BusA_To,
|
||||||
ALU_Op => ALU_Op,
|
ALU_Op => ALU_Op,
|
||||||
Save_ALU => Save_ALU,
|
Save_ALU => Save_ALU,
|
||||||
|
Rot_Akku => Rot_Akku,
|
||||||
PreserveC => PreserveC,
|
PreserveC => PreserveC,
|
||||||
Arith16 => Arith16,
|
Arith16 => Arith16,
|
||||||
Set_Addr_To => Set_Addr_To,
|
Set_Addr_To => Set_Addr_To,
|
||||||
@ -302,11 +316,14 @@ begin
|
|||||||
LDZ => LDZ,
|
LDZ => LDZ,
|
||||||
LDW => LDW,
|
LDW => LDW,
|
||||||
LDSPHL => LDSPHL,
|
LDSPHL => LDSPHL,
|
||||||
|
LDHLSP => LDHLSP,
|
||||||
|
ADDSPdd => ADDSPdd,
|
||||||
Special_LD => Special_LD,
|
Special_LD => Special_LD,
|
||||||
ExchangeDH => ExchangeDH,
|
ExchangeDH => ExchangeDH,
|
||||||
ExchangeRp => ExchangeRp,
|
ExchangeRp => ExchangeRp,
|
||||||
ExchangeAF => ExchangeAF,
|
ExchangeAF => ExchangeAF,
|
||||||
ExchangeRS => ExchangeRS,
|
ExchangeRS => ExchangeRS,
|
||||||
|
ExchangeWH => ExchangeWH,
|
||||||
I_DJNZ => I_DJNZ,
|
I_DJNZ => I_DJNZ,
|
||||||
I_CPL => I_CPL,
|
I_CPL => I_CPL,
|
||||||
I_CCF => I_CCF,
|
I_CCF => I_CCF,
|
||||||
@ -318,16 +335,20 @@ begin
|
|||||||
I_RLD => I_RLD,
|
I_RLD => I_RLD,
|
||||||
I_RRD => I_RRD,
|
I_RRD => I_RRD,
|
||||||
I_INRC => I_INRC,
|
I_INRC => I_INRC,
|
||||||
|
I_MULUB => I_MULUB,
|
||||||
|
I_MULU => I_MULU,
|
||||||
SetWZ => SetWZ,
|
SetWZ => SetWZ,
|
||||||
SetDI => SetDI,
|
SetDI => SetDI,
|
||||||
SetEI => SetEI,
|
SetEI => SetEI,
|
||||||
IMode => IMode,
|
IMode => IMode,
|
||||||
Halt => Halt,
|
Halt => Halt,
|
||||||
NoRead => NoRead,
|
NoRead => NoRead_i,
|
||||||
Write => Write,
|
Write => Write_i,
|
||||||
|
R800_mode => R800_mode,
|
||||||
|
No_PC => No_PC,
|
||||||
XYbit_undoc => XYbit_undoc);
|
XYbit_undoc => XYbit_undoc);
|
||||||
|
|
||||||
alu : work.T80_ALU
|
alu : T80_ALU
|
||||||
generic map(
|
generic map(
|
||||||
Mode => Mode,
|
Mode => Mode,
|
||||||
Flag_C => Flag_C,
|
Flag_C => Flag_C,
|
||||||
@ -344,6 +365,7 @@ begin
|
|||||||
WZ => WZ,
|
WZ => WZ,
|
||||||
XY_State=> XY_State,
|
XY_State=> XY_State,
|
||||||
ALU_Op => ALU_Op_r,
|
ALU_Op => ALU_Op_r,
|
||||||
|
Rot_Akku => Rot_Akku,
|
||||||
IR => IR(5 downto 0),
|
IR => IR(5 downto 0),
|
||||||
ISet => ISet,
|
ISet => ISet,
|
||||||
BusA => BusA,
|
BusA => BusA,
|
||||||
@ -352,6 +374,8 @@ begin
|
|||||||
Q => ALU_Q,
|
Q => ALU_Q,
|
||||||
F_Out => F_Out);
|
F_Out => F_Out);
|
||||||
|
|
||||||
|
Really_Wait <= not Wait_n and (Write_i or not NoRead_i);
|
||||||
|
|
||||||
ClkEn <= CEN and not BusAck;
|
ClkEn <= CEN and not BusAck;
|
||||||
|
|
||||||
T_Res <= '1' when TState = unsigned(TStates) else '0';
|
T_Res <= '1' when TState = unsigned(TStates) else '0';
|
||||||
@ -368,6 +392,8 @@ begin
|
|||||||
process (RESET_n, CLK_n)
|
process (RESET_n, CLK_n)
|
||||||
variable n : std_logic_vector(7 downto 0);
|
variable n : std_logic_vector(7 downto 0);
|
||||||
variable ioq : std_logic_vector(8 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
|
begin
|
||||||
if RESET_n = '0' then
|
if RESET_n = '0' then
|
||||||
PC <= (others => '0'); -- Program Counter
|
PC <= (others => '0'); -- Program Counter
|
||||||
@ -382,6 +408,11 @@ begin
|
|||||||
|
|
||||||
ACC <= (others => '1');
|
ACC <= (others => '1');
|
||||||
F <= (others => '1');
|
F <= (others => '1');
|
||||||
|
if Mode = 3 then
|
||||||
|
ACC <= (others => '0');
|
||||||
|
F <= "11110000";
|
||||||
|
end if;
|
||||||
|
|
||||||
Ap <= (others => '1');
|
Ap <= (others => '1');
|
||||||
Fp <= (others => '1');
|
Fp <= (others => '1');
|
||||||
I <= (others => '0');
|
I <= (others => '0');
|
||||||
@ -390,7 +421,6 @@ begin
|
|||||||
Alternate <= '0';
|
Alternate <= '0';
|
||||||
|
|
||||||
Read_To_Reg_r <= "00000";
|
Read_To_Reg_r <= "00000";
|
||||||
F <= (others => '1');
|
|
||||||
Arith16_r <= '0';
|
Arith16_r <= '0';
|
||||||
BTR_r <= '0';
|
BTR_r <= '0';
|
||||||
Z16_r <= '0';
|
Z16_r <= '0';
|
||||||
@ -402,15 +432,46 @@ begin
|
|||||||
|
|
||||||
elsif rising_edge(CLK_n) then
|
elsif rising_edge(CLK_n) then
|
||||||
|
|
||||||
if ClkEn = '1' then
|
if DIRSet = '1' then
|
||||||
|
ACC <= DIR( 7 downto 0);
|
||||||
|
F <= DIR(15 downto 8);
|
||||||
|
Ap <= DIR(23 downto 16);
|
||||||
|
Fp <= DIR(31 downto 24);
|
||||||
|
I <= DIR(39 downto 32);
|
||||||
|
R <= unsigned(DIR(47 downto 40));
|
||||||
|
SP <= unsigned(DIR(63 downto 48));
|
||||||
|
PC <= unsigned(DIR(79 downto 64));
|
||||||
|
A <= DIR(79 downto 64);
|
||||||
|
IStatus <= DIR(209 downto 208);
|
||||||
|
|
||||||
|
elsif ClkEn = '1' then
|
||||||
ALU_Op_r <= "0000";
|
ALU_Op_r <= "0000";
|
||||||
Save_ALU_r <= '0';
|
Save_ALU_r <= '0';
|
||||||
Read_To_Reg_r <= "00000";
|
Read_To_Reg_r <= "00000";
|
||||||
|
|
||||||
MCycles <= MCycles_d;
|
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;
|
IStatus <= IMode;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
@ -444,6 +505,11 @@ begin
|
|||||||
IR <= DInst;
|
IR <= DInst;
|
||||||
end if;
|
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";
|
ISet <= "00";
|
||||||
if Prefix /= "00" then
|
if Prefix /= "00" then
|
||||||
if Prefix = "11" then
|
if Prefix = "11" then
|
||||||
@ -491,7 +557,8 @@ begin
|
|||||||
elsif MCycle = MCycles and NMICycle = '1' then
|
elsif MCycle = MCycles and NMICycle = '1' then
|
||||||
A <= "0000000001100110";
|
A <= "0000000001100110";
|
||||||
PC <= "0000000001100110";
|
PC <= "0000000001100110";
|
||||||
elsif MCycle = "011" and IntCycle = '1' and IStatus = "10" then
|
elsif ((Mode /= 3 and MCycle = "011") or (Mode = 3 and MCycle = "100"))
|
||||||
|
and IntCycle = '1' and IStatus = "10" then
|
||||||
A(15 downto 8) <= I;
|
A(15 downto 8) <= I;
|
||||||
A(7 downto 0) <= WZ(7 downto 0);
|
A(7 downto 0) <= WZ(7 downto 0);
|
||||||
PC(15 downto 8) <= unsigned(I);
|
PC(15 downto 8) <= unsigned(I);
|
||||||
@ -555,7 +622,12 @@ begin
|
|||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
when others =>
|
when others =>
|
||||||
|
if ISet = "10" and IR(7 downto 4) = x"B" and IR(2 downto 1) = "01" and MCycle = 3 and No_BTR = '0' then
|
||||||
|
-- INIR, INDR, OTIR, OTDR
|
||||||
|
A <= RegBusA_r;
|
||||||
|
elsif No_PC = '0' or No_BTR = '1' or (I_DJNZ = '1' and IncDecZ = '1') or Mode > 1 then
|
||||||
A <= std_logic_vector(PC);
|
A <= std_logic_vector(PC);
|
||||||
|
end if;
|
||||||
end case;
|
end case;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
@ -566,6 +638,26 @@ begin
|
|||||||
Save_ALU_r <= Save_ALU;
|
Save_ALU_r <= Save_ALU;
|
||||||
ALU_Op_r <= ALU_Op;
|
ALU_Op_r <= ALU_Op;
|
||||||
|
|
||||||
|
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
|
if I_CPL = '1' then
|
||||||
-- CPL
|
-- CPL
|
||||||
ACC <= not ACC;
|
ACC <= not ACC;
|
||||||
@ -591,17 +683,18 @@ begin
|
|||||||
F(Flag_N) <= '0';
|
F(Flag_N) <= '0';
|
||||||
end if;
|
end if;
|
||||||
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 Really_Wait = '0' and I_BTR = '1' and IR(0) = '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)));
|
ioq := ('0' & DI_Reg) + ('0' & std_logic_vector(ID16(7 downto 0)));
|
||||||
F(Flag_N) <= DI_Reg(7);
|
F(Flag_N) <= DI_Reg(7);
|
||||||
F(Flag_C) <= ioq(8);
|
F(Flag_C) <= ioq(8);
|
||||||
F(Flag_H) <= 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));
|
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;
|
end if;
|
||||||
|
|
||||||
if TState = 2 and Wait_n = '1' then
|
if TState = 2 and Really_Wait = '0' then
|
||||||
if ISet = "01" and MCycle = "111" then
|
if ISet = "01" and MCycle = "111" then
|
||||||
IR <= DInst;
|
IR <= DInst;
|
||||||
end if;
|
end if;
|
||||||
@ -629,7 +722,7 @@ begin
|
|||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
if (TState = 2 and Wait_n = '1') or (TState = 4 and MCycle = "001") then
|
if (TState = 2 and Really_Wait = '0') or (TState = 4 and MCycle = "001") then
|
||||||
if IncDec_16(2 downto 0) = "111" then
|
if IncDec_16(2 downto 0) = "111" then
|
||||||
if IncDec_16(3) = '1' then
|
if IncDec_16(3) = '1' then
|
||||||
SP <= SP - 1;
|
SP <= SP - 1;
|
||||||
@ -639,6 +732,11 @@ begin
|
|||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
|
if ADDSPdd = '1' and TState = 2 then
|
||||||
|
WZ <= std_logic_vector(SP);
|
||||||
|
SP <= unsigned(signed(SP)+signed(Save_Mux));
|
||||||
|
end if;
|
||||||
|
|
||||||
if LDSPHL = '1' then
|
if LDSPHL = '1' then
|
||||||
SP <= unsigned(RegBusC);
|
SP <= unsigned(RegBusC);
|
||||||
end if;
|
end if;
|
||||||
@ -786,18 +884,56 @@ begin
|
|||||||
when "11001" =>
|
when "11001" =>
|
||||||
SP(15 downto 8) <= unsigned(Save_Mux);
|
SP(15 downto 8) <= unsigned(Save_Mux);
|
||||||
when "11011" =>
|
when "11011" =>
|
||||||
|
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;
|
F <= Save_Mux;
|
||||||
|
end if;
|
||||||
when others =>
|
when others =>
|
||||||
end case;
|
end case;
|
||||||
if XYbit_undoc='1' then
|
if XYbit_undoc='1' then
|
||||||
DO <= ALU_Q;
|
DO <= ALU_Q;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
end if;
|
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;
|
end process;
|
||||||
|
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
@ -855,7 +991,13 @@ begin
|
|||||||
(TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and IncDec_16(1 downto 0) = "10" else
|
(TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and IncDec_16(1 downto 0) = "10" else
|
||||||
-- EX HL,DL
|
-- EX HL,DL
|
||||||
Alternate & "10" when ExchangeDH = '1' and TState = 3 else
|
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
|
||||||
|
-- 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
|
-- Bus A / Write
|
||||||
RegAddrA_r;
|
RegAddrA_r;
|
||||||
|
|
||||||
@ -868,8 +1010,8 @@ begin
|
|||||||
ID16 <= signed(RegBusA) - 1 when IncDec_16(3) = '1' else
|
ID16 <= signed(RegBusA) - 1 when IncDec_16(3) = '1' else
|
||||||
signed(RegBusA) + 1;
|
signed(RegBusA) + 1;
|
||||||
|
|
||||||
process (Save_ALU_r, Auto_Wait_t1, ALU_OP_r, Read_To_Reg_r,
|
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)
|
ExchangeDH, ExchangeWH, IncDec_16, MCycle, TState, Really_Wait, LDHLSP)
|
||||||
begin
|
begin
|
||||||
RegWEH <= '0';
|
RegWEH <= '0';
|
||||||
RegWEL <= '0';
|
RegWEL <= '0';
|
||||||
@ -883,12 +1025,22 @@ begin
|
|||||||
end case;
|
end case;
|
||||||
end if;
|
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
|
if ExchangeDH = '1' and (TState = 3 or TState = 4) then
|
||||||
RegWEH <= '1';
|
RegWEH <= '1';
|
||||||
RegWEL <= '1';
|
RegWEL <= '1';
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
if IncDec_16(2) = '1' and ((TState = 2 and Wait_n = '1' and MCycle /= "001") or (TState = 3 and MCycle = "001")) then
|
if ((LDHLSP = '1' and MCycle = "010") or ExchangeWH = '1') and TState = 4 then
|
||||||
|
RegWEH <= '1';
|
||||||
|
RegWEL <= '1';
|
||||||
|
end if;
|
||||||
|
|
||||||
|
if IncDec_16(2) = '1' and ((TState = 2 and Really_Wait = '0' and MCycle /= "001") or (TState = 3 and MCycle = "001")) then
|
||||||
case IncDec_16(1 downto 0) is
|
case IncDec_16(1 downto 0) is
|
||||||
when "00" | "01" | "10" =>
|
when "00" | "01" | "10" =>
|
||||||
RegWEH <= '1';
|
RegWEH <= '1';
|
||||||
@ -898,12 +1050,29 @@ begin
|
|||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
process (Save_Mux, RegBusB, RegBusA_r, ID16,
|
TmpAddr2 <= std_logic_vector(unsigned(signed(SP) + signed(Save_Mux)));
|
||||||
ExchangeDH, IncDec_16, MCycle, TState, Wait_n)
|
|
||||||
|
process (Save_Mux, RegBusB, RegBusA_r, ID16, I_MULU, MULU_Prod32, MULU_tmp, T_Res,
|
||||||
|
ExchangeDH, ExchangeWH, IncDec_16, MCycle, TState, Really_Wait, LDHLSP, TmpAddr2, WZ)
|
||||||
begin
|
begin
|
||||||
RegDIH <= Save_Mux;
|
RegDIH <= Save_Mux;
|
||||||
RegDIL <= 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
|
if ExchangeDH = '1' and TState = 3 then
|
||||||
RegDIH <= RegBusB(15 downto 8);
|
RegDIH <= RegBusB(15 downto 8);
|
||||||
RegDIL <= RegBusB(7 downto 0);
|
RegDIL <= RegBusB(7 downto 0);
|
||||||
@ -912,14 +1081,17 @@ begin
|
|||||||
RegDIH <= RegBusA_r(15 downto 8);
|
RegDIH <= RegBusA_r(15 downto 8);
|
||||||
RegDIL <= RegBusA_r(7 downto 0);
|
RegDIL <= RegBusA_r(7 downto 0);
|
||||||
end if;
|
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
|
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));
|
RegDIH <= std_logic_vector(ID16(15 downto 8));
|
||||||
RegDIL <= std_logic_vector(ID16(7 downto 0));
|
RegDIL <= std_logic_vector(ID16(7 downto 0));
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
Regs : work.T80_Reg
|
Regs : T80_Reg
|
||||||
port map(
|
port map(
|
||||||
Clk => CLK_n,
|
Clk => CLK_n,
|
||||||
CEN => ClkEn,
|
CEN => ClkEn,
|
||||||
@ -936,7 +1108,9 @@ begin
|
|||||||
DOBL => RegBusB(7 downto 0),
|
DOBL => RegBusB(7 downto 0),
|
||||||
DOCH => RegBusC(15 downto 8),
|
DOCH => RegBusC(15 downto 8),
|
||||||
DOCL => RegBusC(7 downto 0),
|
DOCL => RegBusC(7 downto 0),
|
||||||
DOR => DOR);
|
DOR => DOR,
|
||||||
|
DIRSet => DIRSet,
|
||||||
|
DIR => DIR(207 downto 80));
|
||||||
|
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
--
|
--
|
||||||
@ -1018,7 +1192,7 @@ begin
|
|||||||
if RESET_n = '0' then
|
if RESET_n = '0' then
|
||||||
RFSH_n <= '1';
|
RFSH_n <= '1';
|
||||||
elsif rising_edge(CLK_n) then
|
elsif rising_edge(CLK_n) then
|
||||||
if CEN = '1' then
|
if DIRSet = '0' and CEN = '1' then
|
||||||
if MCycle = "001" and ((TState = 2 and Wait_n = '1') or TState = 3) then
|
if MCycle = "001" and ((TState = 2 and Wait_n = '1') or TState = 3) then
|
||||||
RFSH_n <= '0';
|
RFSH_n <= '0';
|
||||||
else
|
else
|
||||||
@ -1032,12 +1206,13 @@ begin
|
|||||||
TS <= std_logic_vector(TState);
|
TS <= std_logic_vector(TState);
|
||||||
DI_Reg <= DI;
|
DI_Reg <= DI;
|
||||||
HALT_n <= not Halt_FF;
|
HALT_n <= not Halt_FF;
|
||||||
BUSAK_n <= not BusAck;
|
BUSAK_n <= not (BusAck and RESET_n);
|
||||||
IntCycle_n <= not IntCycle;
|
IntCycle_n <= not IntCycle;
|
||||||
IntE <= IntE_FF1;
|
IntE <= IntE_FF1;
|
||||||
IORQ <= IORQ_i;
|
IORQ <= IORQ_i;
|
||||||
|
NoRead <= NoRead_i;
|
||||||
|
Write <= Write_i;
|
||||||
Stop <= I_DJNZ;
|
Stop <= I_DJNZ;
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
--
|
--
|
||||||
-- Main state machine
|
-- Main state machine
|
||||||
@ -1051,7 +1226,7 @@ begin
|
|||||||
TState <= "000";
|
TState <= "000";
|
||||||
Pre_XY_F_M <= "000";
|
Pre_XY_F_M <= "000";
|
||||||
Halt_FF <= '0';
|
Halt_FF <= '0';
|
||||||
BusAck <= '0';
|
--BusAck <= '0';
|
||||||
NMICycle <= '0';
|
NMICycle <= '0';
|
||||||
IntCycle <= '0';
|
IntCycle <= '0';
|
||||||
IntE_FF1 <= '0';
|
IntE_FF1 <= '0';
|
||||||
@ -1060,10 +1235,13 @@ begin
|
|||||||
Auto_Wait_t1 <= '0';
|
Auto_Wait_t1 <= '0';
|
||||||
Auto_Wait_t2 <= '0';
|
Auto_Wait_t2 <= '0';
|
||||||
M1_n <= '1';
|
M1_n <= '1';
|
||||||
BusReq_s <= '0';
|
--BusReq_s <= '0';
|
||||||
NMI_s <= '0';
|
NMI_s <= '0';
|
||||||
elsif rising_edge(CLK_n) then
|
elsif rising_edge(CLK_n) then
|
||||||
|
if DIRSet = '1' then
|
||||||
|
IntE_FF2 <= DIR(211);
|
||||||
|
IntE_FF1 <= DIR(210);
|
||||||
|
else
|
||||||
if NMI_n = '0' and OldNMI_n = '1' then
|
if NMI_n = '0' and OldNMI_n = '1' then
|
||||||
NMI_s <= '1';
|
NMI_s <= '1';
|
||||||
end if;
|
end if;
|
||||||
@ -1105,15 +1283,22 @@ begin
|
|||||||
if BusReq_s = '1' and BusAck = '1' then
|
if BusReq_s = '1' and BusAck = '1' then
|
||||||
else
|
else
|
||||||
BusAck <= '0';
|
BusAck <= '0';
|
||||||
if TState = 2 and Wait_n = '0' then
|
if TState = 2 and Really_Wait = '1' then
|
||||||
elsif T_Res = '1' 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';
|
Halt_FF <= '1';
|
||||||
end if;
|
end if;
|
||||||
if BusReq_s = '1' then
|
if BusReq_s = '1' then
|
||||||
BusAck <= '1';
|
BusAck <= '1';
|
||||||
else
|
else
|
||||||
TState <= "001";
|
TState <= "001";
|
||||||
|
if (IntCycle = '1' and Mode = 3) then -- GB: read interrupt at MCycle 3
|
||||||
|
if (MCycle = "010") then
|
||||||
|
M1_n <= '0';
|
||||||
|
else
|
||||||
|
M1_n <= '1';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
if NextIs_XY_Fetch = '1' then
|
if NextIs_XY_Fetch = '1' then
|
||||||
MCycle <= "110";
|
MCycle <= "110";
|
||||||
Pre_XY_F_M <= MCycle;
|
Pre_XY_F_M <= MCycle;
|
||||||
@ -1135,6 +1320,8 @@ begin
|
|||||||
IntCycle <= '1';
|
IntCycle <= '1';
|
||||||
IntE_FF1 <= '0';
|
IntE_FF1 <= '0';
|
||||||
IntE_FF2 <= '0';
|
IntE_FF2 <= '0';
|
||||||
|
elsif (Halt_FF = '1' and INT_n = '0' and Mode = 3) then
|
||||||
|
Halt_FF <= '0';
|
||||||
end if;
|
end if;
|
||||||
else
|
else
|
||||||
MCycle <= std_logic_vector(unsigned(MCycle) + 1);
|
MCycle <= std_logic_vector(unsigned(MCycle) + 1);
|
||||||
@ -1152,16 +1339,8 @@ begin
|
|||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
|
||||||
|
|
||||||
process (IntCycle, NMICycle, MCycle)
|
|
||||||
begin
|
|
||||||
Auto_Wait <= '0';
|
|
||||||
if IntCycle = '1' or NMICycle = '1' then
|
|
||||||
if MCycle = "001" then
|
|
||||||
Auto_Wait <= '1';
|
|
||||||
end if;
|
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
|
Auto_Wait <= '1' when IntCycle = '1' and MCycle = "001" else '0';
|
||||||
end;
|
end;
|
||||||
|
194
rtl/T80/T8080se.vhd
Normal file
194
rtl/T80/T8080se.vhd
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
-- ****
|
||||||
|
-- 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)
|
||||||
|
--
|
||||||
|
-- ****
|
||||||
|
--
|
||||||
|
-- 8080 compatible microprocessor core, synchronous top level with clock enable
|
||||||
|
-- Different timing than the original 8080
|
||||||
|
-- Inputs needs to be synchronous and outputs may glitch
|
||||||
|
--
|
||||||
|
-- Version : 0242
|
||||||
|
--
|
||||||
|
-- Copyright (c) 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 :
|
||||||
|
-- STACK status output not supported
|
||||||
|
--
|
||||||
|
-- File history :
|
||||||
|
--
|
||||||
|
-- 0237 : First version
|
||||||
|
--
|
||||||
|
-- 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 T8080se is
|
||||||
|
generic(
|
||||||
|
Mode : integer := 2; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
|
||||||
|
T2Write : integer := 0 -- 0 => WR_n active in T3, /=0 => WR_n active in T2
|
||||||
|
);
|
||||||
|
port(
|
||||||
|
RESET_n : in std_logic;
|
||||||
|
CLK : in std_logic;
|
||||||
|
CLKEN : in std_logic;
|
||||||
|
READY : in std_logic;
|
||||||
|
HOLD : in std_logic;
|
||||||
|
INT : in std_logic;
|
||||||
|
INTE : out std_logic;
|
||||||
|
DBIN : out std_logic;
|
||||||
|
SYNC : out std_logic;
|
||||||
|
VAIT : out std_logic;
|
||||||
|
HLDA : out std_logic;
|
||||||
|
WR_n : out std_logic;
|
||||||
|
A : out std_logic_vector(15 downto 0);
|
||||||
|
DI : in std_logic_vector(7 downto 0);
|
||||||
|
DO : out std_logic_vector(7 downto 0)
|
||||||
|
);
|
||||||
|
end T8080se;
|
||||||
|
|
||||||
|
architecture rtl of T8080se is
|
||||||
|
|
||||||
|
signal IntCycle_n : std_logic;
|
||||||
|
signal NoRead : std_logic;
|
||||||
|
signal Write : std_logic;
|
||||||
|
signal IORQ : std_logic;
|
||||||
|
signal INT_n : std_logic;
|
||||||
|
signal HALT_n : std_logic;
|
||||||
|
signal BUSRQ_n : std_logic;
|
||||||
|
signal BUSAK_n : std_logic;
|
||||||
|
signal DO_i : std_logic_vector(7 downto 0);
|
||||||
|
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);
|
||||||
|
signal One : std_logic;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
INT_n <= not INT;
|
||||||
|
BUSRQ_n <= HOLD;
|
||||||
|
HLDA <= not BUSAK_n;
|
||||||
|
SYNC <= '1' when TState = "001" else '0';
|
||||||
|
VAIT <= '1' when TState = "010" else '0';
|
||||||
|
One <= '1';
|
||||||
|
|
||||||
|
DO(0) <= not IntCycle_n when TState = "001" else DO_i(0); -- INTA
|
||||||
|
DO(1) <= Write when TState = "001" else DO_i(1); -- WO_n
|
||||||
|
DO(2) <= DO_i(2); -- STACK not supported !!!!!!!!!!
|
||||||
|
DO(3) <= not HALT_n when TState = "001" else DO_i(3); -- HLTA
|
||||||
|
DO(4) <= IORQ and Write when TState = "001" else DO_i(4); -- OUT
|
||||||
|
DO(5) <= DO_i(5) when TState /= "001" else '1' when MCycle = "001" else '0'; -- M1
|
||||||
|
DO(6) <= IORQ and not Write when TState = "001" else DO_i(6); -- INP
|
||||||
|
DO(7) <= not IORQ and not Write and IntCycle_n when TState = "001" else DO_i(7); -- MEMR
|
||||||
|
|
||||||
|
u0 : T80
|
||||||
|
generic map(
|
||||||
|
Mode => Mode,
|
||||||
|
IOWait => 0)
|
||||||
|
port map(
|
||||||
|
CEN => CLKEN,
|
||||||
|
M1_n => open,
|
||||||
|
IORQ => IORQ,
|
||||||
|
NoRead => NoRead,
|
||||||
|
Write => Write,
|
||||||
|
RFSH_n => open,
|
||||||
|
HALT_n => HALT_n,
|
||||||
|
WAIT_n => READY,
|
||||||
|
INT_n => INT_n,
|
||||||
|
NMI_n => One,
|
||||||
|
RESET_n => RESET_n,
|
||||||
|
BUSRQ_n => One,
|
||||||
|
BUSAK_n => BUSAK_n,
|
||||||
|
CLK_n => CLK,
|
||||||
|
A => A,
|
||||||
|
DInst => DI,
|
||||||
|
DI => DI_Reg,
|
||||||
|
DO => DO_i,
|
||||||
|
MC => MCycle,
|
||||||
|
TS => TState,
|
||||||
|
IntCycle_n => IntCycle_n,
|
||||||
|
IntE => INTE);
|
||||||
|
|
||||||
|
process (RESET_n, CLK)
|
||||||
|
begin
|
||||||
|
if RESET_n = '0' then
|
||||||
|
DBIN <= '0';
|
||||||
|
WR_n <= '1';
|
||||||
|
DI_Reg <= "00000000";
|
||||||
|
elsif CLK'event and CLK = '1' then
|
||||||
|
if CLKEN = '1' then
|
||||||
|
DBIN <= '0';
|
||||||
|
WR_n <= '1';
|
||||||
|
if MCycle = "001" then
|
||||||
|
if TState = "001" or (TState = "010" and READY = '0') then
|
||||||
|
DBIN <= IntCycle_n;
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
if (TState = "001" or (TState = "010" and READY = '0')) and NoRead = '0' and Write = '0' then
|
||||||
|
DBIN <= '1';
|
||||||
|
end if;
|
||||||
|
if T2Write = 0 then
|
||||||
|
if TState = "010" and Write = '1' then
|
||||||
|
WR_n <= '0';
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
if (TState = "001" or (TState = "010" and READY = '0')) and Write = '1' then
|
||||||
|
WR_n <= '0';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
if TState = "010" and READY = '1' then
|
||||||
|
DI_Reg <= DI;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
end;
|
@ -89,6 +89,7 @@ entity T80_ALU is
|
|||||||
WZ : in std_logic_vector(15 downto 0);
|
WZ : in std_logic_vector(15 downto 0);
|
||||||
XY_State : in std_logic_vector(1 downto 0);
|
XY_State : in std_logic_vector(1 downto 0);
|
||||||
ALU_Op : in std_logic_vector(3 downto 0);
|
ALU_Op : in std_logic_vector(3 downto 0);
|
||||||
|
Rot_Akku : in std_logic;
|
||||||
IR : in std_logic_vector(5 downto 0);
|
IR : in std_logic_vector(5 downto 0);
|
||||||
ISet : in std_logic_vector(1 downto 0);
|
ISet : in std_logic_vector(1 downto 0);
|
||||||
BusA : in std_logic_vector(7 downto 0);
|
BusA : in std_logic_vector(7 downto 0);
|
||||||
@ -158,7 +159,7 @@ begin
|
|||||||
end if;
|
end if;
|
||||||
end process;
|
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 Q_t : std_logic_vector(7 downto 0);
|
||||||
variable DAA_Q : unsigned(8 downto 0);
|
variable DAA_Q : unsigned(8 downto 0);
|
||||||
begin
|
begin
|
||||||
@ -220,6 +221,34 @@ begin
|
|||||||
end if;
|
end if;
|
||||||
when "1100" =>
|
when "1100" =>
|
||||||
-- DAA
|
-- DAA
|
||||||
|
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;
|
||||||
|
end if;
|
||||||
|
else
|
||||||
F_Out(Flag_H) <= F_In(Flag_H);
|
F_Out(Flag_H) <= F_In(Flag_H);
|
||||||
F_Out(Flag_C) <= F_In(Flag_C);
|
F_Out(Flag_C) <= F_In(Flag_C);
|
||||||
DAA_Q(7 downto 0) := unsigned(BusA);
|
DAA_Q(7 downto 0) := unsigned(BusA);
|
||||||
@ -251,6 +280,7 @@ begin
|
|||||||
DAA_Q := DAA_Q - 352; -- 0x160
|
DAA_Q := DAA_Q - 352; -- 0x160
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
|
end if;
|
||||||
F_Out(Flag_X) <= DAA_Q(3);
|
F_Out(Flag_X) <= DAA_Q(3);
|
||||||
F_Out(Flag_Y) <= DAA_Q(5);
|
F_Out(Flag_Y) <= DAA_Q(5);
|
||||||
F_Out(Flag_C) <= F_In(Flag_C) or DAA_Q(8);
|
F_Out(Flag_C) <= F_In(Flag_C) or DAA_Q(8);
|
||||||
@ -368,6 +398,9 @@ begin
|
|||||||
F_Out(Flag_S) <= F_In(Flag_S);
|
F_Out(Flag_S) <= F_In(Flag_S);
|
||||||
F_Out(Flag_Z) <= F_In(Flag_Z);
|
F_Out(Flag_Z) <= F_In(Flag_Z);
|
||||||
end if;
|
end if;
|
||||||
|
if Mode = 3 and Rot_Akku = '1' then
|
||||||
|
F_Out(Flag_Z) <= '0';
|
||||||
|
end if;
|
||||||
when others =>
|
when others =>
|
||||||
null;
|
null;
|
||||||
end case;
|
end case;
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
-- ****
|
-- ****
|
||||||
-- Z80 compatible microprocessor core
|
-- Z80 compatible microprocessor core
|
||||||
--
|
--
|
||||||
-- Version : 0242
|
-- Version : 0250
|
||||||
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
||||||
-- All rights reserved
|
-- All rights reserved
|
||||||
--
|
--
|
||||||
@ -69,11 +69,13 @@
|
|||||||
-- 0240 : Added (IX/IY+d) states, removed op-codes from mode 2 and added all remaining mode 3 op-codes
|
-- 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
|
-- 0240mj1 fix for HL inc/dec for INI, IND, INIR, INDR, OUTI, OUTD, OTIR, OTDR
|
||||||
-- 0242 : Fixed I/O instruction timing, cleanup
|
-- 0242 : Fixed I/O instruction timing, cleanup
|
||||||
|
-- 0250 : Added R800 Multiplier by TobiFlex 2017.10.15
|
||||||
--
|
--
|
||||||
|
|
||||||
library IEEE;
|
library IEEE;
|
||||||
use IEEE.std_logic_1164.all;
|
use IEEE.std_logic_1164.all;
|
||||||
use IEEE.numeric_std.all;
|
use IEEE.numeric_std.all;
|
||||||
|
use work.T80_Pack.all;
|
||||||
|
|
||||||
entity T80_MCode is
|
entity T80_MCode is
|
||||||
generic(
|
generic(
|
||||||
@ -108,6 +110,7 @@ entity T80_MCode is
|
|||||||
ALU_Op : out std_logic_vector(3 downto 0);
|
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
|
-- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None
|
||||||
Save_ALU : out std_logic;
|
Save_ALU : out std_logic;
|
||||||
|
Rot_Akku : out std_logic;
|
||||||
PreserveC : out std_logic;
|
PreserveC : out std_logic;
|
||||||
Arith16 : out std_logic;
|
Arith16 : out std_logic;
|
||||||
Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI
|
Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI
|
||||||
@ -120,11 +123,14 @@ entity T80_MCode is
|
|||||||
LDZ : out std_logic;
|
LDZ : out std_logic;
|
||||||
LDW : out std_logic;
|
LDW : out std_logic;
|
||||||
LDSPHL : 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
|
Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None
|
||||||
ExchangeDH : out std_logic;
|
ExchangeDH : out std_logic;
|
||||||
ExchangeRp : out std_logic;
|
ExchangeRp : out std_logic;
|
||||||
ExchangeAF : out std_logic;
|
ExchangeAF : out std_logic;
|
||||||
ExchangeRS : out std_logic;
|
ExchangeRS : out std_logic;
|
||||||
|
ExchangeWH : out std_logic;
|
||||||
I_DJNZ : out std_logic;
|
I_DJNZ : out std_logic;
|
||||||
I_CPL : out std_logic;
|
I_CPL : out std_logic;
|
||||||
I_CCF : out std_logic;
|
I_CCF : out std_logic;
|
||||||
@ -136,6 +142,8 @@ entity T80_MCode is
|
|||||||
I_RLD : out std_logic;
|
I_RLD : out std_logic;
|
||||||
I_RRD : out std_logic;
|
I_RRD : out std_logic;
|
||||||
I_INRC : 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);
|
SetWZ : out std_logic_vector(1 downto 0);
|
||||||
SetDI : out std_logic;
|
SetDI : out std_logic;
|
||||||
SetEI : out std_logic;
|
SetEI : out std_logic;
|
||||||
@ -143,20 +151,14 @@ entity T80_MCode is
|
|||||||
Halt : out std_logic;
|
Halt : out std_logic;
|
||||||
NoRead : out std_logic;
|
NoRead : out std_logic;
|
||||||
Write : out std_logic;
|
Write : out std_logic;
|
||||||
|
R800_mode : in std_logic;
|
||||||
|
No_PC : out std_logic;
|
||||||
XYbit_undoc : out std_logic
|
XYbit_undoc : out std_logic
|
||||||
);
|
);
|
||||||
end T80_MCode;
|
end T80_MCode;
|
||||||
|
|
||||||
architecture rtl of T80_MCode is
|
architecture rtl of T80_MCode is
|
||||||
|
|
||||||
constant aNone : std_logic_vector(2 downto 0) := "111";
|
|
||||||
constant aBC : std_logic_vector(2 downto 0) := "000";
|
|
||||||
constant aDE : std_logic_vector(2 downto 0) := "001";
|
|
||||||
constant aXY : std_logic_vector(2 downto 0) := "010";
|
|
||||||
constant aIOA : std_logic_vector(2 downto 0) := "100";
|
|
||||||
constant aSP : std_logic_vector(2 downto 0) := "101";
|
|
||||||
constant aZI : std_logic_vector(2 downto 0) := "110";
|
|
||||||
|
|
||||||
function is_cc_true(
|
function is_cc_true(
|
||||||
F : std_logic_vector(7 downto 0);
|
F : std_logic_vector(7 downto 0);
|
||||||
cc : bit_vector(2 downto 0)
|
cc : bit_vector(2 downto 0)
|
||||||
@ -164,10 +166,10 @@ architecture rtl of T80_MCode is
|
|||||||
begin
|
begin
|
||||||
if Mode = 3 then
|
if Mode = 3 then
|
||||||
case cc is
|
case cc is
|
||||||
when "000" => return F(Flag_S) = '0'; -- NZ
|
when "000" => return F(Flag_Z) = '0'; -- NZ
|
||||||
when "001" => return F(Flag_S) = '1'; -- Z
|
when "001" => return F(Flag_Z) = '1'; -- Z
|
||||||
when "010" => return F(Flag_H) = '0'; -- NC
|
when "010" => return F(Flag_C) = '0'; -- NC
|
||||||
when "011" => return F(Flag_H) = '1'; -- C
|
when "011" => return F(Flag_C) = '1'; -- C
|
||||||
when "100" => return false;
|
when "100" => return false;
|
||||||
when "101" => return false;
|
when "101" => return false;
|
||||||
when "110" => return false;
|
when "110" => return false;
|
||||||
@ -189,7 +191,7 @@ architecture rtl of T80_MCode is
|
|||||||
|
|
||||||
begin
|
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 DDD : std_logic_vector(2 downto 0);
|
||||||
variable SSS : std_logic_vector(2 downto 0);
|
variable SSS : std_logic_vector(2 downto 0);
|
||||||
variable DPair : std_logic_vector(1 downto 0);
|
variable DPair : std_logic_vector(1 downto 0);
|
||||||
@ -216,6 +218,7 @@ begin
|
|||||||
Set_BusA_To <= "0000";
|
Set_BusA_To <= "0000";
|
||||||
ALU_Op <= "0" & IR(5 downto 3);
|
ALU_Op <= "0" & IR(5 downto 3);
|
||||||
Save_ALU <= '0';
|
Save_ALU <= '0';
|
||||||
|
Rot_Akku <= '0';
|
||||||
PreserveC <= '0';
|
PreserveC <= '0';
|
||||||
Arith16 <= '0';
|
Arith16 <= '0';
|
||||||
IORQ <= '0';
|
IORQ <= '0';
|
||||||
@ -228,11 +231,14 @@ begin
|
|||||||
LDZ <= '0';
|
LDZ <= '0';
|
||||||
LDW <= '0';
|
LDW <= '0';
|
||||||
LDSPHL <= '0';
|
LDSPHL <= '0';
|
||||||
|
LDHLSP <= '0';
|
||||||
|
ADDSPdd <= '0';
|
||||||
Special_LD <= "000";
|
Special_LD <= "000";
|
||||||
ExchangeDH <= '0';
|
ExchangeDH <= '0';
|
||||||
ExchangeRp <= '0';
|
ExchangeRp <= '0';
|
||||||
ExchangeAF <= '0';
|
ExchangeAF <= '0';
|
||||||
ExchangeRS <= '0';
|
ExchangeRS <= '0';
|
||||||
|
ExchangeWH <= '0';
|
||||||
I_DJNZ <= '0';
|
I_DJNZ <= '0';
|
||||||
I_CPL <= '0';
|
I_CPL <= '0';
|
||||||
I_CCF <= '0';
|
I_CCF <= '0';
|
||||||
@ -244,12 +250,15 @@ begin
|
|||||||
I_RLD <= '0';
|
I_RLD <= '0';
|
||||||
I_RRD <= '0';
|
I_RRD <= '0';
|
||||||
I_INRC <= '0';
|
I_INRC <= '0';
|
||||||
|
I_MULUB <= '0';
|
||||||
|
I_MULU <= '0';
|
||||||
SetDI <= '0';
|
SetDI <= '0';
|
||||||
SetEI <= '0';
|
SetEI <= '0';
|
||||||
IMode <= "11";
|
IMode <= "11";
|
||||||
Halt <= '0';
|
Halt <= '0';
|
||||||
NoRead <= '0';
|
NoRead <= '0';
|
||||||
Write <= '0';
|
Write <= '0';
|
||||||
|
No_PC <= '0';
|
||||||
XYbit_undoc <= '0';
|
XYbit_undoc <= '0';
|
||||||
SetWZ <= "00";
|
SetWZ <= "00";
|
||||||
|
|
||||||
@ -520,10 +529,47 @@ begin
|
|||||||
end if;
|
end if;
|
||||||
when "11111001" =>
|
when "11111001" =>
|
||||||
-- LD SP,HL
|
-- LD SP,HL
|
||||||
|
if Mode = 3 then
|
||||||
|
MCycles <= "010";
|
||||||
|
if MCycle = "010" then
|
||||||
|
LDSPHL <= '1';
|
||||||
|
end if;
|
||||||
|
else
|
||||||
TStates <= "110";
|
TStates <= "110";
|
||||||
LDSPHL <= '1';
|
LDSPHL <= '1';
|
||||||
|
end if;
|
||||||
when "11000101"|"11010101"|"11100101"|"11110101" =>
|
when "11000101"|"11010101"|"11100101"|"11110101" =>
|
||||||
-- PUSH qq
|
-- PUSH qq
|
||||||
|
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";
|
MCycles <= "011";
|
||||||
case to_integer(unsigned(MCycle)) is
|
case to_integer(unsigned(MCycle)) is
|
||||||
when 1 =>
|
when 1 =>
|
||||||
@ -552,6 +598,7 @@ begin
|
|||||||
Write <= '1';
|
Write <= '1';
|
||||||
when others => null;
|
when others => null;
|
||||||
end case;
|
end case;
|
||||||
|
end if;
|
||||||
when "11000001"|"11010001"|"11100001"|"11110001" =>
|
when "11000001"|"11010001"|"11100001"|"11110001" =>
|
||||||
-- POP qq
|
-- POP qq
|
||||||
MCycles <= "011";
|
MCycles <= "011";
|
||||||
@ -615,7 +662,7 @@ begin
|
|||||||
when "11011001" =>
|
when "11011001" =>
|
||||||
if Mode = 3 then
|
if Mode = 3 then
|
||||||
-- RETI
|
-- RETI
|
||||||
MCycles <= "011";
|
MCycles <= "100";
|
||||||
case to_integer(unsigned(MCycle)) is
|
case to_integer(unsigned(MCycle)) is
|
||||||
when 1 =>
|
when 1 =>
|
||||||
Set_Addr_TO <= aSP;
|
Set_Addr_TO <= aSP;
|
||||||
@ -626,7 +673,7 @@ begin
|
|||||||
when 3 =>
|
when 3 =>
|
||||||
Jump <= '1';
|
Jump <= '1';
|
||||||
IncDec_16 <= "0111";
|
IncDec_16 <= "0111";
|
||||||
I_RETN <= '1';
|
--I_RETN <= '1';
|
||||||
SetEI <= '1';
|
SetEI <= '1';
|
||||||
when others => null;
|
when others => null;
|
||||||
end case;
|
end case;
|
||||||
@ -642,24 +689,21 @@ begin
|
|||||||
when 1 =>
|
when 1 =>
|
||||||
Set_Addr_To <= aSP;
|
Set_Addr_To <= aSP;
|
||||||
when 2 =>
|
when 2 =>
|
||||||
Read_To_Reg <= '1';
|
|
||||||
Set_BusA_To <= "0101";
|
|
||||||
Set_BusB_To <= "0101";
|
|
||||||
Set_Addr_To <= aSP;
|
Set_Addr_To <= aSP;
|
||||||
LDZ <= '1';
|
LDZ <= '1';
|
||||||
|
IncDec_16 <= "0111"; -- SP <= SP+1
|
||||||
when 3 =>
|
when 3 =>
|
||||||
IncDec_16 <= "0111";
|
|
||||||
Set_Addr_To <= aSP;
|
|
||||||
TStates <= "100";
|
TStates <= "100";
|
||||||
Write <= '1';
|
|
||||||
when 4 =>
|
|
||||||
Read_To_Reg <= '1';
|
|
||||||
Set_BusA_To <= "0100";
|
|
||||||
Set_BusB_To <= "0100";
|
Set_BusB_To <= "0100";
|
||||||
Set_Addr_To <= aSP;
|
Set_Addr_To <= aSP;
|
||||||
LDW <= '1';
|
LDW <= '1';
|
||||||
|
when 4 =>
|
||||||
|
Set_BusB_To <= "0101";
|
||||||
|
Write <= '1';
|
||||||
|
IncDec_16 <= "1111"; -- SP <= SP-1
|
||||||
|
Set_Addr_To <= aSP;
|
||||||
when 5 =>
|
when 5 =>
|
||||||
IncDec_16 <= "1111";
|
ExchangeWH <= '1'; -- save WZ to HL
|
||||||
TStates <= "101";
|
TStates <= "101";
|
||||||
Write <= '1';
|
Write <= '1';
|
||||||
when others => null;
|
when others => null;
|
||||||
@ -806,22 +850,39 @@ begin
|
|||||||
Set_Addr_To <= aSP;
|
Set_Addr_To <= aSP;
|
||||||
Set_BusB_To <= "1101";
|
Set_BusB_To <= "1101";
|
||||||
when 2 =>
|
when 2 =>
|
||||||
TStates <= "100";
|
|
||||||
Write <= '1';
|
Write <= '1';
|
||||||
IncDec_16 <= "1111";
|
IncDec_16 <= "1111";
|
||||||
Set_Addr_To <= aSP;
|
Set_Addr_To <= aSP;
|
||||||
Set_BusB_To <= "1100";
|
Set_BusB_To <= "1100";
|
||||||
when 3 =>
|
when 3 =>
|
||||||
TStates <= "100";
|
|
||||||
Write <= '1';
|
Write <= '1';
|
||||||
when others => null;
|
when others => null;
|
||||||
end case;
|
end case;
|
||||||
elsif IntCycle = '1' then
|
elsif IntCycle = '1' then
|
||||||
-- INT (IM 2)
|
-- INT (IM 2)
|
||||||
|
if Mode = 3 then
|
||||||
|
MCycles <= "100";
|
||||||
|
case to_integer(unsigned(MCycle)) is
|
||||||
|
when 1 =>
|
||||||
|
TStates <= "110";
|
||||||
|
IncDec_16 <= "1111";
|
||||||
|
Set_Addr_To <= aSP;
|
||||||
|
Set_BusB_To <= "1101";
|
||||||
|
when 2 =>
|
||||||
|
Write <= '1';
|
||||||
|
when 3 => -- GB: interrupt is acknowledged on MCycle 3
|
||||||
|
LDZ <= '1';
|
||||||
|
IncDec_16 <= "1111";
|
||||||
|
Set_Addr_To <= aSP;
|
||||||
|
Set_BusB_To <= "1100";
|
||||||
|
when 4 =>
|
||||||
|
Write <= '1';
|
||||||
|
when others => null;
|
||||||
|
end case;
|
||||||
|
else
|
||||||
MCycles <= "101";
|
MCycles <= "101";
|
||||||
case to_integer(unsigned(MCycle)) is
|
case to_integer(unsigned(MCycle)) is
|
||||||
when 1 =>
|
when 1 =>
|
||||||
LDZ <= '1';
|
|
||||||
TStates <= "101";
|
TStates <= "101";
|
||||||
IncDec_16 <= "1111";
|
IncDec_16 <= "1111";
|
||||||
Set_Addr_To <= aSP;
|
Set_Addr_To <= aSP;
|
||||||
@ -842,6 +903,7 @@ begin
|
|||||||
Jump <= '1';
|
Jump <= '1';
|
||||||
when others => null;
|
when others => null;
|
||||||
end case;
|
end case;
|
||||||
|
end if;
|
||||||
else
|
else
|
||||||
-- NOP
|
-- NOP
|
||||||
end if;
|
end if;
|
||||||
@ -858,8 +920,45 @@ begin
|
|||||||
-- 16 BIT ARITHMETIC GROUP
|
-- 16 BIT ARITHMETIC GROUP
|
||||||
when "00001001"|"00011001"|"00101001"|"00111001" =>
|
when "00001001"|"00011001"|"00101001"|"00111001" =>
|
||||||
-- ADD HL,ss
|
-- ADD HL,ss
|
||||||
|
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 =>
|
||||||
|
end case;
|
||||||
|
else
|
||||||
MCycles <= "011";
|
MCycles <= "011";
|
||||||
case to_integer(unsigned(MCycle)) is
|
case to_integer(unsigned(MCycle)) is
|
||||||
|
when 1 =>
|
||||||
|
No_PC <= '1';
|
||||||
when 2 =>
|
when 2 =>
|
||||||
NoRead <= '1';
|
NoRead <= '1';
|
||||||
ALU_Op <= "0000";
|
ALU_Op <= "0000";
|
||||||
@ -876,6 +975,7 @@ begin
|
|||||||
TStates <= "100";
|
TStates <= "100";
|
||||||
Arith16 <= '1';
|
Arith16 <= '1';
|
||||||
SetWZ <= "11";
|
SetWZ <= "11";
|
||||||
|
No_PC <= '1';
|
||||||
when 3 =>
|
when 3 =>
|
||||||
NoRead <= '1';
|
NoRead <= '1';
|
||||||
Read_To_Reg <= '1';
|
Read_To_Reg <= '1';
|
||||||
@ -891,16 +991,37 @@ begin
|
|||||||
Arith16 <= '1';
|
Arith16 <= '1';
|
||||||
when others =>
|
when others =>
|
||||||
end case;
|
end case;
|
||||||
|
end if;
|
||||||
when "00000011"|"00010011"|"00100011"|"00110011" =>
|
when "00000011"|"00010011"|"00100011"|"00110011" =>
|
||||||
-- INC ss
|
-- INC ss
|
||||||
|
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";
|
TStates <= "110";
|
||||||
IncDec_16(3 downto 2) <= "01";
|
IncDec_16(3 downto 2) <= "01";
|
||||||
IncDec_16(1 downto 0) <= DPair;
|
IncDec_16(1 downto 0) <= DPair;
|
||||||
|
end if;
|
||||||
when "00001011"|"00011011"|"00101011"|"00111011" =>
|
when "00001011"|"00011011"|"00101011"|"00111011" =>
|
||||||
-- DEC ss
|
-- DEC ss
|
||||||
|
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";
|
TStates <= "110";
|
||||||
IncDec_16(3 downto 2) <= "11";
|
IncDec_16(3 downto 2) <= "11";
|
||||||
IncDec_16(1 downto 0) <= DPair;
|
IncDec_16(1 downto 0) <= DPair;
|
||||||
|
end if;
|
||||||
|
|
||||||
-- ROTATE AND SHIFT GROUP
|
-- ROTATE AND SHIFT GROUP
|
||||||
when "00000111"
|
when "00000111"
|
||||||
@ -914,12 +1035,17 @@ begin
|
|||||||
Set_BusA_To(2 downto 0) <= "111";
|
Set_BusA_To(2 downto 0) <= "111";
|
||||||
ALU_Op <= "1000";
|
ALU_Op <= "1000";
|
||||||
Read_To_Reg <= '1';
|
Read_To_Reg <= '1';
|
||||||
|
Rot_Akku <= '1';
|
||||||
Save_ALU <= '1';
|
Save_ALU <= '1';
|
||||||
|
|
||||||
-- JUMP GROUP
|
-- JUMP GROUP
|
||||||
when "11000011" =>
|
when "11000011" =>
|
||||||
-- JP nn
|
-- JP nn
|
||||||
|
if Mode = 3 then
|
||||||
|
MCycles <= "100";
|
||||||
|
else
|
||||||
MCycles <= "011";
|
MCycles <= "011";
|
||||||
|
end if;
|
||||||
case to_integer(unsigned(MCycle)) is
|
case to_integer(unsigned(MCycle)) is
|
||||||
when 2 =>
|
when 2 =>
|
||||||
Inc_PC <= '1';
|
Inc_PC <= '1';
|
||||||
@ -927,7 +1053,9 @@ begin
|
|||||||
when 3 =>
|
when 3 =>
|
||||||
Inc_PC <= '1';
|
Inc_PC <= '1';
|
||||||
Jump <= '1';
|
Jump <= '1';
|
||||||
|
if Mode /= 3 then
|
||||||
LDW <= '1';
|
LDW <= '1';
|
||||||
|
end if;
|
||||||
when others => null;
|
when others => null;
|
||||||
end case;
|
end case;
|
||||||
when "11000010"|"11001010"|"11010010"|"11011010"|"11100010"|"11101010"|"11110010"|"11111010" =>
|
when "11000010"|"11001010"|"11010010"|"11011010"|"11100010"|"11101010"|"11110010"|"11111010" =>
|
||||||
@ -940,9 +1068,9 @@ begin
|
|||||||
when 1 =>
|
when 1 =>
|
||||||
Set_Addr_To <= aBC;
|
Set_Addr_To <= aBC;
|
||||||
Set_BusB_To <= "0111";
|
Set_BusB_To <= "0111";
|
||||||
|
IORQ <= '1'; --TH must be earlier to be stable when address is generated
|
||||||
when 2 =>
|
when 2 =>
|
||||||
Write <= '1';
|
Write <= '1';
|
||||||
IORQ <= '1';
|
|
||||||
when others =>
|
when others =>
|
||||||
end case;
|
end case;
|
||||||
when "01" =>
|
when "01" =>
|
||||||
@ -966,9 +1094,9 @@ begin
|
|||||||
case to_integer(unsigned(MCycle)) is
|
case to_integer(unsigned(MCycle)) is
|
||||||
when 1 =>
|
when 1 =>
|
||||||
Set_Addr_To <= aBC;
|
Set_Addr_To <= aBC;
|
||||||
|
IORQ <= '1'; --TH must be earlier to be stable when address is generated
|
||||||
when 2 =>
|
when 2 =>
|
||||||
Read_To_Acc <= '1';
|
Read_To_Acc <= '1';
|
||||||
IORQ <= '1';
|
|
||||||
when others =>
|
when others =>
|
||||||
end case;
|
end case;
|
||||||
when "11" =>
|
when "11" =>
|
||||||
@ -988,16 +1116,24 @@ begin
|
|||||||
end case;
|
end case;
|
||||||
else
|
else
|
||||||
-- JP cc,nn
|
-- JP cc,nn
|
||||||
|
if Mode = 3 then
|
||||||
|
MCycles <= "100";
|
||||||
|
else
|
||||||
MCycles <= "011";
|
MCycles <= "011";
|
||||||
|
end if;
|
||||||
case to_integer(unsigned(MCycle)) is
|
case to_integer(unsigned(MCycle)) is
|
||||||
when 2 =>
|
when 2 =>
|
||||||
Inc_PC <= '1';
|
Inc_PC <= '1';
|
||||||
LDZ <= '1';
|
LDZ <= '1';
|
||||||
when 3 =>
|
when 3 =>
|
||||||
|
if Mode /= 3 then
|
||||||
LDW <= '1';
|
LDW <= '1';
|
||||||
|
end if;
|
||||||
Inc_PC <= '1';
|
Inc_PC <= '1';
|
||||||
if is_cc_true(F, to_bitvector(IR(5 downto 3))) then
|
if is_cc_true(F, to_bitvector(IR(5 downto 3))) then
|
||||||
Jump <= '1';
|
Jump <= '1';
|
||||||
|
elsif Mode = 3 then
|
||||||
|
MCycles <= "011";
|
||||||
end if;
|
end if;
|
||||||
when others => null;
|
when others => null;
|
||||||
end case;
|
end case;
|
||||||
@ -1009,6 +1145,7 @@ begin
|
|||||||
case to_integer(unsigned(MCycle)) is
|
case to_integer(unsigned(MCycle)) is
|
||||||
when 2 =>
|
when 2 =>
|
||||||
Inc_PC <= '1';
|
Inc_PC <= '1';
|
||||||
|
No_PC <= '1';
|
||||||
when 3 =>
|
when 3 =>
|
||||||
NoRead <= '1';
|
NoRead <= '1';
|
||||||
JumpE <= '1';
|
JumpE <= '1';
|
||||||
@ -1025,6 +1162,8 @@ begin
|
|||||||
Inc_PC <= '1';
|
Inc_PC <= '1';
|
||||||
if F(Flag_C) = '0' then
|
if F(Flag_C) = '0' then
|
||||||
MCycles <= "010";
|
MCycles <= "010";
|
||||||
|
else
|
||||||
|
No_PC <= '1';
|
||||||
end if;
|
end if;
|
||||||
when 3 =>
|
when 3 =>
|
||||||
NoRead <= '1';
|
NoRead <= '1';
|
||||||
@ -1042,6 +1181,8 @@ begin
|
|||||||
Inc_PC <= '1';
|
Inc_PC <= '1';
|
||||||
if F(Flag_C) = '1' then
|
if F(Flag_C) = '1' then
|
||||||
MCycles <= "010";
|
MCycles <= "010";
|
||||||
|
else
|
||||||
|
No_PC <= '1';
|
||||||
end if;
|
end if;
|
||||||
when 3 =>
|
when 3 =>
|
||||||
NoRead <= '1';
|
NoRead <= '1';
|
||||||
@ -1059,6 +1200,8 @@ begin
|
|||||||
Inc_PC <= '1';
|
Inc_PC <= '1';
|
||||||
if F(Flag_Z) = '0' then
|
if F(Flag_Z) = '0' then
|
||||||
MCycles <= "010";
|
MCycles <= "010";
|
||||||
|
else
|
||||||
|
No_PC <= '1';
|
||||||
end if;
|
end if;
|
||||||
when 3 =>
|
when 3 =>
|
||||||
NoRead <= '1';
|
NoRead <= '1';
|
||||||
@ -1076,6 +1219,8 @@ begin
|
|||||||
Inc_PC <= '1';
|
Inc_PC <= '1';
|
||||||
if F(Flag_Z) = '1' then
|
if F(Flag_Z) = '1' then
|
||||||
MCycles <= "010";
|
MCycles <= "010";
|
||||||
|
else
|
||||||
|
No_PC <= '1';
|
||||||
end if;
|
end if;
|
||||||
when 3 =>
|
when 3 =>
|
||||||
NoRead <= '1';
|
NoRead <= '1';
|
||||||
@ -1088,8 +1233,14 @@ begin
|
|||||||
-- JP (HL)
|
-- JP (HL)
|
||||||
JumpXY <= '1';
|
JumpXY <= '1';
|
||||||
when "00010000" =>
|
when "00010000" =>
|
||||||
if Mode = 3 then
|
if Mode = 3 then -- STOP and skip next byte
|
||||||
|
MCycles <= "010";
|
||||||
I_DJNZ <= '1';
|
I_DJNZ <= '1';
|
||||||
|
case to_integer(unsigned(MCycle)) is
|
||||||
|
when 2 =>
|
||||||
|
Inc_PC <= '1';
|
||||||
|
when others => null;
|
||||||
|
end case;
|
||||||
elsif Mode < 2 then
|
elsif Mode < 2 then
|
||||||
-- DJNZ,e
|
-- DJNZ,e
|
||||||
MCycles <= "011";
|
MCycles <= "011";
|
||||||
@ -1105,6 +1256,7 @@ begin
|
|||||||
when 2 =>
|
when 2 =>
|
||||||
I_DJNZ <= '1';
|
I_DJNZ <= '1';
|
||||||
Inc_PC <= '1';
|
Inc_PC <= '1';
|
||||||
|
No_PC <= '1';
|
||||||
when 3 =>
|
when 3 =>
|
||||||
NoRead <= '1';
|
NoRead <= '1';
|
||||||
JumpE <= '1';
|
JumpE <= '1';
|
||||||
@ -1116,7 +1268,11 @@ begin
|
|||||||
-- CALL AND RETURN GROUP
|
-- CALL AND RETURN GROUP
|
||||||
when "11001101" =>
|
when "11001101" =>
|
||||||
-- CALL nn
|
-- CALL nn
|
||||||
|
if Mode = 3 then
|
||||||
|
MCycles <= "110";
|
||||||
|
else
|
||||||
MCycles <= "101";
|
MCycles <= "101";
|
||||||
|
end if;
|
||||||
case to_integer(unsigned(MCycle)) is
|
case to_integer(unsigned(MCycle)) is
|
||||||
when 2 =>
|
when 2 =>
|
||||||
Inc_PC <= '1';
|
Inc_PC <= '1';
|
||||||
@ -1141,7 +1297,11 @@ begin
|
|||||||
when "11000100"|"11001100"|"11010100"|"11011100"|"11100100"|"11101100"|"11110100"|"11111100" =>
|
when "11000100"|"11001100"|"11010100"|"11011100"|"11100100"|"11101100"|"11110100"|"11111100" =>
|
||||||
if IR(5) = '0' or Mode /= 3 then
|
if IR(5) = '0' or Mode /= 3 then
|
||||||
-- CALL cc,nn
|
-- CALL cc,nn
|
||||||
|
if Mode = 3 then
|
||||||
|
MCycles <= "110";
|
||||||
|
else
|
||||||
MCycles <= "101";
|
MCycles <= "101";
|
||||||
|
end if;
|
||||||
case to_integer(unsigned(MCycle)) is
|
case to_integer(unsigned(MCycle)) is
|
||||||
when 2 =>
|
when 2 =>
|
||||||
Inc_PC <= '1';
|
Inc_PC <= '1';
|
||||||
@ -1170,6 +1330,21 @@ begin
|
|||||||
end if;
|
end if;
|
||||||
when "11001001" =>
|
when "11001001" =>
|
||||||
-- RET
|
-- RET
|
||||||
|
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";
|
MCycles <= "011";
|
||||||
case to_integer(unsigned(MCycle)) is
|
case to_integer(unsigned(MCycle)) is
|
||||||
when 1 =>
|
when 1 =>
|
||||||
@ -1184,6 +1359,7 @@ begin
|
|||||||
IncDec_16 <= "0111";
|
IncDec_16 <= "0111";
|
||||||
when others => null;
|
when others => null;
|
||||||
end case;
|
end case;
|
||||||
|
end if;
|
||||||
when "11000000"|"11001000"|"11010000"|"11011000"|"11100000"|"11101000"|"11110000"|"11111000" =>
|
when "11000000"|"11001000"|"11010000"|"11011000"|"11100000"|"11101000"|"11110000"|"11111000" =>
|
||||||
if IR(5) = '1' and Mode = 3 then
|
if IR(5) = '1' and Mode = 3 then
|
||||||
case IRB(4 downto 3) is
|
case IRB(4 downto 3) is
|
||||||
@ -1201,22 +1377,11 @@ begin
|
|||||||
end case;
|
end case;
|
||||||
when "01" =>
|
when "01" =>
|
||||||
-- ADD SP,n
|
-- ADD SP,n
|
||||||
MCycles <= "011";
|
MCycles <= "100";
|
||||||
case to_integer(unsigned(MCycle)) is
|
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 =>
|
when 3 =>
|
||||||
NoRead <= '1';
|
Inc_PC <= '1';
|
||||||
Read_To_Reg <= '1';
|
ADDSPdd <= '1';
|
||||||
Save_ALU <= '1';
|
|
||||||
ALU_Op <= "0001";
|
|
||||||
Set_BusA_To <= "1001";
|
|
||||||
Set_BusB_To <= "1110"; -- Incorrect unsigned !!!!!!!!!!!!!!!!!!!!!
|
|
||||||
when others =>
|
when others =>
|
||||||
end case;
|
end case;
|
||||||
when "10" =>
|
when "10" =>
|
||||||
@ -1231,29 +1396,41 @@ begin
|
|||||||
when others => null;
|
when others => null;
|
||||||
end case;
|
end case;
|
||||||
when "11" =>
|
when "11" =>
|
||||||
-- LD HL,SP+n -- Not correct !!!!!!!!!!!!!!!!!!!
|
-- LD HL,SP+n
|
||||||
MCycles <= "101";
|
MCycles <= "011";
|
||||||
case to_integer(unsigned(MCycle)) is
|
case to_integer(unsigned(MCycle)) is
|
||||||
|
when 1 =>
|
||||||
|
Inc_PC <= '1';
|
||||||
when 2 =>
|
when 2 =>
|
||||||
|
LDHLSP <= '1';
|
||||||
Inc_PC <= '1';
|
Inc_PC <= '1';
|
||||||
LDZ <= '1';
|
|
||||||
when 3 =>
|
when 3 =>
|
||||||
Set_Addr_To <= aZI;
|
LDHLSP <= '1';
|
||||||
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';
|
|
||||||
when others => null;
|
when others => null;
|
||||||
end case;
|
end case;
|
||||||
end case;
|
end case;
|
||||||
else
|
else
|
||||||
-- RET cc
|
-- RET cc
|
||||||
|
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";
|
MCycles <= "011";
|
||||||
case to_integer(unsigned(MCycle)) is
|
case to_integer(unsigned(MCycle)) is
|
||||||
when 1 =>
|
when 1 =>
|
||||||
@ -1273,8 +1450,28 @@ begin
|
|||||||
when others => null;
|
when others => null;
|
||||||
end case;
|
end case;
|
||||||
end if;
|
end if;
|
||||||
|
end if;
|
||||||
when "11000111"|"11001111"|"11010111"|"11011111"|"11100111"|"11101111"|"11110111"|"11111111" =>
|
when "11000111"|"11001111"|"11010111"|"11011111"|"11100111"|"11101111"|"11110111"|"11111111" =>
|
||||||
-- RST p
|
-- RST p
|
||||||
|
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";
|
MCycles <= "011";
|
||||||
case to_integer(unsigned(MCycle)) is
|
case to_integer(unsigned(MCycle)) is
|
||||||
when 1 =>
|
when 1 =>
|
||||||
@ -1292,6 +1489,7 @@ begin
|
|||||||
RstP <= '1';
|
RstP <= '1';
|
||||||
when others => null;
|
when others => null;
|
||||||
end case;
|
end case;
|
||||||
|
end if;
|
||||||
|
|
||||||
-- INPUT AND OUTPUT GROUP
|
-- INPUT AND OUTPUT GROUP
|
||||||
when "11011011" =>
|
when "11011011" =>
|
||||||
@ -1591,16 +1789,16 @@ begin
|
|||||||
| "10101100"|"10101101"|"10101110"|"10101111"
|
| "10101100"|"10101101"|"10101110"|"10101111"
|
||||||
| "10110100"|"10110101"|"10110110"|"10110111"
|
| "10110100"|"10110101"|"10110110"|"10110111"
|
||||||
| "10111100"|"10111101"|"10111110"|"10111111"
|
| "10111100"|"10111101"|"10111110"|"10111111"
|
||||||
|"11000000"|"11000001"|"11000010"|"11000011"|"11000100"|"11000101"|"11000110"|"11000111"
|
|"11000000"| "11000010" |"11000100"|"11000101"|"11000110"|"11000111"
|
||||||
|"11001000"|"11001001"|"11001010"|"11001011"|"11001100"|"11001101"|"11001110"|"11001111"
|
|"11001000"| "11001010"|"11001011"|"11001100"|"11001101"|"11001110"|"11001111"
|
||||||
|"11010000"|"11010001"|"11010010"|"11010011"|"11010100"|"11010101"|"11010110"|"11010111"
|
|"11010000"| "11010010"|"11010011"|"11010100"|"11010101"|"11010110"|"11010111"
|
||||||
|"11011000"|"11011001"|"11011010"|"11011011"|"11011100"|"11011101"|"11011110"|"11011111"
|
|"11011000"| "11011010"|"11011011"|"11011100"|"11011101"|"11011110"|"11011111"
|
||||||
|"11100000"|"11100001"|"11100010"|"11100011"|"11100100"|"11100101"|"11100110"|"11100111"
|
|"11100000"|"11100001"|"11100010"|"11100011"|"11100100"|"11100101"|"11100110"|"11100111"
|
||||||
|"11101000"|"11101001"|"11101010"|"11101011"|"11101100"|"11101101"|"11101110"|"11101111"
|
|"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" =>
|
|"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111110"|"11111111" =>
|
||||||
null; -- NOP, undocumented
|
null; -- NOP, undocumented
|
||||||
when "01111110"|"01111111" =>
|
when "01110111"|"01111111" =>
|
||||||
-- NOP, undocumented
|
-- NOP, undocumented
|
||||||
null;
|
null;
|
||||||
-- 8 BIT LOAD GROUP
|
-- 8 BIT LOAD GROUP
|
||||||
@ -1711,6 +1909,7 @@ begin
|
|||||||
else
|
else
|
||||||
IncDec_16 <= "1101";
|
IncDec_16 <= "1101";
|
||||||
end if;
|
end if;
|
||||||
|
No_PC <= '1';
|
||||||
when 4 =>
|
when 4 =>
|
||||||
NoRead <= '1';
|
NoRead <= '1';
|
||||||
TStates <= "101";
|
TStates <= "101";
|
||||||
@ -1734,10 +1933,12 @@ begin
|
|||||||
else
|
else
|
||||||
IncDec_16 <= "1110";
|
IncDec_16 <= "1110";
|
||||||
end if;
|
end if;
|
||||||
|
No_PC <= '1';
|
||||||
when 3 =>
|
when 3 =>
|
||||||
NoRead <= '1';
|
NoRead <= '1';
|
||||||
I_BC <= '1';
|
I_BC <= '1';
|
||||||
TStates <= "101";
|
TStates <= "101";
|
||||||
|
No_PC <= '1';
|
||||||
when 4 =>
|
when 4 =>
|
||||||
NoRead <= '1';
|
NoRead <= '1';
|
||||||
TStates <= "101";
|
TStates <= "101";
|
||||||
@ -1756,7 +1957,7 @@ begin
|
|||||||
when "01010110"|"01110110" =>
|
when "01010110"|"01110110" =>
|
||||||
-- IM 1
|
-- IM 1
|
||||||
IMode <= "01";
|
IMode <= "01";
|
||||||
when "01011110"|"01110111" =>
|
when "01011110"|"01111110" =>
|
||||||
-- IM 2
|
-- IM 2
|
||||||
IMode <= "10";
|
IMode <= "10";
|
||||||
-- 16 bit arithmetic
|
-- 16 bit arithmetic
|
||||||
@ -1764,6 +1965,8 @@ begin
|
|||||||
-- ADC HL,ss
|
-- ADC HL,ss
|
||||||
MCycles <= "011";
|
MCycles <= "011";
|
||||||
case to_integer(unsigned(MCycle)) is
|
case to_integer(unsigned(MCycle)) is
|
||||||
|
when 1 =>
|
||||||
|
No_PC <= '1';
|
||||||
when 2 =>
|
when 2 =>
|
||||||
NoRead <= '1';
|
NoRead <= '1';
|
||||||
ALU_Op <= "0001";
|
ALU_Op <= "0001";
|
||||||
@ -1779,6 +1982,7 @@ begin
|
|||||||
end case;
|
end case;
|
||||||
TStates <= "100";
|
TStates <= "100";
|
||||||
SetWZ <= "11";
|
SetWZ <= "11";
|
||||||
|
No_PC <= '1';
|
||||||
when 3 =>
|
when 3 =>
|
||||||
NoRead <= '1';
|
NoRead <= '1';
|
||||||
Read_To_Reg <= '1';
|
Read_To_Reg <= '1';
|
||||||
@ -1798,6 +2002,8 @@ begin
|
|||||||
-- SBC HL,ss
|
-- SBC HL,ss
|
||||||
MCycles <= "011";
|
MCycles <= "011";
|
||||||
case to_integer(unsigned(MCycle)) is
|
case to_integer(unsigned(MCycle)) is
|
||||||
|
when 1 =>
|
||||||
|
No_PC <= '1';
|
||||||
when 2 =>
|
when 2 =>
|
||||||
NoRead <= '1';
|
NoRead <= '1';
|
||||||
ALU_Op <= "0011";
|
ALU_Op <= "0011";
|
||||||
@ -1813,6 +2019,7 @@ begin
|
|||||||
end case;
|
end case;
|
||||||
TStates <= "100";
|
TStates <= "100";
|
||||||
SetWZ <= "11";
|
SetWZ <= "11";
|
||||||
|
No_PC <= '1';
|
||||||
when 3 =>
|
when 3 =>
|
||||||
NoRead <= '1';
|
NoRead <= '1';
|
||||||
ALU_Op <= "0011";
|
ALU_Op <= "0011";
|
||||||
@ -1839,6 +2046,7 @@ begin
|
|||||||
Set_BusA_To(2 downto 0) <= "111";
|
Set_BusA_To(2 downto 0) <= "111";
|
||||||
ALU_Op <= "1101";
|
ALU_Op <= "1101";
|
||||||
Save_ALU <= '1';
|
Save_ALU <= '1';
|
||||||
|
No_PC <= '1';
|
||||||
when 3 =>
|
when 3 =>
|
||||||
TStates <= "100";
|
TStates <= "100";
|
||||||
I_RLD <= '1';
|
I_RLD <= '1';
|
||||||
@ -1860,6 +2068,7 @@ begin
|
|||||||
Set_BusA_To(2 downto 0) <= "111";
|
Set_BusA_To(2 downto 0) <= "111";
|
||||||
ALU_Op <= "1110";
|
ALU_Op <= "1110";
|
||||||
Save_ALU <= '1';
|
Save_ALU <= '1';
|
||||||
|
No_PC <= '1';
|
||||||
when 3 =>
|
when 3 =>
|
||||||
TStates <= "100";
|
TStates <= "100";
|
||||||
I_RRD <= '1';
|
I_RRD <= '1';
|
||||||
@ -1981,6 +2190,46 @@ begin
|
|||||||
TStates <= "101";
|
TStates <= "101";
|
||||||
when others => null;
|
when others => null;
|
||||||
end case;
|
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;
|
||||||
|
|
||||||
end case;
|
end case;
|
||||||
@ -2013,6 +2262,9 @@ begin
|
|||||||
if IRB = "00110110" or IRB = "11001011" then
|
if IRB = "00110110" or IRB = "11001011" then
|
||||||
Set_Addr_To <= aNone;
|
Set_Addr_To <= aNone;
|
||||||
end if;
|
end if;
|
||||||
|
if not (IRB = "00110110" or ISet = "01") then
|
||||||
|
No_PC <= '1';
|
||||||
|
end if;
|
||||||
end if;
|
end if;
|
||||||
if MCycle = "111" then
|
if MCycle = "111" then
|
||||||
if Mode = 0 then
|
if Mode = 0 then
|
||||||
|
248
rtl/T80/T80_Pack.vhd
Normal file
248
rtl/T80/T80_Pack.vhd
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
-- ****
|
||||||
|
-- T80(b) core. In an effort to merge and maintain bug fixes ....
|
||||||
|
--
|
||||||
|
--
|
||||||
|
-- Ver 303 add undocumented DDCB and FDCB opcodes by TobiFlex 20.04.2010
|
||||||
|
-- Ver 300 started tidyup
|
||||||
|
-- MikeJ March 2005
|
||||||
|
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
|
||||||
|
--
|
||||||
|
-- ****
|
||||||
|
--
|
||||||
|
-- Z80 compatible microprocessor core
|
||||||
|
--
|
||||||
|
-- Version : 0250
|
||||||
|
--
|
||||||
|
-- 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 :
|
||||||
|
--
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.std_logic_1164.all;
|
||||||
|
|
||||||
|
package T80_Pack is
|
||||||
|
|
||||||
|
constant aNone : std_logic_vector(2 downto 0) := "111";
|
||||||
|
constant aBC : std_logic_vector(2 downto 0) := "000";
|
||||||
|
constant aDE : std_logic_vector(2 downto 0) := "001";
|
||||||
|
constant aXY : std_logic_vector(2 downto 0) := "010";
|
||||||
|
constant aIOA : std_logic_vector(2 downto 0) := "100";
|
||||||
|
constant aSP : std_logic_vector(2 downto 0) := "101";
|
||||||
|
constant aZI : std_logic_vector(2 downto 0) := "110";
|
||||||
|
|
||||||
|
component T80
|
||||||
|
generic(
|
||||||
|
Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
|
||||||
|
IOWait : integer := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle
|
||||||
|
Flag_C : integer := 0;
|
||||||
|
Flag_N : integer := 1;
|
||||||
|
Flag_P : integer := 2;
|
||||||
|
Flag_X : integer := 3;
|
||||||
|
Flag_H : integer := 4;
|
||||||
|
Flag_Y : integer := 5;
|
||||||
|
Flag_Z : integer := 6;
|
||||||
|
Flag_S : integer := 7
|
||||||
|
);
|
||||||
|
port(
|
||||||
|
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;
|
||||||
|
IORQ : out std_logic;
|
||||||
|
NoRead : out std_logic;
|
||||||
|
Write : 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);
|
||||||
|
DInst : in std_logic_vector(7 downto 0);
|
||||||
|
DI : in std_logic_vector(7 downto 0);
|
||||||
|
DO : out std_logic_vector(7 downto 0);
|
||||||
|
MC : out std_logic_vector(2 downto 0);
|
||||||
|
TS : out std_logic_vector(2 downto 0);
|
||||||
|
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';
|
||||||
|
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
|
||||||
|
);
|
||||||
|
end component;
|
||||||
|
|
||||||
|
component T80_Reg
|
||||||
|
port(
|
||||||
|
Clk : in std_logic;
|
||||||
|
CEN : in std_logic;
|
||||||
|
WEH : in std_logic;
|
||||||
|
WEL : in std_logic;
|
||||||
|
AddrA : in std_logic_vector(2 downto 0);
|
||||||
|
AddrB : in std_logic_vector(2 downto 0);
|
||||||
|
AddrC : in std_logic_vector(2 downto 0);
|
||||||
|
DIH : in std_logic_vector(7 downto 0);
|
||||||
|
DIL : in std_logic_vector(7 downto 0);
|
||||||
|
DOAH : out std_logic_vector(7 downto 0);
|
||||||
|
DOAL : out std_logic_vector(7 downto 0);
|
||||||
|
DOBH : out std_logic_vector(7 downto 0);
|
||||||
|
DOBL : out std_logic_vector(7 downto 0);
|
||||||
|
DOCH : out std_logic_vector(7 downto 0);
|
||||||
|
DOCL : out std_logic_vector(7 downto 0);
|
||||||
|
DOR : out std_logic_vector(127 downto 0);
|
||||||
|
DIRSet : in std_logic;
|
||||||
|
DIR : in std_logic_vector(127 downto 0)
|
||||||
|
);
|
||||||
|
end component;
|
||||||
|
|
||||||
|
component T80_MCode
|
||||||
|
generic(
|
||||||
|
Mode : integer := 0;
|
||||||
|
Flag_C : integer := 0;
|
||||||
|
Flag_N : integer := 1;
|
||||||
|
Flag_P : integer := 2;
|
||||||
|
Flag_X : integer := 3;
|
||||||
|
Flag_H : integer := 4;
|
||||||
|
Flag_Y : integer := 5;
|
||||||
|
Flag_Z : integer := 6;
|
||||||
|
Flag_S : integer := 7
|
||||||
|
);
|
||||||
|
port(
|
||||||
|
IR : in std_logic_vector(7 downto 0);
|
||||||
|
ISet : in std_logic_vector(1 downto 0);
|
||||||
|
MCycle : in std_logic_vector(2 downto 0);
|
||||||
|
F : in std_logic_vector(7 downto 0);
|
||||||
|
NMICycle : in std_logic;
|
||||||
|
IntCycle : in std_logic;
|
||||||
|
XY_State : in std_logic_vector(1 downto 0);
|
||||||
|
MCycles : out std_logic_vector(2 downto 0);
|
||||||
|
TStates : out std_logic_vector(2 downto 0);
|
||||||
|
Prefix : out std_logic_vector(1 downto 0); -- None,BC,ED,DD/FD
|
||||||
|
Inc_PC : out std_logic;
|
||||||
|
Inc_WZ : out std_logic;
|
||||||
|
IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc
|
||||||
|
Read_To_Reg : out std_logic;
|
||||||
|
Read_To_Acc : out std_logic;
|
||||||
|
Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F
|
||||||
|
Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0
|
||||||
|
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
|
||||||
|
IORQ : out std_logic;
|
||||||
|
Jump : out std_logic;
|
||||||
|
JumpE : out std_logic;
|
||||||
|
JumpXY : out std_logic;
|
||||||
|
Call : out std_logic;
|
||||||
|
RstP : out std_logic;
|
||||||
|
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;
|
||||||
|
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;
|
||||||
|
I_SCF : out std_logic;
|
||||||
|
I_RETN : out std_logic;
|
||||||
|
I_BT : out std_logic;
|
||||||
|
I_BC : out std_logic;
|
||||||
|
I_BTR : out std_logic;
|
||||||
|
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;
|
||||||
|
IMode : out std_logic_vector(1 downto 0);
|
||||||
|
Halt : out std_logic;
|
||||||
|
NoRead : out std_logic;
|
||||||
|
Write : out std_logic;
|
||||||
|
R800_mode : in std_logic;
|
||||||
|
No_PC : out std_logic;
|
||||||
|
XYbit_undoc : out std_logic
|
||||||
|
);
|
||||||
|
end component;
|
||||||
|
|
||||||
|
component T80_ALU
|
||||||
|
generic(
|
||||||
|
Mode : integer := 0;
|
||||||
|
Flag_C : integer := 0;
|
||||||
|
Flag_N : integer := 1;
|
||||||
|
Flag_P : integer := 2;
|
||||||
|
Flag_X : integer := 3;
|
||||||
|
Flag_H : integer := 4;
|
||||||
|
Flag_Y : integer := 5;
|
||||||
|
Flag_Z : integer := 6;
|
||||||
|
Flag_S : integer := 7
|
||||||
|
);
|
||||||
|
port(
|
||||||
|
Arith16 : in std_logic;
|
||||||
|
Z16 : in std_logic;
|
||||||
|
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);
|
||||||
|
BusB : in std_logic_vector(7 downto 0);
|
||||||
|
F_In : in std_logic_vector(7 downto 0);
|
||||||
|
Q : out std_logic_vector(7 downto 0);
|
||||||
|
F_Out : out std_logic_vector(7 downto 0)
|
||||||
|
);
|
||||||
|
end component;
|
||||||
|
|
||||||
|
end;
|
@ -89,7 +89,9 @@ entity T80_Reg is
|
|||||||
DOBL : out std_logic_vector(7 downto 0);
|
DOBL : out std_logic_vector(7 downto 0);
|
||||||
DOCH : out std_logic_vector(7 downto 0);
|
DOCH : out std_logic_vector(7 downto 0);
|
||||||
DOCL : out std_logic_vector(7 downto 0);
|
DOCL : out std_logic_vector(7 downto 0);
|
||||||
DOR : out std_logic_vector(127 downto 0)
|
DOR : out std_logic_vector(127 downto 0);
|
||||||
|
DIRSet : in std_logic;
|
||||||
|
DIR : in std_logic_vector(127 downto 0)
|
||||||
);
|
);
|
||||||
end T80_Reg;
|
end T80_Reg;
|
||||||
|
|
||||||
@ -104,7 +106,31 @@ begin
|
|||||||
process (Clk)
|
process (Clk)
|
||||||
begin
|
begin
|
||||||
if rising_edge(Clk) then
|
if rising_edge(Clk) then
|
||||||
if CEN = '1' then
|
if DIRSet = '1' then
|
||||||
|
RegsL(0) <= DIR( 7 downto 0);
|
||||||
|
RegsH(0) <= DIR( 15 downto 8);
|
||||||
|
|
||||||
|
RegsL(1) <= DIR( 23 downto 16);
|
||||||
|
RegsH(1) <= DIR( 31 downto 24);
|
||||||
|
|
||||||
|
RegsL(2) <= DIR( 39 downto 32);
|
||||||
|
RegsH(2) <= DIR( 47 downto 40);
|
||||||
|
|
||||||
|
RegsL(3) <= DIR( 55 downto 48);
|
||||||
|
RegsH(3) <= DIR( 63 downto 56);
|
||||||
|
|
||||||
|
RegsL(4) <= DIR( 71 downto 64);
|
||||||
|
RegsH(4) <= DIR( 79 downto 72);
|
||||||
|
|
||||||
|
RegsL(5) <= DIR( 87 downto 80);
|
||||||
|
RegsH(5) <= DIR( 95 downto 88);
|
||||||
|
|
||||||
|
RegsL(6) <= DIR(103 downto 96);
|
||||||
|
RegsH(6) <= DIR(111 downto 104);
|
||||||
|
|
||||||
|
RegsL(7) <= DIR(119 downto 112);
|
||||||
|
RegsH(7) <= DIR(127 downto 120);
|
||||||
|
elsif CEN = '1' then
|
||||||
if WEH = '1' then
|
if WEH = '1' then
|
||||||
RegsH(to_integer(unsigned(AddrA))) <= DIH;
|
RegsH(to_integer(unsigned(AddrA))) <= DIH;
|
||||||
end if;
|
end if;
|
||||||
|
342
rtl/T80/T80a.vhd
Normal file
342
rtl/T80/T80a.vhd
Normal file
@ -0,0 +1,342 @@
|
|||||||
|
-- ****
|
||||||
|
-- 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
|
||||||
|
--
|
||||||
|
-- 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 :
|
||||||
|
--
|
||||||
|
-- 0208 : First complete release
|
||||||
|
--
|
||||||
|
-- 0211 : Fixed interrupt cycle
|
||||||
|
--
|
||||||
|
-- 0235 : Updated for T80 interface change
|
||||||
|
--
|
||||||
|
-- 0238 : Updated for T80 interface change
|
||||||
|
--
|
||||||
|
-- 0240 : 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
|
||||||
|
--
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.std_logic_1164.all;
|
||||||
|
use IEEE.numeric_std.all;
|
||||||
|
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
|
||||||
|
);
|
||||||
|
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;
|
||||||
|
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)
|
||||||
|
);
|
||||||
|
end T80a;
|
||||||
|
|
||||||
|
architecture rtl of T80a is
|
||||||
|
|
||||||
|
signal CEN : std_logic;
|
||||||
|
signal Reset_s : std_logic;
|
||||||
|
signal IntCycle_n : std_logic;
|
||||||
|
signal IORQ : std_logic;
|
||||||
|
signal NoRead : std_logic;
|
||||||
|
signal Write : std_logic;
|
||||||
|
signal MREQ : std_logic;
|
||||||
|
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);
|
||||||
|
signal DO : std_logic_vector(7 downto 0);
|
||||||
|
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);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
CEN <= '1';
|
||||||
|
|
||||||
|
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 when BUSAK_n_i = '1' else 'Z';
|
||||||
|
RD_n <= RD_n_i when BUSAK_n_i = '1' else 'Z';
|
||||||
|
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');
|
||||||
|
|
||||||
|
process (RESET_n, CLK_n)
|
||||||
|
begin
|
||||||
|
if RESET_n = '0' then
|
||||||
|
Reset_s <= '0';
|
||||||
|
elsif CLK_n'event and CLK_n = '1' then
|
||||||
|
Reset_s <= '1';
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
u0 : T80
|
||||||
|
generic map(
|
||||||
|
Mode => Mode,
|
||||||
|
IOWait => IOWait)
|
||||||
|
port map(
|
||||||
|
R800_mode => R800_mode,
|
||||||
|
CEN => CEN,
|
||||||
|
M1_n => M1_n,
|
||||||
|
IORQ => IORQ,
|
||||||
|
NoRead => NoRead,
|
||||||
|
Write => Write,
|
||||||
|
RFSH_n => RFSH_n_i,
|
||||||
|
HALT_n => HALT_n,
|
||||||
|
WAIT_n => Wait_s,
|
||||||
|
INT_n => INT_n,
|
||||||
|
NMI_n => NMI_n,
|
||||||
|
RESET_n => Reset_s,
|
||||||
|
BUSRQ_n => BUSRQ_n,
|
||||||
|
BUSAK_n => BUSAK_n_i,
|
||||||
|
CLK_n => CLK_n,
|
||||||
|
A => A_i,
|
||||||
|
DInst => D,
|
||||||
|
DI => DI_Reg,
|
||||||
|
DO => DO,
|
||||||
|
MC => MCycle,
|
||||||
|
TS => TState,
|
||||||
|
IntCycle_n => IntCycle_n);
|
||||||
|
|
||||||
|
process (CLK_n)
|
||||||
|
begin
|
||||||
|
if CLK_n'event and CLK_n = '0' then
|
||||||
|
Wait_s <= WAIT_n;
|
||||||
|
if TState = "011" and BUSAK_n_i = '1' then
|
||||||
|
DI_Reg <= to_x01(D);
|
||||||
|
end if;
|
||||||
|
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;
|
||||||
|
|
||||||
|
-- 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;
|
||||||
|
|
||||||
|
-- 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;
|
||||||
|
|
||||||
|
-- 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;
|
||||||
|
|
||||||
|
-- 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" and Wait_s = '1' then
|
||||||
|
IORQ_int <= '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;
|
289
rtl/T80/T80as.vhd
Normal file
289
rtl/T80/T80as.vhd
Normal file
@ -0,0 +1,289 @@
|
|||||||
|
------------------------------------------------------------------------------
|
||||||
|
-- 2004.10.18 WR_n active was changed from T2 to T3.
|
||||||
|
-- modification by Katsumi Degawa
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
-- t80as.vhd : The non-tristate signal edition of t80a.vhd
|
||||||
|
--
|
||||||
|
-- 2003.2.7 non-tristate modification by Tatsuyuki Satoh
|
||||||
|
--
|
||||||
|
-- 1.separate 'D' to 'DO' and 'DI'.
|
||||||
|
-- 2.added 'DOE' to 'DO' enable signal.(data direction)
|
||||||
|
-- 3.MREQ_n,IORQ_n,RD_n,WR_n,RFSH_n,A doesn't become the condition of 'Z'.
|
||||||
|
--
|
||||||
|
-- There is a mark of "--AS" in all the change points.
|
||||||
|
--
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Z80 compatible microprocessor core, asynchronous top level
|
||||||
|
--
|
||||||
|
-- Version : 0247
|
||||||
|
--
|
||||||
|
-- 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 :
|
||||||
|
--
|
||||||
|
-- 0208 : First complete release
|
||||||
|
--
|
||||||
|
-- 0211 : Fixed interrupt cycle
|
||||||
|
--
|
||||||
|
-- 0235 : Updated for T80 interface change
|
||||||
|
--
|
||||||
|
-- 0238 : Updated for T80 interface change
|
||||||
|
--
|
||||||
|
-- 0240 : Updated for T80 interface change
|
||||||
|
--
|
||||||
|
-- 0242 : Updated for T80 interface change
|
||||||
|
--
|
||||||
|
-- 0247 : Fixed bus req/ack cycle
|
||||||
|
--
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.std_logic_1164.all;
|
||||||
|
use IEEE.numeric_std.all;
|
||||||
|
use work.T80_Pack.all;
|
||||||
|
|
||||||
|
entity T80as is
|
||||||
|
generic(
|
||||||
|
Mode : integer := 0 -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
|
||||||
|
);
|
||||||
|
port(
|
||||||
|
RESET_n : in std_logic;
|
||||||
|
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);
|
||||||
|
--AS-- D : inout std_logic_vector(7 downto 0)
|
||||||
|
--AS>>
|
||||||
|
DI : in std_logic_vector(7 downto 0);
|
||||||
|
DO : out std_logic_vector(7 downto 0);
|
||||||
|
DOE : out std_logic
|
||||||
|
--<<AS
|
||||||
|
);
|
||||||
|
end T80as;
|
||||||
|
|
||||||
|
architecture rtl of T80as is
|
||||||
|
|
||||||
|
signal CEN : std_logic;
|
||||||
|
signal Reset_s : std_logic;
|
||||||
|
signal IntCycle_n : std_logic;
|
||||||
|
signal IORQ : std_logic;
|
||||||
|
signal NoRead : std_logic;
|
||||||
|
signal Write : std_logic;
|
||||||
|
signal MREQ : std_logic;
|
||||||
|
signal MReq_Inhibit : std_logic;
|
||||||
|
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 RFSH_n_i : std_logic;
|
||||||
|
signal BUSAK_n_i : std_logic;
|
||||||
|
signal A_i : std_logic_vector(15 downto 0);
|
||||||
|
--AS-- signal DO : std_logic_vector(7 downto 0);
|
||||||
|
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);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
--AS-- MREQ_n <= MREQ_n_i when BUSAK_n_i = '1' else 'Z';
|
||||||
|
--AS-- IORQ_n <= IORQ_n_i when BUSAK_n_i = '1' else 'Z';
|
||||||
|
--AS-- RD_n <= RD_n_i when BUSAK_n_i = '1' else 'Z';
|
||||||
|
--AS-- WR_n <= WR_n_i when BUSAK_n_i = '1' else 'Z';
|
||||||
|
--AS-- RFSH_n <= RFSH_n_i when BUSAK_n_i = '1' else 'Z';
|
||||||
|
--AS-- A <= A_i when BUSAK_n_i = '1' else (others => 'Z');
|
||||||
|
--AS-- D <= DO when Write = '1' and BUSAK_n_i = '1' else (others => 'Z');
|
||||||
|
--AS>>
|
||||||
|
MREQ_n <= MREQ_n_i;
|
||||||
|
IORQ_n <= IORQ_n_i;
|
||||||
|
RD_n <= RD_n_i;
|
||||||
|
WR_n <= WR_n_i;
|
||||||
|
RFSH_n <= RFSH_n_i;
|
||||||
|
A <= A_i;
|
||||||
|
DOE <= Write when BUSAK_n_i = '1' else '0';
|
||||||
|
--<<AS
|
||||||
|
process (RESET_n, CLK_n)
|
||||||
|
begin
|
||||||
|
if RESET_n = '0' then
|
||||||
|
Reset_s <= '0';
|
||||||
|
elsif CLK_n'event and CLK_n = '1' then
|
||||||
|
Reset_s <= '1';
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
u0 : T80
|
||||||
|
generic map(
|
||||||
|
Mode => Mode,
|
||||||
|
IOWait => 1)
|
||||||
|
port map(
|
||||||
|
CEN => CEN,
|
||||||
|
M1_n => M1_n,
|
||||||
|
IORQ => IORQ,
|
||||||
|
NoRead => NoRead,
|
||||||
|
Write => Write,
|
||||||
|
RFSH_n => RFSH_n_i,
|
||||||
|
HALT_n => HALT_n,
|
||||||
|
WAIT_n => Wait_s,
|
||||||
|
INT_n => INT_n,
|
||||||
|
NMI_n => NMI_n,
|
||||||
|
RESET_n => Reset_s,
|
||||||
|
BUSRQ_n => BUSRQ_n,
|
||||||
|
BUSAK_n => BUSAK_n_i,
|
||||||
|
CLK_n => CLK_n,
|
||||||
|
A => A_i,
|
||||||
|
-- DInst => D,
|
||||||
|
DInst => DI,
|
||||||
|
DI => DI_Reg,
|
||||||
|
DO => DO,
|
||||||
|
MC => MCycle,
|
||||||
|
TS => TState,
|
||||||
|
IntCycle_n => IntCycle_n);
|
||||||
|
|
||||||
|
process (CLK_n)
|
||||||
|
begin
|
||||||
|
if CLK_n'event and CLK_n = '0' then
|
||||||
|
Wait_s <= WAIT_n;
|
||||||
|
if TState = "011" and BUSAK_n_i = '1' then
|
||||||
|
--AS-- DI_Reg <= to_x01(D);
|
||||||
|
--AS>>
|
||||||
|
DI_Reg <= to_x01(DI);
|
||||||
|
--<<AS
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
process (Reset_s,CLK_n)
|
||||||
|
begin
|
||||||
|
if Reset_s = '0' then
|
||||||
|
WR_n_i <= '1';
|
||||||
|
-- 2004.10.18 modification
|
||||||
|
-- elsif CLK_n'event and CLK_n = '1' then
|
||||||
|
elsif CLK_n'event and CLK_n = '0' then
|
||||||
|
WR_n_i <= '1';
|
||||||
|
-- if TState = "001" then -- To short for IO writes !!!!!!!!!!!!!!!!!!!
|
||||||
|
if TState = "010" then
|
||||||
|
WR_n_i <= not Write;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
process (Reset_s,CLK_n)
|
||||||
|
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
|
||||||
|
Req_Inhibit <= '1';
|
||||||
|
else
|
||||||
|
Req_Inhibit <= '0';
|
||||||
|
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;
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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
|
||||||
|
RD <= not Write;
|
||||||
|
IORQ_n_i <= not IORQ;
|
||||||
|
MREQ <= not IORQ;
|
||||||
|
end if;
|
||||||
|
if TState = "011" then
|
||||||
|
RD <= '0';
|
||||||
|
IORQ_n_i <= '1';
|
||||||
|
MREQ <= '0';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
end;
|
@ -52,10 +52,13 @@
|
|||||||
--
|
--
|
||||||
-- v2.3: Output last used Address during non-bus MCycle seems more correct.
|
-- v2.3: Output last used Address during non-bus MCycle seems more correct.
|
||||||
--
|
--
|
||||||
|
-- v2.4: Use the fixed WAIT_n in T80.vhd
|
||||||
|
--
|
||||||
|
|
||||||
library IEEE;
|
library IEEE;
|
||||||
use IEEE.std_logic_1164.all;
|
use IEEE.std_logic_1164.all;
|
||||||
use IEEE.numeric_std.all;
|
use IEEE.numeric_std.all;
|
||||||
|
use work.T80_Pack.all;
|
||||||
|
|
||||||
entity T80pa is
|
entity T80pa is
|
||||||
generic(
|
generic(
|
||||||
@ -82,7 +85,10 @@ entity T80pa is
|
|||||||
A : out std_logic_vector(15 downto 0);
|
A : out std_logic_vector(15 downto 0);
|
||||||
DI : in std_logic_vector(7 downto 0);
|
DI : in std_logic_vector(7 downto 0);
|
||||||
DO : out std_logic_vector(7 downto 0);
|
DO : out std_logic_vector(7 downto 0);
|
||||||
REG : out std_logic_vector(207 downto 0) -- IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A
|
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
|
||||||
);
|
);
|
||||||
end T80pa;
|
end T80pa;
|
||||||
|
|
||||||
@ -98,36 +104,34 @@ architecture rtl of T80pa is
|
|||||||
signal MCycle : std_logic_vector(2 downto 0);
|
signal MCycle : std_logic_vector(2 downto 0);
|
||||||
signal TState : std_logic_vector(2 downto 0);
|
signal TState : std_logic_vector(2 downto 0);
|
||||||
signal CEN_pol : std_logic;
|
signal CEN_pol : std_logic;
|
||||||
signal A_int : std_logic_vector(15 downto 0);
|
signal CEN : std_logic;
|
||||||
signal A_last : std_logic_vector(15 downto 0);
|
signal Wait_s : std_logic;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
A <= A_int when NoRead = '0' or Write = '1' else A_last;
|
CEN <= CEN_p and not CEN_pol;
|
||||||
|
|
||||||
BUSAK_n <= BUSAK;
|
BUSAK_n <= BUSAK;
|
||||||
|
|
||||||
u0 : work.T80
|
u0 : T80
|
||||||
generic map(
|
generic map(
|
||||||
Mode => Mode,
|
Mode => Mode,
|
||||||
IOWait => 1
|
IOWait => 1
|
||||||
)
|
)
|
||||||
port map(
|
port map(
|
||||||
CEN => CEN_p and not CEN_pol,
|
CEN => CEN,
|
||||||
M1_n => M1_n,
|
M1_n => M1_n,
|
||||||
IORQ => IORQ,
|
IORQ => IORQ,
|
||||||
NoRead => NoRead,
|
NoRead => NoRead,
|
||||||
Write => Write,
|
Write => Write,
|
||||||
RFSH_n => RFSH_n,
|
RFSH_n => RFSH_n,
|
||||||
HALT_n => HALT_n,
|
HALT_n => HALT_n,
|
||||||
WAIT_n => '1',
|
WAIT_n => Wait_s,
|
||||||
INT_n => INT_n,
|
INT_n => INT_n,
|
||||||
NMI_n => NMI_n,
|
NMI_n => NMI_n,
|
||||||
RESET_n => RESET_n,
|
RESET_n => RESET_n,
|
||||||
BUSRQ_n => BUSRQ_n,
|
BUSRQ_n => BUSRQ_n,
|
||||||
BUSAK_n => BUSAK,
|
BUSAK_n => BUSAK,
|
||||||
CLK_n => CLK,
|
CLK_n => CLK,
|
||||||
A => A_int,
|
A => A,
|
||||||
DInst => DI, -- valid at beginning of T3
|
DInst => DI, -- valid at beginning of T3
|
||||||
DI => DI_Reg, -- latched at middle of T3
|
DI => DI_Reg, -- latched at middle of T3
|
||||||
DO => DO,
|
DO => DO,
|
||||||
@ -135,7 +139,10 @@ begin
|
|||||||
MC => MCycle,
|
MC => MCycle,
|
||||||
TS => TState,
|
TS => TState,
|
||||||
OUT0 => OUT0,
|
OUT0 => OUT0,
|
||||||
IntCycle_n => IntCycle_n
|
R800_mode => R800_mode,
|
||||||
|
IntCycle_n => IntCycle_n,
|
||||||
|
DIRSet => DIRSet,
|
||||||
|
DIR => DIR
|
||||||
);
|
);
|
||||||
|
|
||||||
process(CLK)
|
process(CLK)
|
||||||
@ -150,6 +157,7 @@ begin
|
|||||||
CEN_pol <= '0';
|
CEN_pol <= '0';
|
||||||
elsif CEN_p = '1' and CEN_pol = '0' then
|
elsif CEN_p = '1' and CEN_pol = '0' then
|
||||||
CEN_pol <= '1';
|
CEN_pol <= '1';
|
||||||
|
if WAIT_s = '1' or TState /= "010" then
|
||||||
if MCycle = "001" then
|
if MCycle = "001" then
|
||||||
if TState = "010" then
|
if TState = "010" then
|
||||||
IORQ_n <= '1';
|
IORQ_n <= '1';
|
||||||
@ -163,12 +171,10 @@ begin
|
|||||||
IORQ_n <= '0';
|
IORQ_n <= '0';
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
elsif CEN_n = '1' and CEN_pol = '1' then
|
|
||||||
if TState = "010" then
|
|
||||||
CEN_pol <= not WAIT_n;
|
|
||||||
else
|
|
||||||
CEN_pol <= '0';
|
|
||||||
end if;
|
end if;
|
||||||
|
elsif CEN_n = '1' and CEN_pol = '1' then
|
||||||
|
Wait_s <= Wait_n;
|
||||||
|
CEN_pol <= '0';
|
||||||
if TState = "011" and BUSAK = '1' then
|
if TState = "011" and BUSAK = '1' then
|
||||||
DI_Reg <= DI;
|
DI_Reg <= DI;
|
||||||
end if;
|
end if;
|
||||||
@ -178,7 +184,6 @@ begin
|
|||||||
RD_n <= not IntCycle_n;
|
RD_n <= not IntCycle_n;
|
||||||
MREQ_n <= not IntCycle_n;
|
MREQ_n <= not IntCycle_n;
|
||||||
IORQ_n <= IntCycleD_n(1);
|
IORQ_n <= IntCycleD_n(1);
|
||||||
A_last <= A_int;
|
|
||||||
end if;
|
end if;
|
||||||
if TState = "011" then
|
if TState = "011" then
|
||||||
IntCycleD_n <= "11";
|
IntCycleD_n <= "11";
|
||||||
@ -193,7 +198,6 @@ begin
|
|||||||
if TState = "001" then
|
if TState = "001" then
|
||||||
RD_n <= Write;
|
RD_n <= Write;
|
||||||
MREQ_n <= '0';
|
MREQ_n <= '0';
|
||||||
A_last <= A_int;
|
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
if TState = "010" then
|
if TState = "010" then
|
||||||
|
@ -69,6 +69,7 @@ library IEEE;
|
|||||||
use IEEE.std_logic_1164.all;
|
use IEEE.std_logic_1164.all;
|
||||||
use IEEE.numeric_std.all;
|
use IEEE.numeric_std.all;
|
||||||
use IEEE.STD_LOGIC_UNSIGNED.all;
|
use IEEE.STD_LOGIC_UNSIGNED.all;
|
||||||
|
use work.T80_Pack.all;
|
||||||
|
|
||||||
entity T80s is
|
entity T80s is
|
||||||
generic(
|
generic(
|
||||||
@ -111,7 +112,7 @@ architecture rtl of T80s is
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
u0 : work.T80
|
u0 : T80
|
||||||
generic map(
|
generic map(
|
||||||
Mode => Mode,
|
Mode => Mode,
|
||||||
IOWait => IOWait)
|
IOWait => IOWait)
|
||||||
|
192
rtl/T80/T80se.vhd
Normal file
192
rtl/T80/T80se.vhd
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
-- ****
|
||||||
|
-- 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 T80se is
|
||||||
|
generic(
|
||||||
|
Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
|
||||||
|
T2Write : integer := 0; -- 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;
|
||||||
|
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 T80se;
|
||||||
|
|
||||||
|
architecture rtl of T80se 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 => Mode,
|
||||||
|
IOWait => IOWait)
|
||||||
|
port map(
|
||||||
|
CEN => CLKEN,
|
||||||
|
M1_n => M1_n,
|
||||||
|
IORQ => IORQ,
|
||||||
|
NoRead => NoRead,
|
||||||
|
Write => Write,
|
||||||
|
RFSH_n => RFSH_n,
|
||||||
|
HALT_n => HALT_n,
|
||||||
|
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;
|
179
rtl/T80/T80sed.vhd
Normal file
179
rtl/T80/T80sed.vhd
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
-- ****
|
||||||
|
-- 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)
|
||||||
|
--
|
||||||
|
-- ****
|
||||||
|
-- ** CUSTOM 2 CLOCK MEMORY ACCESS FOR PACMAN, MIKEJ **
|
||||||
|
--
|
||||||
|
-- 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 : 0238
|
||||||
|
--
|
||||||
|
-- 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
|
||||||
|
--
|
||||||
|
-- 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 T80sed is
|
||||||
|
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;
|
||||||
|
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 T80sed;
|
||||||
|
|
||||||
|
architecture rtl of T80sed 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 => 0,
|
||||||
|
IOWait => 1)
|
||||||
|
port map(
|
||||||
|
CEN => CLKEN,
|
||||||
|
M1_n => M1_n,
|
||||||
|
IORQ => IORQ,
|
||||||
|
NoRead => NoRead,
|
||||||
|
Write => Write,
|
||||||
|
RFSH_n => RFSH_n,
|
||||||
|
HALT_n => HALT_n,
|
||||||
|
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 NoRead = '0' and Write = '0' then
|
||||||
|
RD_n <= '0';
|
||||||
|
IORQ_n <= not IORQ;
|
||||||
|
MREQ_n <= IORQ;
|
||||||
|
end if;
|
||||||
|
if ((TState = "001") or (TState = "010")) and Write = '1' then
|
||||||
|
WR_n <= '0';
|
||||||
|
IORQ_n <= not IORQ;
|
||||||
|
MREQ_n <= IORQ;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
if TState = "010" and Wait_n = '1' then
|
||||||
|
DI_Reg <= DI;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
end;
|
Reference in New Issue
Block a user