Line 1... |
Line 1... |
--
|
--
|
-- Z80 compatible microprocessor core
|
-- Z80 compatible microprocessor core
|
--
|
--
|
-- Version : 0237
|
-- Version : 0238
|
--
|
--
|
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
--
|
--
|
-- All rights reserved
|
-- All rights reserved
|
--
|
--
|
Line 59... |
Line 59... |
--
|
--
|
-- 0235 : Added clock enable and IM 2 fix by Mike Johnson
|
-- 0235 : Added clock enable and IM 2 fix by Mike Johnson
|
--
|
--
|
-- 0237 : Changed 8080 I/O address output, added IntE output
|
-- 0237 : Changed 8080 I/O address output, added IntE output
|
--
|
--
|
|
-- 0238 : Fixed (IX/IY+d) timing and 16 bit ADC and SBC zero flag
|
|
--
|
|
|
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;
|
use work.T80_Pack.all;
|
Line 79... |
Line 81... |
INT_n : in std_logic;
|
INT_n : in std_logic;
|
NMI_n : in std_logic;
|
NMI_n : in std_logic;
|
BUSRQ_n : in std_logic;
|
BUSRQ_n : in std_logic;
|
M1_n : out std_logic;
|
M1_n : out std_logic;
|
IORQ : out std_logic;
|
IORQ : out std_logic;
|
|
NoRead : out std_logic;
|
Write : out std_logic;
|
Write : out std_logic;
|
RFSH_n : out std_logic;
|
RFSH_n : out std_logic;
|
HALT_n : out std_logic;
|
HALT_n : out std_logic;
|
BUSAK_n : out std_logic;
|
BUSAK_n : out std_logic;
|
A : out std_logic_vector(15 downto 0);
|
A : out std_logic_vector(15 downto 0);
|
Line 132... |
Line 135... |
signal IStatus : std_logic_vector(1 downto 0);
|
signal IStatus : std_logic_vector(1 downto 0);
|
|
|
signal DI_Reg : std_logic_vector(7 downto 0);
|
signal DI_Reg : std_logic_vector(7 downto 0);
|
signal T_Res : std_logic;
|
signal T_Res : std_logic;
|
signal XY_State : std_logic_vector(1 downto 0);
|
signal XY_State : std_logic_vector(1 downto 0);
|
signal XY_Fetch : std_logic;
|
signal XY_Fetch : std_logic_vector(1 downto 0);
|
signal NextIs_XY_Fetch : std_logic;
|
signal NextIs_XY_Fetch : std_logic;
|
signal XY_Ind : std_logic;
|
signal XY_Ind : std_logic;
|
|
|
-- ALU signals
|
-- ALU signals
|
signal BusB : std_logic_vector(7 downto 0);
|
signal BusB : std_logic_vector(7 downto 0);
|
Line 146... |
Line 149... |
signal F_Save : std_logic_vector(7 downto 0);
|
signal F_Save : std_logic_vector(7 downto 0);
|
|
|
-- Registered micro code outputs
|
-- Registered micro code outputs
|
signal Read_To_Reg_r : std_logic_vector(4 downto 0);
|
signal Read_To_Reg_r : std_logic_vector(4 downto 0);
|
signal Arith16_r : std_logic;
|
signal Arith16_r : std_logic;
|
|
signal Z16_r : std_logic;
|
signal ALU_Op_r : std_logic_vector(3 downto 0);
|
signal ALU_Op_r : std_logic_vector(3 downto 0);
|
signal AALU_OP_r : std_logic_vector(2 downto 0);
|
signal AALU_OP_r : std_logic_vector(2 downto 0);
|
signal Rot_Op_r : std_logic;
|
signal Rot_Op_r : std_logic;
|
signal Bit_Op_r : std_logic_vector(1 downto 0);
|
signal Bit_Op_r : std_logic_vector(1 downto 0);
|
signal Save_ALU_r : std_logic;
|
signal Save_ALU_r : std_logic;
|
Line 263... |
Line 267... |
I_INRC => I_INRC,
|
I_INRC => I_INRC,
|
SetDI => SetDI,
|
SetDI => SetDI,
|
SetEI => SetEI,
|
SetEI => SetEI,
|
IMode => IMode,
|
IMode => IMode,
|
Halt => Halt,
|
Halt => Halt,
|
|
NoRead => NoRead,
|
Write => Write);
|
Write => Write);
|
|
|
alu : T80_ALU
|
alu : T80_ALU
|
port map(
|
port map(
|
Arith16 => Arith16_r,
|
Arith16 => Arith16_r,
|
|
Z16 => Z16_r,
|
ALU_Op => ALU_Op_r,
|
ALU_Op => ALU_Op_r,
|
Rot_Op => Rot_Op_r,
|
Rot_Op => Rot_Op_r,
|
Bit_Op => Bit_Op_r,
|
Bit_Op => Bit_Op_r,
|
IR => IR,
|
IR => IR,
|
ISet => ISet,
|
ISet => ISet,
|
Line 280... |
Line 286... |
F_In => F,
|
F_In => F,
|
Q => ALU_Q,
|
Q => ALU_Q,
|
F_Out => F_Out,
|
F_Out => F_Out,
|
F_Save => F_Save);
|
F_Save => F_Save);
|
|
|
T_Res <= '1' when (TState = unsigned(TStates) and XY_Fetch = '0') or
|
T_Res <= '1' when (TState = unsigned(TStates) and XY_Fetch(0) = '0') or
|
(XY_Fetch = '1' and TState = 4) else '0'; -- Incorrect, should be 8 !!!!!!!!!!!!!!!!
|
(XY_Fetch(0) = '1' and TState = "111" and Mode = 0) or
|
|
(XY_Fetch(0) = '1' and TState = "100" and Mode = 1) else '0';
|
|
|
NextIs_XY_Fetch <= '1' when XY_State /= "00" and XY_Ind = '0' and ((Set_Addr_To = aXY and IR /= "11001011") or
|
NextIs_XY_Fetch <= '1' when XY_State /= "00" and XY_Ind = '0' and ((Set_Addr_To = aXY and IR /= "11001011") or
|
(MCycle = "001" and IR = "11001011") or
|
(MCycle = "001" and IR = "11001011") or
|
(MCycle = "001" and IR = "00110110")) else '0';
|
(MCycle = "001" and IR = "00110110")) else '0';
|
|
|
Line 309... |
Line 316... |
R <= (others => '0');
|
R <= (others => '0');
|
SP <= (others => '1');
|
SP <= (others => '1');
|
|
|
Read_To_Reg_r <= "00000";
|
Read_To_Reg_r <= "00000";
|
Arith16_r <= '0';
|
Arith16_r <= '0';
|
|
Z16_r <= '0';
|
ALU_Op_r <= "0000";
|
ALU_Op_r <= "0000";
|
Rot_Op_r <= '0';
|
Rot_Op_r <= '0';
|
Bit_Op_r <= "00";
|
Bit_Op_r <= "00";
|
Save_ALU_r <= '0';
|
Save_ALU_r <= '0';
|
PreserveC_r <= '0';
|
PreserveC_r <= '0';
|
Line 321... |
Line 329... |
|
|
elsif CLK_n'event and CLK_n = '1' then
|
elsif CLK_n'event and CLK_n = '1' then
|
|
|
if CEN = '1' then
|
if CEN = '1' then
|
|
|
Arith16_r <= '0';
|
|
ALU_Op_r <= "0000";
|
ALU_Op_r <= "0000";
|
Rot_Op_r <= '0';
|
Rot_Op_r <= '0';
|
Bit_Op_r <= "00";
|
Bit_Op_r <= "00";
|
Save_ALU_r <= '0';
|
Save_ALU_r <= '0';
|
PreserveC_r <= '0';
|
|
AALU_OP_r <= "000";
|
AALU_OP_r <= "000";
|
Read_To_Reg_r <= "00000";
|
Read_To_Reg_r <= "00000";
|
|
|
MCycles <= MCycles_d;
|
MCycles <= MCycles_d;
|
|
|
if IMode /= "11" then
|
if IMode /= "11" then
|
IStatus <= IMode;
|
IStatus <= IMode;
|
end if;
|
end if;
|
|
|
if MCycle = "001" and TState(2) = '0' and XY_Fetch = '0' then
|
Arith16_r <= Arith16;
|
|
PreserveC_r <= PreserveC;
|
|
if ISet = "10" and ALU_OP(2) = '0' and ALU_OP(0) = '1' and MCycle = "011" then
|
|
Z16_r <= '1';
|
|
else
|
|
Z16_r <= '0';
|
|
end if;
|
|
|
|
if MCycle = "001" and TState(2) = '0' and XY_Fetch(0) = '0' then
|
-- MCycle = 1 and TState = 1, 2, or 3
|
-- MCycle = 1 and TState = 1, 2, or 3
|
|
|
if TState = 2 and Wait_n = '1' then
|
if TState = 2 and Wait_n = '1' then
|
if Mode < 2 then
|
if Mode < 2 then
|
A(7 downto 0) <= std_logic_vector(R);
|
A(7 downto 0) <= std_logic_vector(R);
|
Line 382... |
Line 396... |
end if;
|
end if;
|
|
|
else
|
else
|
-- either (MCycle > 1) OR (MCycle = 1 AND TState > 3)
|
-- either (MCycle > 1) OR (MCycle = 1 AND TState > 3)
|
|
|
if XY_Fetch = '1' then
|
if XY_Fetch(0) = '1' then
|
XY_Ind <= '1';
|
XY_Ind <= '1';
|
end if;
|
end if;
|
|
|
if T_Res = '1' then
|
if T_Res = '1' then
|
if Jump = '1' then
|
if Jump = '1' then
|
Line 458... |
Line 472... |
when aNone =>
|
when aNone =>
|
A <= std_logic_vector(PC);
|
A <= std_logic_vector(PC);
|
end case;
|
end case;
|
end if;
|
end if;
|
|
|
Arith16_r <= Arith16;
|
Save_ALU_r <= Save_ALU;
|
ALU_Op_r <= ALU_Op;
|
ALU_Op_r <= ALU_Op;
|
Rot_Op_r <= Rot_Op;
|
Rot_Op_r <= Rot_Op;
|
Bit_Op_r <= Bit_Op;
|
Bit_Op_r <= Bit_Op;
|
Save_ALU_r <= Save_ALU;
|
|
PreserveC_r <= PreserveC;
|
|
if Save_ALU = '1' then
|
if Save_ALU = '1' then
|
if Rot_Op = '0' and Bit_Op = "00" then
|
if Rot_Op = '0' and Bit_Op = "00" then
|
if ALU_Op(3) = '1' then
|
if ALU_Op(3) = '1' then
|
AALU_OP_r <= ALU_Op(2 downto 0);
|
AALU_OP_r <= ALU_Op(2 downto 0);
|
else
|
else
|
Line 503... |
Line 515... |
end if;
|
end if;
|
|
|
if TState = 2 and Wait_n = '1' then
|
if TState = 2 and Wait_n = '1' then
|
if JumpE = '1' then
|
if JumpE = '1' then
|
PC <= unsigned(signed(PC) + signed(DI_Reg));
|
PC <= unsigned(signed(PC) + signed(DI_Reg));
|
elsif Inc_PC = '1' or XY_Fetch = '1' then
|
elsif Inc_PC = '1' or XY_Fetch(0) = '1' then
|
PC <= PC + 1;
|
PC <= PC + 1;
|
end if;
|
end if;
|
if I_BTR = '1' then
|
if I_BTR = '1' then
|
PC <= PC - 2;
|
PC <= PC - 2;
|
end if;
|
end if;
|
if RstP = '1' then
|
if RstP = '1' then
|
TmpAddr <= (others =>'0');
|
TmpAddr <= (others =>'0');
|
TmpAddr(5 downto 3) <= IR(5 downto 3);
|
TmpAddr(5 downto 3) <= IR(5 downto 3);
|
end if;
|
end if;
|
end if;
|
end if;
|
if TState = 3 and XY_Fetch = '1' then
|
if TState = 3 and XY_Fetch = "01" then
|
if XY_State = "01" then
|
if XY_State = "01" then
|
TmpAddr <= std_logic_vector(signed(IX) + signed(DI_Reg));
|
TmpAddr <= std_logic_vector(signed(IX) + signed(DI_Reg));
|
end if;
|
end if;
|
if XY_State = "10" then
|
if XY_State = "10" then
|
TmpAddr <= std_logic_vector(signed(IY) + signed(DI_Reg));
|
TmpAddr <= std_logic_vector(signed(IY) + signed(DI_Reg));
|
Line 915... |
Line 927... |
|
|
MC <= std_logic_vector(MCycle);
|
MC <= std_logic_vector(MCycle);
|
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;
|
False_M1 <= XY_Fetch;
|
False_M1 <= XY_Fetch(0);
|
IntCycle_n <= not IntCycle;
|
IntCycle_n <= not IntCycle;
|
|
|
process (RESET_n,CLK_n)
|
process (RESET_n,CLK_n)
|
begin
|
begin
|
if RESET_n = '0' then
|
if RESET_n = '0' then
|
Line 974... |
Line 986... |
BReq_FF <= '0';
|
BReq_FF <= '0';
|
Halt_FF <= '0';
|
Halt_FF <= '0';
|
BUSAK_n <= '1';
|
BUSAK_n <= '1';
|
NMICycle <= '0';
|
NMICycle <= '0';
|
IntCycle <= '0';
|
IntCycle <= '0';
|
XY_Fetch <= '0';
|
XY_Fetch <= "00";
|
IntE_FF1 <= '0';
|
IntE_FF1 <= '0';
|
IntE_FF2 <= '0';
|
IntE_FF2 <= '0';
|
elsif CLK_n'event and CLK_n = '1' then -- CLK_n is the clock signal
|
elsif CLK_n'event and CLK_n = '1' then -- CLK_n is the clock signal
|
if CEN = '1' then
|
if CEN = '1' then
|
if TState = 2 then
|
if TState = 2 then
|
Line 1004... |
Line 1016... |
BReq_FF <= '0';
|
BReq_FF <= '0';
|
BUSAK_n <= '1';
|
BUSAK_n <= '1';
|
end if;
|
end if;
|
else
|
else
|
if TState = 2 and Wait_n = '0' then
|
if TState = 2 and Wait_n = '0' then
|
|
elsif XY_Fetch = "01" and TState = "100" and Mode = 0 then
|
|
XY_Fetch <= "11";
|
|
TState <= "011";
|
elsif T_Res = '1' then
|
elsif T_Res = '1' then
|
if Halt = '1' then
|
if Halt = '1' then
|
Halt_FF <= '1';
|
Halt_FF <= '1';
|
end if;
|
end if;
|
if BUSRQ_n = '0' then
|
if BUSRQ_n = '0' then
|
BReq_FF <= '1';
|
BReq_FF <= '1';
|
BUSAK_n <= '0';
|
BUSAK_n <= '0';
|
else
|
else
|
TState <= "001";
|
TState <= "001";
|
XY_Fetch <= '0';
|
XY_Fetch <= "00";
|
if NextIs_XY_Fetch = '1' then
|
if NextIs_XY_Fetch = '1' then
|
XY_Fetch <= '1';
|
XY_Fetch <= "01";
|
elsif MCycle = MCycles or (MCycle = "010" and I_DJNZ = '1' and B = "00000000") then
|
elsif MCycle = MCycles or (MCycle = "010" and I_DJNZ = '1' and B = "00000000") then
|
MCycle <= "001";
|
MCycle <= "001";
|
IntCycle <= '0';
|
IntCycle <= '0';
|
NMICycle <= '0';
|
NMICycle <= '0';
|
if NMI_s = '1' and Prefix = "00" then
|
if NMI_s = '1' and Prefix = "00" then
|