+-- ****
+-- T80(b) core. In an effort to merge and maintain bug fixes ....
+--
+--
+-- Ver 300 started tidyup. Rmoved some auto_wait bits from 0247 which caused problems
+--
+-- MikeJ March 2005
+-- Latest version from www.fpgaarcade.com (original www.opencores.org)
+--
+-- ****
--
-- Z80 compatible microprocessor core
--
-- 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/
+-- http://www.opencores.org/cvsweb.shtml/t80/
--
-- Limitations :
--
-- File history :
--
--- 0208 : First complete release
+-- 0208 : First complete release
--
--- 0210 : Fixed wait and halt
+-- 0210 : Fixed wait and halt
--
--- 0211 : Fixed Refresh addition and IM 1
+-- 0211 : Fixed Refresh addition and IM 1
--
--- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test
+-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test
--
--- 0232 : Removed refresh address output for Mode > 1 and added DJNZ M1_n fix by Mike Johnson
+-- 0232 : Removed refresh address output for Mode > 1 and added DJNZ M1_n fix by Mike Johnson
--
--- 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
+-- 0238 : Fixed (IX/IY+d) timing and 16 bit ADC and SBC zero flag
--
--- 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
--
library IEEE;
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
+ 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_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
+ 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
);
end T80;
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";
+ 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 : 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 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;
+ 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 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 IntE_FF1 : std_logic;
- signal IntE_FF2 : std_logic;
- signal Halt_FF : std_logic;
- signal BusReq_s : std_logic;
- signal BusAck : std_logic;
- signal ClkEn : std_logic;
- signal NMI_s : std_logic;
- signal INT_s : std_logic;
- signal IStatus : std_logic_vector(1 downto 0);
-
- signal DI_Reg : std_logic_vector(7 downto 0);
- signal T_Res : std_logic;
- signal XY_State : std_logic_vector(1 downto 0);
- 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;
+ 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 IntE_FF1 : std_logic;
+ signal IntE_FF2 : std_logic;
+ signal Halt_FF : std_logic;
+ signal BusReq_s : std_logic;
+ signal BusAck : std_logic;
+ signal ClkEn : std_logic;
+ signal NMI_s : std_logic;
+ signal INT_s : std_logic;
+ signal IStatus : std_logic_vector(1 downto 0);
+
+ signal DI_Reg : std_logic_vector(7 downto 0);
+ signal T_Res : std_logic;
+ signal XY_State : std_logic_vector(1 downto 0);
+ 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);
- 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 BusB : std_logic_vector(7 downto 0);
+ 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);
-- Registered micro code outputs
- signal Read_To_Reg_r : std_logic_vector(4 downto 0);
- signal Arith16_r : std_logic;
- signal Z16_r : std_logic;
- signal ALU_Op_r : std_logic_vector(3 downto 0);
- signal Save_ALU_r : std_logic;
- signal PreserveC_r : std_logic;
- signal MCycles : std_logic_vector(2 downto 0);
+ signal Read_To_Reg_r : std_logic_vector(4 downto 0);
+ signal Arith16_r : std_logic;
+ signal Z16_r : std_logic;
+ signal ALU_Op_r : std_logic_vector(3 downto 0);
+ signal Save_ALU_r : std_logic;
+ signal PreserveC_r : std_logic;
+ signal MCycles : std_logic_vector(2 downto 0);
-- Micro code outputs
- signal MCycles_d : std_logic_vector(2 downto 0);
- signal TStates : std_logic_vector(2 downto 0);
- signal IntCycle : std_logic;
- signal NMICycle : std_logic;
- signal Inc_PC : std_logic;
- signal Inc_WZ : std_logic;
- signal IncDec_16 : std_logic_vector(3 downto 0);
- signal Prefix : std_logic_vector(1 downto 0);
- signal Read_To_Acc : std_logic;
- signal Read_To_Reg : std_logic;
- 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 Save_ALU : std_logic;
- signal PreserveC : std_logic;
- signal Arith16 : std_logic;
- signal Set_Addr_To : std_logic_vector(2 downto 0);
- signal Jump : std_logic;
- signal JumpE : std_logic;
- signal JumpXY : std_logic;
- signal Call : std_logic;
- signal RstP : std_logic;
- signal LDZ : std_logic;
- signal LDW : std_logic;
- signal LDSPHL : std_logic;
- signal IORQ_i : std_logic;
- signal Special_LD : std_logic_vector(2 downto 0);
- signal ExchangeDH : std_logic;
- signal ExchangeRp : std_logic;
- signal ExchangeAF : std_logic;
- signal ExchangeRS : std_logic;
- signal I_DJNZ : std_logic;
- signal I_CPL : std_logic;
- signal I_CCF : std_logic;
- signal I_SCF : std_logic;
- signal I_RETN : std_logic;
- signal I_BT : std_logic;
- signal I_BC : std_logic;
- signal I_BTR : std_logic;
- signal I_RLD : std_logic;
- signal I_RRD : std_logic;
- signal I_INRC : std_logic;
- signal SetDI : std_logic;
- signal SetEI : std_logic;
- signal IMode : std_logic_vector(1 downto 0);
- signal Halt : std_logic;
+ signal MCycles_d : std_logic_vector(2 downto 0);
+ signal TStates : std_logic_vector(2 downto 0);
+ signal IntCycle : std_logic;
+ signal NMICycle : std_logic;
+ signal Inc_PC : std_logic;
+ signal Inc_WZ : std_logic;
+ signal IncDec_16 : std_logic_vector(3 downto 0);
+ signal Prefix : std_logic_vector(1 downto 0);
+ signal Read_To_Acc : std_logic;
+ signal Read_To_Reg : std_logic;
+ 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 Save_ALU : std_logic;
+ signal PreserveC : std_logic;
+ signal Arith16 : std_logic;
+ signal Set_Addr_To : std_logic_vector(2 downto 0);
+ signal Jump : std_logic;
+ signal JumpE : std_logic;
+ signal JumpXY : std_logic;
+ signal Call : std_logic;
+ signal RstP : std_logic;
+ signal LDZ : std_logic;
+ signal LDW : std_logic;
+ signal LDSPHL : std_logic;
+ signal IORQ_i : std_logic;
+ signal Special_LD : std_logic_vector(2 downto 0);
+ signal ExchangeDH : std_logic;
+ signal ExchangeRp : std_logic;
+ signal ExchangeAF : std_logic;
+ signal ExchangeRS : std_logic;
+ signal I_DJNZ : std_logic;
+ signal I_CPL : std_logic;
+ signal I_CCF : std_logic;
+ signal I_SCF : std_logic;
+ signal I_RETN : std_logic;
+ signal I_BT : std_logic;
+ signal I_BC : std_logic;
+ signal I_BTR : std_logic;
+ signal I_RLD : std_logic;
+ signal I_RRD : std_logic;
+ signal I_INRC : std_logic;
+ signal SetDI : std_logic;
+ signal SetEI : std_logic;
+ signal IMode : std_logic_vector(1 downto 0);
+ signal Halt : std_logic;
begin
mcode : T80_MCode
generic map(
- Mode => Mode,
+ Mode => Mode,
Flag_C => Flag_C,
Flag_N => Flag_N,
Flag_P => Flag_P,
Flag_Z => Flag_Z,
Flag_S => Flag_S)
port map(
- IR => IR,
- ISet => ISet,
- MCycle => MCycle,
- F => F,
- NMICycle => NMICycle,
- IntCycle => IntCycle,
- MCycles => MCycles_d,
- TStates => TStates,
- Prefix => Prefix,
- Inc_PC => Inc_PC,
- Inc_WZ => Inc_WZ,
- IncDec_16 => IncDec_16,
+ IR => IR,
+ ISet => ISet,
+ MCycle => MCycle,
+ F => F,
+ NMICycle => NMICycle,
+ IntCycle => IntCycle,
+ MCycles => MCycles_d,
+ TStates => TStates,
+ Prefix => Prefix,
+ Inc_PC => Inc_PC,
+ Inc_WZ => Inc_WZ,
+ IncDec_16 => IncDec_16,
Read_To_Acc => Read_To_Acc,
Read_To_Reg => Read_To_Reg,
Set_BusB_To => Set_BusB_To,
Set_BusA_To => Set_BusA_To,
- ALU_Op => ALU_Op,
- Save_ALU => Save_ALU,
- PreserveC => PreserveC,
- Arith16 => Arith16,
+ ALU_Op => ALU_Op,
+ Save_ALU => Save_ALU,
+ PreserveC => PreserveC,
+ Arith16 => Arith16,
Set_Addr_To => Set_Addr_To,
- IORQ => IORQ_i,
- Jump => Jump,
- JumpE => JumpE,
- JumpXY => JumpXY,
- Call => Call,
- RstP => RstP,
- LDZ => LDZ,
- LDW => LDW,
- LDSPHL => LDSPHL,
- Special_LD => Special_LD,
- ExchangeDH => ExchangeDH,
- ExchangeRp => ExchangeRp,
- ExchangeAF => ExchangeAF,
- ExchangeRS => ExchangeRS,
- I_DJNZ => I_DJNZ,
- I_CPL => I_CPL,
- I_CCF => I_CCF,
- I_SCF => I_SCF,
- I_RETN => I_RETN,
- I_BT => I_BT,
- I_BC => I_BC,
- I_BTR => I_BTR,
- I_RLD => I_RLD,
- I_RRD => I_RRD,
- I_INRC => I_INRC,
- SetDI => SetDI,
- SetEI => SetEI,
- IMode => IMode,
- Halt => Halt,
- NoRead => NoRead,
- Write => Write);
+ IORQ => IORQ_i,
+ Jump => Jump,
+ JumpE => JumpE,
+ JumpXY => JumpXY,
+ Call => Call,
+ RstP => RstP,
+ LDZ => LDZ,
+ LDW => LDW,
+ LDSPHL => LDSPHL,
+ Special_LD => Special_LD,
+ ExchangeDH => ExchangeDH,
+ ExchangeRp => ExchangeRp,
+ ExchangeAF => ExchangeAF,
+ ExchangeRS => ExchangeRS,
+ I_DJNZ => I_DJNZ,
+ I_CPL => I_CPL,
+ I_CCF => I_CCF,
+ I_SCF => I_SCF,
+ I_RETN => I_RETN,
+ I_BT => I_BT,
+ I_BC => I_BC,
+ I_BTR => I_BTR,
+ I_RLD => I_RLD,
+ I_RRD => I_RRD,
+ I_INRC => I_INRC,
+ SetDI => SetDI,
+ SetEI => SetEI,
+ IMode => IMode,
+ Halt => Halt,
+ NoRead => NoRead,
+ Write => Write);
alu : T80_ALU
generic map(
- Mode => Mode,
+ Mode => Mode,
Flag_C => Flag_C,
Flag_N => Flag_N,
Flag_P => Flag_P,
Flag_S => Flag_S)
port map(
Arith16 => Arith16_r,
- Z16 => Z16_r,
- ALU_Op => ALU_Op_r,
- IR => IR(5 downto 0),
- ISet => ISet,
- BusA => BusA,
- BusB => BusB,
- F_In => F,
- Q => ALU_Q,
- F_Out => F_Out);
+ Z16 => Z16_r,
+ ALU_Op => ALU_Op_r,
+ IR => IR(5 downto 0),
+ ISet => ISet,
+ BusA => BusA,
+ BusB => BusB,
+ F_In => F,
+ Q => ALU_Q,
+ F_Out => F_Out);
ClkEn <= CEN and not BusAck;
DI_Reg(4) xor DI_Reg(5) xor DI_Reg(6) xor DI_Reg(7));
end if;
- if TState = 1 and Auto_Wait_t1 = '0' then
+ if TState = 1 then
DO <= BusB;
if I_RLD = '1' then
DO(3 downto 0) <= BusA(3 downto 0);
F(Flag_P) <= IncDecZ;
end if;
- if (TState = 1 and Save_ALU_r = '0' and Auto_Wait_t1 = '0') or
+ if (TState = 1 and Save_ALU_r = '0') or
(Save_ALU_r = '1' and ALU_OP_r /= "0111") then
case Read_To_Reg_r is
when "10111" =>
begin
RegWEH <= '0';
RegWEL <= '0';
- if (TState = 1 and Save_ALU_r = '0' and Auto_Wait_t1 = '0') or
+ if (TState = 1 and Save_ALU_r = '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" =>
M1_n <= '1';
elsif CLK_n'event and CLK_n = '1' then
if CEN = '1' then
- if T_Res = '1' then
- Auto_Wait_t1 <= '0';
- else
- Auto_Wait_t1 <= Auto_Wait or IORQ_i;
- end if;
+ Auto_Wait_t1 <= Auto_Wait;
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
end if;
end if;
else
- if (Auto_Wait = '1' and Auto_Wait_t2 = '0') nor
- (IOWait = 1 and IORQ_i = '1' and Auto_Wait_t1 = '0') then
+ if Auto_Wait = '1' nand Auto_Wait_t2 = '0' then
+
TState <= TState + 1;
end if;
end if;