URL
https://opencores.org/ocsvn/t80/t80/trunk
Subversion Repositories t80
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 34 to Rev 35
- ↔ Reverse comparison
Rev 34 → Rev 35
/trunk/rtl/vhdl/T80_RegX.vhd
0,0 → 1,150
-- |
-- T80 Registers for Xilinx Select RAM |
-- |
-- 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/t51/ |
-- |
-- Limitations : |
-- |
-- File history : |
-- |
-- 0242 : Initial release |
-- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.numeric_std.all; |
library UNISIM; |
use UNISIM.vcomponents.all; |
|
entity T80_Reg is |
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) |
); |
end T80_Reg; |
|
architecture rtl of T80_Reg is |
|
signal ENH : std_logic; |
signal ENL : std_logic; |
|
begin |
|
ENH <= CEN and WEH; |
ENL <= CEN and WEL; |
|
bG1: for I in 0 to 7 generate |
begin |
Reg1H : RAM16X1D |
port map( |
DPO => DOBH(i), |
SPO => DOAH(i), |
A0 => AddrA(0), |
A1 => AddrA(1), |
A2 => AddrA(2), |
A3 => '0', |
D => DIH(i), |
DPRA0 => AddrB(0), |
DPRA1 => AddrB(1), |
DPRA2 => AddrB(2), |
DPRA3 => '0', |
WCLK => Clk, |
WE => ENH); |
Reg1L : RAM16X1D |
port map( |
DPO => DOBL(i), |
SPO => DOAL(i), |
A0 => AddrA(0), |
A1 => AddrA(1), |
A2 => AddrA(2), |
A3 => '0', |
D => DIL(i), |
DPRA0 => AddrB(0), |
DPRA1 => AddrB(1), |
DPRA2 => AddrB(2), |
DPRA3 => '0', |
WCLK => Clk, |
WE => ENL); |
Reg2H : RAM16X1D |
port map( |
DPO => DOCH(i), |
SPO => open, |
A0 => AddrA(0), |
A1 => AddrA(1), |
A2 => AddrA(2), |
A3 => '0', |
D => DIH(i), |
DPRA0 => AddrC(0), |
DPRA1 => AddrC(1), |
DPRA2 => AddrC(2), |
DPRA3 => '0', |
WCLK => Clk, |
WE => ENH); |
Reg2L : RAM16X1D |
port map( |
DPO => DOCL(i), |
SPO => open, |
A0 => AddrA(0), |
A1 => AddrA(1), |
A2 => AddrA(2), |
A3 => '0', |
D => DIL(i), |
DPRA0 => AddrC(0), |
DPRA1 => AddrC(1), |
DPRA2 => AddrC(2), |
DPRA3 => '0', |
WCLK => Clk, |
WE => ENL); |
end generate; |
|
end; |
/trunk/rtl/vhdl/T80se.vhd
3,7 → 3,7
-- Different timing than the original z80 |
-- Inputs needs to be synchronous and outputs may glitch |
-- |
-- Version : 0240 |
-- Version : 0242 |
-- |
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) |
-- |
56,6 → 56,8
-- |
-- 0240 : Updated for T80 interface change |
-- |
-- 0242 : Updated for T80 interface change |
-- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
65,7 → 67,8
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 |
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; |
103,7 → 106,8
|
u0 : T80 |
generic map( |
Mode => Mode) |
Mode => Mode, |
IOWait => IOWait) |
port map( |
CEN => CLKEN, |
M1_n => M1_n, |
/trunk/rtl/vhdl/DebugSystemXR.vhd
108,7 → 108,7
ROM_D; |
|
u0 : entity work.T80s |
generic map(Mode => 1, T2Write => 1) |
generic map(Mode => 1, T2Write => 1, IOWait => 0) |
port map( |
RESET_n => RESET_s, |
CLK_n => Clk, |
/trunk/rtl/vhdl/T80_Reg.vhd
0,0 → 1,111
-- |
-- T80 Registers for Leonardo |
-- |
-- 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/t51/ |
-- |
-- Limitations : |
-- |
-- File history : |
-- |
-- 0242 : Initial release |
-- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.numeric_std.all; |
|
entity T80_Reg is |
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) |
); |
end T80_Reg; |
|
architecture rtl of T80_Reg is |
|
type Register_Image is array (natural range <>) of std_logic_vector(7 downto 0); |
signal RegsAH : Register_Image(0 to 7); |
signal RegsAL : Register_Image(0 to 7); |
signal RegsBH : Register_Image(0 to 7); |
signal RegsBL : Register_Image(0 to 7); |
signal RegsCH : Register_Image(0 to 7); |
signal RegsCL : Register_Image(0 to 7); |
|
begin |
|
process (Clk) |
begin |
if Clk'event and Clk = '1' then |
if CEN = '1' then |
if WEH = '1' then |
RegsAH(to_integer(unsigned(AddrA))) <= DIH; |
RegsBH(to_integer(unsigned(AddrA))) <= DIH; |
RegsCH(to_integer(unsigned(AddrA))) <= DIH; |
end if; |
if WEL = '1' then |
RegsAL(to_integer(unsigned(AddrA))) <= DIL; |
RegsBL(to_integer(unsigned(AddrA))) <= DIL; |
RegsCL(to_integer(unsigned(AddrA))) <= DIL; |
end if; |
end if; |
end if; |
end process; |
|
DOAH <= RegsAH(to_integer(unsigned(AddrA))); |
DOAL <= RegsAL(to_integer(unsigned(AddrA))); |
DOBH <= RegsBH(to_integer(unsigned(AddrB))); |
DOBL <= RegsBL(to_integer(unsigned(AddrB))); |
DOCH <= RegsCH(to_integer(unsigned(AddrC))); |
DOCL <= RegsCL(to_integer(unsigned(AddrC))); |
|
end; |
/trunk/rtl/vhdl/T80_Pack.vhd
1,7 → 1,7
-- |
-- Z80 compatible microprocessor core |
-- |
-- Version : 0240 |
-- Version : 0242 |
-- |
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) |
-- |
53,6 → 53,7
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; |
89,7 → 90,25
); |
end component; |
|
type AddressOutput is (aXY,aIOA,aSP,aBC,aDE,aZI,aNone); |
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) |
); |
end component; |
|
component T80_MCode |
generic( |
119,15 → 138,13
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) |
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); |
-- (ir)ADD, (ir)ADC, (ir)SUB, (ir)SBC, (ir)AND, (ir)XOR, (ir)OR, (ir)CP, ADD, ADC, SUB, SBC, DAA, RLD, RRD, CP |
Rot_Op : out std_logic; |
Bit_Op : out std_logic_vector(1 downto 0); -- None, BIT, SET, RES |
-- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None |
Save_ALU : out std_logic; |
PreserveC : out std_logic; |
Arith16 : out std_logic; |
Set_Addr_To : out AddressOutput; -- aXY,aIOA,aSP,aBC,aDE,aZI,aNone |
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; |
178,16 → 195,13
Arith16 : in std_logic; |
Z16 : in std_logic; |
ALU_Op : in std_logic_vector(3 downto 0); |
Rot_Op : in std_logic; |
Bit_Op : in std_logic_vector(1 downto 0); |
IR : in std_logic_vector(7 downto 0); |
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); |
F_Save : out std_logic_vector(7 downto 0) |
F_Out : out std_logic_vector(7 downto 0) |
); |
end component; |
|
/trunk/rtl/vhdl/T80.vhd
1,7 → 1,7
-- |
-- Z80 compatible microprocessor core |
-- |
-- Version : 0240 |
-- Version : 0242 |
-- |
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) |
-- |
41,9 → 41,6
-- http://www.opencores.org/cvsweb.shtml/t80/ |
-- |
-- Limitations : |
-- No extra I/O waitstate |
-- GB instruction set is incomplete |
-- Not all instruction timing are correct |
-- |
-- File history : |
-- |
65,6 → 62,8
-- |
-- 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 |
-- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
74,6 → 73,7
entity T80 is |
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; |
112,19 → 112,43
|
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 |
signal ACC, F, B, C, D, E, H, L : std_logic_vector(7 downto 0); |
signal Ap, Fp, Bp, Cp, Dp, Ep, Hp, Lp : 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 I : std_logic_vector(7 downto 0); |
signal R : unsigned(7 downto 0); |
signal IX, IY : std_logic_vector(15 downto 0); |
signal SP, PC : unsigned(15 downto 0); |
signal RegDIH : std_logic_vector(7 downto 0); |
signal RegDIL : std_logic_vector(7 downto 0); |
signal RegBusA : std_logic_vector(15 downto 0); |
signal RegBusB : std_logic_vector(15 downto 0); |
signal RegBusC : std_logic_vector(15 downto 0); |
signal RegAddrA_r : std_logic_vector(2 downto 0); |
signal RegAddrA : std_logic_vector(2 downto 0); |
signal RegAddrB_r : std_logic_vector(2 downto 0); |
signal RegAddrB : std_logic_vector(2 downto 0); |
signal RegAddrC : std_logic_vector(2 downto 0); |
signal RegWEH : std_logic; |
signal RegWEL : std_logic; |
signal Alternate : std_logic; |
|
-- Help Registers |
signal TmpAddr : std_logic_vector(15 downto 0); -- Temporary address register |
signal IR : std_logic_vector(7 downto 0); -- Instruction register |
signal ISet : std_logic_vector(1 downto 0); -- Instruction set selector |
signal RegBusA_r : std_logic_vector(15 downto 0); |
|
signal ID16 : signed(15 downto 0); |
signal Save_Mux : std_logic_vector(7 downto 0); |
|
signal TState : unsigned(2 downto 0); |
signal MCycle : std_logic_vector(2 downto 0); |
signal BReq_FF : std_logic; |
141,9 → 165,12
signal Pre_XY_F_M : std_logic_vector(2 downto 0); |
signal NextIs_XY_Fetch : std_logic; |
signal XY_Ind : std_logic; |
signal No_BTR : std_logic; |
signal BTR_r : std_logic; |
signal Auto_Wait : std_logic; |
signal Auto_Wait_t1 : std_logic; |
signal Auto_Wait_t2 : std_logic; |
signal IncDecZ : std_logic; |
|
-- ALU signals |
signal BusB : std_logic_vector(7 downto 0); |
150,7 → 177,6
signal BusA : std_logic_vector(7 downto 0); |
signal ALU_Q : std_logic_vector(7 downto 0); |
signal F_Out : std_logic_vector(7 downto 0); |
signal F_Save : std_logic_vector(7 downto 0); |
|
-- Registered micro code outputs |
signal Read_To_Reg_r : std_logic_vector(4 downto 0); |
157,9 → 183,6
signal Arith16_r : std_logic; |
signal Z16_r : std_logic; |
signal ALU_Op_r : std_logic_vector(3 downto 0); |
signal AALU_OP_r : std_logic_vector(2 downto 0); |
signal Rot_Op_r : std_logic; |
signal Bit_Op_r : std_logic_vector(1 downto 0); |
signal Save_ALU_r : std_logic; |
signal PreserveC_r : std_logic; |
signal MCycles : std_logic_vector(2 downto 0); |
178,12 → 201,10
signal Set_BusB_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 Rot_Op : std_logic; |
signal Bit_Op : std_logic_vector(1 downto 0); |
signal Save_ALU : std_logic; |
signal PreserveC : std_logic; |
signal Arith16 : std_logic; |
signal Set_Addr_To : AddressOutput; |
signal Set_Addr_To : std_logic_vector(2 downto 0); |
signal Jump : std_logic; |
signal JumpE : std_logic; |
signal JumpXY : std_logic; |
245,8 → 266,6
Set_BusB_To => Set_BusB_To, |
Set_BusA_To => Set_BusA_To, |
ALU_Op => ALU_Op, |
Rot_Op => Rot_Op, |
Bit_Op => Bit_Op, |
Save_ALU => Save_ALU, |
PreserveC => PreserveC, |
Arith16 => Arith16, |
298,16 → 317,13
Arith16 => Arith16_r, |
Z16 => Z16_r, |
ALU_Op => ALU_Op_r, |
Rot_Op => Rot_Op_r, |
Bit_Op => Bit_Op_r, |
IR => IR, |
IR => IR(5 downto 0), |
ISet => ISet, |
BusA => BusA, |
BusB => BusB, |
F_In => F, |
Q => ALU_Q, |
F_Out => F_Out, |
F_Save => F_Save); |
F_Out => F_Out); |
|
T_Res <= '1' when TState = unsigned(TStates) else '0'; |
|
316,35 → 332,40
(MCycle = "001" and IR = "11001011") or |
(MCycle = "001" and IR = "00110110")) else '0'; |
|
Save_Mux <= BusB when ExchangeRp = '1' else |
DI_Reg when Save_ALU_r = '0' else |
ALU_Q; |
|
process (RESET_n, CLK_n) |
|
variable ID16 : signed(15 downto 0); |
variable Save_Mux : std_logic_vector(7 downto 0); |
|
begin |
if RESET_n = '0' then |
PC <= (others => '0'); -- Program Counter |
A <= (others => '0'); |
TmpAddr <= (others => '0'); |
IR <= "00000000"; |
ISet <= "00"; |
XY_State <= "00"; |
IStatus <= "00"; |
MCycles <= "000"; |
DO <= "00000000"; |
|
ACC <= (others => '1'); |
F <= (others => '1'); |
Ap <= (others => '1'); |
Fp <= (others => '1'); |
I <= (others => '0'); |
R <= (others => '0'); |
SP <= (others => '1'); |
Alternate <= '0'; |
|
Read_To_Reg_r <= "00000"; |
F <= (others => '1'); |
Arith16_r <= '0'; |
BTR_r <= '0'; |
Z16_r <= '0'; |
ALU_Op_r <= "0000"; |
Rot_Op_r <= '0'; |
Bit_Op_r <= "00"; |
Save_ALU_r <= '0'; |
PreserveC_r <= '0'; |
AALU_OP_r <= "000"; |
XY_Ind <= '0'; |
|
elsif CLK_n'event and CLK_n = '1' then |
352,10 → 373,7
if CEN = '1' then |
|
ALU_Op_r <= "0000"; |
Rot_Op_r <= '0'; |
Bit_Op_r <= "00"; |
Save_ALU_r <= '0'; |
AALU_OP_r <= "000"; |
Read_To_Reg_r <= "00000"; |
|
MCycles <= MCycles_d; |
420,9 → 438,13
|
if MCycle = "110" then |
XY_Ind <= '1'; |
if Prefix = "01" then |
ISet <= "01"; |
end if; |
end if; |
|
if T_Res = '1' then |
BTR_r <= (I_BT or I_BC or I_BTR) and not No_BTR; |
if Jump = '1' then |
A(15 downto 8) <= DI_Reg; |
A(7 downto 0) <= TmpAddr(7 downto 0); |
429,19 → 451,8
PC(15 downto 8) <= unsigned(DI_Reg); |
PC(7 downto 0) <= unsigned(TmpAddr(7 downto 0)); |
elsif JumpXY = '1' then |
case XY_State is |
when "01" => |
A <= IX; |
PC <= unsigned(IX); |
when "10" => |
A <= IY; |
PC <= unsigned(IY); |
when others => |
A(15 downto 8) <= H; |
A(7 downto 0) <= L; |
PC(15 downto 8) <= unsigned(H); |
PC(7 downto 0) <= unsigned(L); |
end case; |
A <= RegBusC; |
PC <= unsigned(RegBusC); |
elsif Call = '1' or RstP = '1' then |
A <= TmpAddr; |
PC <= unsigned(TmpAddr); |
457,8 → 468,7
case Set_Addr_To is |
when aXY => |
if XY_State = "00" then |
A(15 downto 8) <= H; |
A(7 downto 0) <= L; |
A <= RegBusC; |
else |
if NextIs_XY_Fetch = '1' then |
A <= std_logic_vector(PC); |
483,14 → 493,12
if Mode = 3 and IORQ_i = '1' then |
-- Memory map I/O on GBZ80 |
A(15 downto 8) <= (others => '1'); |
A(7 downto 0) <= C; |
A(7 downto 0) <= RegBusC(7 downto 0); |
else |
A(15 downto 8) <= B; |
A(7 downto 0) <= C; |
A <= RegBusC; |
end if; |
when aDE => |
A(15 downto 8) <= D; |
A(7 downto 0) <= E; |
A <= RegBusC; |
when aZI => |
if Inc_WZ = '1' then |
A <= std_logic_vector(unsigned(TmpAddr) + 1); |
498,7 → 506,7
A(15 downto 8) <= DI_Reg; |
A(7 downto 0) <= TmpAddr(7 downto 0); |
end if; |
when aNone => |
when others => |
A <= std_logic_vector(PC); |
end case; |
end if; |
505,17 → 513,6
|
Save_ALU_r <= Save_ALU; |
ALU_Op_r <= ALU_Op; |
Rot_Op_r <= Rot_Op; |
Bit_Op_r <= Bit_Op; |
if Save_ALU = '1' then |
if Rot_Op = '0' and Bit_Op = "00" then |
if ALU_Op(3) = '1' then |
AALU_OP_r <= ALU_Op(2 downto 0); |
else |
AALU_OP_r <= IR(5 downto 3); |
end if; |
end if; |
end if; |
|
if I_CPL = '1' then |
-- CPL |
544,12 → 541,15
end if; |
|
if TState = 2 and Wait_n = '1' then |
if ISet = "01" and MCycle = "111" then |
IR <= DInst; |
end if; |
if JumpE = '1' then |
PC <= unsigned(signed(PC) + signed(DI_Reg)); |
elsif Inc_PC = '1' then |
PC <= PC + 1; |
end if; |
if I_BTR = '1' then |
if BTR_r = '1' then |
PC <= PC - 2; |
end if; |
if RstP = '1' then |
558,96 → 558,22
end if; |
end if; |
if TState = 3 and MCycle = "110" then |
if XY_State = "01" then |
TmpAddr <= std_logic_vector(signed(IX) + signed(DI_Reg)); |
end if; |
if XY_State = "10" then |
TmpAddr <= std_logic_vector(signed(IY) + signed(DI_Reg)); |
end if; |
TmpAddr <= std_logic_vector(signed(RegBusC) + signed(DI_Reg)); |
end if; |
|
if (TState = 2 and Wait_n = '1') or (TState = 4 and MCycle = "001") then |
if IncDec_16 = "1100" then |
ID16(15 downto 8) := signed(B); |
ID16(7 downto 0) := signed(C); |
ID16 := ID16 - 1; |
B <= std_logic_vector(ID16(15 downto 8)); |
C <= std_logic_vector(ID16(7 downto 0)); |
if IncDec_16(2 downto 0) = "111" then |
if IncDec_16(3) = '1' then |
SP <= SP - 1; |
else |
SP <= SP + 1; |
end if; |
end if; |
if IncDec_16 = "1101" then |
ID16(15 downto 8) := signed(D); |
ID16(7 downto 0) := signed(E); |
ID16 := ID16 - 1; |
D <= std_logic_vector(ID16(15 downto 8)); |
E <= std_logic_vector(ID16(7 downto 0)); |
end if; |
if IncDec_16 = "1110" then |
case XY_State is |
when "01" => |
IX <= std_logic_vector(unsigned(IX) - 1); |
when "10" => |
IY <= std_logic_vector(unsigned(IY) - 1); |
when others => |
ID16(15 downto 8) := signed(H); |
ID16(7 downto 0) := signed(L); |
ID16 := ID16 - 1; |
H <= std_logic_vector(ID16(15 downto 8)); |
L <= std_logic_vector(ID16(7 downto 0)); |
end case; |
end if; |
if IncDec_16 = "1111" then |
SP <= SP - 1; |
end if; |
if IncDec_16 = "0100" then |
ID16(15 downto 8) := signed(B); |
ID16(7 downto 0) := signed(C); |
ID16 := ID16 + 1; |
B <= std_logic_vector(ID16(15 downto 8)); |
C <= std_logic_vector(ID16(7 downto 0)); |
end if; |
if IncDec_16 = "0101" then |
ID16(15 downto 8) := signed(D); |
ID16(7 downto 0) := signed(E); |
ID16 := ID16 + 1; |
D <= std_logic_vector(ID16(15 downto 8)); |
E <= std_logic_vector(ID16(7 downto 0)); |
end if; |
if IncDec_16 = "0110" then |
case XY_State is |
when "01" => |
IX <= std_logic_vector(unsigned(IX) + 1); |
when "10" => |
IY <= std_logic_vector(unsigned(IY) + 1); |
when others => |
ID16(15 downto 8) := signed(H); |
ID16(7 downto 0) := signed(L); |
ID16 := ID16 + 1; |
H <= std_logic_vector(ID16(15 downto 8)); |
L <= std_logic_vector(ID16(7 downto 0)); |
end case; |
end if; |
if IncDec_16 = "0111" then |
SP <= SP + 1; |
end if; |
end if; |
|
if LDSPHL = '1' then |
case XY_State is |
when "01" => |
SP <= unsigned(IX); |
when "10" => |
SP <= unsigned(IY); |
when others => |
SP(15 downto 8) <= unsigned(H); |
SP(7 downto 0) <= unsigned(L); |
end case; |
SP <= unsigned(RegBusC); |
end if; |
if ExchangeDH = '1' then |
D <= H; |
E <= L; |
H <= D; |
L <= E; |
end if; |
if ExchangeAF = '1' then |
Ap <= ACC; |
ACC <= Ap; |
655,18 → 581,7
F <= Fp; |
end if; |
if ExchangeRS = '1' then |
Bp <= B; |
B <= Bp; |
Cp <= C; |
C <= Cp; |
Dp <= D; |
D <= Dp; |
Ep <= E; |
E <= Ep; |
Lp <= L; |
L <= Lp; |
Hp <= H; |
H <= Hp; |
Alternate <= not Alternate; |
end if; |
end if; |
|
694,18 → 609,17
end if; |
end if; |
|
if (I_DJNZ = '0' and Save_ALU_r = '1') or Bit_Op_r = "01" then |
if (I_DJNZ = '0' and Save_ALU_r = '1') or ALU_Op_r = "1001" then |
if Mode = 3 then |
F(6) <= (F(6) and not F_Save(1)) or (F_Out(6) and F_Save(1)); |
F(5) <= (F(5) and not F_Save(4)) or (F_Out(5) and F_Save(4)); |
F(7) <= (F(7) and not F_Save(6)) or (F_Out(7) and F_Save(6)); |
if PreserveC_r = '0' and F_Save(0) = '1' then |
F(6) <= F_Out(6); |
F(5) <= F_Out(5); |
F(7) <= F_Out(7); |
if PreserveC_r = '0' then |
F(4) <= F_Out(4); |
end if; |
else |
F(7 downto 1) <= (F(7 downto 1) and not F_Save(7 downto 1)) or |
(F_Out(7 downto 1) and F_Save(7 downto 1)); |
if PreserveC_r = '0' and F_Save(0) = '1' then |
F(7 downto 1) <= F_Out(7 downto 1); |
if PreserveC_r = '0' then |
F(Flag_C) <= F_Out(0); |
end if; |
end if; |
723,7 → 637,7
DI_Reg(4) xor DI_Reg(5) xor DI_Reg(6) xor DI_Reg(7)); |
end if; |
|
if TState = 1 then |
if TState = 1 and Auto_Wait_t1 = '0' then |
DO <= BusB; |
if I_RLD = '1' then |
DO(3 downto 0) <= BusA(3 downto 0); |
751,60 → 665,14
F(Flag_N) <= '0'; |
end if; |
if I_BC = '1' or I_BT = '1' then |
if B = "00000000" and C = "00000000" then |
F(Flag_P) <= '0'; |
else |
F(Flag_P) <= '1'; |
end if; |
F(Flag_P) <= IncDecZ; |
end if; |
|
if (TState = 1 and Save_ALU_r = '0') or |
(Save_ALU_r = '1' and AALU_OP_r /= "111") then |
if ExchangeRp = '1' then |
Save_Mux := BusB; |
elsif Save_ALU_r = '0' then |
Save_Mux := DI_Reg; |
else |
Save_Mux := ALU_Q; |
end if; |
|
if (TState = 1 and Save_ALU_r = '0' and Auto_Wait_t1 = '0') or |
(Save_ALU_r = '1' and ALU_OP_r /= "0111") then |
case Read_To_Reg_r is |
when "10111" => |
ACC <= Save_Mux; |
when "10000" => |
B <= Save_Mux; |
when "10001" => |
C <= Save_Mux; |
when "10010" => |
D <= Save_Mux; |
when "10011" => |
E <= Save_Mux; |
when "10100" => |
if XY_Ind = '1' then |
H <= Save_Mux; |
else |
case XY_State is |
when "01" => |
IX(15 downto 8) <= Save_Mux; |
when "10" => |
IY(15 downto 8) <= Save_Mux; |
when others => |
H <= Save_Mux; |
end case; |
end if; |
when "10101" => |
if XY_Ind = '1' then |
L <= Save_Mux; |
else |
case XY_State is |
when "01" => |
IX(7 downto 0) <= Save_Mux; |
when "10" => |
IY(7 downto 0) <= Save_Mux; |
when others => |
L <= Save_Mux; |
end case; |
end if; |
when "10110" => |
DO <= Save_Mux; |
when "11000" => |
825,6 → 693,143
|
--------------------------------------------------------------------------- |
-- |
-- BC('), DE('), HL('), IX and IY |
-- |
--------------------------------------------------------------------------- |
process (CLK_n) |
begin |
if CLK_n'event and CLK_n = '1' then |
if CEN = '1' then |
-- Bus A / Write |
RegAddrA_r <= Alternate & Set_BusA_To(2 downto 1); |
if XY_Ind = '0' and XY_State /= "00" and Set_BusA_To(2 downto 1) = "10" then |
RegAddrA_r <= XY_State(1) & "11"; |
end if; |
|
-- Bus B |
RegAddrB_r <= Alternate & Set_BusB_To(2 downto 1); |
if XY_Ind = '0' and XY_State /= "00" and Set_BusB_To(2 downto 1) = "10" then |
RegAddrB_r <= XY_State(1) & "11"; |
end if; |
|
-- Address from register |
RegAddrC <= Alternate & Set_Addr_To(1 downto 0); |
-- Jump (HL), LD SP,HL |
if (JumpXY = '1' or LDSPHL = '1') then |
RegAddrC <= Alternate & "10"; |
end if; |
if ((JumpXY = '1' or LDSPHL = '1') and XY_State /= "00") or (MCycle = "110") then |
RegAddrC <= XY_State(1) & "11"; |
end if; |
|
if I_DJNZ = '1' and Save_ALU_r = '1' and Mode < 2 then |
IncDecZ <= F_Out(Flag_Z); |
end if; |
if (TState = 2 or (TState = 3 and MCycle = "001")) and IncDec_16(2 downto 0) = "100" then |
if ID16 = 0 then |
IncDecZ <= '0'; |
else |
IncDecZ <= '1'; |
end if; |
end if; |
|
RegBusA_r <= RegBusA; |
end if; |
end if; |
end process; |
|
RegAddrA <= |
-- 16 bit increment/decrement |
Alternate & IncDec_16(1 downto 0) when (TState = 2 or |
(TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and XY_State = "00" else |
XY_State(1) & "11" when (TState = 2 or |
(TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and IncDec_16(1 downto 0) = "10" else |
-- EX HL,DL |
Alternate & "10" when ExchangeDH = '1' and TState = 3 else |
Alternate & "01" when ExchangeDH = '1' and TState = 4 else |
-- Bus A / Write |
RegAddrA_r; |
|
RegAddrB <= |
-- EX HL,DL |
Alternate & "01" when ExchangeDH = '1' and TState = 3 else |
-- Bus B |
RegAddrB_r; |
|
ID16 <= signed(RegBusA) - 1 when IncDec_16(3) = '1' else |
signed(RegBusA) + 1; |
|
process (Save_ALU_r, Auto_Wait_t1, ALU_OP_r, Read_To_Reg_r, |
ExchangeDH, IncDec_16, MCycle, TState, Wait_n) |
begin |
RegWEH <= '0'; |
RegWEL <= '0'; |
if (TState = 1 and Save_ALU_r = '0' and Auto_Wait_t1 = '0') or |
(Save_ALU_r = '1' and ALU_OP_r /= "0111") then |
case Read_To_Reg_r is |
when "10000" | "10001" | "10010" | "10011" | "10100" | "10101" => |
RegWEH <= not Read_To_Reg_r(0); |
RegWEL <= Read_To_Reg_r(0); |
when others => |
end case; |
end if; |
|
if ExchangeDH = '1' and (TState = 3 or TState = 4) then |
RegWEH <= '1'; |
RegWEL <= '1'; |
end if; |
|
if IncDec_16(2) = '1' and ((TState = 2 and Wait_n = '1' and MCycle /= "001") or (TState = 3 and MCycle = "001")) then |
case IncDec_16(1 downto 0) is |
when "00" | "01" | "10" => |
RegWEH <= '1'; |
RegWEL <= '1'; |
when others => |
end case; |
end if; |
end process; |
|
process (Save_Mux, RegBusB, RegBusA_r, ID16, |
ExchangeDH, IncDec_16, MCycle, TState, Wait_n) |
begin |
RegDIH <= Save_Mux; |
RegDIL <= Save_Mux; |
|
if ExchangeDH = '1' and TState = 3 then |
RegDIH <= RegBusB(15 downto 8); |
RegDIL <= RegBusB(7 downto 0); |
end if; |
if ExchangeDH = '1' and TState = 4 then |
RegDIH <= RegBusA_r(15 downto 8); |
RegDIL <= RegBusA_r(7 downto 0); |
end if; |
|
if IncDec_16(2) = '1' and ((TState = 2 and MCycle /= "001") or (TState = 3 and MCycle = "001")) then |
RegDIH <= std_logic_vector(ID16(15 downto 8)); |
RegDIL <= std_logic_vector(ID16(7 downto 0)); |
end if; |
end process; |
|
Regs : T80_Reg |
port map( |
Clk => CLK_n, |
CEN => CEN, |
WEH => RegWEH, |
WEL => RegWEL, |
AddrA => RegAddrA, |
AddrB => RegAddrB, |
AddrC => RegAddrC, |
DIH => RegDIH, |
DIL => RegDIL, |
DOAH => RegBusA(15 downto 8), |
DOAL => RegBusA(7 downto 0), |
DOBH => RegBusB(15 downto 8), |
DOBL => RegBusB(7 downto 0), |
DOCH => RegBusC(15 downto 8), |
DOCL => RegBusC(7 downto 0)); |
|
--------------------------------------------------------------------------- |
-- |
-- Buses |
-- |
--------------------------------------------------------------------------- |
835,40 → 840,12
case Set_BusB_To is |
when "0111" => |
BusB <= ACC; |
when "0000" => |
BusB <= B; |
when "0001" => |
BusB <= C; |
when "0010" => |
BusB <= D; |
when "0011" => |
BusB <= E; |
when "0100" => |
if XY_Ind = '1' then |
BusB <= H; |
when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" => |
if Set_BusB_To(0) = '1' then |
BusB <= RegBusB(7 downto 0); |
else |
case XY_State is |
when "01" => |
BusB <= IX(15 downto 8); |
when "10" => |
BusB <= IY(15 downto 8); |
when others => |
BusB <= H; |
end case; |
BusB <= RegBusB(15 downto 8); |
end if; |
when "0101" => |
if XY_Ind = '1' then |
BusB <= L; |
else |
case XY_State is |
when "01" => |
BusB <= IX(7 downto 0); |
when "10" => |
BusB <= IY(7 downto 0); |
when others => |
BusB <= L; |
end case; |
end if; |
when "0110" => |
BusB <= DI_Reg; |
when "1000" => |
892,40 → 869,12
case Set_BusA_To is |
when "0111" => |
BusA <= ACC; |
when "0000" => |
BusA <= B; |
when "0001" => |
BusA <= C; |
when "0010" => |
BusA <= D; |
when "0011" => |
BusA <= E; |
when "0100" => |
if XY_Ind = '1' then |
BusA <= H; |
when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" => |
if Set_BusA_To(0) = '1' then |
BusA <= RegBusA(7 downto 0); |
else |
case XY_State is |
when "01" => |
BusA <= IX(15 downto 8); |
when "10" => |
BusA <= IY(15 downto 8); |
when others => |
BusA <= H; |
end case; |
BusA <= RegBusA(15 downto 8); |
end if; |
when "0101" => |
if XY_Ind = '1' then |
BusA <= L; |
else |
case XY_State is |
when "01" => |
BusA <= IX(7 downto 0); |
when "10" => |
BusA <= IY(7 downto 0); |
when others => |
BusA <= L; |
end case; |
end if; |
when "0110" => |
BusA <= DI_Reg; |
when "1000" => |
937,9 → 886,8
when others => |
BusB <= "--------"; |
end case; |
|
end if; |
end if; |
end if; |
end process; |
|
--------------------------------------------------------------------------- |
947,7 → 895,6
-- Generate external control signals |
-- |
--------------------------------------------------------------------------- |
|
process (RESET_n,CLK_n) |
begin |
if RESET_n = '0' then |
972,22 → 919,6
IORQ <= IORQ_i; |
Stop <= I_DJNZ; |
|
process (RESET_n,CLK_n) |
begin |
if RESET_n = '0' then |
M1_n <= '1'; |
elsif CLK_n'event and CLK_n = '1' then |
if CEN = '1' then |
if (T_Res = '1' and (MCycle = MCycles or (MCycle = "010" and I_DJNZ = '1' and B = "00000000"))) or TState = 0 then |
M1_n <= '0'; |
end if; |
if MCycle = "001" and TState = 2 and Wait_n = '1' then |
M1_n <= '1'; |
end if; |
end if; |
end if; |
end process; |
|
------------------------------------------------------------------------- |
-- |
-- Syncronise inputs |
1031,12 → 962,21
IntCycle <= '0'; |
IntE_FF1 <= '0'; |
IntE_FF2 <= '0'; |
No_BTR <= '0'; |
Auto_Wait_t1 <= '0'; |
Auto_Wait_t2 <= '0'; |
M1_n <= '1'; |
elsif CLK_n'event and CLK_n = '1' then -- CLK_n is the clock signal |
if CEN = '1' then |
Auto_Wait_t1 <= Auto_Wait; |
if T_Res = '1' then |
Auto_Wait_t1 <= '0'; |
else |
Auto_Wait_t1 <= Auto_Wait or IORQ_i; |
end if; |
Auto_Wait_t2 <= Auto_Wait_t1; |
No_BTR <= (I_BT and (not IR(4) or not F(Flag_P))) or |
(I_BC and (not IR(4) or F(Flag_Z) or not F(Flag_P))) or |
(I_BTR and (not IR(4) or F(Flag_Z))); |
if TState = 2 then |
if SetEI = '1' then |
IntE_FF1 <= '1'; |
1055,6 → 995,9
if IntCycle = '1' or NMICycle = '1' then |
Halt_FF <= '0'; |
end if; |
if MCycle = "001" and TState = 2 and Wait_n = '1' then |
M1_n <= '1'; |
end if; |
if BReq_FF = '1' then |
if BUSRQ_n = '1' then |
BReq_FF <= '0'; |
1074,15 → 1017,16
if NextIs_XY_Fetch = '1' then |
MCycle <= "110"; |
Pre_XY_F_M <= MCycle; |
if Set_Addr_To = aNone and Mode = 0 then |
if IR = "00110110" and Mode = 0 then |
Pre_XY_F_M <= "010"; |
end if; |
elsif (MCycle = "111" and Mode = 0) or |
(MCycle = "110" and Prefix /= "01" and Mode = 1) then |
elsif (MCycle = "111") or |
(MCycle = "110" and Mode = 1 and ISet /= "01") then |
MCycle <= std_logic_vector(unsigned(Pre_XY_F_M) + 1); |
elsif (MCycle = MCycles) or |
(MCycle = "110" and Prefix = "01") or |
(MCycle = "010" and I_DJNZ = '1' and B = "00000000") then |
No_BTR = '1' or |
(MCycle = "010" and I_DJNZ = '1' and IncDecZ = '1') then |
M1_n <= '0'; |
MCycle <= "001"; |
IntCycle <= '0'; |
NMICycle <= '0'; |
1099,12 → 1043,16
end if; |
end if; |
else |
if Auto_Wait = '1' nand Auto_Wait_t2 = '0' then |
if (Auto_Wait = '1' and Auto_Wait_t2 = '0') nor |
(IOWait = 1 and IORQ_i = '1' and Auto_Wait_t1 = '0') then |
TState <= TState + 1; |
end if; |
end if; |
end if; |
if TState = 0 then |
M1_n <= '0'; |
end if; |
end if; |
end if; |
end process; |
|
/trunk/rtl/vhdl/T8080se.vhd
3,7 → 3,7
-- Different timing than the original 8080 |
-- Inputs needs to be synchronous and outputs may glitch |
-- |
-- Version : 0240 |
-- Version : 0242 |
-- |
-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) |
-- |
53,6 → 53,8
-- |
-- 0240 : Updated for T80 interface change |
-- |
-- 0242 : Updated for T80 interface change |
-- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
119,7 → 121,8
|
u0 : T80 |
generic map( |
Mode => Mode) |
Mode => Mode, |
IOWait => 0) |
port map( |
CEN => CLKEN, |
M1_n => open, |
/trunk/rtl/vhdl/T80_ALU.vhd
1,9 → 1,9
-- |
-- Z80 compatible microprocessor core |
-- |
-- Version : 0240 |
-- Version : 0242 |
-- |
-- Copyright (c) 2001-2002 Daniel Wallner (dwallner@hem2.passagen.se) |
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) |
-- |
-- All rights reserved |
-- |
38,7 → 38,7
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://hem.passagen.se/dwallner/vhdl.html |
-- http://www.opencores.org/cvsweb.shtml/t80/ |
-- |
-- Limitations : |
-- |
50,6 → 50,8
-- |
-- 0240 : Added GB operations |
-- |
-- 0242 : Cleanup |
-- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
71,16 → 73,13
Arith16 : in std_logic; |
Z16 : in std_logic; |
ALU_Op : in std_logic_vector(3 downto 0); |
Rot_Op : in std_logic; |
Bit_Op : in std_logic_vector(1 downto 0); |
IR : in std_logic_vector(7 downto 0); |
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); |
F_Save : out std_logic_vector(7 downto 0) |
F_Out : out std_logic_vector(7 downto 0) |
); |
end T80_ALU; |
|
112,9 → 111,6
Res <= std_logic_vector(Res_i(A'length - 1 downto 0)); |
end; |
|
-- Micro code outputs |
signal AALU_Op : std_logic_vector(2 downto 0); |
|
-- AddSub variables (temporary signals) |
signal UseCarry : std_logic; |
signal Carry7_v : std_logic; |
136,25 → 132,74
"01000000" when "110", |
"10000000" when others; |
|
UseCarry <= not AALU_OP(2) and AALU_OP(0); |
AddSub(BusA(3 downto 0), BusB(3 downto 0), AALU_OP(1), AALU_OP(1) xor (UseCarry and F_In(Flag_C)), Q_v(3 downto 0), HalfCarry_v); |
AddSub(BusA(6 downto 4), BusB(6 downto 4), AALU_OP(1), HalfCarry_v, Q_v(6 downto 4), Carry7_v); |
AddSub(BusA(7 downto 7), BusB(7 downto 7), AALU_OP(1), Carry7_v, Q_v(7 downto 7), Carry_v); |
UseCarry <= not ALU_Op(2) and ALU_Op(0); |
AddSub(BusA(3 downto 0), BusB(3 downto 0), ALU_Op(1), ALU_Op(1) xor (UseCarry and F_In(Flag_C)), Q_v(3 downto 0), HalfCarry_v); |
AddSub(BusA(6 downto 4), BusB(6 downto 4), ALU_Op(1), HalfCarry_v, Q_v(6 downto 4), Carry7_v); |
AddSub(BusA(7 downto 7), BusB(7 downto 7), ALU_Op(1), Carry7_v, Q_v(7 downto 7), Carry_v); |
OverFlow_v <= Carry_v xor Carry7_v; |
|
AALU_Op <= ALU_Op(2 downto 0) when Rot_Op = '0' and Bit_Op = "00" and ALU_Op(3) = '1' else |
IR(5 downto 3) when Rot_Op = '0' and Bit_Op = "00" and ALU_Op(3) = '0' else "000"; |
|
process (Arith16, AALU_OP, ALU_Op, Rot_Op, Bit_Op, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet) |
process (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16) |
variable Q_t : std_logic_vector(7 downto 0); |
variable DAA_Q : unsigned(8 downto 0); |
begin |
Q_t := "--------"; |
F_Out <= "--------"; |
F_Save <= "00000000"; |
F_Out <= F_In; |
DAA_Q := "---------"; |
if ALU_Op = "1100" then -- DAA |
F_Save <= "11111101"; |
case ALU_Op is |
when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" | "0110" | "0111" => |
F_Out(Flag_N) <= '0'; |
F_Out(Flag_C) <= '0'; |
case ALU_OP(2 downto 0) is |
when "000" | "001" => -- ADD, ADC |
Q_t := Q_v; |
F_Out(Flag_C) <= Carry_v; |
F_Out(Flag_H) <= HalfCarry_v; |
F_Out(Flag_P) <= OverFlow_v; |
when "010" | "011" | "111" => -- SUB, SBC, CP |
Q_t := Q_v; |
F_Out(Flag_N) <= '1'; |
F_Out(Flag_C) <= not Carry_v; |
F_Out(Flag_H) <= not HalfCarry_v; |
F_Out(Flag_P) <= OverFlow_v; |
when "100" => -- AND |
Q_t(7 downto 0) := BusA and BusB; |
F_Out(Flag_H) <= '1'; |
when "101" => -- XOR |
Q_t(7 downto 0) := BusA xor BusB; |
F_Out(Flag_H) <= '0'; |
when others => -- OR "110" |
Q_t(7 downto 0) := BusA or BusB; |
F_Out(Flag_H) <= '0'; |
end case; |
if ALU_Op(2 downto 0) = "111" then -- CP |
F_Out(Flag_X) <= BusB(3); |
F_Out(Flag_Y) <= BusB(5); |
else |
F_Out(Flag_X) <= Q_t(3); |
F_Out(Flag_Y) <= Q_t(5); |
end if; |
if Q_t(7 downto 0) = "00000000" then |
F_Out(Flag_Z) <= '1'; |
if Z16 = '1' then |
F_Out(Flag_Z) <= F_In(Flag_Z); -- 16 bit ADC,SBC |
end if; |
else |
F_Out(Flag_Z) <= '0'; |
end if; |
F_Out(Flag_S) <= Q_t(7); |
case ALU_Op(2 downto 0) is |
when "000" | "001" | "010" | "011" | "111" => -- ADD, ADC, SUB, SBC, CP |
when others => |
F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor |
Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); |
end case; |
if Arith16 = '1' then |
F_Out(Flag_S) <= F_In(Flag_S); |
F_Out(Flag_Z) <= F_In(Flag_Z); |
F_Out(Flag_P) <= F_In(Flag_P); |
end if; |
when "1100" => |
-- DAA |
F_Out(Flag_H) <= F_In(Flag_H); |
F_Out(Flag_C) <= F_In(Flag_C); |
DAA_Q(7 downto 0) := unsigned(BusA); |
198,7 → 243,8
F_Out(Flag_S) <= DAA_Q(7); |
F_Out(Flag_P) <= not (DAA_Q(0) xor DAA_Q(1) xor DAA_Q(2) xor DAA_Q(3) xor |
DAA_Q(4) xor DAA_Q(5) xor DAA_Q(6) xor DAA_Q(7)); |
elsif ALU_Op = "1101" or ALU_Op = "1110" then -- RLD, RRD |
when "1101" | "1110" => |
-- RLD, RRD |
Q_t(7 downto 4) := BusA(7 downto 4); |
if ALU_Op(0) = '1' then |
Q_t(3 downto 0) := BusB(7 downto 4); |
205,7 → 251,6
else |
Q_t(3 downto 0) := BusB(3 downto 0); |
end if; |
F_Save <= "11111110"; |
F_Out(Flag_H) <= '0'; |
F_Out(Flag_N) <= '0'; |
F_Out(Flag_X) <= Q_t(3); |
218,92 → 263,33
F_Out(Flag_S) <= Q_t(7); |
F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor |
Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); |
elsif Rot_Op = '0' and Bit_Op = "00" then |
F_Save <= "11111111"; |
F_Out(Flag_N) <= '0'; |
F_Out(Flag_C) <= '0'; |
case AALU_OP is |
when "000" | "001" => -- ADD, ADC |
Q_t := Q_v; |
F_Out(Flag_C) <= Carry_v; |
F_Out(Flag_H) <= HalfCarry_v; |
F_Out(Flag_P) <= OverFlow_v; |
when "010" | "011" | "111" => -- SUB, SBC, CP |
Q_t := Q_v; |
F_Out(Flag_N) <= '1'; |
F_Out(Flag_C) <= not Carry_v; |
F_Out(Flag_H) <= not HalfCarry_v; |
F_Out(Flag_P) <= OverFlow_v; |
when "100" => -- AND |
Q_t(7 downto 0) := BusA and BusB; |
F_Out(Flag_H) <= '1'; |
when "101" => -- XOR |
Q_t(7 downto 0) := BusA xor BusB; |
F_Out(Flag_H) <= '0'; |
when others => -- OR "110" |
Q_t(7 downto 0) := BusA or BusB; |
F_Out(Flag_H) <= '0'; |
end case; |
if AALU_OP = "111" then -- CP |
F_Out(Flag_X) <= BusB(3); |
F_Out(Flag_Y) <= BusB(5); |
else |
F_Out(Flag_X) <= Q_t(3); |
F_Out(Flag_Y) <= Q_t(5); |
end if; |
when "1001" => |
-- BIT |
Q_t(7 downto 0) := BusB and BitMask; |
F_Out(Flag_S) <= Q_t(7); |
if Q_t(7 downto 0) = "00000000" then |
F_Out(Flag_Z) <= '1'; |
if Z16 = '1' then |
F_Out(Flag_Z) <= F_In(Flag_Z); -- 16 bit ADC,SBC |
end if; |
F_Out(Flag_P) <= '1'; |
else |
F_Out(Flag_Z) <= '0'; |
F_Out(Flag_P) <= '0'; |
end if; |
F_Out(Flag_S) <= Q_t(7); |
case AALU_OP is |
when "000" | "001" | "010" | "011" | "111" => -- ADD, ADC, SUB, SBC, CP |
when others => |
F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor |
Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); |
end case; |
if Arith16 = '1' then |
F_Out(Flag_S) <= F_In(Flag_S); |
F_Out(Flag_Z) <= F_In(Flag_Z); |
F_Out(Flag_P) <= F_In(Flag_P); |
F_Out(Flag_H) <= '1'; |
F_Out(Flag_N) <= '0'; |
F_Out(Flag_X) <= '0'; |
F_Out(Flag_Y) <= '0'; |
if IR(2 downto 0) /= "110" then |
F_Out(Flag_X) <= BusB(3); |
F_Out(Flag_Y) <= BusB(5); |
end if; |
elsif Bit_Op /= "00" then |
case Bit_Op is |
when "01" => -- Bit |
F_Save <= "11111110"; |
Q_t(7 downto 0) := BusB and BitMask; |
F_Out(Flag_S) <= Q_t(7); |
if Q_t(7 downto 0) = "00000000" then |
F_Out(Flag_Z) <= '1'; |
F_Out(Flag_P) <= '1'; |
else |
F_Out(Flag_Z) <= '0'; |
F_Out(Flag_P) <= '0'; |
end if; |
F_Out(Flag_H) <= '1'; |
F_Out(Flag_N) <= '0'; |
F_Out(Flag_X) <= '0'; |
F_Out(Flag_Y) <= '0'; |
if IR(2 downto 0) /= "110" then |
F_Out(Flag_X) <= BusB(3); |
F_Out(Flag_Y) <= BusB(5); |
end if; |
Q_t := "--------"; |
when "10" => -- Set |
Q_t(7 downto 0) := BusB or BitMask; |
when "11" => -- Res |
Q_t(7 downto 0) := BusB and not BitMask; |
when others => |
end case; |
else |
F_Save <= "00111011"; |
if ISet /= "00" then |
F_Save <= "11111111"; |
end if; |
when "1010" => |
-- SET |
Q_t(7 downto 0) := BusB or BitMask; |
when "1011" => |
-- RES |
Q_t(7 downto 0) := BusB and not BitMask; |
when "1000" => |
-- ROT |
case IR(5 downto 3) is |
when "000" => -- RLC |
Q_t(7 downto 1) := BusA(6 downto 0); |
356,7 → 342,14
end if; |
F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor |
Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); |
end if; |
if ISet = "00" then |
F_Out(Flag_P) <= F_In(Flag_P); |
F_Out(Flag_S) <= F_In(Flag_S); |
F_Out(Flag_Z) <= F_In(Flag_Z); |
end if; |
when others => |
null; |
end case; |
Q <= Q_t; |
end process; |
|
/trunk/rtl/vhdl/T80a.vhd
1,7 → 1,7
-- |
-- Z80 compatible microprocessor core, asynchronous top level |
-- |
-- Version : 0240 |
-- Version : 0242 |
-- |
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) |
-- |
54,6 → 54,8
-- |
-- 0240 : Updated for T80 interface change |
-- |
-- 0242 : Updated for T80 interface change |
-- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
118,7 → 120,8
|
u0 : T80 |
generic map( |
Mode => Mode) |
Mode => Mode, |
IOWait => 1) |
port map( |
CEN => CEN, |
M1_n => M1_n, |
/trunk/rtl/vhdl/T80_MCode.vhd
1,7 → 1,7
-- |
-- Z80 compatible microprocessor core |
-- |
-- Version : 0240 |
-- Version : 0242 |
-- |
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) |
-- |
58,11 → 58,12
-- |
-- 0240 : Added (IX/IY+d) states, removed op-codes from mode 2 and added all remaining mode 3 op-codes |
-- |
-- 0242 : Fixed I/O instruction timing, cleanup |
-- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.numeric_std.all; |
use work.T80_Pack.all; |
|
entity T80_MCode is |
generic( |
94,13 → 95,11
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); |
-- (ir)ADD, (ir)ADC, (ir)SUB, (ir)SBC, (ir)AND, (ir)XOR, (ir)OR, (ir)CP, ADD, ADC, SUB, SBC, DAA, RLD, RRD, CP |
Rot_Op : out std_logic; |
Bit_Op : out std_logic_vector(1 downto 0); -- None, BIT, SET, RES |
-- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None |
Save_ALU : out std_logic; |
PreserveC : out std_logic; |
Arith16 : out std_logic; |
Set_Addr_To : out AddressOutput; -- aXY,aIOA,aSP,aBC,aDE,aZI,aNone |
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; |
137,6 → 136,21
|
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"; |
-- constant aNone : std_logic_vector(2 downto 0) := "000"; |
-- constant aXY : std_logic_vector(2 downto 0) := "001"; |
-- constant aIOA : std_logic_vector(2 downto 0) := "010"; |
-- constant aSP : std_logic_vector(2 downto 0) := "011"; |
-- constant aBC : std_logic_vector(2 downto 0) := "100"; |
-- constant aDE : std_logic_vector(2 downto 0) := "101"; |
-- constant aZI : std_logic_vector(2 downto 0) := "110"; |
|
function is_cc_true( |
F : std_logic_vector(7 downto 0); |
cc : bit_vector(2 downto 0) |
194,9 → 208,7
Read_To_Reg <= '0'; |
Set_BusB_To <= "0000"; |
Set_BusA_To <= "0000"; |
ALU_Op <= "0000"; |
Rot_Op <= '0'; |
Bit_Op <= "00"; |
ALU_Op <= "0" & IR(5 downto 3); |
Save_ALU <= '0'; |
PreserveC <= '0'; |
Arith16 <= '0'; |
706,7 → 718,7
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
PreserveC <= '1'; |
ALU_Op <= "1000"; |
ALU_Op <= "0000"; |
when "00110100" => |
-- INC (HL) |
MCycles <= "011"; |
719,7 → 731,7
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
PreserveC <= '1'; |
ALU_Op <= "1000"; |
ALU_Op <= "0000"; |
Set_BusB_To <= "1010"; |
Set_BusA_To(2 downto 0) <= DDD; |
when 3 => |
733,7 → 745,7
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
PreserveC <= '1'; |
ALU_Op <= "1010"; |
ALU_Op <= "0010"; |
when "00110101" => |
-- DEC (HL) |
MCycles <= "011"; |
743,7 → 755,7
when 2 => |
TStates <= "100"; |
Set_Addr_To <= aXY; |
ALU_Op <= "1010"; |
ALU_Op <= "0010"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
PreserveC <= '1'; |
837,7 → 849,7
case to_integer(unsigned(MCycle)) is |
when 2 => |
NoRead <= '1'; |
ALU_Op <= "1000"; |
ALU_Op <= "0000"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
Set_BusA_To(2 downto 0) <= "101"; |
854,7 → 866,7
NoRead <= '1'; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
ALU_Op <= "1001"; |
ALU_Op <= "0001"; |
Set_BusA_To(2 downto 0) <= "100"; |
case to_integer(unsigned(IR(5 downto 4))) is |
when 0|1|2 => |
886,7 → 898,7
|"00011111" => |
-- RRA |
Set_BusA_To(2 downto 0) <= "111"; |
Rot_Op <= '1'; |
ALU_Op <= "1000"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
|
1073,7 → 1085,7
Set_BusA_To(2 downto 0) <= "000"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
ALU_Op <= "1010"; |
ALU_Op <= "0010"; |
when 2 => |
I_DJNZ <= '1'; |
Inc_PC <= '1'; |
1176,7 → 1188,7
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 2 => |
ALU_Op <= "1000"; |
ALU_Op <= "0000"; |
Inc_PC <= '1'; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
1186,7 → 1198,7
NoRead <= '1'; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
ALU_Op <= "1001"; |
ALU_Op <= "0001"; |
Set_BusA_To <= "1001"; |
Set_BusB_To <= "1110"; -- Incorrect unsigned !!!!!!!!!!!!!!!!!!!!! |
when others => |
1347,9 → 1359,11
-- SRA r |
-- SRL r |
-- SLL r (Undocumented) / SWAP r |
Rot_Op <= '1'; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
if MCycle = "001" then |
ALU_Op <= "1000"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
end if; |
when "00000110"|"00010110"|"00001110"|"00011110"|"00101110"|"00111110"|"00100110"|"00110110" => |
-- RLC (HL) |
-- RL (HL) |
1361,10 → 1375,10
-- SLL (HL) (Undocumented) / SWAP (HL) |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
when 1 | 7 => |
Set_Addr_To <= aXY; |
when 2 => |
Rot_Op <= '1'; |
ALU_Op <= "1000"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
Set_Addr_To <= aXY; |
1382,18 → 1396,20
|"01110000"|"01110001"|"01110010"|"01110011"|"01110100"|"01110101"|"01110111" |
|"01111000"|"01111001"|"01111010"|"01111011"|"01111100"|"01111101"|"01111111" => |
-- BIT b,r |
Set_BusB_To(2 downto 0) <= IR(2 downto 0); |
Bit_Op <= "01"; |
if MCycle = "001" then |
Set_BusB_To(2 downto 0) <= IR(2 downto 0); |
ALU_Op <= "1001"; |
end if; |
when "01000110"|"01001110"|"01010110"|"01011110"|"01100110"|"01101110"|"01110110"|"01111110" => |
-- BIT b,(HL) |
MCycles <= "010"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
when 1 | 7 => |
Set_Addr_To <= aXY; |
when 2 => |
Bit_Op <= "01"; |
ALU_Op <= "1001"; |
TStates <= "100"; |
when others => null; |
when others => |
end case; |
when "11000000"|"11000001"|"11000010"|"11000011"|"11000100"|"11000101"|"11000111" |
|"11001000"|"11001001"|"11001010"|"11001011"|"11001100"|"11001101"|"11001111" |
1404,17 → 1420,19
|"11110000"|"11110001"|"11110010"|"11110011"|"11110100"|"11110101"|"11110111" |
|"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111111" => |
-- SET b,r |
Bit_Op <= "10"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
if MCycle = "001" then |
ALU_Op <= "1010"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
end if; |
when "11000110"|"11001110"|"11010110"|"11011110"|"11100110"|"11101110"|"11110110"|"11111110" => |
-- SET b,(HL) |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
when 1 | 7 => |
Set_Addr_To <= aXY; |
when 2 => |
Bit_Op <= "10"; |
ALU_Op <= "1010"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
Set_Addr_To <= aXY; |
1421,7 → 1439,7
TStates <= "100"; |
when 3 => |
Write <= '1'; |
when others => null; |
when others => |
end case; |
when "10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000111" |
|"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001111" |
1432,17 → 1450,19
|"10110000"|"10110001"|"10110010"|"10110011"|"10110100"|"10110101"|"10110111" |
|"10111000"|"10111001"|"10111010"|"10111011"|"10111100"|"10111101"|"10111111" => |
-- RES b,r |
Bit_Op <= "11"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
if MCycle = "001" then |
ALU_Op <= "1011"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
end if; |
when "10000110"|"10001110"|"10010110"|"10011110"|"10100110"|"10101110"|"10110110"|"10111110" => |
-- RES b,(HL) |
MCycles <= "011"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
when 1 | 7 => |
Set_Addr_To <= aXY; |
when 2 => |
Bit_Op <= "11"; |
ALU_Op <= "1011"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
Set_Addr_To <= aXY; |
1449,7 → 1469,7
TStates <= "100"; |
when 3 => |
Write <= '1'; |
when others => null; |
when others => |
end case; |
end case; |
|
1576,7 → 1596,7
end case; |
when "10100000" | "10101000" | "10110000" | "10111000" => |
-- LDI, LDD, LDIR, LDDR |
MCycles <= "011"; |
MCycles <= "100"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
Set_Addr_To <= aXY; |
1584,7 → 1604,7
when 2 => |
Set_BusB_To <= "0110"; |
Set_BusA_To(2 downto 0) <= "111"; |
ALU_Op <= "1000"; |
ALU_Op <= "0000"; |
Set_Addr_To <= aDE; |
if IR(3) = '0' then |
IncDec_16 <= "0110"; -- IX |
1600,19 → 1620,14
else |
IncDec_16 <= "1101"; |
end if; |
if IR(4) = '1' and F(Flag_P) = '1' then |
MCycles <= "100"; |
end if; |
when 4 => |
NoRead <= '1'; |
I_BTR <= '1'; |
TStates <= "101"; |
MCycles <= "100"; |
when others => null; |
end case; |
when "10100001" | "10101001" | "10110001" | "10111001" => |
-- CPI, CPD, CPIR, CPDR |
MCycles <= "011"; |
MCycles <= "100"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
Set_Addr_To <= aXY; |
1620,7 → 1635,7
when 2 => |
Set_BusB_To <= "0110"; |
Set_BusA_To(2 downto 0) <= "111"; |
ALU_Op <= "1111"; |
ALU_Op <= "0111"; |
Save_ALU <= '1'; |
PreserveC <= '1'; |
if IR(3) = '0' then |
1632,19 → 1647,14
NoRead <= '1'; |
I_BC <= '1'; |
TStates <= "101"; |
if IR(4) = '1' and F(Flag_P) = '1' and F(Flag_Z) = '0' then |
MCycles <= "100"; |
end if; |
when 4 => |
NoRead <= '1'; |
I_BTR <= '1'; |
TStates <= "101"; |
MCycles <= "100"; |
when others => null; |
end case; |
when "01000100"|"01001100"|"01010100"|"01011100"|"01100100"|"01101100"|"01110100"|"01111100" => |
-- NEG |
Alu_OP <= "1010"; |
Alu_OP <= "0010"; |
Set_BusB_To <= "0111"; |
Set_BusA_To <= "1010"; |
Read_To_Acc <= '1'; |
1665,7 → 1675,7
case to_integer(unsigned(MCycle)) is |
when 2 => |
NoRead <= '1'; |
ALU_Op <= "1001"; |
ALU_Op <= "0001"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
Set_BusA_To(2 downto 0) <= "101"; |
1681,7 → 1691,7
NoRead <= '1'; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
ALU_Op <= "1001"; |
ALU_Op <= "0001"; |
Set_BusA_To(2 downto 0) <= "100"; |
case to_integer(unsigned(IR(5 downto 4))) is |
when 0|1|2 => |
1698,7 → 1708,7
case to_integer(unsigned(MCycle)) is |
when 2 => |
NoRead <= '1'; |
ALU_Op <= "1011"; |
ALU_Op <= "0011"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
Set_BusA_To(2 downto 0) <= "101"; |
1712,7 → 1722,7
TStates <= "100"; |
when 3 => |
NoRead <= '1'; |
ALU_Op <= "1011"; |
ALU_Op <= "0011"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
Set_BusA_To(2 downto 0) <= "100"; |
1812,16 → 1822,15
end case; |
when "10100010" | "10101010" | "10110010" | "10111010" => |
-- INI, IND, INIR, INDR |
MCycles <= "011"; |
MCycles <= "100"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
TStates <= "101"; |
Set_Addr_To <= aBC; |
Set_BusB_To <= "1010"; |
Set_BusA_To <= "0000"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
ALU_Op <= "1010"; |
ALU_Op <= "0010"; |
when 2 => |
IORQ <= '1'; |
Set_BusB_To <= "0110"; |
1834,19 → 1843,15
end if; |
TStates <= "100"; |
Write <= '1'; |
if IR(4) = '1' and F(Flag_Z) = '0' then |
MCycles <= "100"; |
end if; |
I_BTR <= '1'; |
when 4 => |
NoRead <= '1'; |
I_BTR <= '1'; |
TStates <= "101"; |
MCycles <= "100"; |
when others => null; |
end case; |
when "10100011" | "10101011" | "10110011" | "10111011" => |
-- OUTI, OUTD, OTIR, OTDR |
MCycles <= "011"; |
MCycles <= "100"; |
case to_integer(unsigned(MCycle)) is |
when 1 => |
TStates <= "101"; |
1855,7 → 1860,7
Set_BusA_To <= "0000"; |
Read_To_Reg <= '1'; |
Save_ALU <= '1'; |
ALU_Op <= "1010"; |
ALU_Op <= "0010"; |
when 2 => |
Set_BusB_To <= "0110"; |
Set_Addr_To <= aBC; |
1866,16 → 1871,11
IncDec_16 <= "1010"; |
end if; |
IORQ <= '1'; |
TStates <= "100"; |
Write <= '1'; |
if IR(4) = '1' and F(Flag_Z) = '0' then |
MCycles <= "100"; |
end if; |
I_BTR <= '1'; |
when 4 => |
NoRead <= '1'; |
I_BTR <= '1'; |
TStates <= "101"; |
MCycles <= "100"; |
when others => null; |
end case; |
end case; |
1901,23 → 1901,26
if Mode < 2 then |
if MCycle = "110" then |
Inc_PC <= '1'; |
Set_Addr_To <= aNone; |
if Mode = 1 then |
Set_Addr_To <= aXY; |
TStates <= "100"; |
Set_Addr_To <= aXY; |
Set_BusB_To(2 downto 0) <= SSS; |
Set_BusB_To(3) <= '0'; |
if IRB = "00110110" or IRB = "11001011" then |
Set_Addr_To <= aNone; |
end if; |
end if; |
if IRB = "00110110" or IRB = "11001011" then |
Set_Addr_To <= aNone; |
end if; |
end if; |
if MCycle = "111" then |
TStates <= "101"; |
Set_Addr_To <= aXY; |
if Mode = 0 then |
TStates <= "101"; |
end if; |
if ISet /= "01" then |
Set_Addr_To <= aXY; |
end if; |
Set_BusB_To(2 downto 0) <= SSS; |
Set_BusB_To(3) <= '0'; |
if IRB = "00110110" then |
if IRB = "00110110" or ISet = "01" then |
-- LD (HL),n |
Inc_PC <= '1'; |
else |
/trunk/rtl/vhdl/DebugSystem.vhd
93,7 → 93,7
ROM_D; |
|
u0 : entity work.T80s |
generic map(Mode => 1, T2Write => 1) |
generic map(Mode => 1, T2Write => 1, IOWait => 0) |
port map( |
RESET_n => RESET_s, |
CLK_n => Clk, |
/trunk/rtl/vhdl/T80s.vhd
3,7 → 3,7
-- Different timing than the original z80 |
-- Inputs needs to be synchronous and outputs may glitch |
-- |
-- Version : 0240 |
-- Version : 0242 |
-- |
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) |
-- |
62,6 → 62,8
-- |
-- 0240 : Updated for T80 interface change |
-- |
-- 0242 : Updated for T80 interface change |
-- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
71,7 → 73,8
entity T80s 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 |
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; |
111,7 → 114,8
|
u0 : T80 |
generic map( |
Mode => Mode) |
Mode => Mode, |
IOWait => IOWait) |
port map( |
CEN => CEN, |
M1_n => M1_n, |
/trunk/sim/rtl_sim/bin/compile.do
1,6 → 1,7
vcom ../../../rtl/vhdl/T80_Pack.vhd |
vcom ../../../rtl/vhdl/T80_MCode.vhd |
vcom ../../../rtl/vhdl/T80_ALU.vhd |
vcom ../../../rtl/vhdl/T80_Reg.vhd |
vcom ../../../rtl/vhdl/T80.vhd |
vcom ../../../rtl/vhdl/T80a.vhd |
vcom ../../../rtl/vhdl/T80s.vhd |
/trunk/syn/xilinx/run/t80.bat
33,7 → 33,7
map -p %target% -cm speed -c 100 -tx on -o %name%_map %name% |
move %name%_map.mrp ..\log\%name%.mrp |
|
par -ol 3 -t 1 -c 0 %name%_map -w %name% |
par -ol 3 -t 1 %name%_map -w %name% |
move %name%.par ..\log |
|
trce %name%.ncd -o ../log/%name%.twr %name%_map.pcf |
/trunk/syn/xilinx/run/t80debugxr.bat
35,7 → 35,7
map -p %target% -cm speed -c 100 -pr b -timing -tx on -o %name%_map %name% |
move %name%_map.mrp ..\log\%name%.mrp |
|
par -ol 3 -t 1 -c 0 %name%_map -w %name% |
par -ol 3 -t 1 %name%_map -w %name% |
move %name%.par ..\log |
|
trce %name%.ncd -o ../log/%name%.twr %name%_map.pcf |
/trunk/syn/xilinx/run/t80debug.bat
35,7 → 35,7
map -p %target% -cm speed -c 100 -pr b -timing -tx on -o %name%_map %name% |
move %name%_map.mrp ..\log\%name%.mrp |
|
par -ol 3 -t 1 -c 0 %name%_map -w %name% |
par -ol 3 -t 1 %name%_map -w %name% |
move %name%.par ..\log |
|
trce %name%.ncd -o ../log/%name%.twr %name%_map.pcf |
/trunk/syn/xilinx/bin/t80debug.tcl
22,6 → 22,7
../../../rtl/vhdl/T80_Pack.vhd |
../../../rtl/vhdl/T80_MCode.vhd |
../../../rtl/vhdl/T80_ALU.vhd |
../../../rtl/vhdl/T80_Reg.vhd |
../../../rtl/vhdl/T80.vhd |
../../../rtl/vhdl/T80s.vhd |
../../../rtl/vhdl/T16450.vhd |
/trunk/syn/xilinx/bin/t80.prj
1,5 → 1,6
../../../rtl/vhdl/T80_Pack.vhd |
../../../rtl/vhdl/T80_MCode.vhd |
../../../rtl/vhdl/T80_ALU.vhd |
../../../rtl/vhdl/T80_RegX.vhd |
../../../rtl/vhdl/T80.vhd |
../../../rtl/vhdl/T80s.vhd |
/trunk/syn/xilinx/bin/t80debugxr.prj
1,6 → 1,7
../../../rtl/vhdl/T80_Pack.vhd |
../../../rtl/vhdl/T80_MCode.vhd |
../../../rtl/vhdl/T80_ALU.vhd |
../../../rtl/vhdl/T80_RegX.vhd |
../../../rtl/vhdl/T80.vhd |
../../../rtl/vhdl/T80s.vhd |
../../../rtl/vhdl/T16450.vhd |
/trunk/syn/xilinx/bin/t80.tcl
22,6 → 22,7
../../../rtl/vhdl/T80_Pack.vhd |
../../../rtl/vhdl/T80_MCode.vhd |
../../../rtl/vhdl/T80_ALU.vhd |
../../../rtl/vhdl/T80_Reg.vhd |
../../../rtl/vhdl/T80.vhd |
../../../rtl/vhdl/T80s.vhd |
} |
28,7 → 29,7
|
pre_optimize |
|
optimize -hierarchy=auto |
optimize -area -hierarchy=auto -pass 1 -pass 2 -pass 3 -pass 4 |
|
optimize_timing |
|
/trunk/syn/xilinx/bin/t80debug.prj
1,6 → 1,7
../../../rtl/vhdl/T80_Pack.vhd |
../../../rtl/vhdl/T80_MCode.vhd |
../../../rtl/vhdl/T80_ALU.vhd |
../../../rtl/vhdl/T80_RegX.vhd |
../../../rtl/vhdl/T80.vhd |
../../../rtl/vhdl/T80s.vhd |
../../../rtl/vhdl/T16450.vhd |
/trunk/syn/xilinx/bin/t80debugxr.tcl
22,6 → 22,7
../../../rtl/vhdl/T80_Pack.vhd |
../../../rtl/vhdl/T80_MCode.vhd |
../../../rtl/vhdl/T80_ALU.vhd |
../../../rtl/vhdl/T80_Reg.vhd |
../../../rtl/vhdl/T80.vhd |
../../../rtl/vhdl/T80s.vhd |
../../../rtl/vhdl/T16450.vhd |