📄 t80.vhd
字号:
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') 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
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
(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' nand Auto_Wait_t2 = '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 + -