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.                 ResetPC         : in  std_logic_vector(15 downto 0);
  123.                 ResetSP         : in  std_logic_vector(15 downto 0)
  124.         );
  125. end T80;
  126.  
  127. architecture rtl of T80 is
  128.  
  129.         constant aNone              : std_logic_vector(2 downto 0) := "111";
  130.         constant aBC                : std_logic_vector(2 downto 0) := "000";
  131.         constant aDE                : std_logic_vector(2 downto 0) := "001";
  132.         constant aXY                : std_logic_vector(2 downto 0) := "010";
  133.         constant aIOA               : std_logic_vector(2 downto 0) := "100";
  134.         constant aSP                : std_logic_vector(2 downto 0) := "101";
  135.         constant aZI                : std_logic_vector(2 downto 0) := "110";
  136.  
  137.         -- Registers
  138.         signal ACC, F               : std_logic_vector(7 downto 0);
  139.         signal Ap, Fp               : std_logic_vector(7 downto 0);
  140.         signal I                    : std_logic_vector(7 downto 0);
  141.         signal R                    : unsigned(7 downto 0);
  142.         signal SP, PC               : unsigned(15 downto 0);
  143.  
  144.         signal RegDIH               : std_logic_vector(7 downto 0);
  145.         signal RegDIL               : std_logic_vector(7 downto 0);
  146.         signal RegBusA              : std_logic_vector(15 downto 0);
  147.         signal RegBusB              : std_logic_vector(15 downto 0);
  148.         signal RegBusC              : std_logic_vector(15 downto 0);
  149.         signal RegAddrA_r           : std_logic_vector(2 downto 0);
  150.         signal RegAddrA             : std_logic_vector(2 downto 0);
  151.         signal RegAddrB_r           : std_logic_vector(2 downto 0);
  152.         signal RegAddrB             : std_logic_vector(2 downto 0);
  153.         signal RegAddrC             : std_logic_vector(2 downto 0);
  154.         signal RegWEH               : std_logic;
  155.         signal RegWEL               : std_logic;
  156.         signal Alternate            : std_logic;
  157.  
  158.         -- Help Registers
  159.         signal TmpAddr              : std_logic_vector(15 downto 0);        -- Temporary address register
  160.         signal IR                   : std_logic_vector(7 downto 0);         -- Instruction register
  161.         signal ISet                 : std_logic_vector(1 downto 0);         -- Instruction set selector
  162.         signal RegBusA_r            : std_logic_vector(15 downto 0);
  163.  
  164.         signal ID16                 : signed(15 downto 0);
  165.         signal Save_Mux             : std_logic_vector(7 downto 0);
  166.  
  167.         signal TState               : unsigned(2 downto 0);
  168.         signal MCycle               : std_logic_vector(2 downto 0);
  169.         signal IntE_FF1             : std_logic;
  170.         signal IntE_FF2             : std_logic;
  171.         signal Halt_FF              : std_logic;
  172.         signal BusReq_s             : std_logic;
  173.         signal BusAck               : std_logic;
  174.         signal ClkEn                : std_logic;
  175.         signal NMI_s                : std_logic;
  176.         signal INT_s                : std_logic;
  177.         signal IStatus              : std_logic_vector(1 downto 0);
  178.  
  179.         signal DI_Reg               : std_logic_vector(7 downto 0);
  180.         signal T_Res                : std_logic;
  181.         signal XY_State             : std_logic_vector(1 downto 0);
  182.         signal Pre_XY_F_M           : std_logic_vector(2 downto 0);
  183.         signal NextIs_XY_Fetch      : std_logic;
  184.         signal XY_Ind               : std_logic;
  185.         signal No_BTR               : std_logic;
  186.         signal BTR_r                : std_logic;
  187.         signal Auto_Wait            : std_logic;
  188.         signal Auto_Wait_t1         : std_logic;
  189.         signal Auto_Wait_t2         : std_logic;
  190.         signal IncDecZ              : std_logic;
  191.  
  192.         -- ALU signals
  193.         signal BusB                 : std_logic_vector(7 downto 0);
  194.         signal BusA                 : std_logic_vector(7 downto 0);
  195.         signal ALU_Q                : std_logic_vector(7 downto 0);
  196.         signal F_Out                : std_logic_vector(7 downto 0);
  197.  
  198.         -- Registered micro code outputs
  199.         signal Read_To_Reg_r        : std_logic_vector(4 downto 0);
  200.         signal Arith16_r            : std_logic;
  201.         signal Z16_r                : std_logic;
  202.         signal ALU_Op_r             : std_logic_vector(3 downto 0);
  203.         signal Save_ALU_r           : std_logic;
  204.         signal PreserveC_r          : std_logic;
  205.         signal MCycles              : std_logic_vector(2 downto 0);
  206.  
  207.         -- Micro code outputs
  208.         signal MCycles_d            : std_logic_vector(2 downto 0);
  209.         signal TStates              : std_logic_vector(2 downto 0);
  210.         signal IntCycle             : std_logic;
  211.         signal NMICycle             : std_logic;
  212.         signal Inc_PC               : std_logic;
  213.         signal Inc_WZ               : std_logic;
  214.         signal IncDec_16            : std_logic_vector(3 downto 0);
  215.         signal Prefix               : std_logic_vector(1 downto 0);
  216.         signal Read_To_Acc          : std_logic;
  217.         signal Read_To_Reg          : std_logic;
  218.         signal Set_BusB_To          : std_logic_vector(3 downto 0);
  219.         signal Set_BusA_To          : std_logic_vector(3 downto 0);
  220.         signal ALU_Op               : std_logic_vector(3 downto 0);
  221.         signal Save_ALU             : std_logic;
  222.         signal PreserveC            : std_logic;
  223.         signal Arith16              : std_logic;
  224.         signal Set_Addr_To          : std_logic_vector(2 downto 0);
  225.         signal Jump                 : std_logic;
  226.         signal JumpE                : std_logic;
  227.         signal JumpXY               : std_logic;
  228.         signal Call                 : std_logic;
  229.         signal RstP                 : std_logic;
  230.         signal LDZ                  : std_logic;
  231.         signal LDW                  : std_logic;
  232.         signal LDSPHL               : std_logic;
  233.         signal IORQ_i               : std_logic;
  234.         signal Special_LD           : std_logic_vector(2 downto 0);
  235.         signal ExchangeDH           : std_logic;
  236.         signal ExchangeRp           : std_logic;
  237.         signal ExchangeAF           : std_logic;
  238.         signal ExchangeRS           : std_logic;
  239.         signal I_DJNZ               : std_logic;
  240.         signal I_CPL                : std_logic;
  241.         signal I_CCF                : std_logic;
  242.         signal I_SCF                : std_logic;
  243.         signal I_RETN               : std_logic;
  244.         signal I_BT                 : std_logic;
  245.         signal I_BC                 : std_logic;
  246.         signal I_BTR                : std_logic;
  247.         signal I_RLD                : std_logic;
  248.         signal I_RRD                : std_logic;
  249.         signal I_INRC               : std_logic;
  250.         signal SetDI                : std_logic;
  251.         signal SetEI                : std_logic;
  252.         signal IMode                : std_logic_vector(1 downto 0);
  253.         signal Halt                 : std_logic;
  254.  
  255. begin
  256.  
  257.         mcode : T80_MCode
  258.                 generic map(
  259.                         Mode   => Mode,
  260.                         Flag_C => Flag_C,
  261.                         Flag_N => Flag_N,
  262.                         Flag_P => Flag_P,
  263.                         Flag_X => Flag_X,
  264.                         Flag_H => Flag_H,
  265.                         Flag_Y => Flag_Y,
  266.                         Flag_Z => Flag_Z,
  267.                         Flag_S => Flag_S)
  268.                 port map(
  269.                         IR          => IR,
  270.                         ISet        => ISet,
  271.                         MCycle      => MCycle,
  272.                         F           => F,
  273.                         NMICycle    => NMICycle,
  274.                         IntCycle    => IntCycle,
  275.                         MCycles     => MCycles_d,
  276.                         TStates     => TStates,
  277.                         Prefix      => Prefix,
  278.                         Inc_PC      => Inc_PC,
  279.                         Inc_WZ      => Inc_WZ,
  280.                         IncDec_16   => IncDec_16,
  281.                         Read_To_Acc => Read_To_Acc,
  282.                         Read_To_Reg => Read_To_Reg,
  283.                         Set_BusB_To => Set_BusB_To,
  284.                         Set_BusA_To => Set_BusA_To,
  285.                         ALU_Op      => ALU_Op,
  286.                         Save_ALU    => Save_ALU,
  287.                         PreserveC   => PreserveC,
  288.                         Arith16     => Arith16,
  289.                         Set_Addr_To => Set_Addr_To,
  290.                         IORQ        => IORQ_i,
  291.                         Jump        => Jump,
  292.                         JumpE       => JumpE,
  293.                         JumpXY      => JumpXY,
  294.                         Call        => Call,
  295.                         RstP        => RstP,
  296.                         LDZ         => LDZ,
  297.                         LDW         => LDW,
  298.                         LDSPHL      => LDSPHL,
  299.                         Special_LD  => Special_LD,
  300.                         ExchangeDH  => ExchangeDH,
  301.                         ExchangeRp  => ExchangeRp,
  302.                         ExchangeAF  => ExchangeAF,
  303.                         ExchangeRS  => ExchangeRS,
  304.                         I_DJNZ      => I_DJNZ,
  305.                         I_CPL       => I_CPL,
  306.                         I_CCF       => I_CCF,
  307.                         I_SCF       => I_SCF,
  308.                         I_RETN      => I_RETN,
  309.                         I_BT        => I_BT,
  310.                         I_BC        => I_BC,
  311.                         I_BTR       => I_BTR,
  312.                         I_RLD       => I_RLD,
  313.                         I_RRD       => I_RRD,
  314.                         I_INRC      => I_INRC,
  315.                         SetDI       => SetDI,
  316.                         SetEI       => SetEI,
  317.                         IMode       => IMode,
  318.                         Halt        => Halt,
  319.                         NoRead      => NoRead,
  320.                         Write       => Write);
  321.  
  322.         alu : T80_ALU
  323.                 generic map(
  324.                         Mode   => Mode,
  325.                         Flag_C => Flag_C,
  326.                         Flag_N => Flag_N,
  327.                         Flag_P => Flag_P,
  328.                         Flag_X => Flag_X,
  329.                         Flag_H => Flag_H,
  330.                         Flag_Y => Flag_Y,
  331.                         Flag_Z => Flag_Z,
  332.                         Flag_S => Flag_S)
  333.                 port map(
  334.                         Arith16 => Arith16_r,
  335.                         Z16     => Z16_r,
  336.                         ALU_Op  => ALU_Op_r,
  337.                         IR      => IR(5 downto 0),
  338.                         ISet    => ISet,
  339.                         BusA    => BusA,
  340.                         BusB    => BusB,
  341.                         F_In    => F,
  342.                         Q       => ALU_Q,
  343.                         F_Out   => F_Out);
  344.  
  345.         ClkEn <= CEN and not BusAck;
  346.  
  347.         T_Res <= '1' when TState = unsigned(TStates) else '0';
  348.  
  349.         NextIs_XY_Fetch <= '1' when XY_State /= "00" and XY_Ind = '0' and
  350.                                                         ((Set_Addr_To = aXY) or
  351.                                                         (MCycle = "001" and IR = "11001011") or
  352.                                                         (MCycle = "001" and IR = "00110110")) else '0';
  353.  
  354.         Save_Mux <= BusB when ExchangeRp = '1' else
  355.                 DI_Reg when Save_ALU_r = '0' else
  356.                 ALU_Q;
  357.  
  358.         process (RESET_n, CLK_n)
  359.         begin
  360.                 if RESET_n = '0' then
  361.                         PC <= unsigned(ResetPC);
  362.                         -- (others => '0')  -- Program Counter
  363.                         A <= ResetPC; -- (others => '0');
  364.                         TmpAddr <= (others => '0');
  365.                         IR <= "00000000";
  366.                         ISet <= "00";
  367.                         XY_State <= "00";
  368.                         IStatus <= "00";
  369.                         MCycles <= "000";
  370.                         DO <= "00000000";
  371.  
  372.                         ACC <= (others => '1');
  373.                         F <= (others => '1');
  374.                         Ap <= (others => '1');
  375.                         Fp <= (others => '1');
  376.                         I <= (others => '0');
  377.                         R <= (others => '0');
  378.                         SP <= unsigned(ResetSP);
  379.                         -- (others => '1')
  380.                         Alternate <= '0';
  381.  
  382.                         Read_To_Reg_r <= "00000";
  383.                         F <= (others => '1');
  384.                         Arith16_r <= '0';
  385.                         BTR_r <= '0';
  386.                         Z16_r <= '0';
  387.                         ALU_Op_r <= "0000";
  388.                         Save_ALU_r <= '0';
  389.                         PreserveC_r <= '0';
  390.                         XY_Ind <= '0';
  391.  
  392.                 elsif CLK_n'event and CLK_n = '1' then
  393.  
  394.                         if ClkEn = '1' then
  395.  
  396.                         ALU_Op_r <= "0000";
  397.                         Save_ALU_r <= '0';
  398.                         Read_To_Reg_r <= "00000";
  399.  
  400.                         MCycles <= MCycles_d;
  401.  
  402.                         if IMode /= "11" then
  403.                                 IStatus <= IMode;
  404.                         end if;
  405.  
  406.                         Arith16_r <= Arith16;
  407.                         PreserveC_r <= PreserveC;
  408.                         if ISet = "10" and ALU_OP(2) = '0' and ALU_OP(0) = '1' and MCycle = "011" then
  409.                                 Z16_r <= '1';
  410.                         else
  411.                                 Z16_r <= '0';
  412.                         end if;
  413.  
  414.                         if MCycle  = "001" and TState(2) = '0' then
  415.                         -- MCycle = 1 and TState = 1, 2, or 3
  416.  
  417.                                 if TState = 2 and Wait_n = '1' then
  418.                                         if Mode < 2 then
  419.                                                 A(7 downto 0) <= std_logic_vector(R);
  420.                                                 A(15 downto 8) <= I;
  421.                                                 R(6 downto 0) <= R(6 downto 0) + 1;
  422.                                         end if;
  423.  
  424.                                         if Jump = '0' and Call = '0' and NMICycle = '0' and IntCycle = '0' and not (Halt_FF = '1' or Halt = '1') then
  425.                                                 PC <= PC + 1;
  426.                                         end if;
  427.  
  428.                                         if IntCycle = '1' and IStatus = "01" then
  429.                                                 IR <= "11111111";
  430.                                         elsif Halt_FF = '1' or (IntCycle = '1' and IStatus = "10") or NMICycle = '1' then
  431.                                                 IR <= "00000000";
  432.                                         else
  433.                                                 IR <= DInst;
  434.                                         end if;
  435.  
  436.                                         ISet <= "00";
  437.                                         if Prefix /= "00" then
  438.                                                 if Prefix = "11" then
  439.                                                         if IR(5) = '1' then
  440.                                                                 XY_State <= "10";
  441.                                                         else
  442.                                                                 XY_State <= "01";
  443.                                                         end if;
  444.                                                 else
  445.                                                         if Prefix = "10" then
  446.                                                                 XY_State <= "00";
  447.                                                                 XY_Ind <= '0';
  448.                                                         end if;
  449.                                                         ISet <= Prefix;
  450.                                                 end if;
  451.                                         else
  452.                                                 XY_State <= "00";
  453.                                                 XY_Ind <= '0';
  454.                                         end if;
  455.                                 end if;
  456.  
  457.                         else
  458.                         -- either (MCycle > 1) OR (MCycle = 1 AND TState > 3)
  459.  
  460.                                 if MCycle = "110" then
  461.                                         XY_Ind <= '1';
  462.                                         if Prefix = "01" then
  463.                                                 ISet <= "01";
  464.                                         end if;
  465.                                 end if;
  466.  
  467.                                 if T_Res = '1' then
  468.                                         BTR_r <= (I_BT or I_BC or I_BTR) and not No_BTR;
  469.                                         if Jump = '1' then
  470.                                                 A(15 downto 8) <= DI_Reg;
  471.                                                 A(7 downto 0) <= TmpAddr(7 downto 0);
  472.                                                 PC(15 downto 8) <= unsigned(DI_Reg);
  473.                                                 PC(7 downto 0) <= unsigned(TmpAddr(7 downto 0));
  474.                                         elsif JumpXY = '1' then
  475.                                                 A <= RegBusC;
  476.                                                 PC <= unsigned(RegBusC);
  477.                                         elsif Call = '1' or RstP = '1' then
  478.                                                 A <= TmpAddr;
  479.                                                 PC <= unsigned(TmpAddr);
  480.                                         elsif MCycle = MCycles and NMICycle = '1' then
  481.                                                 A <= "0000000001100110";
  482.                                                 PC <= "0000000001100110";
  483.                                         elsif MCycle = "011" and IntCycle = '1' and IStatus = "10" then
  484.                                                 A(15 downto 8) <= I;
  485.                                                 A(7 downto 0) <= TmpAddr(7 downto 0);
  486.                                                 PC(15 downto 8) <= unsigned(I);
  487.                                                 PC(7 downto 0) <= unsigned(TmpAddr(7 downto 0));
  488.                                         else
  489.                                                 case Set_Addr_To is
  490.                                                 when aXY =>
  491.                                                         if XY_State = "00" then
  492.                                                                 A <= RegBusC;
  493.                                                         else
  494.                                                                 if NextIs_XY_Fetch = '1' then
  495.                                                                         A <= std_logic_vector(PC);
  496.                                                                 else
  497.                                                                         A <= TmpAddr;
  498.                                                                 end if;
  499.                                                         end if;
  500.                                                 when aIOA =>
  501.                                                         if Mode = 3 then
  502.                                                                 -- Memory map I/O on GBZ80
  503.                                                                 A(15 downto 8) <= (others => '1');
  504.                                                         elsif Mode = 2 then
  505.                                                                 -- Duplicate I/O address on 8080
  506.                                                                 A(15 downto 8) <= DI_Reg;
  507.                                                         else
  508.                                                                 A(15 downto 8) <= ACC;
  509.                                                         end if;
  510.                                                         A(7 downto 0) <= DI_Reg;
  511.                                                 when aSP =>
  512.                                                         A <= std_logic_vector(SP);
  513.                                                 when aBC =>
  514.                                                         if Mode = 3 and IORQ_i = '1' then
  515.                                                                 -- Memory map I/O on GBZ80
  516.                                                                 A(15 downto 8) <= (others => '1');
  517.                                                                 A(7 downto 0) <= RegBusC(7 downto 0);
  518.                                                         else
  519.                                                                 A <= RegBusC;
  520.                                                         end if;
  521.                                                 when aDE =>
  522.                                                         A <= RegBusC;
  523.                                                 when aZI =>
  524.                                                         if Inc_WZ = '1' then
  525.                                                                 A <= std_logic_vector(unsigned(TmpAddr) + 1);
  526.                                                         else
  527.                                                                 A(15 downto 8) <= DI_Reg;
  528.                                                                 A(7 downto 0) <= TmpAddr(7 downto 0);
  529.                                                         end if;
  530.                                                 when others =>
  531.                                                         A <= std_logic_vector(PC);
  532.                                                 end case;
  533.                                         end if;
  534.  
  535.                                         Save_ALU_r <= Save_ALU;
  536.                                         ALU_Op_r <= ALU_Op;
  537.  
  538.                                         if I_CPL = '1' then
  539.                                                 -- CPL
  540.                                                 ACC <= not ACC;
  541.                                                 F(Flag_Y) <= not ACC(5);
  542.                                                 F(Flag_H) <= '1';
  543.                                                 F(Flag_X) <= not ACC(3);
  544.                                                 F(Flag_N) <= '1';
  545.                                         end if;
  546.                                         if I_CCF = '1' then
  547.                                                 -- CCF
  548.                                                 F(Flag_C) <= not F(Flag_C);
  549.                                                 F(Flag_Y) <= ACC(5);
  550.                                                 F(Flag_H) <= F(Flag_C);
  551.                                                 F(Flag_X) <= ACC(3);
  552.                                                 F(Flag_N) <= '0';
  553.                                         end if;
  554.                                         if I_SCF = '1' then
  555.                                                 -- SCF
  556.                                                 F(Flag_C) <= '1';
  557.                                                 F(Flag_Y) <= ACC(5);
  558.                                                 F(Flag_H) <= '0';
  559.                                                 F(Flag_X) <= ACC(3);
  560.                                                 F(Flag_N) <= '0';
  561.                                         end if;
  562.                                 end if;
  563.  
  564.                                 if TState = 2 and Wait_n = '1' then
  565.                                         if ISet = "01" and MCycle = "111" then
  566.                                                 IR <= DInst;
  567.                                         end if;
  568.                                         if JumpE = '1' then
  569.                                                 PC <= unsigned(signed(PC) + signed(DI_Reg));
  570.                                         elsif Inc_PC = '1' then
  571.                                                 PC <= PC + 1;
  572.                                         end if;
  573.                                         if BTR_r = '1' then
  574.                                                 PC <= PC - 2;
  575.                                         end if;
  576.                                         if RstP = '1' then
  577.                                                 TmpAddr <= (others =>'0');
  578.                                                 TmpAddr(5 downto 3) <= IR(5 downto 3);
  579.                                         end if;
  580.                                 end if;
  581.                                 if TState = 3 and MCycle = "110" then
  582.                                         TmpAddr <= std_logic_vector(signed(RegBusC) + signed(DI_Reg));
  583.                                 end if;
  584.  
  585.                                 if (TState = 2 and Wait_n = '1') or (TState = 4 and MCycle = "001") then
  586.                                         if IncDec_16(2 downto 0) = "111" then
  587.                                                 if IncDec_16(3) = '1' then
  588.                                                         SP <= SP - 1;
  589.                                                 else
  590.                                                         SP <= SP + 1;
  591.                                                 end if;
  592.                                         end if;
  593.                                 end if;
  594.  
  595.                                 if LDSPHL = '1' then
  596.                                         SP <= unsigned(RegBusC);
  597.                                 end if;
  598.                                 if ExchangeAF = '1' then
  599.                                         Ap <= ACC;
  600.                                         ACC <= Ap;
  601.                                         Fp <= F;
  602.                                         F <= Fp;
  603.                                 end if;
  604.                                 if ExchangeRS = '1' then
  605.                                         Alternate <= not Alternate;
  606.                                 end if;
  607.                         end if;
  608.  
  609.                         if TState = 3 then
  610.                                 if LDZ = '1' then
  611.                                         TmpAddr(7 downto 0) <= DI_Reg;
  612.                                 end if;
  613.                                 if LDW = '1' then
  614.                                         TmpAddr(15 downto 8) <= DI_Reg;
  615.                                 end if;
  616.  
  617.                                 if Special_LD(2) = '1' then
  618.                                         case Special_LD(1 downto 0) is
  619.                                         when "00" =>
  620.                                                 ACC <= I;
  621.                                                 F(Flag_P) <= IntE_FF2;
  622.                                         when "01" =>
  623.                                                 ACC <= std_logic_vector(R);
  624.                                                 F(Flag_P) <= IntE_FF2;
  625.                                         when "10" =>
  626.                                                 I <= ACC;
  627.                                         when others =>
  628.                                                 R <= unsigned(ACC);
  629.                                         end case;
  630.                                 end if;
  631.                         end if;
  632.  
  633.                         if (I_DJNZ = '0' and Save_ALU_r = '1') or ALU_Op_r = "1001" then
  634.                                 if Mode = 3 then
  635.                                         F(6) <= F_Out(6);
  636.                                         F(5) <= F_Out(5);
  637.                                         F(7) <= F_Out(7);
  638.                                         if PreserveC_r = '0' then
  639.                                                 F(4) <= F_Out(4);
  640.                                         end if;
  641.                                 else
  642.                                         F(7 downto 1) <= F_Out(7 downto 1);
  643.                                         if PreserveC_r = '0' then
  644.                                                 F(Flag_C) <= F_Out(0);
  645.                                         end if;
  646.                                 end if;
  647.                         end if;
  648.                         if T_Res = '1' and I_INRC = '1' then
  649.                                 F(Flag_H) <= '0';
  650.                                 F(Flag_N) <= '0';
  651.                                 if DI_Reg(7 downto 0) = "00000000" then
  652.                                         F(Flag_Z) <= '1';
  653.                                 else
  654.                                         F(Flag_Z) <= '0';
  655.                                 end if;
  656.                                 F(Flag_S) <= DI_Reg(7);
  657.                                 F(Flag_P) <= not (DI_Reg(0) xor DI_Reg(1) xor DI_Reg(2) xor DI_Reg(3) xor
  658.                                         DI_Reg(4) xor DI_Reg(5) xor DI_Reg(6) xor DI_Reg(7));
  659.                         end if;
  660.  
  661.                         if TState = 1 then
  662.                                 DO <= BusB;
  663.                                 if I_RLD = '1' then
  664.                                         DO(3 downto 0) <= BusA(3 downto 0);
  665.                                         DO(7 downto 4) <= BusB(3 downto 0);
  666.                                 end if;
  667.                                 if I_RRD = '1' then
  668.                                         DO(3 downto 0) <= BusB(7 downto 4);
  669.                                         DO(7 downto 4) <= BusA(3 downto 0);
  670.                                 end if;
  671.                         end if;
  672.  
  673.                         if T_Res = '1' then
  674.                                 Read_To_Reg_r(3 downto 0) <= Set_BusA_To;
  675.                                 Read_To_Reg_r(4) <= Read_To_Reg;
  676.                                 if Read_To_Acc = '1' then
  677.                                         Read_To_Reg_r(3 downto 0) <= "0111";
  678.                                         Read_To_Reg_r(4) <= '1';
  679.                                 end if;
  680.                         end if;
  681.  
  682.                         if TState = 1 and I_BT = '1' then
  683.                                 F(Flag_X) <= ALU_Q(3);
  684.                                 F(Flag_Y) <= ALU_Q(1);
  685.                                 F(Flag_H) <= '0';
  686.                                 F(Flag_N) <= '0';
  687.                         end if;
  688.                         if I_BC = '1' or I_BT = '1' then
  689.                                 F(Flag_P) <= IncDecZ;
  690.                         end if;
  691.  
  692.                         if (TState = 1 and Save_ALU_r = '0') or
  693.                                 (Save_ALU_r = '1' and ALU_OP_r /= "0111") then
  694.                                 case Read_To_Reg_r is
  695.                                 when "10111" =>
  696.                                         ACC <= Save_Mux;
  697.                                 when "10110" =>
  698.                                         DO <= Save_Mux;
  699.                                 when "11000" =>
  700.                                         SP(7 downto 0) <= unsigned(Save_Mux);
  701.                                 when "11001" =>
  702.                                         SP(15 downto 8) <= unsigned(Save_Mux);
  703.                                 when "11011" =>
  704.                                         F <= Save_Mux;
  705.                                 when others =>
  706.                                 end case;
  707.                         end if;
  708.  
  709.                 end if;
  710.  
  711.                 end if;
  712.  
  713.         end process;
  714.  
  715. ---------------------------------------------------------------------------
  716. --
  717. -- BC('), DE('), HL('), IX and IY
  718. --
  719. ---------------------------------------------------------------------------
  720.         process (CLK_n)
  721.         begin
  722.                 if CLK_n'event and CLK_n = '1' then
  723.                         if ClkEn = '1' then
  724.                                 -- Bus A / Write
  725.                                 RegAddrA_r <= Alternate & Set_BusA_To(2 downto 1);
  726.                                 if XY_Ind = '0' and XY_State /= "00" and Set_BusA_To(2 downto 1) = "10" then
  727.                                         RegAddrA_r <= XY_State(1) & "11";
  728.                                 end if;
  729.  
  730.                                 -- Bus B
  731.                                 RegAddrB_r <= Alternate & Set_BusB_To(2 downto 1);
  732.                                 if XY_Ind = '0' and XY_State /= "00" and Set_BusB_To(2 downto 1) = "10" then
  733.                                         RegAddrB_r <= XY_State(1) & "11";
  734.                                 end if;
  735.  
  736.                                 -- Address from register
  737.                                 RegAddrC <= Alternate & Set_Addr_To(1 downto 0);
  738.                                 -- Jump (HL), LD SP,HL
  739.                                 if (JumpXY = '1' or LDSPHL = '1') then
  740.                                         RegAddrC <= Alternate & "10";
  741.                                 end if;
  742.                                 if ((JumpXY = '1' or LDSPHL = '1') and XY_State /= "00") or (MCycle = "110") then
  743.                                         RegAddrC <= XY_State(1) & "11";
  744.                                 end if;
  745.  
  746.                                 if I_DJNZ = '1' and Save_ALU_r = '1' and Mode < 2 then
  747.                                         IncDecZ <= F_Out(Flag_Z);
  748.                                 end if;
  749.                                 if (TState = 2 or (TState = 3 and MCycle = "001")) and IncDec_16(2 downto 0) = "100" then
  750.                                         if ID16 = 0 then
  751.                                                 IncDecZ <= '0';
  752.                                         else
  753.                                                 IncDecZ <= '1';
  754.                                         end if;
  755.                                 end if;
  756.  
  757.                                 RegBusA_r <= RegBusA;
  758.                         end if;
  759.                 end if;
  760.         end process;
  761.  
  762.         RegAddrA <=
  763.                         -- 16 bit increment/decrement
  764.                         Alternate & IncDec_16(1 downto 0) when (TState = 2 or
  765.                                 (TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and XY_State = "00" else
  766.                         XY_State(1) & "11" when (TState = 2 or
  767.                                 (TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and IncDec_16(1 downto 0) = "10" else
  768.                         -- EX HL,DL
  769.                         Alternate & "10" when ExchangeDH = '1' and TState = 3 else
  770.                         Alternate & "01" when ExchangeDH = '1' and TState = 4 else
  771.                         -- Bus A / Write
  772.                         RegAddrA_r;
  773.  
  774.         RegAddrB <=
  775.                         -- EX HL,DL
  776.                         Alternate & "01" when ExchangeDH = '1' and TState = 3 else
  777.                         -- Bus B
  778.                         RegAddrB_r;
  779.  
  780.         ID16 <= signed(RegBusA) - 1 when IncDec_16(3) = '1' else
  781.                         signed(RegBusA) + 1;
  782.  
  783.         process (Save_ALU_r, Auto_Wait_t1, ALU_OP_r, Read_To_Reg_r,
  784.                         ExchangeDH, IncDec_16, MCycle, TState, Wait_n)
  785.         begin
  786.                 RegWEH <= '0';
  787.                 RegWEL <= '0';
  788.                 if (TState = 1 and Save_ALU_r = '0') or
  789.                         (Save_ALU_r = '1' and ALU_OP_r /= "0111") then
  790.                         case Read_To_Reg_r is
  791.                         when "10000" | "10001" | "10010" | "10011" | "10100" | "10101" =>
  792.                                 RegWEH <= not Read_To_Reg_r(0);
  793.                                 RegWEL <= Read_To_Reg_r(0);
  794.                         when others =>
  795.                         end case;
  796.                 end if;
  797.  
  798.                 if ExchangeDH = '1' and (TState = 3 or TState = 4) then
  799.                         RegWEH <= '1';
  800.                         RegWEL <= '1';
  801.                 end if;
  802.  
  803.                 if IncDec_16(2) = '1' and ((TState = 2 and Wait_n = '1' and MCycle /= "001") or (TState = 3 and MCycle = "001")) then
  804.                         case IncDec_16(1 downto 0) is
  805.                         when "00" | "01" | "10" =>
  806.                                 RegWEH <= '1';
  807.                                 RegWEL <= '1';
  808.                         when others =>
  809.                         end case;
  810.                 end if;
  811.         end process;
  812.  
  813.         process (Save_Mux, RegBusB, RegBusA_r, ID16,
  814.                         ExchangeDH, IncDec_16, MCycle, TState, Wait_n)
  815.         begin
  816.                 RegDIH <= Save_Mux;
  817.                 RegDIL <= Save_Mux;
  818.  
  819.                 if ExchangeDH = '1' and TState = 3 then
  820.                         RegDIH <= RegBusB(15 downto 8);
  821.                         RegDIL <= RegBusB(7 downto 0);
  822.                 end if;
  823.                 if ExchangeDH = '1' and TState = 4 then
  824.                         RegDIH <= RegBusA_r(15 downto 8);
  825.                         RegDIL <= RegBusA_r(7 downto 0);
  826.                 end if;
  827.  
  828.                 if IncDec_16(2) = '1' and ((TState = 2 and MCycle /= "001") or (TState = 3 and MCycle = "001")) then
  829.                         RegDIH <= std_logic_vector(ID16(15 downto 8));
  830.                         RegDIL <= std_logic_vector(ID16(7 downto 0));
  831.                 end if;
  832.         end process;
  833.  
  834.         Regs : T80_Reg
  835.                 port map(
  836.                         Clk => CLK_n,
  837.                         CEN => ClkEn,
  838.                         WEH => RegWEH,
  839.                         WEL => RegWEL,
  840.                         AddrA => RegAddrA,
  841.                         AddrB => RegAddrB,
  842.                         AddrC => RegAddrC,
  843.                         DIH => RegDIH,
  844.                         DIL => RegDIL,
  845.                         DOAH => RegBusA(15 downto 8),
  846.                         DOAL => RegBusA(7 downto 0),
  847.                         DOBH => RegBusB(15 downto 8),
  848.                         DOBL => RegBusB(7 downto 0),
  849.                         DOCH => RegBusC(15 downto 8),
  850.                         DOCL => RegBusC(7 downto 0));
  851.  
  852. ---------------------------------------------------------------------------
  853. --
  854. -- Buses
  855. --
  856. ---------------------------------------------------------------------------
  857.         process (CLK_n)
  858.         begin
  859.                 if CLK_n'event and CLK_n = '1' then
  860.                         if ClkEn = '1' then
  861.                         case Set_BusB_To is
  862.                         when "0111" =>
  863.                                 BusB <= ACC;
  864.                         when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" =>
  865.                                 if Set_BusB_To(0) = '1' then
  866.                                         BusB <= RegBusB(7 downto 0);
  867.                                 else
  868.                                         BusB <= RegBusB(15 downto 8);
  869.                                 end if;
  870.                         when "0110" =>
  871.                                 BusB <= DI_Reg;
  872.                         when "1000" =>
  873.                                 BusB <= std_logic_vector(SP(7 downto 0));
  874.                         when "1001" =>
  875.                                 BusB <= std_logic_vector(SP(15 downto 8));
  876.                         when "1010" =>
  877.                                 BusB <= "00000001";
  878.                         when "1011" =>
  879.                                 BusB <= F;
  880.                         when "1100" =>
  881.                                 BusB <= std_logic_vector(PC(7 downto 0));
  882.                         when "1101" =>
  883.                                 BusB <= std_logic_vector(PC(15 downto 8));
  884.                         when "1110" =>
  885.                                 BusB <= "00000000";
  886.                         when others =>
  887.                                 BusB <= "--------";
  888.                         end case;
  889.  
  890.                         case Set_BusA_To is
  891.                         when "0111" =>
  892.                                 BusA <= ACC;
  893.                         when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" =>
  894.                                 if Set_BusA_To(0) = '1' then
  895.                                         BusA <= RegBusA(7 downto 0);
  896.                                 else
  897.                                         BusA <= RegBusA(15 downto 8);
  898.                                 end if;
  899.                         when "0110" =>
  900.                                 BusA <= DI_Reg;
  901.                         when "1000" =>
  902.                                 BusA <= std_logic_vector(SP(7 downto 0));
  903.                         when "1001" =>
  904.                                 BusA <= std_logic_vector(SP(15 downto 8));
  905.                         when "1010" =>
  906.                                 BusA <= "00000000";
  907.                         when others =>
  908.                                 BusB <= "--------";
  909.                         end case;
  910.                         end if;
  911.                 end if;
  912.         end process;
  913.  
  914. ---------------------------------------------------------------------------
  915. --
  916. -- Generate external control signals
  917. --
  918. ---------------------------------------------------------------------------
  919.         process (RESET_n,CLK_n)
  920.         begin
  921.                 if RESET_n = '0' then
  922.                         RFSH_n <= '1';
  923.                 elsif CLK_n'event and CLK_n = '1' then
  924.                         if CEN = '1' then
  925.                         if MCycle = "001" and ((TState = 2  and Wait_n = '1') or TState = 3) then
  926.                                 RFSH_n <= '0';
  927.                         else
  928.                                 RFSH_n <= '1';
  929.                         end if;
  930.                         end if;
  931.                 end if;
  932.         end process;
  933.  
  934.         MC <= std_logic_vector(MCycle);
  935.         TS <= std_logic_vector(TState);
  936.         DI_Reg <= DI;
  937.         HALT_n <= not Halt_FF;
  938.         BUSAK_n <= not BusAck;
  939.         IntCycle_n <= not IntCycle;
  940.         IntE <= IntE_FF1;
  941.         IORQ <= IORQ_i;
  942.         Stop <= I_DJNZ;
  943.  
  944. -------------------------------------------------------------------------
  945. --
  946. -- Syncronise inputs
  947. --
  948. -------------------------------------------------------------------------
  949.         process (RESET_n, CLK_n)
  950.                 variable OldNMI_n : std_logic;
  951.         begin
  952.                 if RESET_n = '0' then
  953.                         BusReq_s <= '0';
  954.                         INT_s <= '0';
  955.                         NMI_s <= '0';
  956.                         OldNMI_n := '0';
  957.                 elsif CLK_n'event and CLK_n = '1' then
  958.                         if CEN = '1' then
  959.                         BusReq_s <= not BUSRQ_n;
  960.                         INT_s <= not INT_n;
  961.                         if NMICycle = '1' then
  962.                                 NMI_s <= '0';
  963.                         elsif NMI_n = '0' and OldNMI_n = '1' then
  964.                                 NMI_s <= '1';
  965.                         end if;
  966.                         OldNMI_n := NMI_n;
  967.                         end if;
  968.                 end if;
  969.         end process;
  970.  
  971. -------------------------------------------------------------------------
  972. --
  973. -- Main state machine
  974. --
  975. -------------------------------------------------------------------------
  976.         process (RESET_n, CLK_n)
  977.         begin
  978.                 if RESET_n = '0' then
  979.                         MCycle <= "001";
  980.                         TState <= "000";
  981.                         Pre_XY_F_M <= "000";
  982.                         Halt_FF <= '0';
  983.                         BusAck <= '0';
  984.                         NMICycle <= '0';
  985.                         IntCycle <= '0';
  986.                         IntE_FF1 <= '0';
  987.                         IntE_FF2 <= '0';
  988.                         No_BTR <= '0';
  989.                         Auto_Wait_t1 <= '0';
  990.                         Auto_Wait_t2 <= '0';
  991.                         M1_n <= '1';
  992.                 elsif CLK_n'event and CLK_n = '1' then
  993.                         if CEN = '1' then
  994.                         Auto_Wait_t1 <= Auto_Wait;
  995.                         Auto_Wait_t2 <= Auto_Wait_t1;
  996.                         No_BTR <= (I_BT and (not IR(4) or not F(Flag_P))) or
  997.                                         (I_BC and (not IR(4) or F(Flag_Z) or not F(Flag_P))) or
  998.                                         (I_BTR and (not IR(4) or F(Flag_Z)));
  999.                         if TState = 2 then
  1000.                                 if SetEI = '1' then
  1001.                                         IntE_FF1 <= '1';
  1002.                                         IntE_FF2 <= '1';
  1003.                                 end if;
  1004.                                 if I_RETN = '1' then
  1005.                                         IntE_FF1 <= IntE_FF2;
  1006.                                 end if;
  1007.                         end if;
  1008.                         if TState = 3 then
  1009.                                 if SetDI = '1' then
  1010.                                         IntE_FF1 <= '0';
  1011.                                         IntE_FF2 <= '0';
  1012.                                 end if;
  1013.                         end if;
  1014.                         if IntCycle = '1' or NMICycle = '1' then
  1015.                                 Halt_FF <= '0';
  1016.                         end if;
  1017.                         if MCycle = "001" and TState = 2 and Wait_n = '1' then
  1018.                                 M1_n <= '1';
  1019.                         end if;
  1020.                         if BusReq_s = '1' and BusAck = '1' then
  1021.                         else
  1022.                                 BusAck <= '0';
  1023.                                 if TState = 2 and Wait_n = '0' then
  1024.                                 elsif T_Res = '1' then
  1025.                                         if Halt = '1' then
  1026.                                                 Halt_FF <= '1';
  1027.                                         end if;
  1028.                                         if BusReq_s = '1' then
  1029.                                                 BusAck <= '1';
  1030.                                         else
  1031.                                                 TState <= "001";
  1032.                                                 if NextIs_XY_Fetch = '1' then
  1033.                                                         MCycle <= "110";
  1034.                                                         Pre_XY_F_M <= MCycle;
  1035.                                                         if IR = "00110110" and Mode = 0 then
  1036.                                                                 Pre_XY_F_M <= "010";
  1037.                                                         end if;
  1038.                                                 elsif (MCycle = "111") or
  1039.                                                         (MCycle = "110" and Mode = 1 and ISet /= "01") then
  1040.                                                         MCycle <= std_logic_vector(unsigned(Pre_XY_F_M) + 1);
  1041.                                                 elsif (MCycle = MCycles) or
  1042.                                                         No_BTR = '1' or
  1043.                                                         (MCycle = "010" and I_DJNZ = '1' and IncDecZ = '1') then
  1044.                                                         M1_n <= '0';
  1045.                                                         MCycle <= "001";
  1046.                                                         IntCycle <= '0';
  1047.                                                         NMICycle <= '0';
  1048.                                                         if NMI_s = '1' and Prefix = "00" then
  1049.                                                                 NMICycle <= '1';
  1050.                                                                 IntE_FF1 <= '0';
  1051.                                                         elsif (IntE_FF1 = '1' and INT_s = '1') and Prefix = "00" and SetEI = '0' then
  1052.                                                                 IntCycle <= '1';
  1053.                                                                 IntE_FF1 <= '0';
  1054.                                                                 IntE_FF2 <= '0';
  1055.                                                         end if;
  1056.                                                 else
  1057.                                                         MCycle <= std_logic_vector(unsigned(MCycle) + 1);
  1058.                                                 end if;
  1059.                                         end if;
  1060.                                 else
  1061.                                         if Auto_Wait = '1' nand Auto_Wait_t2 = '0' then
  1062.  
  1063.                                                 TState <= TState + 1;
  1064.                                         end if;
  1065.                                 end if;
  1066.                         end if;
  1067.                         if TState = 0 then
  1068.                                 M1_n <= '0';
  1069.                         end if;
  1070.                         end if;
  1071.                 end if;
  1072.         end process;
  1073.  
  1074.         process (IntCycle, NMICycle, MCycle)
  1075.         begin
  1076.                 Auto_Wait <= '0';
  1077.                 if IntCycle = '1' or NMICycle = '1' then
  1078.                         if MCycle = "001" then
  1079.                                 Auto_Wait <= '1';
  1080.                         end if;
  1081.                 end if;
  1082.         end process;
  1083.  
  1084. end;
  1085.