📄 t80.vhd
字号:
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; 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 BTR_r = '1' then PC <= PC - 2; end if; if RstP = '1' then TmpAddr <= (others =>'0'); TmpAddr(5 downto 3) <= IR(5 downto 3); end if; end if; if TState = 3 and MCycle = "110" then 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(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 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 TState = 3 then if LDZ = '1' then TmpAddr(7 downto 0) <= DI_Reg; end if; if LDW = '1' then TmpAddr(15 downto 8) <= DI_Reg; end if; if Special_LD(2) = '1' then case Special_LD(1 downto 0) is when "00" => ACC <= I; F(Flag_P) <= IntE_FF2; when "01" => ACC <= std_logic_vector(R); F(Flag_P) <= IntE_FF2; when "10" => I <= ACC; when others => R <= unsigned(ACC); end case; 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); 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; end if; if T_Res = '1' and I_INRC = '1' then F(Flag_H) <= '0'; F(Flag_N) <= '0'; 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; if TState = 1 and Auto_Wait_t1 = '0' then DO <= BusB; 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; 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 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_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; end if; end if; end if; end process;------------------------------------------------------------------------------- BC('), DE('), HL('), IX and IY----------------------------------------------------------------------------- process (CLK_n) begin if CLK_n'event and CLK_n = '1' then if ClkEn = '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 => ClkEn, 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----------------------------------------------------------------------------- process (CLK_n) begin if CLK_n'event and CLK_n = '1' 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_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 => BusB <= "--------"; end case; end if; end if; end process;------------------------------------------------------------------------------- Generate external control signals----------------------------------------------------------------------------- process (RESET_n,CLK_n) begin if RESET_n = '0' then RFSH_n <= '1'; elsif CLK_n'event and CLK_n = '1' 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; end if; end if; end process; MC <= std_logic_vector(MCycle); TS <= std_logic_vector(TState); DI_Reg <= DI; HALT_n <= not Halt_FF; BUSAK_n <= not BusAck; IntCycle_n <= not IntCycle; IntE <= IntE_FF1; 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'; INT_s <= '0'; NMI_s <= '0'; OldNMI_n := '0'; elsif CLK_n'event and CLK_n = '1' then if CEN = '1' then BusReq_s <= not BUSRQ_n; INT_s <= not INT_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) begin if RESET_n = '0' then MCycle <= "001"; TState <= "000"; Pre_XY_F_M <= "000"; Halt_FF <= '0'; BusAck <= '0'; NMICycle <= '0'; 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 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_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'; IntE_FF2 <= '1'; end if; if I_RETN = '1' then IntE_FF1 <= IntE_FF2; end if; end if; if TState = 3 then if SetDI = '1' then 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 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_s = '1') 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; 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;end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -