Subversion Repositories pentevo

Rev

Rev 4 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed | ?url?

  1. -- ****
  2. -- T80(b) core. In an effort to merge and maintain bug fixes ....
  3. --
  4. --
  5. -- Ver 300 started tidyup. Rmoved some auto_wait bits from 0247 which caused problems
  6. --
  7. -- MikeJ March 2005
  8. -- Latest version from www.fpgaarcade.com (original www.opencores.org)
  9. --
  10. -- ****
  11. --
  12. -- Z80 compatible microprocessor core
  13. --
  14. -- Version : 0247
  15. --
  16. -- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
  17. --
  18. -- All rights reserved
  19. --
  20. -- Redistribution and use in source and synthezised forms, with or without
  21. -- modification, are permitted provided that the following conditions are met:
  22. --
  23. -- Redistributions of source code must retain the above copyright notice,
  24. -- this list of conditions and the following disclaimer.
  25. --
  26. -- Redistributions in synthesized form must reproduce the above copyright
  27. -- notice, this list of conditions and the following disclaimer in the
  28. -- documentation and/or other materials provided with the distribution.
  29. --
  30. -- Neither the name of the author nor the names of other contributors may
  31. -- be used to endorse or promote products derived from this software without
  32. -- specific prior written permission.
  33. --
  34. -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  35. -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  36. -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  37. -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
  38. -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  39. -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  40. -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  41. -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  42. -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  43. -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  44. -- POSSIBILITY OF SUCH DAMAGE.
  45. --
  46. -- Please report bugs to the author, but before you do so, please
  47. -- make sure that this is not a derivative work and that
  48. -- you have the latest version of this file.
  49. --
  50. -- The latest version of this file can be found at:
  51. --      http://www.opencores.org/cvsweb.shtml/t80/
  52. --
  53. -- Limitations :
  54. --
  55. -- File history :
  56. --
  57. --      0208 : First complete release
  58. --
  59. --      0210 : Fixed wait and halt
  60. --
  61. --      0211 : Fixed Refresh addition and IM 1
  62. --
  63. --      0214 : Fixed mostly flags, only the block instructions now fail the zex regression test
  64. --
  65. --      0232 : Removed refresh address output for Mode > 1 and added DJNZ M1_n fix by Mike Johnson
  66. --
  67. --      0235 : Added clock enable and IM 2 fix by Mike Johnson
  68. --
  69. --      0237 : Changed 8080 I/O address output, added IntE output
  70. --
  71. --      0238 : Fixed (IX/IY+d) timing and 16 bit ADC and SBC zero flag
  72. --
  73. --      0240 : Added interrupt ack fix by Mike Johnson, changed (IX/IY+d) timing and changed flags in GB mode
  74. --
  75. --      0242 : Added I/O wait, fixed refresh address, moved some registers to RAM
  76. --
  77. --      0247 : Fixed bus req/ack cycle
  78. --
  79.  
  80. library IEEE;
  81. use IEEE.std_logic_1164.all;
  82. use IEEE.numeric_std.all;
  83. use work.T80_Pack.all;
  84.  
  85. entity T80 is
  86.         generic(
  87.                 Mode   : integer := 0;  -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
  88.                 IOWait : integer := 0;  -- 1 => Single cycle I/O, 1 => Std I/O cycle
  89.                 Flag_C : integer := 0;
  90.                 Flag_N : integer := 1;
  91.                 Flag_P : integer := 2;
  92.                 Flag_X : integer := 3;
  93.                 Flag_H : integer := 4;
  94.                 Flag_Y : integer := 5;
  95.                 Flag_Z : integer := 6;
  96.                 Flag_S : integer := 7
  97.         );
  98.         port(
  99.                 RESET_n         : in  std_logic;
  100.                 CLK_n           : in  std_logic;
  101.                 CEN             : in  std_logic;
  102.                 WAIT_n          : in  std_logic;
  103.                 INT_n           : in  std_logic;
  104.                 NMI_n           : in  std_logic;
  105.                 BUSRQ_n         : in  std_logic;
  106.                 M1_n            : out std_logic;
  107.                 IORQ            : out std_logic;
  108.                 NoRead          : out std_logic;
  109.                 Write           : out std_logic;
  110.                 RFSH_n          : out std_logic;
  111.                 HALT_n          : out std_logic;
  112.                 BUSAK_n         : out std_logic;
  113.                 A               : out std_logic_vector(15 downto 0);
  114.                 DInst           : in  std_logic_vector(7 downto 0);
  115.                 DI              : in  std_logic_vector(7 downto 0);
  116.                 DO              : out std_logic_vector(7 downto 0);
  117.                 MC              : out std_logic_vector(2 downto 0);
  118.                 TS              : out std_logic_vector(2 downto 0);
  119.                 IntCycle_n      : out std_logic;
  120.                 IntE            : out std_logic;
  121.                 Stop            : out std_logic
  122.         );
  123. end T80;
  124.  
  125. architecture rtl of T80 is
  126.  
  127.         constant aNone              : std_logic_vector(2 downto 0) := "111";
  128.         constant aBC                : std_logic_vector(2 downto 0) := "000";
  129.         constant aDE                : std_logic_vector(2 downto 0) := "001";
  130.         constant aXY                : std_logic_vector(2 downto 0) := "010";
  131.         constant aIOA               : std_logic_vector(2 downto 0) := "100";
  132.         constant aSP                : std_logic_vector(2 downto 0) := "101";
  133.         constant aZI                : std_logic_vector(2 downto 0) := "110";
  134.  
  135.         -- Registers
  136.         signal ACC, F               : std_logic_vector(7 downto 0);
  137.         signal Ap, Fp               : std_logic_vector(7 downto 0);
  138.         signal I                    : std_logic_vector(7 downto 0);
  139.         signal R                    : unsigned(7 downto 0);
  140.         signal SP, PC               : unsigned(15 downto 0);
  141.  
  142.         signal RegDIH               : std_logic_vector(7 downto 0);
  143.         signal RegDIL               : std_logic_vector(7 downto 0);
  144.         signal RegBusA              : std_logic_vector(15 downto 0);
  145.         signal RegBusB              : std_logic_vector(15 downto 0);
  146.         signal RegBusC              : std_logic_vector(15 downto 0);
  147.         signal RegAddrA_r           : std_logic_vector(2 downto 0);
  148.         signal RegAddrA             : std_logic_vector(2 downto 0);
  149.         signal RegAddrB_r           : std_logic_vector(2 downto 0);
  150.         signal RegAddrB             : std_logic_vector(2 downto 0);
  151.         signal RegAddrC             : std_logic_vector(2 downto 0);
  152.         signal RegWEH               : std_logic;
  153.         signal RegWEL               : std_logic;
  154.         signal Alternate            : std_logic;
  155.  
  156.         -- Help Registers
  157.         signal TmpAddr              : std_logic_vector(15 downto 0);        -- Temporary address register
  158.         signal IR                   : std_logic_vector(7 downto 0);         -- Instruction register
  159.         signal ISet                 : std_logic_vector(1 downto 0);         -- Instruction set selector
  160.         signal RegBusA_r            : std_logic_vector(15 downto 0);
  161.  
  162.         signal ID16                 : signed(15 downto 0);
  163.         signal Save_Mux             : std_logic_vector(7 downto 0);
  164.  
  165.         signal TState               : unsigned(2 downto 0);
  166.         signal MCycle               : std_logic_vector(2 downto 0);
  167.         signal IntE_FF1             : std_logic;
  168.         signal IntE_FF2             : std_logic;
  169.         signal Halt_FF              : std_logic;
  170.         signal BusReq_s             : std_logic;
  171.         signal BusAck               : std_logic;
  172.         signal ClkEn                : std_logic;
  173.         signal NMI_s                : std_logic;
  174.         signal INT_s                : std_logic;
  175.         signal IStatus              : std_logic_vector(1 downto 0);
  176.  
  177.         signal DI_Reg               : std_logic_vector(7 downto 0);
  178.         signal T_Res                : std_logic;
  179.         signal XY_State             : std_logic_vector(1 downto 0);
  180.         signal Pre_XY_F_M           : std_logic_vector(2 downto 0);
  181.         signal NextIs_XY_Fetch      : std_logic;
  182.         signal XY_Ind               : std_logic;
  183.         signal No_BTR               : std_logic;
  184.         signal BTR_r                : std_logic;
  185.         signal Auto_Wait            : std_logic;
  186.         signal Auto_Wait_t1         : std_logic;
  187.         signal Auto_Wait_t2         : std_logic;
  188.         signal IncDecZ              : std_logic;
  189.  
  190.         -- ALU signals
  191.         signal BusB                 : std_logic_vector(7 downto 0);
  192.         signal BusA                 : std_logic_vector(7 downto 0);
  193.         signal ALU_Q                : std_logic_vector(7 downto 0);
  194.         signal F_Out                : std_logic_vector(7 downto 0);
  195.  
  196.         -- Registered micro code outputs
  197.         signal Read_To_Reg_r        : std_logic_vector(4 downto 0);
  198.         signal Arith16_r            : std_logic;
  199.         signal Z16_r                : std_logic;
  200.         signal ALU_Op_r             : std_logic_vector(3 downto 0);
  201.         signal Save_ALU_r           : std_logic;
  202.         signal PreserveC_r          : std_logic;
  203.         signal MCycles              : std_logic_vector(2 downto 0);
  204.  
  205.         -- Micro code outputs
  206.         signal MCycles_d            : std_logic_vector(2 downto 0);
  207.         signal TStates              : std_logic_vector(2 downto 0);
  208.         signal IntCycle             : std_logic;
  209.         signal NMICycle             : std_logic;
  210.         signal Inc_PC               : std_logic;
  211.         signal Inc_WZ               : std_logic;
  212.         signal IncDec_16            : std_logic_vector(3 downto 0);
  213.         signal Prefix               : std_logic_vector(1 downto 0);
  214.         signal Read_To_Acc          : std_logic;
  215.         signal Read_To_Reg          : std_logic;
  216.         signal Set_BusB_To          : std_logic_vector(3 downto 0);
  217.         signal Set_BusA_To          : std_logic_vector(3 downto 0);
  218.         signal ALU_Op               : std_logic_vector(3 downto 0);
  219.         signal Save_ALU             : std_logic;
  220.         signal PreserveC            : std_logic;
  221.         signal Arith16              : std_logic;
  222.         signal Set_Addr_To          : std_logic_vector(2 downto 0);
  223.         signal Jump                 : std_logic;
  224.         signal JumpE                : std_logic;
  225.         signal JumpXY               : std_logic;
  226.         signal Call                 : std_logic;
  227.         signal RstP                 : std_logic;
  228.         signal LDZ                  : std_logic;
  229.         signal LDW                  : std_logic;
  230.         signal LDSPHL               : std_logic;
  231.         signal IORQ_i               : std_logic;
  232.         signal Special_LD           : std_logic_vector(2 downto 0);
  233.         signal ExchangeDH           : std_logic;
  234.         signal ExchangeRp           : std_logic;
  235.         signal ExchangeAF           : std_logic;
  236.         signal ExchangeRS           : std_logic;
  237.         signal I_DJNZ               : std_logic;
  238.         signal I_CPL                : std_logic;
  239.         signal I_CCF                : std_logic;
  240.         signal I_SCF                : std_logic;
  241.         signal I_RETN               : std_logic;
  242.         signal I_BT                 : std_logic;
  243.         signal I_BC                 : std_logic;
  244.         signal I_BTR                : std_logic;
  245.         signal I_RLD                : std_logic;
  246.         signal I_RRD                : std_logic;
  247.         signal I_INRC               : std_logic;
  248.         signal SetDI                : std_logic;
  249.         signal SetEI                : std_logic;
  250.         signal IMode                : std_logic_vector(1 downto 0);
  251.         signal Halt                 : std_logic;
  252.  
  253. begin
  254.  
  255.         mcode : T80_MCode
  256.                 generic map(
  257.                         Mode   => Mode,
  258.                         Flag_C => Flag_C,
  259.                         Flag_N => Flag_N,
  260.                         Flag_P => Flag_P,
  261.                         Flag_X => Flag_X,
  262.                         Flag_H => Flag_H,
  263.                         Flag_Y => Flag_Y,
  264.                         Flag_Z => Flag_Z,
  265.                         Flag_S => Flag_S)
  266.                 port map(
  267.                         IR          => IR,
  268.                         ISet        => ISet,
  269.                         MCycle      => MCycle,
  270.                         F           => F,
  271.                         NMICycle    => NMICycle,
  272.                         IntCycle    => IntCycle,
  273.                         MCycles     => MCycles_d,
  274.                         TStates     => TStates,
  275.                         Prefix      => Prefix,
  276.                         Inc_PC      => Inc_PC,
  277.                         Inc_WZ      => Inc_WZ,
  278.                         IncDec_16   => IncDec_16,
  279.                         Read_To_Acc => Read_To_Acc,
  280.                         Read_To_Reg => Read_To_Reg,
  281.                         Set_BusB_To => Set_BusB_To,
  282.                         Set_BusA_To => Set_BusA_To,
  283.                         ALU_Op      => ALU_Op,
  284.                         Save_ALU    => Save_ALU,
  285.                         PreserveC   => PreserveC,
  286.                         Arith16     => Arith16,
  287.                         Set_Addr_To => Set_Addr_To,
  288.                         IORQ        => IORQ_i,
  289.                         Jump        => Jump,
  290.                         JumpE       => JumpE,
  291.                         JumpXY      => JumpXY,
  292.                         Call        => Call,
  293.                         RstP        => RstP,
  294.                         LDZ         => LDZ,
  295.                         LDW         => LDW,
  296.                         LDSPHL      => LDSPHL,
  297.                         Special_LD  => Special_LD,
  298.                         ExchangeDH  => ExchangeDH,
  299.                         ExchangeRp  => ExchangeRp,
  300.                         ExchangeAF  => ExchangeAF,
  301.                         ExchangeRS  => ExchangeRS,
  302.                         I_DJNZ      => I_DJNZ,
  303.                         I_CPL       => I_CPL,
  304.                         I_CCF       => I_CCF,
  305.                         I_SCF       => I_SCF,
  306.                         I_RETN      => I_RETN,
  307.                         I_BT        => I_BT,
  308.                         I_BC        => I_BC,
  309.                         I_BTR       => I_BTR,
  310.                         I_RLD       => I_RLD,
  311.                         I_RRD       => I_RRD,
  312.                         I_INRC      => I_INRC,
  313.                         SetDI       => SetDI,
  314.                         SetEI       => SetEI,
  315.                         IMode       => IMode,
  316.                         Halt        => Halt,
  317.                         NoRead      => NoRead,
  318.                         Write       => Write);
  319.  
  320.         alu : T80_ALU
  321.                 generic map(
  322.                         Mode   => Mode,
  323.                         Flag_C => Flag_C,
  324.                         Flag_N => Flag_N,
  325.                         Flag_P => Flag_P,
  326.                         Flag_X => Flag_X,
  327.                         Flag_H => Flag_H,
  328.                         Flag_Y => Flag_Y,
  329.                         Flag_Z => Flag_Z,
  330.                         Flag_S => Flag_S)
  331.                 port map(
  332.                         Arith16 => Arith16_r,
  333.                         Z16     => Z16_r,
  334.                         ALU_Op  => ALU_Op_r,
  335.                         IR      => IR(5 downto 0),
  336.                         ISet    => ISet,
  337.                         BusA    => BusA,
  338.                         BusB    => BusB,
  339.                         F_In    => F,
  340.                         Q       => ALU_Q,
  341.                         F_Out   => F_Out);
  342.  
  343.         ClkEn <= CEN and not BusAck;
  344.  
  345.         T_Res <= '1' when TState = unsigned(TStates) else '0';
  346.  
  347.         NextIs_XY_Fetch <= '1' when XY_State /= "00" and XY_Ind = '0' and
  348.                                                         ((Set_Addr_To = aXY) or
  349.                                                         (MCycle = "001" and IR = "11001011") or
  350.                                                         (MCycle = "001" and IR = "00110110")) else '0';
  351.  
  352.         Save_Mux <= BusB when ExchangeRp = '1' else
  353.                 DI_Reg when Save_ALU_r = '0' else
  354.                 ALU_Q;
  355.  
  356.         process (RESET_n, CLK_n)
  357.         begin
  358.                 if RESET_n = '0' then
  359.                         PC <= (others => '0');  -- Program Counter
  360.                         A <= (others => '0');
  361.                         TmpAddr <= (others => '0');
  362.                         IR <= "00000000";
  363.                         ISet <= "00";
  364.                         XY_State <= "00";
  365.                         IStatus <= "00";
  366.                         MCycles <= "000";
  367.                         DO <= "00000000";
  368.  
  369.                         ACC <= (others => '1');
  370.                         F <= (others => '1');
  371.                         Ap <= (others => '1');
  372.                         Fp <= (others => '1');
  373.                         I <= (others => '0');
  374.                         R <= (others => '0');
  375.                         SP <= (others => '1');
  376.                         Alternate <= '0';
  377.  
  378.                         Read_To_Reg_r <= "00000";
  379.                         F <= (others => '1');
  380.                         Arith16_r <= '0';
  381.                         BTR_r <= '0';
  382.                         Z16_r <= '0';
  383.                         ALU_Op_r <= "0000";
  384.                         Save_ALU_r <= '0';
  385.                         PreserveC_r <= '0';
  386.                         XY_Ind <= '0';
  387.  
  388.                 elsif CLK_n'event and CLK_n = '1' then
  389.  
  390.                         if ClkEn = '1' then
  391.  
  392.                         ALU_Op_r <= "0000";
  393.                         Save_ALU_r <= '0';
  394.                         Read_To_Reg_r <= "00000";
  395.  
  396.                         MCycles <= MCycles_d;
  397.  
  398.                         if IMode /= "11" then
  399.                                 IStatus <= IMode;
  400.                         end if;
  401.  
  402.                         Arith16_r <= Arith16;
  403.                         PreserveC_r <= PreserveC;
  404.                         if ISet = "10" and ALU_OP(2) = '0' and ALU_OP(0) = '1' and MCycle = "011" then
  405.                                 Z16_r <= '1';
  406.                         else
  407.                                 Z16_r <= '0';
  408.                         end if;
  409.  
  410.                         if MCycle  = "001" and TState(2) = '0' then
  411.                         -- MCycle = 1 and TState = 1, 2, or 3
  412.  
  413.                                 if TState = 2 and Wait_n = '1' then
  414.                                         if Mode < 2 then
  415.                                                 A(7 downto 0) <= std_logic_vector(R);
  416.                                                 A(15 downto 8) <= I;
  417.                                                 R(6 downto 0) <= R(6 downto 0) + 1;
  418.                                         end if;
  419.  
  420.                                         if Jump = '0' and Call = '0' and NMICycle = '0' and IntCycle = '0' and not (Halt_FF = '1' or Halt = '1') then
  421.                                                 PC <= PC + 1;
  422.                                         end if;
  423.  
  424.                                         if IntCycle = '1' and IStatus = "01" then
  425.                                                 IR <= "11111111";
  426.                                         elsif Halt_FF = '1' or (IntCycle = '1' and IStatus = "10") or NMICycle = '1' then
  427.                                                 IR <= "00000000";
  428.                                         else
  429.                                                 IR <= DInst;
  430.                                         end if;
  431.  
  432.                                         ISet <= "00";
  433.                                         if Prefix /= "00" then
  434.                                                 if Prefix = "11" then
  435.                                                         if IR(5) = '1' then
  436.                                                                 XY_State <= "10";
  437.                                                         else
  438.                                                                 XY_State <= "01";
  439.                                                         end if;
  440.                                                 else
  441.                                                         if Prefix = "10" then
  442.                                                                 XY_State <= "00";
  443.                                                                 XY_Ind <= '0';
  444.                                                         end if;
  445.                                                         ISet <= Prefix;
  446.                                                 end if;
  447.                                         else
  448.                                                 XY_State <= "00";
  449.                                                 XY_Ind <= '0';
  450.                                         end if;
  451.                                 end if;
  452.  
  453.                         else
  454.                         -- either (MCycle > 1) OR (MCycle = 1 AND TState > 3)
  455.  
  456.                                 if MCycle = "110" then
  457.                                         XY_Ind <= '1';
  458.                                         if Prefix = "01" then
  459.                                                 ISet <= "01";
  460.                                         end if;
  461.                                 end if;
  462.  
  463.                                 if T_Res = '1' then
  464.                                         BTR_r <= (I_BT or I_BC or I_BTR) and not No_BTR;
  465.                                         if Jump = '1' then
  466.                                                 A(15 downto 8) <= DI_Reg;
  467.                                                 A(7 downto 0) <= TmpAddr(7 downto 0);
  468.                                                 PC(15 downto 8) <= unsigned(DI_Reg);
  469.                                                 PC(7 downto 0) <= unsigned(TmpAddr(7 downto 0));
  470.                                         elsif JumpXY = '1' then
  471.                                                 A <= RegBusC;
  472.                                                 PC <= unsigned(RegBusC);
  473.                                         elsif Call = '1' or RstP = '1' then
  474.                                                 A <= TmpAddr;
  475.                                                 PC <= unsigned(TmpAddr);
  476.                                         elsif MCycle = MCycles and NMICycle = '1' then
  477.                                                 A <= "0000000001100110";
  478.                                                 PC <= "0000000001100110";
  479.                                         elsif MCycle = "011" and IntCycle = '1' and IStatus = "10" then
  480.                                                 A(15 downto 8) <= I;
  481.                                                 A(7 downto 0) <= TmpAddr(7 downto 0);
  482.                                                 PC(15 downto 8) <= unsigned(I);
  483.                                                 PC(7 downto 0) <= unsigned(TmpAddr(7 downto 0));
  484.                                         else
  485.                                                 case Set_Addr_To is
  486.                                                 when aXY =>
  487.                                                         if XY_State = "00" then
  488.                                                                 A <= RegBusC;
  489.                                                         else
  490.                                                                 if NextIs_XY_Fetch = '1' then
  491.                                                                         A <= std_logic_vector(PC);
  492.                                                                 else
  493.                                                                         A <= TmpAddr;
  494.                                                                 end if;
  495.                                                         end if;
  496.                                                 when aIOA =>
  497.                                                         if Mode = 3 then
  498.                                                                 -- Memory map I/O on GBZ80
  499.                                                                 A(15 downto 8) <= (others => '1');
  500.                                                         elsif Mode = 2 then
  501.                                                                 -- Duplicate I/O address on 8080
  502.                                                                 A(15 downto 8) <= DI_Reg;
  503.                                                         else
  504.                                                                 A(15 downto 8) <= ACC;
  505.                                                         end if;
  506.                                                         A(7 downto 0) <= DI_Reg;
  507.                                                 when aSP =>
  508.                                                         A <= std_logic_vector(SP);
  509.                                                 when aBC =>
  510.                                                         if Mode = 3 and IORQ_i = '1' then
  511.                                                                 -- Memory map I/O on GBZ80
  512.                                                                 A(15 downto 8) <= (others => '1');
  513.                                                                 A(7 downto 0) <= RegBusC(7 downto 0);
  514.                                                         else
  515.                                                                 A <= RegBusC;
  516.                                                         end if;
  517.                                                 when aDE =>
  518.                                                         A <= RegBusC;
  519.                                                 when aZI =>
  520.                                                         if Inc_WZ = '1' then
  521.                                                                 A <= std_logic_vector(unsigned(TmpAddr) + 1);
  522.                                                         else
  523.                                                                 A(15 downto 8) <= DI_Reg;
  524.                                                                 A(7 downto 0) <= TmpAddr(7 downto 0);
  525.                                                         end if;
  526.                                                 when others =>
  527.                                                         A <= std_logic_vector(PC);
  528.                                                 end case;
  529.                                         end if;
  530.  
  531.                                         Save_ALU_r <= Save_ALU;
  532.                                         ALU_Op_r <= ALU_Op;
  533.  
  534.                                         if I_CPL = '1' then
  535.                                                 -- CPL
  536.                                                 ACC <= not ACC;
  537.                                                 F(Flag_Y) <= not ACC(5);
  538.                                                 F(Flag_H) <= '1';
  539.                                                 F(Flag_X) <= not ACC(3);
  540.                                                 F(Flag_N) <= '1';
  541.                                         end if;
  542.                                         if I_CCF = '1' then
  543.                                                 -- CCF
  544.                                                 F(Flag_C) <= not F(Flag_C);
  545.                                                 F(Flag_Y) <= ACC(5);
  546.                                                 F(Flag_H) <= F(Flag_C);
  547.                                                 F(Flag_X) <= ACC(3);
  548.                                                 F(Flag_N) <= '0';
  549.                                         end if;
  550.                                         if I_SCF = '1' then
  551.                                                 -- SCF
  552.                                                 F(Flag_C) <= '1';
  553.                                                 F(Flag_Y) <= ACC(5);
  554.                                                 F(Flag_H) <= '0';
  555.                                                 F(Flag_X) <= ACC(3);
  556.                                                 F(Flag_N) <= '0';
  557.                                         end if;
  558.                                 end if;
  559.  
  560.                                 if TState = 2 and Wait_n = '1' then
  561.                                         if ISet = "01" and MCycle = "111" then
  562.                                                 IR <= DInst;
  563.                                         end if;
  564.                                         if JumpE = '1' then
  565.                                                 PC <= unsigned(signed(PC) + signed(DI_Reg));
  566.                                         elsif Inc_PC = '1' then
  567.                                                 PC <= PC + 1;
  568.                                         end if;
  569.                                         if BTR_r = '1' then
  570.                                                 PC <= PC - 2;
  571.                                         end if;
  572.                                         if RstP = '1' then
  573.                                                 TmpAddr <= (others =>'0');
  574.                                                 TmpAddr(5 downto 3) <= IR(5 downto 3);
  575.                                         end if;
  576.                                 end if;
  577.                                 if TState = 3 and MCycle = "110" then
  578.                                         TmpAddr <= std_logic_vector(signed(RegBusC) + signed(DI_Reg));
  579.                                 end if;
  580.  
  581.                                 if (TState = 2 and Wait_n = '1') or (TState = 4 and MCycle = "001") then
  582.                                         if IncDec_16(2 downto 0) = "111" then
  583.                                                 if IncDec_16(3) = '1' then
  584.                                                         SP <= SP - 1;
  585.                                                 else
  586.                                                         SP <= SP + 1;
  587.                                                 end if;
  588.                                         end if;
  589.                                 end if;
  590.  
  591.                                 if LDSPHL = '1' then
  592.                                         SP <= unsigned(RegBusC);
  593.                                 end if;
  594.                                 if ExchangeAF = '1' then
  595.                                         Ap <= ACC;
  596.                                         ACC <= Ap;
  597.                                         Fp <= F;
  598.                                         F <= Fp;
  599.                                 end if;
  600.                                 if ExchangeRS = '1' then
  601.                                         Alternate <= not Alternate;
  602.                                 end if;
  603.                         end if;
  604.  
  605.                         if TState = 3 then
  606.                                 if LDZ = '1' then
  607.                                         TmpAddr(7 downto 0) <= DI_Reg;
  608.                                 end if;
  609.                                 if LDW = '1' then
  610.                                         TmpAddr(15 downto 8) <= DI_Reg;
  611.                                 end if;
  612.  
  613.                                 if Special_LD(2) = '1' then
  614.                                         case Special_LD(1 downto 0) is
  615.                                         when "00" =>
  616.                                                 ACC <= I;
  617.                                                 F(Flag_P) <= IntE_FF2;
  618.                                         when "01" =>
  619.                                                 ACC <= std_logic_vector(R);
  620.                                                 F(Flag_P) <= IntE_FF2;
  621.                                         when "10" =>
  622.                                                 I <= ACC;
  623.                                         when others =>
  624.                                                 R <= unsigned(ACC);
  625.                                         end case;
  626.                                 end if;
  627.                         end if;
  628.  
  629.                         if (I_DJNZ = '0' and Save_ALU_r = '1') or ALU_Op_r = "1001" then
  630.                                 if Mode = 3 then
  631.                                         F(6) <= F_Out(6);
  632.                                         F(5) <= F_Out(5);
  633.                                         F(7) <= F_Out(7);
  634.                                         if PreserveC_r = '0' then
  635.                                                 F(4) <= F_Out(4);
  636.                                         end if;
  637.                                 else
  638.                                         F(7 downto 1) <= F_Out(7 downto 1);
  639.                                         if PreserveC_r = '0' then
  640.                                                 F(Flag_C) <= F_Out(0);
  641.                                         end if;
  642.                                 end if;
  643.                         end if;
  644.                         if T_Res = '1' and I_INRC = '1' then
  645.                                 F(Flag_H) <= '0';
  646.                                 F(Flag_N) <= '0';
  647.                                 if DI_Reg(7 downto 0) = "00000000" then
  648.                                         F(Flag_Z) <= '1';
  649.                                 else
  650.                                         F(Flag_Z) <= '0';
  651.                                 end if;
  652.                                 F(Flag_S) <= DI_Reg(7);
  653.                                 F(Flag_P) <= not (DI_Reg(0) xor DI_Reg(1) xor DI_Reg(2) xor DI_Reg(3) xor
  654.                                         DI_Reg(4) xor DI_Reg(5) xor DI_Reg(6) xor DI_Reg(7));
  655.                         end if;
  656.  
  657.                         if TState = 1 then
  658.                                 DO <= BusB;
  659.                                 if I_RLD = '1' then
  660.                                         DO(3 downto 0) <= BusA(3 downto 0);
  661.                                         DO(7 downto 4) <= BusB(3 downto 0);
  662.                                 end if;
  663.                                 if I_RRD = '1' then
  664.                                         DO(3 downto 0) <= BusB(7 downto 4);
  665.                                         DO(7 downto 4) <= BusA(3 downto 0);
  666.                                 end if;
  667.                         end if;
  668.  
  669.                         if T_Res = '1' then
  670.                                 Read_To_Reg_r(3 downto 0) <= Set_BusA_To;
  671.                                 Read_To_Reg_r(4) <= Read_To_Reg;
  672.                                 if Read_To_Acc = '1' then
  673.                                         Read_To_Reg_r(3 downto 0) <= "0111";
  674.                                         Read_To_Reg_r(4) <= '1';
  675.                                 end if;
  676.                         end if;
  677.  
  678.                         if TState = 1 and I_BT = '1' then
  679.                                 F(Flag_X) <= ALU_Q(3);
  680.                                 F(Flag_Y) <= ALU_Q(1);
  681.                                 F(Flag_H) <= '0';
  682.                                 F(Flag_N) <= '0';
  683.                         end if;
  684.                         if I_BC = '1' or I_BT = '1' then
  685.                                 F(Flag_P) <= IncDecZ;
  686.                         end if;
  687.  
  688.                         if (TState = 1 and Save_ALU_r = '0') or
  689.                                 (Save_ALU_r = '1' and ALU_OP_r /= "0111") then
  690.                                 case Read_To_Reg_r is
  691.                                 when "10111" =>
  692.                                         ACC <= Save_Mux;
  693.                                 when "10110" =>
  694.                                         DO <= Save_Mux;
  695.                                 when "11000" =>
  696.                                         SP(7 downto 0) <= unsigned(Save_Mux);
  697.                                 when "11001" =>
  698.                                         SP(15 downto 8) <= unsigned(Save_Mux);
  699.                                 when "11011" =>
  700.                                         F <= Save_Mux;
  701.                                 when others =>
  702.                                 end case;
  703.                         end if;
  704.  
  705.                 end if;
  706.  
  707.                 end if;
  708.  
  709.         end process;
  710.  
  711. ---------------------------------------------------------------------------
  712. --
  713. -- BC('), DE('), HL('), IX and IY
  714. --
  715. ---------------------------------------------------------------------------
  716.         process (CLK_n)
  717.         begin
  718.                 if CLK_n'event and CLK_n = '1' then
  719.                         if ClkEn = '1' then
  720.                                 -- Bus A / Write
  721.                                 RegAddrA_r <= Alternate & Set_BusA_To(2 downto 1);
  722.                                 if XY_Ind = '0' and XY_State /= "00" and Set_BusA_To(2 downto 1) = "10" then
  723.                                         RegAddrA_r <= XY_State(1) & "11";
  724.                                 end if;
  725.  
  726.                                 -- Bus B
  727.                                 RegAddrB_r <= Alternate & Set_BusB_To(2 downto 1);
  728.                                 if XY_Ind = '0' and XY_State /= "00" and Set_BusB_To(2 downto 1) = "10" then
  729.                                         RegAddrB_r <= XY_State(1) & "11";
  730.                                 end if;
  731.  
  732.                                 -- Address from register
  733.                                 RegAddrC <= Alternate & Set_Addr_To(1 downto 0);
  734.                                 -- Jump (HL), LD SP,HL
  735.                                 if (JumpXY = '1' or LDSPHL = '1') then
  736.                                         RegAddrC <= Alternate & "10";
  737.                                 end if;
  738.                                 if ((JumpXY = '1' or LDSPHL = '1') and XY_State /= "00") or (MCycle = "110") then
  739.                                         RegAddrC <= XY_State(1) & "11";
  740.                                 end if;
  741.  
  742.                                 if I_DJNZ = '1' and Save_ALU_r = '1' and Mode < 2 then
  743.                                         IncDecZ <= F_Out(Flag_Z);
  744.                                 end if;
  745.                                 if (TState = 2 or (TState = 3 and MCycle = "001")) and IncDec_16(2 downto 0) = "100" then
  746.                                         if ID16 = 0 then
  747.                                                 IncDecZ <= '0';
  748.                                         else
  749.                                                 IncDecZ <= '1';
  750.                                         end if;
  751.                                 end if;
  752.  
  753.                                 RegBusA_r <= RegBusA;
  754.                         end if;
  755.                 end if;
  756.         end process;
  757.  
  758.         RegAddrA <=
  759.                         -- 16 bit increment/decrement
  760.                         Alternate & IncDec_16(1 downto 0) when (TState = 2 or
  761.                                 (TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and XY_State = "00" else
  762.                         XY_State(1) & "11" when (TState = 2 or
  763.                                 (TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and IncDec_16(1 downto 0) = "10" else
  764.                         -- EX HL,DL
  765.                         Alternate & "10" when ExchangeDH = '1' and TState = 3 else
  766.                         Alternate & "01" when ExchangeDH = '1' and TState = 4 else
  767.                         -- Bus A / Write
  768.                         RegAddrA_r;
  769.  
  770.         RegAddrB <=
  771.                         -- EX HL,DL
  772.                         Alternate & "01" when ExchangeDH = '1' and TState = 3 else
  773.                         -- Bus B
  774.                         RegAddrB_r;
  775.  
  776.         ID16 <= signed(RegBusA) - 1 when IncDec_16(3) = '1' else
  777.                         signed(RegBusA) + 1;
  778.  
  779.         process (Save_ALU_r, Auto_Wait_t1, ALU_OP_r, Read_To_Reg_r,
  780.                         ExchangeDH, IncDec_16, MCycle, TState, Wait_n)
  781.         begin
  782.                 RegWEH <= '0';
  783.                 RegWEL <= '0';
  784.                 if (TState = 1 and Save_ALU_r = '0') or
  785.                         (Save_ALU_r = '1' and ALU_OP_r /= "0111") then
  786.                         case Read_To_Reg_r is
  787.                         when "10000" | "10001" | "10010" | "10011" | "10100" | "10101" =>
  788.                                 RegWEH <= not Read_To_Reg_r(0);
  789.                                 RegWEL <= Read_To_Reg_r(0);
  790.                         when others =>
  791.                         end case;
  792.                 end if;
  793.  
  794.                 if ExchangeDH = '1' and (TState = 3 or TState = 4) then
  795.                         RegWEH <= '1';
  796.                         RegWEL <= '1';
  797.                 end if;
  798.  
  799.                 if IncDec_16(2) = '1' and ((TState = 2 and Wait_n = '1' and MCycle /= "001") or (TState = 3 and MCycle = "001")) then
  800.                         case IncDec_16(1 downto 0) is
  801.                         when "00" | "01" | "10" =>
  802.                                 RegWEH <= '1';
  803.                                 RegWEL <= '1';
  804.                         when others =>
  805.                         end case;
  806.                 end if;
  807.         end process;
  808.  
  809.         process (Save_Mux, RegBusB, RegBusA_r, ID16,
  810.                         ExchangeDH, IncDec_16, MCycle, TState, Wait_n)
  811.         begin
  812.                 RegDIH <= Save_Mux;
  813.                 RegDIL <= Save_Mux;
  814.  
  815.                 if ExchangeDH = '1' and TState = 3 then
  816.                         RegDIH <= RegBusB(15 downto 8);
  817.                         RegDIL <= RegBusB(7 downto 0);
  818.                 end if;
  819.                 if ExchangeDH = '1' and TState = 4 then
  820.                         RegDIH <= RegBusA_r(15 downto 8);
  821.                         RegDIL <= RegBusA_r(7 downto 0);
  822.                 end if;
  823.  
  824.                 if IncDec_16(2) = '1' and ((TState = 2 and MCycle /= "001") or (TState = 3 and MCycle = "001")) then
  825.                         RegDIH <= std_logic_vector(ID16(15 downto 8));
  826.                         RegDIL <= std_logic_vector(ID16(7 downto 0));
  827.                 end if;
  828.         end process;
  829.  
  830.         Regs : T80_Reg
  831.                 port map(
  832.                         Clk => CLK_n,
  833.                         CEN => ClkEn,
  834.                         WEH => RegWEH,
  835.                         WEL => RegWEL,
  836.                         AddrA => RegAddrA,
  837.                         AddrB => RegAddrB,
  838.                         AddrC => RegAddrC,
  839.                         DIH => RegDIH,
  840.                         DIL => RegDIL,
  841.                         DOAH => RegBusA(15 downto 8),
  842.                         DOAL => RegBusA(7 downto 0),
  843.                         DOBH => RegBusB(15 downto 8),
  844.                         DOBL => RegBusB(7 downto 0),
  845.                         DOCH => RegBusC(15 downto 8),
  846.                         DOCL => RegBusC(7 downto 0));
  847.  
  848. ---------------------------------------------------------------------------
  849. --
  850. -- Buses
  851. --
  852. ---------------------------------------------------------------------------
  853.         process (CLK_n)
  854.         begin
  855.                 if CLK_n'event and CLK_n = '1' then
  856.                         if ClkEn = '1' then
  857.                         case Set_BusB_To is
  858.                         when "0111" =>
  859.                                 BusB <= ACC;
  860.                         when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" =>
  861.                                 if Set_BusB_To(0) = '1' then
  862.                                         BusB <= RegBusB(7 downto 0);
  863.                                 else
  864.                                         BusB <= RegBusB(15 downto 8);
  865.                                 end if;
  866.                         when "0110" =>
  867.                                 BusB <= DI_Reg;
  868.                         when "1000" =>
  869.                                 BusB <= std_logic_vector(SP(7 downto 0));
  870.                         when "1001" =>
  871.                                 BusB <= std_logic_vector(SP(15 downto 8));
  872.                         when "1010" =>
  873.                                 BusB <= "00000001";
  874.                         when "1011" =>
  875.                                 BusB <= F;
  876.                         when "1100" =>
  877.                                 BusB <= std_logic_vector(PC(7 downto 0));
  878.                         when "1101" =>
  879.                                 BusB <= std_logic_vector(PC(15 downto 8));
  880.                         when "1110" =>
  881.                                 BusB <= "00000000";
  882.                         when others =>
  883.                                 BusB <= "--------";
  884.                         end case;
  885.  
  886.                         case Set_BusA_To is
  887.                         when "0111" =>
  888.                                 BusA <= ACC;
  889.                         when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" =>
  890.                                 if Set_BusA_To(0) = '1' then
  891.                                         BusA <= RegBusA(7 downto 0);
  892.                                 else
  893.                                         BusA <= RegBusA(15 downto 8);
  894.                                 end if;
  895.                         when "0110" =>
  896.                                 BusA <= DI_Reg;
  897.                         when "1000" =>
  898.                                 BusA <= std_logic_vector(SP(7 downto 0));
  899.                         when "1001" =>
  900.                                 BusA <= std_logic_vector(SP(15 downto 8));
  901.                         when "1010" =>
  902.                                 BusA <= "00000000";
  903.                         when others =>
  904.                                 BusB <= "--------";
  905.                         end case;
  906.                         end if;
  907.                 end if;
  908.         end process;
  909.  
  910. ---------------------------------------------------------------------------
  911. --
  912. -- Generate external control signals
  913. --
  914. ---------------------------------------------------------------------------
  915.         process (RESET_n,CLK_n)
  916.         begin
  917.                 if RESET_n = '0' then
  918.                         RFSH_n <= '1';
  919.                 elsif CLK_n'event and CLK_n = '1' then
  920.                         if CEN = '1' then
  921.                         if MCycle = "001" and ((TState = 2  and Wait_n = '1') or TState = 3) then
  922.                                 RFSH_n <= '0';
  923.                         else
  924.                                 RFSH_n <= '1';
  925.                         end if;
  926.                         end if;
  927.                 end if;
  928.         end process;
  929.  
  930.         MC <= std_logic_vector(MCycle);
  931.         TS <= std_logic_vector(TState);
  932.         DI_Reg <= DI;
  933.         HALT_n <= not Halt_FF;
  934.         BUSAK_n <= not BusAck;
  935.         IntCycle_n <= not IntCycle;
  936.         IntE <= IntE_FF1;
  937.         IORQ <= IORQ_i;
  938.         Stop <= I_DJNZ;
  939.  
  940. -------------------------------------------------------------------------
  941. --
  942. -- Syncronise inputs
  943. --
  944. -------------------------------------------------------------------------
  945.         process (RESET_n, CLK_n)
  946.                 variable OldNMI_n : std_logic;
  947.         begin
  948.                 if RESET_n = '0' then
  949.                         BusReq_s <= '0';
  950.                         INT_s <= '0';
  951.                         NMI_s <= '0';
  952.                         OldNMI_n := '0';
  953.                 elsif CLK_n'event and CLK_n = '1' then
  954.                         if CEN = '1' then
  955.                         BusReq_s <= not BUSRQ_n;
  956.                         INT_s <= not INT_n;
  957.                         if NMICycle = '1' then
  958.                                 NMI_s <= '0';
  959.                         elsif NMI_n = '0' and OldNMI_n = '1' then
  960.                                 NMI_s <= '1';
  961.                         end if;
  962.                         OldNMI_n := NMI_n;
  963.                         end if;
  964.                 end if;
  965.         end process;
  966.  
  967. -------------------------------------------------------------------------
  968. --
  969. -- Main state machine
  970. --
  971. -------------------------------------------------------------------------
  972.         process (RESET_n, CLK_n)
  973.         begin
  974.                 if RESET_n = '0' then
  975.                         MCycle <= "001";
  976.                         TState <= "000";
  977.                         Pre_XY_F_M <= "000";
  978.                         Halt_FF <= '0';
  979.                         BusAck <= '0';
  980.                         NMICycle <= '0';
  981.                         IntCycle <= '0';
  982.                         IntE_FF1 <= '0';
  983.                         IntE_FF2 <= '0';
  984.                         No_BTR <= '0';
  985.                         Auto_Wait_t1 <= '0';
  986.                         Auto_Wait_t2 <= '0';
  987.                         M1_n <= '1';
  988.                 elsif CLK_n'event and CLK_n = '1' then
  989.                         if CEN = '1' then
  990.                         Auto_Wait_t1 <= Auto_Wait;
  991.                         Auto_Wait_t2 <= Auto_Wait_t1;
  992.                         No_BTR <= (I_BT and (not IR(4) or not F(Flag_P))) or
  993.                                         (I_BC and (not IR(4) or F(Flag_Z) or not F(Flag_P))) or
  994.                                         (I_BTR and (not IR(4) or F(Flag_Z)));
  995.                         if TState = 2 then
  996.                                 if SetEI = '1' then
  997.                                         IntE_FF1 <= '1';
  998.                                         IntE_FF2 <= '1';
  999.                                 end if;
  1000.                                 if I_RETN = '1' then
  1001.                                         IntE_FF1 <= IntE_FF2;
  1002.                                 end if;
  1003.                         end if;
  1004.                         if TState = 3 then
  1005.                                 if SetDI = '1' then
  1006.                                         IntE_FF1 <= '0';
  1007.                                         IntE_FF2 <= '0';
  1008.                                 end if;
  1009.                         end if;
  1010.                         if IntCycle = '1' or NMICycle = '1' then
  1011.                                 Halt_FF <= '0';
  1012.                         end if;
  1013.                         if MCycle = "001" and TState = 2 and Wait_n = '1' then
  1014.                                 M1_n <= '1';
  1015.                         end if;
  1016.                         if BusReq_s = '1' and BusAck = '1' then
  1017.                         else
  1018.                                 BusAck <= '0';
  1019.                                 if TState = 2 and Wait_n = '0' then
  1020.                                 elsif T_Res = '1' then
  1021.                                         if Halt = '1' then
  1022.                                                 Halt_FF <= '1';
  1023.                                         end if;
  1024.                                         if BusReq_s = '1' then
  1025.                                                 BusAck <= '1';
  1026.                                         else
  1027.                                                 TState <= "001";
  1028.                                                 if NextIs_XY_Fetch = '1' then
  1029.                                                         MCycle <= "110";
  1030.                                                         Pre_XY_F_M <= MCycle;
  1031.                                                         if IR = "00110110" and Mode = 0 then
  1032.                                                                 Pre_XY_F_M <= "010";
  1033.                                                         end if;
  1034.                                                 elsif (MCycle = "111") or
  1035.                                                         (MCycle = "110" and Mode = 1 and ISet /= "01") then
  1036.                                                         MCycle <= std_logic_vector(unsigned(Pre_XY_F_M) + 1);
  1037.                                                 elsif (MCycle = MCycles) or
  1038.                                                         No_BTR = '1' or
  1039.                                                         (MCycle = "010" and I_DJNZ = '1' and IncDecZ = '1') then
  1040.                                                         M1_n <= '0';
  1041.                                                         MCycle <= "001";
  1042.                                                         IntCycle <= '0';
  1043.                                                         NMICycle <= '0';
  1044.                                                         if NMI_s = '1' and Prefix = "00" then
  1045.                                                                 NMICycle <= '1';
  1046.                                                                 IntE_FF1 <= '0';
  1047.                                                         elsif (IntE_FF1 = '1' and INT_s = '1') and Prefix = "00" and SetEI = '0' then
  1048.                                                                 IntCycle <= '1';
  1049.                                                                 IntE_FF1 <= '0';
  1050.                                                                 IntE_FF2 <= '0';
  1051.                                                         end if;
  1052.                                                 else
  1053.                                                         MCycle <= std_logic_vector(unsigned(MCycle) + 1);
  1054.                                                 end if;
  1055.                                         end if;
  1056.                                 else
  1057.                                         if Auto_Wait = '1' nand Auto_Wait_t2 = '0' then
  1058.  
  1059.                                                 TState <= TState + 1;
  1060.                                         end if;
  1061.                                 end if;
  1062.                         end if;
  1063.                         if TState = 0 then
  1064.                                 M1_n <= '0';
  1065.                         end if;
  1066.                         end if;
  1067.                 end if;
  1068.         end process;
  1069.  
  1070.         process (IntCycle, NMICycle, MCycle)
  1071.         begin
  1072.                 Auto_Wait <= '0';
  1073.                 if IntCycle = '1' or NMICycle = '1' then
  1074.                         if MCycle = "001" then
  1075.                                 Auto_Wait <= '1';
  1076.                         end if;
  1077.                 end if;
  1078.         end process;
  1079.  
  1080. end;
  1081.