⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 t80_mcode.vhd

📁 DE1-FPGA-Board
💻 VHD
📖 第 1 页 / 共 4 页
字号:
---- 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 :----	0208 : First complete release----	0211 : Fixed IM 1----	0214 : Fixed mostly flags, only the block instructions now fail the zex regression test----	0235 : Added IM 2 fix by Mike Johnson----	0238 : Added NoRead signal----	0238b: Fixed instruction timing for POP and DJNZ----	0240 : Added (IX/IY+d) states, removed op-codes from mode 2 and added all remaining mode 3 op-codes----	0242 : Fixed I/O instruction timing, cleanup--library IEEE;use IEEE.std_logic_1164.all;use IEEE.numeric_std.all;entity T80_MCode is	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;		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;		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	);end T80_MCode;architecture rtl of T80_MCode 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) := "000";--	constant aXY	: std_logic_vector(2 downto 0) := "001";--	constant aIOA	: std_logic_vector(2 downto 0) := "010";--	constant aSP	: std_logic_vector(2 downto 0) := "011";--	constant aBC	: std_logic_vector(2 downto 0) := "100";--	constant aDE	: std_logic_vector(2 downto 0) := "101";--	constant aZI	: std_logic_vector(2 downto 0) := "110";	function is_cc_true(		F : std_logic_vector(7 downto 0);		cc : bit_vector(2 downto 0)		) return boolean is	begin		if Mode = 3 then			case cc is			when "000" => return F(7) = '0'; -- NZ			when "001" => return F(7) = '1'; -- Z			when "010" => return F(4) = '0'; -- NC			when "011" => return F(4) = '1'; -- C			when "100" => return false;			when "101" => return false;			when "110" => return false;			when "111" => return false;			end case;		else			case cc is			when "000" => return F(6) = '0'; -- NZ			when "001" => return F(6) = '1'; -- Z			when "010" => return F(0) = '0'; -- NC			when "011" => return F(0) = '1'; -- C			when "100" => return F(2) = '0'; -- PO			when "101" => return F(2) = '1'; -- PE			when "110" => return F(7) = '0'; -- P			when "111" => return F(7) = '1'; -- M			end case;		end if;	end;begin	process (IR, ISet, MCycle, F, NMICycle, IntCycle)		variable DDD : std_logic_vector(2 downto 0);		variable SSS : std_logic_vector(2 downto 0);		variable DPair : std_logic_vector(1 downto 0);		variable IRB : bit_vector(7 downto 0);	begin		DDD := IR(5 downto 3);		SSS := IR(2 downto 0);		DPair := IR(5 downto 4);		IRB := to_bitvector(IR);		MCycles <= "001";		if MCycle = "001" then			TStates <= "100";		else			TStates <= "011";		end if;		Prefix <= "00";		Inc_PC <= '0';		Inc_WZ <= '0';		IncDec_16 <= "0000";		Read_To_Acc <= '0';		Read_To_Reg <= '0';		Set_BusB_To <= "0000";		Set_BusA_To <= "0000";		ALU_Op <= "0" & IR(5 downto 3);		Save_ALU <= '0';		PreserveC <= '0';		Arith16 <= '0';		IORQ <= '0';		Set_Addr_To <= aNone;		Jump <= '0';		JumpE <= '0';		JumpXY <= '0';		Call <= '0';		RstP <= '0';		LDZ <= '0';		LDW <= '0';		LDSPHL <= '0';		Special_LD <= "000";		ExchangeDH <= '0';		ExchangeRp <= '0';		ExchangeAF <= '0';		ExchangeRS <= '0';		I_DJNZ <= '0';		I_CPL <= '0';		I_CCF <= '0';		I_SCF <= '0';		I_RETN <= '0';		I_BT <= '0';		I_BC <= '0';		I_BTR <= '0';		I_RLD <= '0';		I_RRD <= '0';		I_INRC <= '0';		SetDI <= '0';		SetEI <= '0';		IMode <= "11";		Halt <= '0';		NoRead <= '0';		Write <= '0';		case ISet is		when "00" =>----------------------------------------------------------------------------------	Unprefixed instructions--------------------------------------------------------------------------------		case IRB is-- 8 BIT LOAD GROUP		when "01000000"|"01000001"|"01000010"|"01000011"|"01000100"|"01000101"|"01000111"			|"01001000"|"01001001"|"01001010"|"01001011"|"01001100"|"01001101"|"01001111"			|"01010000"|"01010001"|"01010010"|"01010011"|"01010100"|"01010101"|"01010111"			|"01011000"|"01011001"|"01011010"|"01011011"|"01011100"|"01011101"|"01011111"			|"01100000"|"01100001"|"01100010"|"01100011"|"01100100"|"01100101"|"01100111"			|"01101000"|"01101001"|"01101010"|"01101011"|"01101100"|"01101101"|"01101111"			|"01111000"|"01111001"|"01111010"|"01111011"|"01111100"|"01111101"|"01111111" =>			-- LD r,r'			Set_BusB_To(2 downto 0) <= SSS;			ExchangeRp <= '1';			Set_BusA_To(2 downto 0) <= DDD;			Read_To_Reg <= '1';		when "00000110"|"00001110"|"00010110"|"00011110"|"00100110"|"00101110"|"00111110" =>			-- LD r,n			MCycles <= "010";			case to_integer(unsigned(MCycle)) is			when 2 =>				Inc_PC <= '1';				Set_BusA_To(2 downto 0) <= DDD;				Read_To_Reg <= '1';			when others => null;			end case;		when "01000110"|"01001110"|"01010110"|"01011110"|"01100110"|"01101110"|"01111110" =>			-- LD r,(HL)			MCycles <= "010";			case to_integer(unsigned(MCycle)) is			when 1 =>				Set_Addr_To <= aXY;			when 2 =>				Set_BusA_To(2 downto 0) <= DDD;				Read_To_Reg <= '1';			when others => null;			end case;		when "01110000"|"01110001"|"01110010"|"01110011"|"01110100"|"01110101"|"01110111" =>			-- LD (HL),r			MCycles <= "010";			case to_integer(unsigned(MCycle)) is			when 1 =>				Set_Addr_To <= aXY;				Set_BusB_To(2 downto 0) <= SSS;				Set_BusB_To(3) <= '0';			when 2 =>				Write <= '1';			when others => null;			end case;		when "00110110" =>			-- LD (HL),n			MCycles <= "011";			case to_integer(unsigned(MCycle)) is			when 2 =>				Inc_PC <= '1';				Set_Addr_To <= aXY;				Set_BusB_To(2 downto 0) <= SSS;				Set_BusB_To(3) <= '0';			when 3 =>				Write <= '1';			when others => null;			end case;		when "00001010" =>			-- LD A,(BC)			MCycles <= "010";			case to_integer(unsigned(MCycle)) is			when 1 =>				Set_Addr_To <= aBC;			when 2 =>				Read_To_Acc <= '1';			when others => null;			end case;		when "00011010" =>			-- LD A,(DE)			MCycles <= "010";			case to_integer(unsigned(MCycle)) is			when 1 =>				Set_Addr_To <= aDE;			when 2 =>				Read_To_Acc <= '1';			when others => null;			end case;		when "00111010" =>			if Mode = 3 then				-- LDD A,(HL)				MCycles <= "010";				case to_integer(unsigned(MCycle)) is				when 1 =>					Set_Addr_To <= aXY;				when 2 =>					Read_To_Acc <= '1';					IncDec_16 <= "1110";				when others => null;				end case;			else				-- LD A,(nn)				MCycles <= "100";				case to_integer(unsigned(MCycle)) is				when 2 =>					Inc_PC <= '1';					LDZ <= '1';				when 3 =>					Set_Addr_To <= aZI;					Inc_PC <= '1';				when 4 =>					Read_To_Acc <= '1';				when others => null;				end case;			end if;		when "00000010" =>			-- LD (BC),A			MCycles <= "010";			case to_integer(unsigned(MCycle)) is			when 1 =>				Set_Addr_To <= aBC;				Set_BusB_To <= "0111";			when 2 =>				Write <= '1';			when others => null;			end case;		when "00010010" =>			-- LD (DE),A			MCycles <= "010";			case to_integer(unsigned(MCycle)) is			when 1 =>				Set_Addr_To <= aDE;				Set_BusB_To <= "0111";			when 2 =>				Write <= '1';			when others => null;			end case;		when "00110010" =>			if Mode = 3 then				-- LDD (HL),A				MCycles <= "010";				case to_integer(unsigned(MCycle)) is				when 1 =>					Set_Addr_To <= aXY;					Set_BusB_To <= "0111";				when 2 =>					Write <= '1';					IncDec_16 <= "1110";				when others => null;				end case;			else				-- LD (nn),A				MCycles <= "100";				case to_integer(unsigned(MCycle)) is				when 2 =>					Inc_PC <= '1';					LDZ <= '1';				when 3 =>					Set_Addr_To <= aZI;					Inc_PC <= '1';					Set_BusB_To <= "0111";				when 4 =>					Write <= '1';				when others => null;				end case;			end if;-- 16 BIT LOAD GROUP		when "00000001"|"00010001"|"00100001"|"00110001" =>			-- LD dd,nn			MCycles <= "011";			case to_integer(unsigned(MCycle)) is			when 2 =>				Inc_PC <= '1';				Read_To_Reg <= '1';				if DPAIR = "11" then					Set_BusA_To(3 downto 0) <= "1000";				else					Set_BusA_To(2 downto 1) <= DPAIR;					Set_BusA_To(0) <= '1';				end if;			when 3 =>				Inc_PC <= '1';				Read_To_Reg <= '1';				if DPAIR = "11" then					Set_BusA_To(3 downto 0) <= "1001";				else					Set_BusA_To(2 downto 1) <= DPAIR;					Set_BusA_To(0) <= '0';				end if;			when others => null;			end case;		when "00101010" =>			if Mode = 3 then				-- LDI A,(HL)				MCycles <= "010";				case to_integer(unsigned(MCycle)) is				when 1 =>					Set_Addr_To <= aXY;				when 2 =>					Read_To_Acc <= '1';					IncDec_16 <= "0110";				when others => null;				end case;			else				-- LD HL,(nn)				MCycles <= "101";				case to_integer(unsigned(MCycle)) is				when 2 =>					Inc_PC <= '1';					LDZ <= '1';				when 3 =>					Set_Addr_To <= aZI;					Inc_PC <= '1';					LDW <= '1';				when 4 =>					Set_BusA_To(2 downto 0) <= "101"; -- L					Read_To_Reg <= '1';					Inc_WZ <= '1';					Set_Addr_To <= aZI;				when 5 =>					Set_BusA_To(2 downto 0) <= "100"; -- H					Read_To_Reg <= '1';				when others => null;				end case;			end if;		when "00100010" =>			if Mode = 3 then				-- LDI (HL),A				MCycles <= "010";				case to_integer(unsigned(MCycle)) is				when 1 =>					Set_Addr_To <= aXY;					Set_BusB_To <= "0111";				when 2 =>					Write <= '1';

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -