X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/fpga-games/blobdiff_plain/0840cca68ecfa59ea10e60db9c02dbbd081215e7..be8a9b96554636d47b7d5113b4c4aab3b6ebb8e3:/galaxian/t80_ip/T80_MCode.vhd diff --git a/galaxian/t80_ip/T80_MCode.vhd b/galaxian/t80_ip/T80_MCode.vhd index 4cc30f3..43cea1b 100644 --- a/galaxian/t80_ip/T80_MCode.vhd +++ b/galaxian/t80_ip/T80_MCode.vhd @@ -1,3 +1,12 @@ +-- **** +-- T80(b) core. In an effort to merge and maintain bug fixes .... +-- +-- +-- Ver 300 started tidyup +-- MikeJ March 2005 +-- Latest version from www.fpgaarcade.com (original www.opencores.org) +-- +-- **** -- -- Z80 compatible microprocessor core -- @@ -38,32 +47,35 @@ -- 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 -- --- 0211 : Fixed IM 1 +-- 0211 : Fixed 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 -- --- 0235 : Added IM 2 fix by Mike Johnson +-- 0235 : Added IM 2 fix by Mike Johnson -- --- 0238 : Added NoRead signal +-- 0238 : Added NoRead signal -- --- 0238b: Fixed instruction timing for POP and DJNZ +-- 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 +-- 0240 : Added (IX/IY+d) states, removed op-codes from mode 2 and added all remaining mode 3 op-codes + +-- 0240mj1 fix for HL inc/dec for INI, IND, INIR, INDR, OUTI, OUTD, OTIR, OTDR -- --- 0242 : Fixed I/O instruction timing, cleanup +-- 0242 : Fixed I/O instruction timing, cleanup -- library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; +use work.T80_Pack.all; entity T80_MCode is generic( @@ -78,78 +90,71 @@ entity T80_MCode is 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); + 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 + 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"; + 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"; function is_cc_true( F : std_logic_vector(7 downto 0); @@ -250,7 +255,7 @@ begin ------------------------------------------------------------------------------ -- --- Unprefixed instructions +-- Unprefixed instructions -- ------------------------------------------------------------------------------ @@ -924,7 +929,7 @@ begin case to_integer(unsigned(MCycle)) is when 1 => Set_Addr_To <= aBC; - Set_BusB_To <= "0111"; + Set_BusB_To <= "0111"; when 2 => Write <= '1'; IORQ <= '1'; @@ -1178,7 +1183,7 @@ begin when 2 => Inc_PC <= '1'; Set_Addr_To <= aIOA; - Set_BusB_To <= "0111"; + Set_BusB_To <= "0111"; when 3 => Write <= '1'; when others => null; @@ -1200,7 +1205,7 @@ begin Save_ALU <= '1'; ALU_Op <= "0001"; Set_BusA_To <= "1001"; - Set_BusB_To <= "1110"; -- Incorrect unsigned !!!!!!!!!!!!!!!!!!!!! + Set_BusB_To <= "1110"; -- Incorrect unsigned !!!!!!!!!!!!!!!!!!!!! when others => end case; when "10" => @@ -1215,7 +1220,7 @@ begin when others => null; end case; when "11" => - -- LD HL,SP+n -- Not correct !!!!!!!!!!!!!!!!!!! + -- LD HL,SP+n -- Not correct !!!!!!!!!!!!!!!!!!! MCycles <= "101"; case to_integer(unsigned(MCycle)) is when 2 => @@ -1300,7 +1305,7 @@ begin when 2 => Inc_PC <= '1'; Set_Addr_To <= aIOA; - Set_BusB_To <= "0111"; + Set_BusB_To <= "0111"; when 3 => Write <= '1'; IORQ <= '1'; @@ -1335,7 +1340,7 @@ begin ------------------------------------------------------------------------------ -- --- CB prefixed instructions +-- CB prefixed instructions -- ------------------------------------------------------------------------------ @@ -1360,9 +1365,9 @@ begin -- SRL r -- SLL r (Undocumented) / SWAP r if MCycle = "001" then - ALU_Op <= "1000"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; + ALU_Op <= "1000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; end if; when "00000110"|"00010110"|"00001110"|"00011110"|"00101110"|"00111110"|"00100110"|"00110110" => -- RLC (HL) @@ -1397,19 +1402,19 @@ begin |"01111000"|"01111001"|"01111010"|"01111011"|"01111100"|"01111101"|"01111111" => -- BIT b,r if MCycle = "001" then - Set_BusB_To(2 downto 0) <= IR(2 downto 0); - ALU_Op <= "1001"; + Set_BusB_To(2 downto 0) <= IR(2 downto 0); + ALU_Op <= "1001"; end if; when "01000110"|"01001110"|"01010110"|"01011110"|"01100110"|"01101110"|"01110110"|"01111110" => -- BIT b,(HL) MCycles <= "010"; case to_integer(unsigned(MCycle)) is - when 1 | 7 => + when 1 | 7=> Set_Addr_To <= aXY; when 2 => ALU_Op <= "1001"; TStates <= "100"; - when others => + when others => null; end case; when "11000000"|"11000001"|"11000010"|"11000011"|"11000100"|"11000101"|"11000111" |"11001000"|"11001001"|"11001010"|"11001011"|"11001100"|"11001101"|"11001111" @@ -1421,15 +1426,15 @@ begin |"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111111" => -- SET b,r if MCycle = "001" then - ALU_Op <= "1010"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; + ALU_Op <= "1010"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; end if; when "11000110"|"11001110"|"11010110"|"11011110"|"11100110"|"11101110"|"11110110"|"11111110" => -- SET b,(HL) MCycles <= "011"; case to_integer(unsigned(MCycle)) is - when 1 | 7 => + when 1 | 7=> Set_Addr_To <= aXY; when 2 => ALU_Op <= "1010"; @@ -1439,7 +1444,7 @@ begin TStates <= "100"; when 3 => Write <= '1'; - when others => + when others => null; end case; when "10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000111" |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001111" @@ -1469,7 +1474,7 @@ begin TStates <= "100"; when 3 => Write <= '1'; - when others => + when others => null; end case; end case; @@ -1477,7 +1482,7 @@ begin ------------------------------------------------------------------------------ -- --- ED prefixed instructions +-- ED prefixed instructions -- ------------------------------------------------------------------------------ @@ -1811,7 +1816,7 @@ begin case to_integer(unsigned(MCycle)) is when 1 => Set_Addr_To <= aBC; - Set_BusB_To(2 downto 0) <= IR(5 downto 3); + Set_BusB_To(2 downto 0) <= IR(5 downto 3); if IR(5 downto 3) = "110" then Set_BusB_To(3) <= '1'; end if; @@ -1822,6 +1827,7 @@ begin end case; when "10100010" | "10101010" | "10110010" | "10111010" => -- INI, IND, INIR, INDR + -- note B is decremented AFTER being put on the bus MCycles <= "100"; case to_integer(unsigned(MCycle)) is when 1 => @@ -1837,9 +1843,11 @@ begin Set_Addr_To <= aXY; when 3 => if IR(3) = '0' then - IncDec_16 <= "0010"; + --IncDec_16 <= "0010"; + IncDec_16 <= "0110"; else - IncDec_16 <= "1010"; + --IncDec_16 <= "1010"; + IncDec_16 <= "1110"; end if; TStates <= "100"; Write <= '1'; @@ -1851,6 +1859,8 @@ begin end case; when "10100011" | "10101011" | "10110011" | "10111011" => -- OUTI, OUTD, OTIR, OTDR + -- note B is decremented BEFORE being put on the bus. + -- mikej fix for hl inc MCycles <= "100"; case to_integer(unsigned(MCycle)) is when 1 => @@ -1866,9 +1876,9 @@ begin Set_Addr_To <= aBC; when 3 => if IR(3) = '0' then - IncDec_16 <= "0010"; + IncDec_16 <= "0110"; -- mikej else - IncDec_16 <= "1010"; + IncDec_16 <= "1110"; -- mikej end if; IORQ <= '1'; Write <= '1'; @@ -1884,7 +1894,7 @@ begin if Mode = 1 then if MCycle = "001" then --- TStates <= "100"; +-- TStates <= "100"; else TStates <= "011"; end if; @@ -1892,7 +1902,7 @@ begin if Mode = 3 then if MCycle = "001" then --- TStates <= "100"; +-- TStates <= "100"; else TStates <= "100"; end if;