diff --git a/t80/T80.qip b/t80/T80.qip index 32f03e5..f42aad1 100644 --- a/t80/T80.qip +++ b/t80/T80.qip @@ -1,6 +1,5 @@ set_global_assignment -name VHDL_FILE t80/T80pa.vhd set_global_assignment -name VHDL_FILE t80/T80_Reg.vhd -set_global_assignment -name VHDL_FILE t80/T80_Pack.vhd set_global_assignment -name VHDL_FILE t80/T80_MCode.vhd set_global_assignment -name VHDL_FILE t80/T80_ALU.vhd set_global_assignment -name VHDL_FILE t80/T80.vhd diff --git a/t80/T80.vhd b/t80/T80.vhd index c4dc923..495e1d6 100644 --- a/t80/T80.vhd +++ b/t80/T80.vhd @@ -79,7 +79,6 @@ library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; use IEEE.STD_LOGIC_UNSIGNED.all; -use work.T80_Pack.all; entity T80 is generic( @@ -118,7 +117,11 @@ entity T80 is IntCycle_n : out std_logic; IntE : out std_logic; Stop : out std_logic; - REG : out std_logic_vector(207 downto 0) -- IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A + 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 T80; @@ -255,11 +258,11 @@ architecture rtl of T80 is begin - REG <= 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) & + 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 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; - mcode : T80_MCode + mcode : work.T80_MCode generic map( Mode => Mode, Flag_C => Flag_C, @@ -327,7 +330,7 @@ begin Write => Write, XYbit_undoc => XYbit_undoc); - alu : T80_ALU + alu : work.T80_ALU generic map( Mode => Mode, Flag_C => Flag_C, @@ -390,7 +393,6 @@ begin Alternate <= '0'; Read_To_Reg_r <= "00000"; - F <= (others => '1'); Arith16_r <= '0'; BTR_r <= '0'; Z16_r <= '0'; @@ -402,402 +404,410 @@ begin elsif rising_edge(CLK_n) then - if ClkEn = '1' then - - ALU_Op_r <= "0000"; - Save_ALU_r <= '0'; - Read_To_Reg_r <= "00000"; - - MCycles <= MCycles_d; - - if IMode /= "11" then - IStatus <= IMode; - end if; + 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"; + Save_ALU_r <= '0'; + Read_To_Reg_r <= "00000"; + + MCycles <= MCycles_d; + + if IMode /= "11" then + IStatus <= IMode; + end if; - 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; + 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' then - -- MCycle = 1 and TState = 1, 2, or 3 + if MCycle = "001" and TState(2) = '0' then + -- MCycle = 1 and TState = 1, 2, or 3 - if TState = 2 and Wait_n = '1' then - if Mode < 2 then - A(7 downto 0) <= std_logic_vector(R); - A(15 downto 8) <= I; - R(6 downto 0) <= R(6 downto 0) + 1; - end if; + if TState = 2 and Wait_n = '1' then + if Mode < 2 then + A(7 downto 0) <= std_logic_vector(R); + A(15 downto 8) <= I; + R(6 downto 0) <= R(6 downto 0) + 1; + end if; - if Jump = '0' and Call = '0' and NMICycle = '0' and IntCycle = '0' and not (Halt_FF = '1' or Halt = '1') then - PC <= PC + 1; - end if; + if Jump = '0' and Call = '0' and NMICycle = '0' and IntCycle = '0' and not (Halt_FF = '1' or Halt = '1') then + PC <= PC + 1; + end if; - if IntCycle = '1' and IStatus = "01" then - IR <= "11111111"; - elsif Halt_FF = '1' or (IntCycle = '1' and IStatus = "10") or NMICycle = '1' then - IR <= "00000000"; - else - IR <= DInst; - end if; + if IntCycle = '1' and IStatus = "01" then + IR <= "11111111"; + elsif Halt_FF = '1' or (IntCycle = '1' and IStatus = "10") or NMICycle = '1' then + IR <= "00000000"; + else + IR <= DInst; + end if; - ISet <= "00"; - if Prefix /= "00" then - if Prefix = "11" then - if IR(5) = '1' then - XY_State <= "10"; + ISet <= "00"; + if Prefix /= "00" then + if Prefix = "11" then + if IR(5) = '1' then + XY_State <= "10"; + else + XY_State <= "01"; + end if; else - XY_State <= "01"; + if Prefix = "10" then + XY_State <= "00"; + XY_Ind <= '0'; + end if; + ISet <= Prefix; end if; else - if Prefix = "10" then - XY_State <= "00"; - XY_Ind <= '0'; - end if; - ISet <= Prefix; + XY_State <= "00"; + XY_Ind <= '0'; end if; - else - XY_State <= "00"; - XY_Ind <= '0'; end if; - end if; - else - -- either (MCycle > 1) OR (MCycle = 1 AND TState > 3) + else + -- either (MCycle > 1) OR (MCycle = 1 AND TState > 3) - if MCycle = "110" then - XY_Ind <= '1'; - if Prefix = "01" then - ISet <= "01"; + if MCycle = "110" then + XY_Ind <= '1'; + if Prefix = "01" then + ISet <= "01"; + end if; 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) <= WZ(7 downto 0); - PC(15 downto 8) <= unsigned(DI_Reg); - PC(7 downto 0) <= unsigned(WZ(7 downto 0)); - elsif JumpXY = '1' then - A <= RegBusC; - PC <= unsigned(RegBusC); - elsif Call = '1' or RstP = '1' then - A <= WZ; - PC <= unsigned(WZ); - elsif MCycle = MCycles and NMICycle = '1' then - A <= "0000000001100110"; - PC <= "0000000001100110"; - elsif MCycle = "011" and IntCycle = '1' and IStatus = "10" then - A(15 downto 8) <= I; - A(7 downto 0) <= WZ(7 downto 0); - PC(15 downto 8) <= unsigned(I); - PC(7 downto 0) <= unsigned(WZ(7 downto 0)); - else - case Set_Addr_To is - when aXY => - if XY_State = "00" then - A <= RegBusC; - else - if NextIs_XY_Fetch = '1' then - A <= std_logic_vector(PC); + if T_Res = '1' then + BTR_r <= (I_BT or I_BC or I_BTR) and not No_BTR; + if Jump = '1' then + A(15 downto 8) <= DI_Reg; + A(7 downto 0) <= WZ(7 downto 0); + PC(15 downto 8) <= unsigned(DI_Reg); + PC(7 downto 0) <= unsigned(WZ(7 downto 0)); + elsif JumpXY = '1' then + A <= RegBusC; + PC <= unsigned(RegBusC); + elsif Call = '1' or RstP = '1' then + A <= WZ; + PC <= unsigned(WZ); + elsif MCycle = MCycles and NMICycle = '1' then + A <= "0000000001100110"; + PC <= "0000000001100110"; + elsif MCycle = "011" and IntCycle = '1' and IStatus = "10" then + A(15 downto 8) <= I; + A(7 downto 0) <= WZ(7 downto 0); + PC(15 downto 8) <= unsigned(I); + PC(7 downto 0) <= unsigned(WZ(7 downto 0)); + else + case Set_Addr_To is + when aXY => + if XY_State = "00" then + A <= RegBusC; else - A <= WZ; + if NextIs_XY_Fetch = '1' then + A <= std_logic_vector(PC); + else + A <= WZ; + end if; end if; - end if; - when aIOA => - if Mode = 3 then - -- Memory map I/O on GBZ80 - A(15 downto 8) <= (others => '1'); - elsif Mode = 2 then - -- Duplicate I/O address on 8080 - A(15 downto 8) <= DI_Reg; - else - A(15 downto 8) <= ACC; - end if; - A(7 downto 0) <= DI_Reg; - WZ <= (ACC & DI_Reg) + "1"; - when aSP => - A <= std_logic_vector(SP); - when aBC => - if Mode = 3 and IORQ_i = '1' then - -- Memory map I/O on GBZ80 - A(15 downto 8) <= (others => '1'); - A(7 downto 0) <= RegBusC(7 downto 0); - else - A <= RegBusC; - if SetWZ = "01" then - WZ <= RegBusC + "1"; + when aIOA => + if Mode = 3 then + -- Memory map I/O on GBZ80 + A(15 downto 8) <= (others => '1'); + elsif Mode = 2 then + -- Duplicate I/O address on 8080 + A(15 downto 8) <= DI_Reg; + else + A(15 downto 8) <= ACC; end if; + A(7 downto 0) <= DI_Reg; + WZ <= (ACC & DI_Reg) + "1"; + when aSP => + A <= std_logic_vector(SP); + when aBC => + if Mode = 3 and IORQ_i = '1' then + -- Memory map I/O on GBZ80 + A(15 downto 8) <= (others => '1'); + A(7 downto 0) <= RegBusC(7 downto 0); + else + A <= RegBusC; + if SetWZ = "01" then + WZ <= RegBusC + "1"; + end if; + if SetWZ = "10" then + WZ(7 downto 0) <= RegBusC(7 downto 0) + "1"; + WZ(15 downto 8) <= ACC; + end if; + end if; + when aDE => + A <= RegBusC; if SetWZ = "10" then WZ(7 downto 0) <= RegBusC(7 downto 0) + "1"; WZ(15 downto 8) <= ACC; end if; - end if; - when aDE => - A <= RegBusC; - if SetWZ = "10" then - WZ(7 downto 0) <= RegBusC(7 downto 0) + "1"; - WZ(15 downto 8) <= ACC; - end if; - when aZI => - if Inc_WZ = '1' then - A <= std_logic_vector(unsigned(WZ) + 1); - else - A(15 downto 8) <= DI_Reg; - A(7 downto 0) <= WZ(7 downto 0); - if SetWZ = "10" then - WZ(7 downto 0) <= WZ(7 downto 0) + "1"; - WZ(15 downto 8) <= ACC; + when aZI => + if Inc_WZ = '1' then + A <= std_logic_vector(unsigned(WZ) + 1); + else + A(15 downto 8) <= DI_Reg; + A(7 downto 0) <= WZ(7 downto 0); + if SetWZ = "10" then + WZ(7 downto 0) <= WZ(7 downto 0) + "1"; + WZ(15 downto 8) <= ACC; + end if; end if; - end if; - when others => - A <= std_logic_vector(PC); - end case; - end if; - - if SetWZ = "11" then - WZ <= std_logic_vector(ID16); + when others => + A <= std_logic_vector(PC); + end case; + end if; + + if SetWZ = "11" then + WZ <= std_logic_vector(ID16); + end if; + + Save_ALU_r <= Save_ALU; + ALU_Op_r <= ALU_Op; + + if I_CPL = '1' then + -- CPL + ACC <= not ACC; + F(Flag_Y) <= not ACC(5); + F(Flag_H) <= '1'; + F(Flag_X) <= not ACC(3); + F(Flag_N) <= '1'; + end if; + if I_CCF = '1' then + -- CCF + F(Flag_C) <= not F(Flag_C); + F(Flag_Y) <= ACC(5); + F(Flag_H) <= F(Flag_C); + F(Flag_X) <= ACC(3); + F(Flag_N) <= '0'; + end if; + if I_SCF = '1' then + -- SCF + F(Flag_C) <= '1'; + F(Flag_Y) <= ACC(5); + F(Flag_H) <= '0'; + F(Flag_X) <= ACC(3); + F(Flag_N) <= '0'; + end if; end if; - Save_ALU_r <= Save_ALU; - ALU_Op_r <= ALU_Op; + if (TState = 2 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))); + F(Flag_N) <= DI_Reg(7); + F(Flag_C) <= ioq(8); + F(Flag_H) <= ioq(8); + ioq := (ioq and x"7") 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)); + end if; - if I_CPL = '1' then - -- CPL - ACC <= not ACC; - F(Flag_Y) <= not ACC(5); - F(Flag_H) <= '1'; - F(Flag_X) <= not ACC(3); - F(Flag_N) <= '1'; + 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)); + WZ <= std_logic_vector(signed(PC) + signed(DI_Reg)); + elsif Inc_PC = '1' then + PC <= PC + 1; + end if; + if BTR_r = '1' then + PC <= PC - 2; + end if; + if RstP = '1' then + WZ <= (others =>'0'); + WZ(5 downto 3) <= IR(5 downto 3); + end if; end if; - if I_CCF = '1' then - -- CCF - F(Flag_C) <= not F(Flag_C); - F(Flag_Y) <= ACC(5); - F(Flag_H) <= F(Flag_C); - F(Flag_X) <= ACC(3); - F(Flag_N) <= '0'; + if TState = 3 and MCycle = "110" then + WZ <= std_logic_vector(signed(RegBusC) + signed(DI_Reg)); end if; - if I_SCF = '1' then - -- SCF - F(Flag_C) <= '1'; - F(Flag_Y) <= ACC(5); - F(Flag_H) <= '0'; - F(Flag_X) <= ACC(3); - F(Flag_N) <= '0'; + + if MCycle = "011" and TState = 4 and No_BTR = '0' then + if I_BT = '1' or I_BC = '1' then + WZ <= std_logic_vector(PC)-"1"; + 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 - ioq := ('0' & DI_Reg) + ('0' & std_logic_vector(ID16(7 downto 0))); - F(Flag_N) <= DI_Reg(7); - F(Flag_C) <= ioq(8); - F(Flag_H) <= ioq(8); - ioq := (ioq and x"7") 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)); - end if; - if TState = 2 and Wait_n = '1' then - if ISet = "01" and MCycle = "111" then - IR <= DInst; + if (TState = 2 and Wait_n = '1') or (TState = 4 and MCycle = "001") then + 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; end if; - if JumpE = '1' then - PC <= unsigned(signed(PC) + signed(DI_Reg)); - WZ <= std_logic_vector(signed(PC) + signed(DI_Reg)); - elsif Inc_PC = '1' then - PC <= PC + 1; + + if LDSPHL = '1' then + SP <= unsigned(RegBusC); end if; - if BTR_r = '1' then - PC <= PC - 2; + if ExchangeAF = '1' then + Ap <= ACC; + ACC <= Ap; + Fp <= F; + F <= Fp; end if; - if RstP = '1' then - WZ <= (others =>'0'); - WZ(5 downto 3) <= IR(5 downto 3); + if ExchangeRS = '1' then + Alternate <= not Alternate; end if; end if; - if TState = 3 and MCycle = "110" then - WZ <= std_logic_vector(signed(RegBusC) + signed(DI_Reg)); - end if; - if MCycle = "011" and TState = 4 and No_BTR = '0' then - if I_BT = '1' or I_BC = '1' then - WZ <= std_logic_vector(PC)-"1"; + if TState = 3 then + if LDZ = '1' then + WZ(7 downto 0) <= DI_Reg; end if; - end if; - - if (TState = 2 and Wait_n = '1') or (TState = 4 and MCycle = "001") then - if IncDec_16(2 downto 0) = "111" then - if IncDec_16(3) = '1' then - SP <= SP - 1; - else - SP <= SP + 1; - end if; + if LDW = '1' then + WZ(15 downto 8) <= DI_Reg; end if; - end if; - if LDSPHL = '1' then - SP <= unsigned(RegBusC); - end if; - if ExchangeAF = '1' then - Ap <= ACC; - ACC <= Ap; - Fp <= F; - F <= Fp; - end if; - if ExchangeRS = '1' then - Alternate <= not Alternate; - end if; - end if; + if Special_LD(2) = '1' then + case Special_LD(1 downto 0) is + when "00" => + ACC <= I; + F(Flag_P) <= IntE_FF2; + F(Flag_S) <= I(7); - if TState = 3 then - if LDZ = '1' then - WZ(7 downto 0) <= DI_Reg; - end if; - if LDW = '1' then - WZ(15 downto 8) <= DI_Reg; - end if; + if I = x"00" then + F(Flag_Z) <= '1'; + else + F(Flag_Z) <= '0'; + end if; - if Special_LD(2) = '1' then - case Special_LD(1 downto 0) is - when "00" => - ACC <= I; - F(Flag_P) <= IntE_FF2; - F(Flag_S) <= I(7); - - if I = x"00" then - F(Flag_Z) <= '1'; - else - F(Flag_Z) <= '0'; - end if; + F(Flag_Y) <= I(5); + F(Flag_H) <= '0'; + F(Flag_X) <= I(3); + F(Flag_N) <= '0'; - F(Flag_Y) <= I(5); - F(Flag_H) <= '0'; - F(Flag_X) <= I(3); - F(Flag_N) <= '0'; + when "01" => + ACC <= std_logic_vector(R); + F(Flag_P) <= IntE_FF2; + F(Flag_S) <= R(7); - when "01" => - ACC <= std_logic_vector(R); - F(Flag_P) <= IntE_FF2; - F(Flag_S) <= R(7); - - if R = x"00" then - F(Flag_Z) <= '1'; - else - F(Flag_Z) <= '0'; - end if; - - F(Flag_Y) <= R(5); - F(Flag_H) <= '0'; - F(Flag_X) <= R(3); - F(Flag_N) <= '0'; - - when "10" => - I <= ACC; - when others => - R <= unsigned(ACC); - end case; + if R = x"00" then + F(Flag_Z) <= '1'; + else + F(Flag_Z) <= '0'; + end if; + + F(Flag_Y) <= R(5); + F(Flag_H) <= '0'; + F(Flag_X) <= R(3); + F(Flag_N) <= '0'; + + when "10" => + I <= ACC; + when others => + R <= unsigned(ACC); + end case; + end if; end if; - end if; - if (I_DJNZ = '0' and Save_ALU_r = '1') or ALU_Op_r = "1001" then - if Mode = 3 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); + if (I_DJNZ = '0' and Save_ALU_r = '1') or ALU_Op_r = "1001" then + if Mode = 3 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_Out(7 downto 1); + if PreserveC_r = '0' then + F(Flag_C) <= F_Out(0); + end if; end if; - else - F(7 downto 1) <= F_Out(7 downto 1); - if PreserveC_r = '0' then - F(Flag_C) <= F_Out(0); + end if; + if T_Res = '1' and I_INRC = '1' then + F(Flag_H) <= '0'; + F(Flag_N) <= '0'; + F(Flag_X) <= DI_Reg(3); + F(Flag_Y) <= DI_Reg(5); + if DI_Reg(7 downto 0) = "00000000" then + F(Flag_Z) <= '1'; + else + F(Flag_Z) <= '0'; end if; + F(Flag_S) <= DI_Reg(7); + F(Flag_P) <= not (DI_Reg(0) xor DI_Reg(1) xor DI_Reg(2) xor DI_Reg(3) xor + DI_Reg(4) xor DI_Reg(5) xor DI_Reg(6) xor DI_Reg(7)); end if; - end if; - if T_Res = '1' and I_INRC = '1' then - F(Flag_H) <= '0'; - F(Flag_N) <= '0'; - F(Flag_X) <= DI_Reg(3); - F(Flag_Y) <= DI_Reg(5); - if DI_Reg(7 downto 0) = "00000000" then - F(Flag_Z) <= '1'; - else - F(Flag_Z) <= '0'; + + if TState = 1 and Auto_Wait_t1 = '0' then + -- Keep D0 from M3 for RLD/RRD (Sorgelig) + I_RXDD <= I_RLD or I_RRD; + if I_RXDD='0' then + DO <= BusB; + end if; + if I_RLD = '1' then + DO(3 downto 0) <= BusA(3 downto 0); + DO(7 downto 4) <= BusB(3 downto 0); + end if; + if I_RRD = '1' then + DO(3 downto 0) <= BusB(7 downto 4); + DO(7 downto 4) <= BusA(3 downto 0); + end if; end if; - F(Flag_S) <= DI_Reg(7); - F(Flag_P) <= not (DI_Reg(0) xor DI_Reg(1) xor DI_Reg(2) xor DI_Reg(3) xor - 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 - -- Keep D0 from M3 for RLD/RRD (Sorgelig) - I_RXDD <= I_RLD or I_RRD; - if I_RXDD='0' then - DO <= BusB; + if T_Res = '1' then + Read_To_Reg_r(3 downto 0) <= Set_BusA_To; + Read_To_Reg_r(4) <= Read_To_Reg; + if Read_To_Acc = '1' then + Read_To_Reg_r(3 downto 0) <= "0111"; + Read_To_Reg_r(4) <= '1'; + end if; end if; - if I_RLD = '1' then - DO(3 downto 0) <= BusA(3 downto 0); - DO(7 downto 4) <= BusB(3 downto 0); + + if TState = 1 and I_BT = '1' then + F(Flag_X) <= ALU_Q(3); + F(Flag_Y) <= ALU_Q(1); + F(Flag_H) <= '0'; + F(Flag_N) <= '0'; end if; - if I_RRD = '1' then - DO(3 downto 0) <= BusB(7 downto 4); - DO(7 downto 4) <= BusA(3 downto 0); + if TState = 1 and I_BC = '1' then + n := ALU_Q - ("0000000" & F_Out(Flag_H)); + F(Flag_X) <= n(3); + F(Flag_Y) <= n(1); end if; - end if; - - if T_Res = '1' then - Read_To_Reg_r(3 downto 0) <= Set_BusA_To; - Read_To_Reg_r(4) <= Read_To_Reg; - if Read_To_Acc = '1' then - Read_To_Reg_r(3 downto 0) <= "0111"; - Read_To_Reg_r(4) <= '1'; + if I_BC = '1' or I_BT = '1' then + F(Flag_P) <= IncDecZ; end if; - end if; - if TState = 1 and I_BT = '1' then - F(Flag_X) <= ALU_Q(3); - F(Flag_Y) <= ALU_Q(1); - F(Flag_H) <= '0'; - F(Flag_N) <= '0'; - end if; - if TState = 1 and I_BC = '1' then - n := ALU_Q - ("0000000" & F_Out(Flag_H)); - F(Flag_X) <= n(3); - F(Flag_Y) <= n(1); - end if; - if I_BC = '1' or I_BT = '1' then - F(Flag_P) <= IncDecZ; - 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 "10110" => - DO <= Save_Mux; - when "11000" => - SP(7 downto 0) <= unsigned(Save_Mux); - when "11001" => - SP(15 downto 8) <= unsigned(Save_Mux); - when "11011" => - F <= Save_Mux; - when others => - end case; - if XYbit_undoc='1' then - DO <= ALU_Q; + 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 "10110" => + DO <= Save_Mux; + when "11000" => + SP(7 downto 0) <= unsigned(Save_Mux); + when "11001" => + SP(15 downto 8) <= unsigned(Save_Mux); + when "11011" => + F <= Save_Mux; + when others => + end case; + if XYbit_undoc='1' then + DO <= ALU_Q; + end if; end if; end if; - - end if; - end if; - end process; --------------------------------------------------------------------------- @@ -919,7 +929,7 @@ begin end if; end process; - Regs : T80_Reg + Regs : work.T80_Reg port map( Clk => CLK_n, CEN => ClkEn, @@ -936,7 +946,9 @@ begin DOBL => RegBusB(7 downto 0), DOCH => RegBusC(15 downto 8), DOCL => RegBusC(7 downto 0), - DOR => DOR); + DOR => DOR, + DIRSet => DIRSet, + DIR => DIR(207 downto 80)); --------------------------------------------------------------------------- -- @@ -947,59 +959,63 @@ begin begin if rising_edge(CLK_n) then if ClkEn = '1' then - case Set_BusB_To is - when "0111" => - BusB <= ACC; - when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" => - if Set_BusB_To(0) = '1' then - BusB <= RegBusB(7 downto 0); - else - BusB <= RegBusB(15 downto 8); - end if; - when "0110" => - BusB <= DI_Reg; - when "1000" => - BusB <= std_logic_vector(SP(7 downto 0)); - when "1001" => - BusB <= std_logic_vector(SP(15 downto 8)); - when "1010" => - BusB <= "00000001"; - when "1011" => - BusB <= F; - when "1100" => - BusB <= std_logic_vector(PC(7 downto 0)); - when "1101" => - BusB <= std_logic_vector(PC(15 downto 8)); - when "1110" => - BusB <= "00000000"; - when others => - BusB <= "--------"; - end case; + case Set_BusB_To is + when "0111" => + BusB <= ACC; + when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" => + if Set_BusB_To(0) = '1' then + BusB <= RegBusB(7 downto 0); + else + BusB <= RegBusB(15 downto 8); + end if; + when "0110" => + BusB <= DI_Reg; + when "1000" => + BusB <= std_logic_vector(SP(7 downto 0)); + when "1001" => + BusB <= std_logic_vector(SP(15 downto 8)); + when "1010" => + BusB <= "00000001"; + when "1011" => + BusB <= F; + when "1100" => + BusB <= std_logic_vector(PC(7 downto 0)); + when "1101" => + BusB <= std_logic_vector(PC(15 downto 8)); + when "1110" => + if IR = x"71" and out0 = '1' then + BusB <= "11111111"; + else + BusB <= "00000000"; + end if; + when others => + BusB <= "--------"; + end case; - case Set_BusA_To is - when "0111" => - BusA <= ACC; - when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" => - if Set_BusA_To(0) = '1' then - BusA <= RegBusA(7 downto 0); - else - BusA <= RegBusA(15 downto 8); + case Set_BusA_To is + when "0111" => + BusA <= ACC; + when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" => + if Set_BusA_To(0) = '1' then + BusA <= RegBusA(7 downto 0); + else + BusA <= RegBusA(15 downto 8); + end if; + when "0110" => + BusA <= DI_Reg; + when "1000" => + BusA <= std_logic_vector(SP(7 downto 0)); + when "1001" => + BusA <= std_logic_vector(SP(15 downto 8)); + when "1010" => + BusA <= "00000000"; + when others => + BusA <= "--------"; + end case; + if XYbit_undoc='1' then + BusA <= DI_Reg; + BusB <= DI_Reg; end if; - when "0110" => - BusA <= DI_Reg; - when "1000" => - BusA <= std_logic_vector(SP(7 downto 0)); - when "1001" => - BusA <= std_logic_vector(SP(15 downto 8)); - when "1010" => - BusA <= "00000000"; - when others => - BusA <= "--------"; - end case; - if XYbit_undoc='1' then - BusA <= DI_Reg; - BusB <= DI_Reg; - end if; end if; end if; end process; @@ -1014,12 +1030,12 @@ begin if RESET_n = '0' then RFSH_n <= '1'; elsif rising_edge(CLK_n) then - if CEN = '1' then - if MCycle = "001" and ((TState = 2 and Wait_n = '1') or TState = 3) then - RFSH_n <= '0'; - else - RFSH_n <= '1'; - end if; + if DIRSet = '0' and CEN = '1' then + if MCycle = "001" and ((TState = 2 and Wait_n = '1') or TState = 3) then + RFSH_n <= '0'; + else + RFSH_n <= '1'; + end if; end if; end if; end process; @@ -1034,37 +1050,13 @@ begin IORQ <= IORQ_i; Stop <= I_DJNZ; -------------------------------------------------------------------------- --- --- Syncronise inputs --- -------------------------------------------------------------------------- - process (RESET_n, CLK_n) - variable OldNMI_n : std_logic; - begin - if RESET_n = '0' then - BusReq_s <= '0'; - NMI_s <= '0'; - OldNMI_n := '0'; - elsif rising_edge(CLK_n) then - if CEN = '1' then - BusReq_s <= not BUSRQ_n; - if NMICycle = '1' then - NMI_s <= '0'; - elsif NMI_n = '0' and OldNMI_n = '1' then - NMI_s <= '1'; - end if; - OldNMI_n := NMI_n; - end if; - end if; - end process; - ------------------------------------------------------------------------- -- -- Main state machine -- ------------------------------------------------------------------------- process (RESET_n, CLK_n) + variable OldNMI_n : std_logic; begin if RESET_n = '0' then MCycle <= "001"; @@ -1080,99 +1072,104 @@ begin Auto_Wait_t1 <= '0'; Auto_Wait_t2 <= '0'; M1_n <= '1'; + BusReq_s <= '0'; + NMI_s <= '0'; elsif rising_edge(CLK_n) then - - if CEN = '1' then - Auto_Wait_t2 <= Auto_Wait_t1; - if T_Res = '1' then - Auto_Wait_t1 <= '0'; - Auto_Wait_t2 <= '0'; - else - Auto_Wait_t1 <= Auto_Wait or IORQ_i; + + if DIRSet = '1' then + IntE_FF2 <= DIR(211); + IntE_FF1 <= DIR(210); + else + if NMI_n = '0' and OldNMI_n = '1' then + NMI_s <= '1'; end if; - 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'; - IntE_FF2 <= '1'; - end if; - if I_RETN = '1' then - IntE_FF1 <= IntE_FF2; + OldNMI_n := NMI_n; + + if CEN = '1' then + BusReq_s <= not BUSRQ_n; + Auto_Wait_t2 <= Auto_Wait_t1; + if T_Res = '1' then + Auto_Wait_t1 <= '0'; + Auto_Wait_t2 <= '0'; + else + Auto_Wait_t1 <= Auto_Wait or IORQ_i; end if; - end if; - if TState = 3 then - if SetDI = '1' then - IntE_FF1 <= '0'; - IntE_FF2 <= '0'; + 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'; + IntE_FF2 <= '1'; + end if; + if I_RETN = '1' then + IntE_FF1 <= IntE_FF2; + end if; end if; - end if; - 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 BusReq_s = '1' and BusAck = '1' then - else - BusAck <= '0'; - if TState = 2 and Wait_n = '0' then - elsif T_Res = '1' then - if Halt = '1' then - Halt_FF <= '1'; + if TState = 3 then + if SetDI = '1' then + IntE_FF1 <= '0'; + IntE_FF2 <= '0'; end if; - if BusReq_s = '1' then - BusAck <= '1'; - else - TState <= "001"; - if NextIs_XY_Fetch = '1' then - MCycle <= "110"; - Pre_XY_F_M <= MCycle; - if IR = "00110110" and Mode = 0 then - Pre_XY_F_M <= "010"; - end if; - 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 No_BTR = '1' or (MCycle = "010" and I_DJNZ = '1' and IncDecZ = '1') then - M1_n <= '0'; - MCycle <= "001"; - IntCycle <= '0'; - NMICycle <= '0'; - if NMI_s = '1' and Prefix = "00" then - NMICycle <= '1'; - IntE_FF1 <= '0'; - elsif IntE_FF1 = '1' and INT_n='0' and Prefix = "00" and SetEI = '0' then - IntCycle <= '1'; - IntE_FF1 <= '0'; - IntE_FF2 <= '0'; - end if; + end if; + 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 BusReq_s = '1' and BusAck = '1' then + else + BusAck <= '0'; + if TState = 2 and Wait_n = '0' then + elsif T_Res = '1' then + if Halt = '1' then + Halt_FF <= '1'; + end if; + if BusReq_s = '1' then + BusAck <= '1'; else - MCycle <= std_logic_vector(unsigned(MCycle) + 1); + TState <= "001"; + if NextIs_XY_Fetch = '1' then + MCycle <= "110"; + Pre_XY_F_M <= MCycle; + if IR = "00110110" and Mode = 0 then + Pre_XY_F_M <= "010"; + end if; + 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 No_BTR = '1' or (MCycle = "010" and I_DJNZ = '1' and IncDecZ = '1') then + M1_n <= '0'; + MCycle <= "001"; + IntCycle <= '0'; + NMICycle <= '0'; + if NMI_s = '1' and Prefix = "00" then + NMI_s <= '0'; + NMICycle <= '1'; + IntE_FF1 <= '0'; + elsif IntE_FF1 = '1' and INT_n='0' and Prefix = "00" and SetEI = '0' then + IntCycle <= '1'; + IntE_FF1 <= '0'; + IntE_FF2 <= '0'; + end if; + else + MCycle <= std_logic_vector(unsigned(MCycle) + 1); + 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 + TState <= TState + 1; 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 - TState <= TState + 1; end if; end if; + if TState = 0 then + M1_n <= '0'; + end if; end if; - if TState = 0 then - M1_n <= '0'; - 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 process; + Auto_Wait <= '1' when IntCycle = '1' and MCycle = "001" else '0'; end; diff --git a/t80/T80_MCode.vhd b/t80/T80_MCode.vhd index 8e9f8d7..f5312bd 100644 --- a/t80/T80_MCode.vhd +++ b/t80/T80_MCode.vhd @@ -74,7 +74,6 @@ library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; -use work.T80_Pack.all; entity T80_MCode is generic( diff --git a/t80/T80_Pack.vhd b/t80/T80_Pack.vhd deleted file mode 100644 index 35100ec..0000000 --- a/t80/T80_Pack.vhd +++ /dev/null @@ -1,235 +0,0 @@ --------------------------------------------------------------------------------- --- **** --- T80(c) core. Attempt to finish all undocumented features and provide --- accurate timings. --- 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 300 started tidyup --- MikeJ March 2005 --- Latest version from www.fpgaarcade.com (original www.opencores.org) --- --- **** --- --- Z80 compatible microprocessor core --- --- Version : 0242 --- --- 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 - - component T80 - generic( - Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB - IOWait : integer := 0; -- 0 => 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; - REG : out std_logic_vector(207 downto 0) -- 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) - ); - 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; - 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; - 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; - 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; - 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; - 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); - 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; diff --git a/t80/T80_Reg.vhd b/t80/T80_Reg.vhd index dbb895e..e7e8645 100644 --- a/t80/T80_Reg.vhd +++ b/t80/T80_Reg.vhd @@ -89,7 +89,9 @@ entity T80_Reg is 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) + DOR : out std_logic_vector(127 downto 0); + DIRSet : in std_logic; + DIR : in std_logic_vector(127 downto 0) ); end T80_Reg; @@ -104,7 +106,31 @@ begin process (Clk) begin 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 RegsH(to_integer(unsigned(AddrA))) <= DIH; end if; diff --git a/t80/T80pa.vhd b/t80/T80pa.vhd index 6261bf5..c09f15a 100644 --- a/t80/T80pa.vhd +++ b/t80/T80pa.vhd @@ -56,33 +56,35 @@ library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; -use work.T80_Pack.all; entity T80pa is generic( Mode : integer := 0 -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB ); port( - RESET_n : in std_logic; - CLK : in std_logic; - CEN_p : in std_logic; - CEN_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); - DI : in 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 + RESET_n : in std_logic; + CLK : in std_logic; + CEN_p : in std_logic := '1'; + CEN_n : in std_logic := '1'; + WAIT_n : in std_logic := '1'; + INT_n : in std_logic := '1'; + NMI_n : in std_logic := '1'; + BUSRQ_n : in std_logic := '1'; + 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; + OUT0 : in std_logic := '0'; -- 0 => OUT(C),0, 1 => OUT(C),255 + A : out std_logic_vector(15 downto 0); + DI : in std_logic_vector(7 downto 0); + DO : out std_logic_vector(7 downto 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; @@ -107,7 +109,7 @@ begin BUSAK_n <= BUSAK; - u0 : T80 + u0 : work.T80 generic map( Mode => Mode, IOWait => 1 @@ -134,7 +136,10 @@ begin REG => REG, MC => MCycle, TS => TState, - IntCycle_n => IntCycle_n + OUT0 => OUT0, + IntCycle_n => IntCycle_n, + DIRSet => DIRSet, + DIR => DIR ); process(CLK) @@ -168,6 +173,9 @@ begin else CEN_pol <= '0'; end if; + if TState = "011" and BUSAK = '1' then + DI_Reg <= DI; + end if; if MCycle = "001" then if TState = "001" then IntCycleD_n <= IntCycleD_n(0) & IntCycle_n; @@ -185,9 +193,6 @@ begin MREQ_n <= '1'; end if; else - if TState = "011" and BUSAK = '1' then - DI_Reg <= DI; - end if; if NoRead = '0' and IORQ = '0' then if TState = "001" then RD_n <= Write;