Subversion Repositories Games.Chess Giants

Rev

Rev 81 | Blame | Last modification | View Log | Download | RSS feed

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <ctype.h>
  5. #if defined(_WIN32)
  6. #include <windows.h>
  7. #endif
  8.  
  9. #define NEW
  10. #define T41_INCLUDE
  11. #define T42_INCLUDE
  12. #define T33_INCLUDE
  13. #define T_INDEX64
  14. #define  XX  127
  15.  
  16. #if defined (T_INDEX64) && defined (_MSC_VER)
  17. typedef unsigned __int64 INDEX;
  18. #elif defined (T_INDEX64)
  19. typedef unsigned long long INDEX;
  20. #else
  21. typedef unsigned long INDEX;
  22. #endif
  23.  
  24. typedef unsigned int square;
  25.  
  26. typedef int color;
  27.  
  28. #define  x_colorWhite    0
  29. #define  x_colorBlack    1
  30. #define  x_colorNeutral  2
  31.  
  32. typedef int piece;
  33.  
  34. #define  x_pieceNone     0
  35. #define  x_piecePawn     1
  36. #define  x_pieceKnight   2
  37. #define  x_pieceBishop   3
  38. #define  x_pieceRook     4
  39. #define  x_pieceQueen    5
  40. #define  x_pieceKing     6
  41.  
  42. /*
  43.    Macro that fetches positions of pieces
  44.  */
  45.  
  46. #define  C_PIECES  3    /* Maximum # of pieces of one color OTB */
  47.  
  48. #define  SqFindKing(psq)       (psq[C_PIECES*(x_pieceKing-1)])
  49. #define  SqFindOne(psq, pi)    (psq[C_PIECES*(pi-1)])
  50. #define  SqFindFirst(psq, pi)  (psq[C_PIECES*(pi-1)])
  51. #define  SqFindSecond(psq, pi) (psq[C_PIECES*(pi-1)+1])
  52. #define  SqFindThird(psq, pi)  (psq[C_PIECES*(pi-1)+2])
  53.  
  54. #include "lock.h"
  55.  
  56. /*
  57.    All defined, now include probing code
  58.  */
  59.  
  60. /* -------------------------------------------------------------------- */
  61. /*                                                                      */
  62. /*              Probe chess endgame database ("tablebase")              */
  63. /*                                                                      */
  64. /*               Copyright (c) 1998--2001 Eugene Nalimov                */
  65. /*                                                                      */
  66. /* The code listed below should not be used in any product (software or */
  67. /* hardware,  commercial or not,  and so on) without written permission */
  68. /* from the author.                                                     */
  69. /*                                                                      */
  70. /* -------------------------------------------------------------------- */
  71.  
  72. #if defined (_WIN32) || defined(_WIN64)
  73. #  include <windows.h>
  74. #endif
  75.  
  76. #include <string.h>
  77. #include <stdlib.h>
  78. #include <stdio.h>
  79. #if !defined (DEBUG) && !defined(NDEBUG)
  80. #  define   NDEBUG
  81. #endif
  82. #include <assert.h>
  83.  
  84. static  lock_t  lockLRU;
  85.  
  86. // Declarations
  87.  
  88. typedef unsigned    char BYTE;
  89. typedef unsigned    long ULONG;
  90. typedef signed      char tb_t;
  91.  
  92. #if !defined (COLOR_DECLARED)
  93. typedef int color;
  94. #  define   x_colorWhite    0
  95. #  define   x_colorBlack    1
  96. #  define   x_colorNeutral  2
  97. #  define COLOR_DECLARED
  98. #endif
  99.  
  100. #if !defined (PIECES_DECLARED)
  101. typedef int piece;
  102. #  define   x_pieceNone     0
  103. #  define   x_piecePawn     1
  104. #  define   x_pieceKnight   2
  105. #  define   x_pieceBishop   3
  106. #  define   x_pieceRook     4
  107. #  define   x_pieceQueen    5
  108. #  define   x_pieceKing     6
  109. #  define PIECES_DECLARED
  110. #endif
  111.  
  112. #if !defined (SqFind2)
  113. #  define   SqFind2(psq,pi1,sq1,pi2,sq2)    sq1=SqFindFirst(psq,pi1);sq2=SqFindFirst(psq,pi2);
  114. #endif
  115.  
  116. // Machine and compiler-specific declarations
  117.  
  118. #if defined (_MSC_VER)
  119.  
  120. #  undef    TB_CDECL
  121. #  define   TB_CDECL    __cdecl
  122. #  define   TB_FASTCALL __fastcall
  123. #  if _MSC_VER >= 1200
  124. #    define INLINE      __forceinline
  125. #  endif
  126.  
  127. #else
  128.  
  129. #  define   TB_CDECL
  130. #  define   TB_FASTCALL
  131.  
  132. #endif
  133.  
  134. #if !defined (INLINE)
  135. #  define   INLINE  inline
  136. #endif
  137.  
  138. // Printf formats
  139.  
  140. #if defined (T_INDEX64) && defined (_MSC_VER)
  141. #   define HEX_INDEX_FORMAT "%016I64X"
  142. #   define DEC_INDEX_FORMAT "%I64u"
  143. #elif defined (T_INDEX64)
  144. #   define HEX_INDEX_FORMAT "%016llX"
  145. #   define DEC_INDEX_FORMAT "%llu"
  146. #else
  147. #   define HEX_INDEX_FORMAT "%08X"
  148. #   define DEC_INDEX_FORMAT "%lu"
  149. #endif
  150.  
  151. // Directory delimiter
  152.  
  153. #if defined (_WIN32) || defined(_WIN64)
  154. #   define DELIMITER   "\\"
  155. #elif defined (__MWERKS__)
  156. #   define DELIMITER   ":"
  157. #else
  158. #   define DELIMITER   "/"
  159. #endif
  160.  
  161.  
  162. // Some constants from SJE program
  163.  
  164. #define pageL 256
  165.  
  166. /* tablebase byte entry semispan length */
  167.  
  168. #define tbbe_ssL ((pageL - 4) / 2)
  169.  
  170. /* tablebase signed byte entry values */
  171.  
  172. #define bev_broken  (tbbe_ssL + 1)  /* illegal or busted */
  173.  
  174. #define bev_mi1     tbbe_ssL        /* mate in 1 move */
  175. #define bev_mimin   1               /* mate in 126 moves */
  176.  
  177. #define bev_draw    0               /* draw */
  178.  
  179. #define bev_limax   (-1)            /* mated in 125 moves */
  180. #define bev_li0     (-tbbe_ssL)     /* mated in 0 moves */
  181.  
  182. #define bev_limaxx  (-tbbe_ssL - 1) /* mated in 126 moves */
  183. #define bev_miminx  (-tbbe_ssL - 2) /* mate in 127 moves */
  184.  
  185. // Some constants for 16-bit tables
  186.  
  187. #define L_pageL 65536
  188.  
  189. /* tablebase short entry semispan length */
  190.  
  191. #define L_tbbe_ssL ((L_pageL - 4) / 2)
  192.  
  193. /* tablebase signed short entry values */
  194.  
  195. #define L_bev_broken  (L_tbbe_ssL + 1)      /* illegal or busted */
  196.  
  197. #define L_bev_mi1     L_tbbe_ssL            /* mate in 1 move */
  198. #define L_bev_mimin   1                     /* mate in 32766 moves */
  199.  
  200. #define L_bev_draw    0                     /* draw */
  201.  
  202. #define L_bev_limax   (-1)                  /* mated in 32765 moves */
  203. #define L_bev_li0     (-L_tbbe_ssL)         /* mated in 0 moves */
  204.  
  205. #define L_bev_limaxx    (-L_tbbe_ssL - 1)   /* mated in 32766 moves */
  206. #define L_bev_miminx    (-L_tbbe_ssL - 2)   /* mate in 32767 moves */
  207.  
  208. // Convertion from 8-bit to 16-bit score
  209. // UNDONE: Maybe implement via lookup table?
  210.  
  211. #define S_to_L(tbt)\
  212.     (\
  213.      (0 == tbt) ? 0:\
  214.      (tbt > 0) ? (bev_broken != tbt ? tbt + 32640 : L_bev_broken):\
  215.      (tbt >= bev_li0) ? tbt - 32640:\
  216.      (bev_limaxx == tbt) ? -32640:\
  217.      /*bev_miminx == tbt*/  32640\
  218.     )
  219.  
  220. // Constants
  221.  
  222. #define i8  ((unsigned) 8)
  223. #define i14 ((unsigned) 14)
  224. #define i42 ((unsigned) 42)
  225. #define i43 ((unsigned) 43)
  226. #define i44 ((unsigned) 44)
  227. #define i45 ((unsigned) 45)
  228. #define i46 ((unsigned) 46)
  229. #define i47 ((unsigned) 47)
  230. #define i48 ((unsigned) 48)
  231. #define i57 ((unsigned) 57)
  232. #define i58 ((unsigned) 58)
  233. #define i59 ((unsigned) 59)
  234. #define i60 ((unsigned) 60)
  235. #define i61 ((unsigned) 61)
  236. #define i62 ((unsigned) 62)
  237. #define i63 ((unsigned) 63)
  238. #define i64 ((unsigned) 64)
  239.  
  240. #define x_row_1 0
  241. #define x_row_2 1
  242. #define x_row_3 2
  243. #define x_row_4 3
  244. #define x_row_5 4
  245. #define x_row_6 5
  246. #define x_row_7 6
  247. #define x_row_8 7
  248.  
  249. #define x_column_a 0
  250. #define x_column_b 1
  251. #define x_column_c 2
  252. #define x_column_d 3
  253. #define x_column_e 4
  254. #define x_column_f 5
  255. #define x_column_g 6
  256. #define x_column_h 7
  257.  
  258. /* reflection macros */
  259.  
  260. #define reflect_x(sq) ((sq) ^ 0x38)
  261. #define reflect_y(sq) ((sq) ^ 0x07)
  262. #define reflect_xy(sq) rgsqReflectXY[sq]
  263.  
  264. static const square rgsqReflectXY [] =
  265. {
  266.   0,  8, 16, 24, 32, 40, 48, 56,
  267.   1,  9, 17, 25, 33, 41, 49, 57,
  268.   2, 10, 18, 26, 34, 42, 50, 58,
  269.   3, 11, 19, 27, 35, 43, 51, 59,
  270.   4, 12, 20, 28, 36, 44, 52, 60,
  271.   5, 13, 21, 29, 37, 45, 53, 61,
  272.   6, 14, 22, 30, 38, 46, 54, 62,
  273.   7, 15, 23, 31, 39, 47, 55, 63,
  274. };
  275.  
  276. static const square rgsqReflectMaskY [] =
  277. {
  278.  0, 0, 0, 0, 7, 7, 7, 7,
  279.  0, 0, 0, 0, 7, 7, 7, 7,
  280.  0, 0, 0, 0, 7, 7, 7, 7,
  281.  0, 0, 0, 0, 7, 7, 7, 7,
  282.  0, 0, 0, 0, 7, 7, 7, 7,
  283.  0, 0, 0, 0, 7, 7, 7, 7,
  284.  0, 0, 0, 0, 7, 7, 7, 7,
  285.  0, 0, 0, 0, 7, 7, 7, 7,
  286. };
  287.  
  288. static const square rgsqReflectMaskYandX [] =
  289. {
  290.  0, 0, 0, 0, 7, 7, 7, 7,
  291.  0, 0, 0, 0, 7, 7, 7, 7,
  292.  0, 0, 0, 0, 7, 7, 7, 7,
  293.  0, 0, 0, 0, 7, 7, 7, 7,
  294.  0x38, 0x38, 0x38, 0x38, 0x38+7, 0x38+7, 0x38+7, 0x38+7,
  295.  0x38, 0x38, 0x38, 0x38, 0x38+7, 0x38+7, 0x38+7, 0x38+7,
  296.  0x38, 0x38, 0x38, 0x38, 0x38+7, 0x38+7, 0x38+7, 0x38+7,
  297.  0x38, 0x38, 0x38, 0x38, 0x38+7, 0x38+7, 0x38+7, 0x38+7,
  298. };
  299.  
  300. static const square rgsqReflectInvertMask[] = { 0, 0x38 };
  301.  
  302. /* useful macros */
  303.  
  304. #define TbRow(sq)               ((sq) >> 3)
  305. #define TbColumn(sq)            ((sq) & 7)
  306.  
  307. #if defined (NEW)
  308. #  define   PchExt(side) ((x_colorWhite == side) ? ".nbw" : ".nbb")
  309. #else
  310. #  define   PchExt(side) ((x_colorWhite == side) ? ".tbw" : ".tbb")
  311. #endif
  312.  
  313. // Verbose levels
  314.  
  315. static bool     fPrint = false;     // Print some technical statistics
  316. static bool     fVerbose = false;   // Print additional information
  317.  
  318. // Malloc that checks for out-of-memory condition
  319.  
  320. static size_t   cbAllocated;
  321. static int      cOpenFilesAttempts;
  322. static int      cOpenFilesSuceed;
  323.  
  324. static void* PvMalloc
  325.     (
  326.     size_t cb
  327.     )
  328.     {
  329.     void    *pv;
  330.  
  331.     pv = malloc (cb);
  332.     if (NULL == pv)
  333.         {
  334.         printf ("*** Cannot allocate %lu bytes of memory\n", cb);
  335.         exit (1);
  336.         }
  337.     cbAllocated += cb;
  338.     return pv;
  339.     }
  340.  
  341. #if defined (NEW)   // New index schema ----------------------------------------
  342.  
  343. // 'Invalid' value have to be large, so index
  344. // of invalid position will be very large, too.
  345.  
  346. #define INF 4000
  347.  
  348. // Enumeration: valid positions with 2 kings on board; white king restricted to
  349. // a1-d1-d4 triangle; also, if it's at a1-d4 half-diagonal, then black king
  350. // must be in a1-h1-h8 triangle// Enumeration: all valid positions with 2 kings on board when white king
  351. // restricted to left half of the board// Useful macro and enumeration tables
  352.  
  353. #define IndTriKings(sqk1,sqk2)  ((unsigned) rgsTriKings[sqk1*64+sqk2])
  354. #define IndHalfKings(sqk1,sqk2) ((unsigned) rgsHalfKings[sqk1*64+sqk2])
  355.  
  356. static const bool rgfTriangle[64] =
  357. {
  358.      true,  true,  true,  true,  false, false, false, false,
  359.      false, true,  true,  true,  false, false, false, false,
  360.      false, false, true,  true,  false, false, false, false,
  361.      false, false, false, true,  false, false, false, false,
  362.      false, false, false, false, false, false, false, false,
  363.      false, false, false, false, false, false, false, false,
  364.      false, false, false, false, false, false, false, false,
  365.      false, false, false, false, false, false, false, false,
  366. };
  367.  
  368. static const bool rgfNotDiagonal[64] =
  369. {
  370.      false, true,  true,  true,  true,  true,  true,  true,
  371.      true,  false, true,  true,  true,  true,  true,  true,
  372.      true,  true,  false, true,  true,  true,  true,  true,
  373.      true,  true,  true,  false, true,  true,  true,  true,
  374.      true,  true,  true,  true,  false, true,  true,  true,
  375.      true,  true,  true,  true,  true,  false, true,  true,
  376.      true,  true,  true,  true,  true,  true,  false, true,
  377.      true,  true,  true,  true,  true,  true,  true,  false,
  378. };
  379.  
  380. static const bool rgfInLargeTriangle[64] =
  381. {
  382.      true,  true,  true,  true,  true,  true,  true,  true,
  383.      false, true,  true,  true,  true,  true,  true,  true,
  384.      false, false, true,  true,  true,  true,  true,  true,
  385.      false, false, false, true,  true,  true,  true,  true,
  386.      false, false, false, false, true,  true,  true,  true,
  387.      false, false, false, false, false, true,  true,  true,
  388.      false, false, false, false, false, false, true,  true,
  389.      false, false, false, false, false, false, false, true,
  390. };
  391.  
  392. #define FInTriangle(sqwk,sqbk)  (rgfTriangle[sqwk] & (rgfNotDiagonal[sqwk]|rgfInLargeTriangle[sqbk]))
  393.  
  394. // Sort pieces
  395.  
  396. #define SORT(sq1,sq2)   if (sq1>sq2) { square sqTmp; sqTmp=sq1; sq1=sq2; sq2=sqTmp; }
  397.  
  398. // Exclude occupied squares
  399.  
  400. #define EXCLUDE1(sq,sq1)                         (sq-(sq>sq1))
  401. #define EXCLUDE2(sq,sq1,sq2)                     (sq-((sq>sq1)+(sq>sq2)))
  402. #define EXCLUDE3(sq,sq1,sq2,sq3)                 (sq-((sq>sq1)+(sq>sq2)+(sq>sq3)))
  403. #define EXCLUDE4(sq,sq1,sq2,sq3,sq4)             (sq-((sq>sq1)+(sq>sq2)+(sq>sq3)+(sq>sq4)))
  404. #define EXCLUDE5(sq,sq1,sq2,sq3,sq4,sq5)         (sq-((sq>sq1)+(sq>sq2)+(sq>sq3)+(sq>sq4)+(sq>sq5)))
  405. #define EXCLUDE6(sq,sq1,sq2,sq3,sq4,sq5,sq6)     (sq-((sq>sq1)+(sq>sq2)+(sq>sq3)+(sq>sq4)+(sq>sq5)+(sq>sq6)))
  406. #define EXCLUDE7(sq,sq1,sq2,sq3,sq4,sq5,sq6,sq7) (sq-((sq>sq1)+(sq>sq2)+(sq>sq3)+(sq>sq4)+(sq>sq5)+(sq>sq6)+(sq>sq7)))
  407.  
  408. #if !defined(SWAP)
  409. #define SWAP(sq1, sq2)  {square sq_tmp = sq2; sq2 = sq1; sq1 = sq_tmp;}
  410. #endif
  411.  
  412. // Calculate index - a lot of functions...
  413.  
  414. // Enumeration tables
  415.  
  416. static BYTE     *rgprgsqPiece[6];   // Enumeration for each piece (0 - black pawn)
  417.                                     // For each position of the King, all legal squares
  418.                                     // of the opposite piece enumerated
  419. static BYTE     rgcLegal[6][64];    // # of enumerated positions for each piece and each
  420.                                     // location of enemy king
  421.  
  422. // Enumerations - indexed by [piece] and [kings enumeration].
  423. // In each table for each [piece] and [king enumeration] we store # of preceeding positions.
  424.  
  425. static ULONG    *rgprgulSinglePawnless[6];
  426. static ULONG    *rgprgulPairPawnless[6][6];
  427. #if defined (T41_INCLUDE) || defined (T42_INCLUDE)
  428.   static ULONG  *rgprgulTriplePawnless[6][6][6];
  429. #endif
  430. static ULONG    *rgprgulSinglePawnPresent[6];
  431. static ULONG    *rgprgulPairPawnPresent[6][6];
  432. #if defined (T41_INCLUDE) || defined (T42_INCLUDE)
  433.   static ULONG  *rgprgulTriplePawnPresent[6][6][6];
  434. #endif
  435.  
  436. // Total # of enumerated positions
  437.  
  438. static ULONG    rgcSinglePawnPresent[6];
  439. static ULONG    rgcSinglePawnless[6];
  440. static ULONG    rgcPairPawnPresent[6][6];
  441. static ULONG    rgcPairPawnless[6][6];
  442. #if defined (T41_INCLUDE) || defined (T42_INCLUDE)
  443.   static ULONG  rgcTriplePawnPresent[6][6][6];
  444.   static ULONG  rgcTriplePawnless[6][6][6];
  445. #endif
  446.  
  447. // Infinities. Have to be larger than any legal enumeration yet small enough
  448. // so there will be no overflow when combining them with remaining pieces.
  449.  
  450. #define INF_SINGLE  (110000)
  451. #define INF_PAIR    (6500000)
  452. #define INF_TRIPLE  (500000000)
  453.  
  454. // Initialize squares and counters table for one piece.
  455. // Piece can be x_pieceNone - that means 'pawn of the wrong color', e.g. KPK BTM.
  456.  
  457. static void VInitSquaresTable
  458.     (
  459.     piece   pi,
  460.     BYTE    *prgsqPiece,
  461.     BYTE    *prgcLegal
  462.     )
  463.     {
  464.     int sqLo, sqHi;
  465.  
  466.     memset (prgsqPiece, -1, 64*64);
  467.     sqLo = 0;
  468.     sqHi = 64;
  469.     if (pi <= x_piecePawn)
  470.         {
  471.         sqLo = 8;
  472.         sqHi = 56;
  473.         }
  474.     for (int sqKing = 0; sqKing < 64; sqKing ++)
  475.         {
  476.         int iPiece;
  477.  
  478.         iPiece = 0;
  479.         for (int sq = sqLo; sq < sqHi; sq ++)
  480.             {
  481.             if (sq == sqKing)
  482.                 continue;
  483.             switch (pi)
  484.                 {
  485.             case x_piecePawn:
  486.                 if (
  487.                     (0 != TbColumn (sq) && sqKing == sq+7) ||
  488.                     (7 != TbColumn (sq) && sqKing == sq+9)
  489.                    )
  490.                    continue;
  491.                 break;
  492.             case x_pieceKnight:
  493.                 if (
  494.                     (TbRow (sq) >= 2 && TbColumn (sq) >= 1 && sqKing == sq-17) ||
  495.                     (TbRow (sq) >= 2 && TbColumn (sq) <= 6 && sqKing == sq-15) ||
  496.                     (TbRow (sq) >= 1 && TbColumn (sq) >= 2 && sqKing == sq-10) ||
  497.                     (TbRow (sq) >= 1 && TbColumn (sq) <= 5 && sqKing == sq-6) ||
  498.                     (TbRow (sq) <= 6 && TbColumn (sq) >= 2 && sqKing == sq+6) ||
  499.                     (TbRow (sq) <= 6 && TbColumn (sq) <= 5 && sqKing == sq+10) ||
  500.                     (TbRow (sq) <= 5 && TbColumn (sq) >= 1 && sqKing == sq+15) ||
  501.                     (TbRow (sq) <= 5 && TbColumn (sq) <= 6 && sqKing == sq+17)
  502.                    )
  503.                     continue;
  504.                 break;
  505.             case x_pieceBishop:
  506.                 if (
  507.                     (0 != TbRow (sq) && 0 != TbColumn (sq) && sqKing == sq-9) ||
  508.                     (0 != TbRow (sq) && 7 != TbColumn (sq) && sqKing == sq-7) ||
  509.                     (7 != TbRow (sq) && 0 != TbColumn (sq) && sqKing == sq+7) ||
  510.                     (7 != TbRow (sq) && 7 != TbColumn (sq) && sqKing == sq+9)
  511.                    )
  512.                     continue;
  513.                 break;
  514.             case x_pieceRook:
  515.                 if (
  516.                     (0 != TbColumn (sq) && sqKing == sq-1) ||
  517.                     (7 != TbColumn (sq) && sqKing == sq+1) ||
  518.                     (0 != TbRow (sq) && sqKing == sq-8) ||
  519.                     (7 != TbRow (sq) && sqKing == sq+8)
  520.                    )
  521.                     continue;
  522.                 break;
  523.             case x_pieceQueen:
  524.                 if (
  525.                     (0 != TbColumn (sq) && sqKing == sq-1) ||
  526.                     (7 != TbColumn (sq) && sqKing == sq+1) ||
  527.                     (0 != TbRow (sq) && sqKing == sq-8) ||
  528.                     (7 != TbRow (sq) && sqKing == sq+8) ||
  529.                     (0 != TbRow (sq) && 0 != TbColumn (sq) && sqKing == sq-9) ||
  530.                     (0 != TbRow (sq) && 7 != TbColumn (sq) && sqKing == sq-7) ||
  531.                     (7 != TbRow (sq) && 0 != TbColumn (sq) && sqKing == sq+7) ||
  532.                     (7 != TbRow (sq) && 7 != TbColumn (sq) && sqKing == sq+9)
  533.                    )
  534.                     continue;
  535.                 break;
  536.                 }
  537.             prgsqPiece[sqKing*64+sq] = (BYTE) iPiece;
  538.             iPiece ++;
  539.             }
  540.         prgcLegal[sqKing] = (BYTE) iPiece;
  541.         }
  542.     }
  543.  
  544. // Initialize enumeration table for single piece
  545.  
  546. static void VInitSingle
  547.     (
  548.     ULONG       *prgIndex,
  549.     const short *prgsKings,
  550.     const BYTE  *prgcLegal,
  551.     const BYTE  *prgsqPiece,
  552.     ULONG       *pcEnumeration
  553.     )
  554.     {
  555.     ULONG iIndex;
  556.  
  557.     iIndex = 0;
  558.     for (int sqKing1 = 0; sqKing1 < 64; sqKing1 ++)
  559.         for (int sqKing2 = 0; sqKing2 < 64; sqKing2 ++)
  560.             {
  561.             if (INF != prgsKings[sqKing1*64+sqKing2])
  562.                 {
  563.                 prgIndex[prgsKings[sqKing1*64+sqKing2]] = iIndex;
  564.                 iIndex += prgcLegal[sqKing2] - ((BYTE) -1 != prgsqPiece[sqKing2*64+sqKing1]);
  565.                 }
  566.             }
  567.     *pcEnumeration = iIndex;
  568.     }
  569.  
  570. // Initialize enumeration table for pair of pieces
  571.  
  572. static void VInitPair
  573.     (
  574.     ULONG       *prgIndex,
  575.     const short *prgsKings,
  576.     const BYTE  *prgcLegal1,
  577.     const BYTE  *prgsqPiece1,
  578.     const BYTE  *prgcLegal2,
  579.     const BYTE  *prgsqPiece2,
  580.     ULONG       *pcEnumeration
  581.     )
  582.     {
  583.     ULONG iIndex;
  584.     ULONG cPositions1, cPositions2;
  585.  
  586.     iIndex = 0;
  587.     for (int sqKing1 = 0; sqKing1 < 64; sqKing1 ++)
  588.         for (int sqKing2 = 0; sqKing2 < 64; sqKing2 ++)
  589.             {
  590.             if (INF != prgsKings[sqKing1*64+sqKing2])
  591.                 {
  592.                 prgIndex[prgsKings[sqKing1*64+sqKing2]] = iIndex;
  593.                 cPositions1 = prgcLegal1[sqKing2] - ((BYTE) -1 != prgsqPiece1[sqKing2*64+sqKing1]);
  594.                 if (prgcLegal1 == prgcLegal2)
  595.                     iIndex += cPositions1*(cPositions1-1)/2;
  596.                 else
  597.                     {
  598.                     cPositions2 = prgcLegal2[sqKing2] - ((BYTE) -1 != prgsqPiece2[sqKing2*64+sqKing1]);
  599.                     iIndex += cPositions1*cPositions2;
  600.                     }
  601.                 }
  602.             }
  603.     *pcEnumeration = iIndex;
  604.     }
  605.  
  606. #if defined (T41_INCLUDE) || defined (T42_INCLUDE)
  607.  
  608. // Initialize enumeration table for triple piece
  609.  
  610. static void VInitTriple
  611.     (
  612.     ULONG       *prgIndex,
  613.     const short *prgsKings,
  614.     const BYTE  *prgcLegal1,
  615.     const BYTE  *prgsqPiece1,
  616.     const BYTE  *prgcLegal2,
  617.     const BYTE  *prgsqPiece2,
  618.     const BYTE  *prgcLegal3,
  619.     const BYTE  *prgsqPiece3,
  620.     ULONG       *pcEnumeration
  621.     )
  622.     {
  623.     ULONG iIndex;
  624.     ULONG cPositions1, cPositions2, cPositions3;
  625.  
  626.     iIndex = 0;
  627.     for (int sqKing1 = 0; sqKing1 < 64; sqKing1 ++)
  628.         for (int sqKing2 = 0; sqKing2 < 64; sqKing2 ++)
  629.             {
  630.             if (INF != prgsKings[sqKing1*64+sqKing2])
  631.                 {
  632.                 prgIndex[prgsKings[sqKing1*64+sqKing2]] = iIndex;
  633.                 cPositions1 = prgcLegal1[sqKing2] - ((BYTE) -1 != prgsqPiece1[sqKing2*64+sqKing1]);
  634.                 if (prgcLegal1 == prgcLegal2 && prgcLegal2 == prgcLegal3)
  635.                     iIndex += cPositions1*(cPositions1-1)*(cPositions1-2)/6;
  636.                 else if (prgcLegal1 == prgcLegal2)
  637.                     {
  638.                     cPositions3 = prgcLegal3[sqKing2] - ((BYTE) -1 != prgsqPiece3[sqKing2*64+sqKing1]);
  639.                     iIndex += cPositions1*(cPositions1-1)/2*cPositions3;
  640.                     }
  641.                 else if (prgcLegal2 == prgcLegal3)
  642.                     {
  643.                     cPositions2 = prgcLegal2[sqKing2] - ((BYTE) -1 != prgsqPiece2[sqKing2*64+sqKing1]);
  644.                     iIndex += cPositions1*cPositions2*(cPositions2-1)/2;
  645.                     }
  646.                 else
  647.                     {
  648.                     cPositions2 = prgcLegal2[sqKing2] - ((BYTE) -1 != prgsqPiece2[sqKing2*64+sqKing1]);
  649.                     cPositions3 = prgcLegal3[sqKing2] - ((BYTE) -1 != prgsqPiece3[sqKing2*64+sqKing1]);
  650.                     iIndex += cPositions1*cPositions2*cPositions3;
  651.                     }
  652.                 }
  653.             }
  654.     *pcEnumeration = iIndex;
  655.     }
  656.  
  657. #endif
  658.  
  659. // Initialize all Enumeration tables
  660.  
  661. static bool fEnumerationInitted = false;
  662.  
  663. static void VInitEnumerations (void)
  664.     {
  665.     piece   pi1;
  666.     piece   pi2;
  667. #if defined (T41_INCLUDE) || defined (T42_INCLUDE)
  668.     piece   pi3;
  669. #endif
  670.  
  671.     if (fEnumerationInitted)
  672.         return;
  673.     fEnumerationInitted = true;
  674.     // Initialize square tables
  675.     for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
  676.         {
  677.         rgprgsqPiece[pi1] = (BYTE *) PvMalloc (64*64);
  678.         VInitSquaresTable (pi1, rgprgsqPiece[pi1], rgcLegal[pi1]);
  679.         }
  680.  
  681.     for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
  682.         {
  683.         // Initialize enumeration tables for single piece
  684.         rgprgulSinglePawnPresent[pi1] = (ULONG *) PvMalloc (1806*sizeof (ULONG));
  685.         VInitSingle (rgprgulSinglePawnPresent[pi1], rgsHalfKings,
  686.                      rgcLegal[pi1], rgprgsqPiece[pi1], &rgcSinglePawnPresent[pi1]);
  687.         if (pi1 > x_piecePawn)
  688.             {
  689.             rgprgulSinglePawnless[pi1] = (ULONG *) PvMalloc (462*sizeof (ULONG));
  690.             VInitSingle (rgprgulSinglePawnless[pi1], rgsTriKings,
  691.                          rgcLegal[pi1], rgprgsqPiece[pi1], &rgcSinglePawnless[pi1]);
  692.             }
  693.         // Initialize enumeration tables for pair of pieces
  694.         for (pi2 = (x_pieceNone == pi1 ? x_pieceNone : x_piecePawn); pi2 <= pi1; pi2 = (piece) (pi2 + 1))
  695.             {
  696.             rgprgulPairPawnPresent[pi1][pi2] = (ULONG *) PvMalloc (1806*sizeof (ULONG));
  697.             VInitPair (rgprgulPairPawnPresent[pi1][pi2], rgsHalfKings,
  698.                        rgcLegal[pi1], rgprgsqPiece[pi1], rgcLegal[pi2], rgprgsqPiece[pi2],
  699.                        &rgcPairPawnPresent[pi1][pi2]);
  700.             if (pi1 > x_piecePawn && pi2 > x_piecePawn)
  701.                 {
  702.                 rgprgulPairPawnless[pi1][pi2] = (ULONG *) PvMalloc (462*sizeof (ULONG));
  703.                 VInitPair (rgprgulPairPawnless[pi1][pi2], rgsTriKings,
  704.                            rgcLegal[pi1], rgprgsqPiece[pi1], rgcLegal[pi2], rgprgsqPiece[pi2],
  705.                            &rgcPairPawnless[pi1][pi2]);
  706.                 }
  707. #if defined (T41_INCLUDE) || defined (T42_INCLUDE)
  708.             // Initialize enumeration tables for three pieces
  709.             for (pi3 = (x_pieceNone == pi1 ? x_pieceNone : x_piecePawn); pi3 <= pi2; pi3 = (piece) (pi3 + 1))
  710.                 {
  711.                 if (pi1 <= x_piecePawn || pi2 <= x_piecePawn || pi3 <= x_piecePawn)
  712.                     {
  713.                     rgprgulTriplePawnPresent[pi1][pi2][pi3] = (ULONG *) PvMalloc (1806*sizeof (ULONG));
  714.                     VInitTriple (rgprgulTriplePawnPresent[pi1][pi2][pi3], rgsHalfKings,
  715.                                  rgcLegal[pi1], rgprgsqPiece[pi1],
  716.                                  rgcLegal[pi2], rgprgsqPiece[pi2],
  717.                                  rgcLegal[pi3], rgprgsqPiece[pi3],
  718.                                  &rgcTriplePawnPresent[pi1][pi2][pi3]);
  719.                     }
  720.                 else
  721.                     {
  722.                     rgprgulTriplePawnless[pi1][pi2][pi3] = (ULONG *) PvMalloc (462*sizeof (ULONG));
  723.                     VInitTriple (rgprgulTriplePawnless[pi1][pi2][pi3], rgsTriKings,
  724.                         rgcLegal[pi1], rgprgsqPiece[pi1],
  725.                         rgcLegal[pi2], rgprgsqPiece[pi2],
  726.                         rgcLegal[pi3], rgprgsqPiece[pi3],
  727.                         &rgcTriplePawnless[pi1][pi2][pi3]);
  728. #if defined (T42_INCLUDE)
  729.                     rgprgulTriplePawnPresent[pi1][pi2][pi3] = (ULONG *) PvMalloc (1806*sizeof (ULONG));
  730.                     VInitTriple (rgprgulTriplePawnPresent[pi1][pi2][pi3], rgsHalfKings,
  731.                                  rgcLegal[pi1], rgprgsqPiece[pi1],
  732.                                  rgcLegal[pi2], rgprgsqPiece[pi2],
  733.                                  rgcLegal[pi3], rgprgsqPiece[pi3],
  734.                                  &rgcTriplePawnPresent[pi1][pi2][pi3]);
  735. #endif
  736.                     }
  737.                 }
  738. #endif
  739.             }
  740.         }
  741.  
  742.     // All done!
  743.     if (fPrint)
  744.         {
  745.         for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
  746.             printf ("%c - %lud enumerated positions\n", "pPNBRQ"[pi1], rgcSinglePawnPresent[pi1]);
  747.         for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
  748.             {
  749.             if (0 != rgcSinglePawnless[pi1])
  750.                 printf ("pawnless %c - %lud enumerated positions\n", "pPNBRQ"[pi1], rgcSinglePawnless[pi1]);
  751.             }
  752.         for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
  753.             for (pi2 = x_pieceNone; pi2 <= pi1; pi2 = (piece) (pi2 + 1))
  754.                 {
  755.                 if (0 != rgcPairPawnPresent[pi1][pi2])
  756.                     printf ("%c%c - %lu enumerated positions\n", "pPNBRQ"[pi1], "pPNBRQ"[pi2],
  757.                             rgcPairPawnPresent[pi1][pi2]);
  758.                 }
  759.         for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
  760.             for (pi2 = x_pieceNone; pi2 <= pi1; pi2 = (piece) (pi2 + 1))
  761.                 {
  762.                 if (0 != rgcPairPawnless[pi1][pi2])
  763.                     printf ("pawnless %c%c - %lu enumerated positions\n", "pPNBRQ"[pi1], "pPNBRQ"[pi2],
  764.                             rgcPairPawnless[pi1][pi2]);
  765.                 }
  766. #if defined (T41_INCLUDE) || defined (T42_INCLUDE)
  767.         for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
  768.             for (pi2 = x_pieceNone; pi2 <= pi1; pi2 = (piece) (pi2 + 1))
  769.                 for (pi3 = x_pieceNone; pi3 <= pi2; pi3 = (piece) (pi3 + 1))
  770.                     {
  771.                     if (0 != rgcTriplePawnPresent[pi1][pi2][pi3])
  772.                         printf ("%c%c%c - %lu enumerated positions\n",
  773.                                 "pPNBRQ"[pi1], "pPNBRQ"[pi2], "pPNBRQ"[pi3],
  774.                                 rgcTriplePawnPresent[pi1][pi2][pi3]);
  775.                     }
  776.         for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
  777.             for (pi2 = x_pieceNone; pi2 <= pi1; pi2 = (piece) (pi2 + 1))
  778.                 for (pi3 = x_pieceNone; pi3 <= pi2; pi3 = (piece) (pi3 + 1))
  779.                     {
  780.                     if (0 != rgcTriplePawnless[pi1][pi2][pi3])
  781.                         printf ("pawnless %c%c%c - %lu enumerated positions\n",
  782.                                 "pPNBRQ"[pi1], "pPNBRQ"[pi2], "pPNBRQ"[pi3],
  783.                                 rgcTriplePawnless[pi1][pi2][pi3]);
  784.                     }
  785. #endif
  786.         printf ("\nAllocated %luk\n\n", (cbAllocated + 1023)/1024);
  787.         }
  788.     }
  789.  
  790. // Return enumeration of 2 kings and single piece
  791.  
  792. template <int piw1, bool fPawns, bool fInvert> class TEnumerate1
  793.     {
  794. public:
  795.     static INLINE unsigned TB_FASTCALL Index
  796.         (
  797.         square  sqwk,
  798.         square  sqw1,
  799.         square  sqbk
  800.         )
  801.         {
  802.         unsigned ind;
  803.         ULONG    ulKings;
  804.  
  805.         // For black pawn invert the board
  806.         if (piw1 <= x_piecePawn && fInvert)
  807.             {
  808.             sqwk = reflect_x(sqwk);
  809.             sqw1 = reflect_x(sqw1);
  810.             sqbk = reflect_x(sqbk);
  811.             }
  812.        
  813.         // Get enumerated square
  814.         ind = rgprgsqPiece[piw1][sqbk*64+sqw1];
  815. #if defined (ILLEGAL_POSSIBLE)
  816.         if ((BYTE) -1 == ind)
  817.             return INF_SINGLE;
  818. #endif
  819.         // Get enumerated position of both kings
  820.         if (fPawns)
  821.             ulKings = rgsHalfKings[sqwk*64+sqbk];   // 0..1805
  822.         else
  823.             ulKings = rgsTriKings[sqwk*64+sqbk];    // 0..461
  824. #if defined (ILLEGAL_POSSIBLE)
  825.         if (INF == ulKings)
  826.             return INF_SINGLE;
  827. #endif
  828.         // Can we remove one extra square?
  829.         if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk]))
  830.             ind -= (sqw1 > sqwk);
  831.         // Add enumerated square to the # of the preceeding positions
  832.         return ind + (fPawns ? rgprgulSinglePawnPresent[piw1][ulKings] : rgprgulSinglePawnless[piw1][ulKings]);
  833.         }
  834.     };
  835.  
  836. // Return enumeration of 2 kings and 2 pieces
  837.  
  838. template <int piw1, int piw2, bool fPawns, bool fInvert> class TEnumerate2
  839.     {
  840. public:
  841.     static INLINE unsigned TB_FASTCALL Index
  842.         (
  843.         square  sqwk,
  844.         square  sqw1,
  845.         square  sqw2,
  846.         square  sqbk
  847.         )
  848.         {
  849.         unsigned ind1, ind2, cInd2;
  850.         ULONG    ulKings;
  851.  
  852.         // For black pawn invert the board
  853.         if (piw2 <= x_piecePawn && fInvert)
  854.             {
  855.             sqwk = reflect_x(sqwk);
  856.             sqw1 = reflect_x(sqw1);
  857.             sqw2 = reflect_x(sqw2);
  858.             sqbk = reflect_x(sqbk);
  859.             }
  860.        
  861.         // Get enumerated squares for both pieces
  862.         if (piw1 == piw2)
  863.             SORT (sqw1, sqw2);
  864.         ind1 = rgprgsqPiece[piw1][sqbk*64+sqw1];
  865.         ind2 = rgprgsqPiece[piw2][sqbk*64+sqw2];
  866. #if defined (ILLEGAL_POSSIBLE)
  867.         if ((BYTE) -1 == ind1 || (BYTE) -1 == ind2)
  868.             return INF_PAIR;
  869. #endif
  870.         // Get enumerated position of both kings
  871.         if (fPawns)
  872.             ulKings = rgsHalfKings[sqwk*64+sqbk];   // 0..1805
  873.         else
  874.             ulKings = rgsTriKings[sqwk*64+sqbk];    // 0..461
  875. #if defined (ILLEGAL_POSSIBLE)
  876.         if (INF == ulKings)
  877.             return INF_PAIR;
  878. #endif
  879.         if (piw1 == piw2)
  880.             {
  881.             // Can we remove one extra square?
  882.             if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk]))
  883.                 {
  884.                 ind1 -= (sqw1 > sqwk);
  885.                 ind2 -= (sqw2 > sqwk);
  886.                 }
  887.             // Add enumerated squares to the # of the preceeding positions
  888.             return  ind2*(ind2-1)/2 + ind1 +
  889.                     (fPawns ? rgprgulPairPawnPresent[piw1][piw2][ulKings] : rgprgulPairPawnless[piw1][piw2][ulKings]);
  890.             }
  891.         else
  892.             {
  893.             // Can we remove WK square from 1st piece Enumeration?
  894.             if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk]))
  895.                 ind1 -= (sqw1 > sqwk);
  896.             // Get # of enumerated positions of 2nd piece
  897.             cInd2 = rgcLegal[piw2][sqbk];
  898.             // Can we remove WK square from 2nd piece Enumeration?
  899.             if ((piw2>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw2][sqbk*64+sqwk]))
  900.                 {
  901.                 cInd2 --;
  902.                 ind2 -= (sqw2 > sqwk);
  903.                 }
  904.             // Add enumerated square to the # of the preceeding positions
  905.             return cInd2*ind1 + ind2 + (fPawns ? rgprgulPairPawnPresent[piw1][piw2][ulKings] : rgprgulPairPawnless[piw1][piw2][ulKings]);
  906.             }
  907.         }
  908.     };
  909.  
  910. #if defined (T41_INCLUDE) || defined (T42_INCLUDE)
  911.  
  912. // Return enumeration of 2 kings and 3 pieces
  913.  
  914. template <int piw1, int piw2, int piw3, bool fPawns, bool fInvert> class TEnumerate3
  915.     {
  916. public:
  917.     static INLINE unsigned TB_FASTCALL Index
  918.         (
  919.         square  sqwk,
  920.         square  sqw1,
  921.         square  sqw2,
  922.         square  sqw3,
  923.         square  sqbk
  924.         )
  925.         {
  926.         unsigned ind1, ind2, ind3, cInd1, cInd2, cInd3;
  927.         ULONG    ulKings;
  928.  
  929.         // For black pawn invert the board
  930.         if (piw3 <= x_piecePawn && fInvert)
  931.             {
  932.             sqwk = reflect_x(sqwk);
  933.             sqw1 = reflect_x(sqw1);
  934.             sqw2 = reflect_x(sqw2);
  935.             sqw3 = reflect_x(sqw3);
  936.             sqbk = reflect_x(sqbk);
  937.             }
  938.        
  939.         // Get enumerated squares for all pieces
  940.         if (piw1 == piw2 && piw1 == piw3)
  941.             {
  942.             SORT (sqw1, sqw2);
  943.             SORT (sqw2, sqw3);
  944.             SORT (sqw1, sqw2);
  945.             }
  946.         else if (piw1 == piw2)
  947.             {
  948.             SORT (sqw1, sqw2);
  949.             }
  950.         else if (piw2 == piw3)
  951.             {
  952.             SORT (sqw2, sqw3);
  953.             }
  954.         ind1 = rgprgsqPiece[piw1][sqbk*64+sqw1];
  955.         ind2 = rgprgsqPiece[piw2][sqbk*64+sqw2];
  956.         ind3 = rgprgsqPiece[piw3][sqbk*64+sqw3];
  957. #if defined (ILLEGAL_POSSIBLE)
  958.         if ((BYTE) -1 == ind1 || (BYTE) -1 == ind2 || (BYTE) -1 == ind3)
  959.             return INF_TRIPLE;
  960. #endif
  961.         // Get enumerated position of both kings
  962.         if (fPawns)
  963.             ulKings = rgsHalfKings[sqwk*64+sqbk];   // 0..1805
  964.         else
  965.             ulKings = rgsTriKings[sqwk*64+sqbk];    // 0..461
  966. #if defined (ILLEGAL_POSSIBLE)
  967.         if (INF == ulKings)
  968.             return INF_TRIPLE;
  969. #endif
  970.         if (piw1 == piw2 && piw2 == piw3)
  971.             {
  972.             // Can we remove one extra square?
  973.             if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk]))
  974.                 {
  975.                 ind1 -= (sqw1 > sqwk);
  976.                 ind2 -= (sqw2 > sqwk);
  977.                 ind3 -= (sqw3 > sqwk);
  978.                 }
  979.             // Add enumerated squares to the # of the preceeding positions
  980.             return  ind3*(ind3-1)*(ind3-2)/6 + ind2*(ind2-1)/2 + ind1 +
  981.                     (fPawns ? rgprgulTriplePawnPresent[piw1][piw2][piw3][ulKings] :
  982.                               rgprgulTriplePawnless[piw1][piw2][piw3][ulKings]);
  983.             }
  984.         else if (piw1 == piw2)
  985.             {
  986.             // Can we remove one extra square?
  987.             if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk]))
  988.                 {
  989.                 ind1 -= (sqw1 > sqwk);
  990.                 ind2 -= (sqw2 > sqwk);
  991.                 }
  992.             // Get # of enumerated positions of 3rd piece
  993.             cInd3 = rgcLegal[piw3][sqbk];
  994.             // Can we remove WK square from 3rd piece Enumeration?
  995.             if ((piw3>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw3][sqbk*64+sqwk]))
  996.                 {
  997.                 cInd3 --;
  998.                 ind3 -= (sqw3 > sqwk);
  999.                 }
  1000.             // Add enumerated squares to the # of the preceeding positions
  1001.             return  (ind2*(ind2-1)/2 + ind1)*cInd3 + ind3 +
  1002.                     (fPawns ? rgprgulTriplePawnPresent[piw1][piw2][piw3][ulKings] :
  1003.                               rgprgulTriplePawnless[piw1][piw2][piw3][ulKings]);
  1004.             }
  1005.         else if (piw2 == piw3)
  1006.             {
  1007.             // Can we remove one extra square?
  1008.             if ((piw2>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw2][sqbk*64+sqwk]))
  1009.                 {
  1010.                 ind2 -= (sqw2 > sqwk);
  1011.                 ind3 -= (sqw3 > sqwk);
  1012.                 }
  1013.             // Get # of enumerated positions of 1st piece
  1014.             cInd1 = rgcLegal[piw1][sqbk];
  1015.             // Can we remove WK square from 3rd piece Enumeration?
  1016.             if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk]))
  1017.                 {
  1018.                 cInd1 --;
  1019.                 ind1 -= (sqw1 > sqwk);
  1020.                 }
  1021.             // Add enumerated squares to the # of the preceeding positions
  1022.             return  (ind3*(ind3-1)/2 + ind2)*cInd1 + ind1 +
  1023.                     (fPawns ? rgprgulTriplePawnPresent[piw1][piw2][piw3][ulKings] :
  1024.                               rgprgulTriplePawnless[piw1][piw2][piw3][ulKings]);
  1025.             }
  1026.         else
  1027.             {
  1028.             // Can we remove WK square from 1st piece Enumeration?
  1029.             if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk]))
  1030.                 ind1 -= (sqw1 > sqwk);
  1031.             // Get # of enumerated positions of 2nd piece
  1032.             cInd2 = rgcLegal[piw2][sqbk];
  1033.             // Can we remove WK square from 2nd piece Enumeration?
  1034.             if ((piw2>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw2][sqbk*64+sqwk]))
  1035.                 {
  1036.                 cInd2 --;
  1037.                 ind2 -= (sqw2 > sqwk);
  1038.                 }
  1039.             // Get # of enumerated positions of 3rd piece
  1040.             cInd3 = rgcLegal[piw3][sqbk];
  1041.             // Can we remove WK square from 3rd piece Enumeration?
  1042.             if ((piw3>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw3][sqbk*64+sqwk]))
  1043.                 {
  1044.                 cInd3 --;
  1045.                 ind3 -= (sqw3 > sqwk);
  1046.                 }
  1047.             // Add enumerated square to the # of the preceeding positions
  1048.             return  cInd3*(cInd2*ind1 + ind2) + ind3 +
  1049.                     (fPawns ? rgprgulTriplePawnPresent[piw1][piw2][piw3][ulKings] :
  1050.                               rgprgulTriplePawnless[piw1][piw2][piw3][ulKings]);
  1051.             }
  1052.         }
  1053.     };
  1054.  
  1055. #endif
  1056.  
  1057. // Enumerate en passant captures
  1058.  
  1059. static INLINE unsigned TB_FASTCALL IndEnPassant11W
  1060.     (
  1061.     square  sqw,
  1062.     square  sqb,
  1063.     square  sqEnP
  1064.     )
  1065.     {
  1066.     assert (sqb+8 == sqEnP);
  1067.     if (sqw+7 == sqEnP)
  1068.         // Capture to the left
  1069.         return  (sqw&7)-1;
  1070.     else
  1071.         {
  1072.         // Capture to the right
  1073.         assert (sqw+9 == sqEnP);
  1074.         return  (sqw&7)+7;
  1075.         }
  1076.     }
  1077.  
  1078. static INLINE unsigned TB_FASTCALL IndEnPassant11B
  1079.     (
  1080.     square  sqw,
  1081.     square  sqb,
  1082.     square  sqEnP
  1083.     )
  1084.     {
  1085.     assert (sqw-8 == sqEnP);
  1086.     if (sqb-9 == sqEnP)
  1087.         // Capture to the left
  1088.         return (sqb&7)-1;
  1089.     else
  1090.         {
  1091.         // Capture to the right
  1092.         assert (sqb-7 == sqEnP);
  1093.         return (sqb&7)+7;
  1094.         }
  1095.     }
  1096.  
  1097. static INLINE unsigned TB_FASTCALL IndEnPassant21W
  1098.     (
  1099.     square  sqw1,
  1100.     square  sqw2,
  1101.     square  sqb,
  1102.     square  sqEnP
  1103.     )
  1104.     {
  1105.     assert (sqb+8 == sqEnP);
  1106.     SORT (sqw1, sqw2);
  1107.     if (sqw1+7 == sqEnP && 0 != TbColumn(sqw1))
  1108.         // Capture to the left
  1109.         return (sqw1&7)-1+(EXCLUDE3(sqw2,sqb,sqEnP,sqEnP+8)-i8-1)*i14;
  1110.     else if (sqw1+9 == sqEnP && 7 != TbColumn(sqw1))
  1111.         // Capture to the right
  1112.         return (sqw1&7)+7+(EXCLUDE3(sqw2,sqb,sqEnP,sqEnP+8)-i8-1)*i14;
  1113.     else if (sqw2+7 == sqEnP && 0 != TbColumn(sqw2))
  1114.         // Capture to the left
  1115.         return (sqw2&7)-1+(EXCLUDE3(sqw1,sqb,sqEnP,sqEnP+8)-i8)*i14;
  1116.     else
  1117.         {
  1118.         // Capture to the right
  1119.         assert (sqw2+9 == sqEnP && 7 != TbColumn(sqw2));
  1120.         return (sqw2&7)+7+(EXCLUDE3(sqw1,sqb,sqEnP,sqEnP+8)-i8)*i14;
  1121.         }
  1122.     }
  1123.  
  1124. static INLINE unsigned TB_FASTCALL IndEnPassant21B
  1125.     (
  1126.     square  sqw1,
  1127.     square  sqw2,
  1128.     square  sqb,
  1129.     square  sqEnP
  1130.     )
  1131.     {
  1132.     assert (sqw1 < sqw2);   // Must be already sorted
  1133.     if (sqb-9 == sqEnP && 0 != TbColumn(sqb))
  1134.         // Capture to the left
  1135.         if (sqw1-8 == sqEnP)
  1136.             return (sqb&7)-1+(EXCLUDE3(sqw2,sqb,sqEnP,sqEnP-8)-i8-1)*i14;
  1137.         else
  1138.             {
  1139.             assert (sqw2-8 == sqEnP);
  1140.             return (sqb&7)-1+(EXCLUDE3(sqw1,sqb,sqEnP,sqEnP-8)-i8)*i14;
  1141.             }
  1142.     else
  1143.         {
  1144.         // Capture to the right
  1145.         assert (sqb-7 == sqEnP && 7 != TbColumn(sqb));
  1146.         if (sqw1-8 == sqEnP)
  1147.             return (sqb&7)+7+(EXCLUDE3(sqw2,sqb,sqEnP,sqEnP-8)-i8-1)*i14;
  1148.         else
  1149.             {
  1150.             assert (sqw2-8 == sqEnP);
  1151.             return (sqb&7)+7+(EXCLUDE3(sqw1,sqb,sqEnP,sqEnP-8)-i8)*i14;
  1152.             }
  1153.         }
  1154.     }
  1155.  
  1156. static INLINE unsigned TB_FASTCALL IndEnPassant12W
  1157.     (
  1158.     square  sqw,
  1159.     square  sqb1,
  1160.     square  sqb2,
  1161.     square  sqEnP
  1162.     )
  1163. {
  1164.     if(sqb2+8 == sqEnP)
  1165.         SWAP(sqb1, sqb2);
  1166.  
  1167.     assert(sqb1+8 == sqEnP);
  1168.  
  1169.     if (sqw+7 == sqEnP && 0 != TbColumn(sqw))
  1170.         // Capture to the left
  1171.         return TbColumn(sqw)-1+(EXCLUDE4(sqb2,sqb1,sqw,sqEnP,sqEnP+8)-i8)*i14;
  1172.  
  1173.     assert(sqw+9 == sqEnP && 7 != TbColumn(sqw));
  1174.  
  1175.     // Capture to the right
  1176.     return TbColumn(sqw)+7 + (EXCLUDE4(sqb2,sqb1,sqw,sqEnP,sqEnP+8)-i8)*i14;
  1177. }
  1178.  
  1179. static INLINE unsigned TB_FASTCALL IndEnPassant12B
  1180.     (
  1181.     square  sqw,
  1182.     square  sqb1,
  1183.     square  sqb2,
  1184.     square  sqEnP
  1185.     )
  1186. {
  1187.     assert(sqw-8 == sqEnP);
  1188.  
  1189.     SORT(sqb1, sqb2);
  1190.  
  1191.     if(sqb1-9 == sqEnP && 0 != TbColumn(sqb1))
  1192.         // Capture to the left
  1193.         return TbColumn(sqb1) - 1 + (sqb2-i8-4)*i14;
  1194.     else if(sqb1-7 == sqEnP && 7 != TbColumn(sqb1))
  1195.         // Capture to the right
  1196.         return TbColumn(sqb1) + 7 + (sqb2-i8-4)*i14;
  1197.     else if(sqb2-9 == sqEnP && 0 != TbColumn(sqb2))
  1198.         // Capture to the left
  1199.         return TbColumn(sqb2) - 1 + (EXCLUDE2(sqb1,sqEnP,sqEnP-8)-i8)*i14;
  1200.  
  1201.     // Capture to the right
  1202.     assert(sqb2-7 == sqEnP && 7 != TbColumn(sqb2));
  1203.     return TbColumn(sqb2) + 7 + (EXCLUDE2(sqb1,sqEnP,sqEnP-8)-i8)*i14;
  1204. }
  1205.  
  1206. static INLINE unsigned TB_FASTCALL IndEnPassant22W
  1207.     (
  1208.     square  sqw1,
  1209.     square  sqw2,
  1210.     square  sqb1,
  1211.     square  sqb2,
  1212.     square  sqEnP
  1213.     )
  1214. {
  1215.     square sqEmptyEnP = sqEnP + 8;
  1216.  
  1217.     if(sqb2+8== sqEnP)
  1218.        SWAP(sqb1, sqb2);
  1219.  
  1220.     assert(sqb1+8 == sqEnP);
  1221.  
  1222.     SORT(sqw1, sqw2);
  1223.  
  1224.     if (sqw1+7 == sqEnP && 0 != TbColumn(sqw1))
  1225.             // Capture to the left
  1226.         return TbColumn(sqw1)-1+
  1227.            (EXCLUDE2(sqw2,sqEnP,sqEmptyEnP)-i8-2)*i14+
  1228.            (EXCLUDE5(sqb2,sqb1,sqw1,sqw2,sqEnP,sqEmptyEnP)-i8)*(i14*i44);
  1229.     else if (sqw1+9 == sqEnP && 7 != TbColumn(sqw1))
  1230.             // Capture to the right
  1231.         return TbColumn(sqw1)+7+
  1232.            (EXCLUDE2(sqw2,sqEnP,sqEmptyEnP)-i8-2)*i14+
  1233.            (EXCLUDE5(sqb2,sqb1,sqw1,sqw2,sqEnP,sqEmptyEnP)-i8)*(i14*i44);
  1234.     else if (sqw2+7 == sqEnP && 0 != TbColumn(sqw2))
  1235.             // Capture to the left
  1236.         return TbColumn(sqw2)-1+
  1237.            (sqw1-i8)*i14+
  1238.            (EXCLUDE5(sqb2,sqb1,sqw1,sqw2,sqEnP,sqEmptyEnP)-i8)*(i14*i44);
  1239.  
  1240.     // Capture to the right
  1241.     assert(sqw2+9 == sqEnP && 7 != TbColumn(sqw2));
  1242.     return TbColumn(sqw2)+7+
  1243.            (sqw1-i8)*i14+
  1244.        (EXCLUDE5(sqb2,sqb1,sqw1,sqw2,sqEnP,sqEmptyEnP)-i8)*(i14*i44);
  1245. }
  1246.  
  1247. static INLINE unsigned TB_FASTCALL IndEnPassant22B
  1248.     (
  1249.     square  sqw1,
  1250.     square  sqw2,
  1251.     square  sqb1,
  1252.     square  sqb2,
  1253.     square  sqEnP
  1254.     )
  1255. {
  1256.     square sqEmptyEnP = sqEnP - 8;
  1257.  
  1258.     if(sqw2-8 == sqEnP)
  1259.        SWAP(sqw1, sqw2);
  1260.  
  1261.     assert(sqw1-8 == sqEnP);
  1262.  
  1263.     SORT(sqb1, sqb2);
  1264.  
  1265.     if (sqb1-9 == sqEnP && 0 != TbColumn(sqb1))
  1266.         // Capture to the left
  1267.         return TbColumn(sqb1)-1+
  1268.            (sqb2-i8-4)*i14+
  1269.            (EXCLUDE5(sqw2,sqw1,sqb1,sqb2,sqEnP,sqEmptyEnP)-i8)*(i14*i44);
  1270.     else if (sqb1-7 == sqEnP && 7 != TbColumn(sqb1))
  1271.         // Capture to the right
  1272.         return TbColumn(sqb1)+7+
  1273.            (sqb2-i8-4)*i14+
  1274.            (EXCLUDE5(sqw2,sqw1,sqb1,sqb2,sqEnP,sqEmptyEnP)-i8)*(i14*i44);
  1275.     else if (sqb2-9 == sqEnP && 0 != TbColumn(sqb2))
  1276.         // Capture to the left
  1277.         return TbColumn(sqb2)-1+
  1278.            (EXCLUDE2(sqb1,sqEnP,sqEmptyEnP)-i8)*i14+
  1279.            (EXCLUDE5(sqw2,sqw1,sqb1,sqb2,sqEnP,sqEmptyEnP)-i8)*(i14*i44);
  1280.  
  1281.     // Capture to the right
  1282.     assert(sqb2-7 == sqEnP && 7 != TbColumn(sqb2));
  1283.     return TbColumn(sqb2)+7+
  1284.            (EXCLUDE2(sqb1,sqEnP,sqEmptyEnP)-i8)*i14+
  1285.        (EXCLUDE5(sqw2,sqw1,sqb1,sqb2,sqEnP,sqEmptyEnP)-i8)*(i14*i44);
  1286. }
  1287.  
  1288. static INLINE unsigned TB_FASTCALL IndEnPassant31W
  1289.     (
  1290.     square  sqw1,
  1291.     square  sqw2,
  1292.     square  sqw3,
  1293.     square  sqb,
  1294.     square  sqEnP
  1295.     )
  1296. {
  1297.     square sqEmptyEnP = sqEnP + 8;
  1298.  
  1299.     assert(sqb + 8 == sqEnP);
  1300.  
  1301.     SORT (sqw1, sqw2);
  1302.     SORT (sqw2, sqw3);
  1303.     SORT (sqw1, sqw2);
  1304.  
  1305.     if (sqw1+7 == sqEnP && 0 != TbColumn(sqw1)) {
  1306.         // Capture to the left
  1307.         sqw3 = EXCLUDE2(sqw3,sqEnP,sqEmptyEnP)-i8-2;
  1308.         return TbColumn(sqw1)-1+
  1309.                (EXCLUDE2(sqw2,sqEnP,sqEmptyEnP)-i8-2)*i14+
  1310.                (sqw3*(sqw3-1)/2)*i14;
  1311.         }
  1312.     else if (sqw1+9 == sqEnP && 7 != TbColumn(sqw1)) {
  1313.         // Capture to the right
  1314.         sqw3 = EXCLUDE2(sqw3,sqEnP,sqEmptyEnP)-i8-2;
  1315.         return TbColumn(sqw1)+7+
  1316.                (EXCLUDE2(sqw2,sqEnP,sqEmptyEnP)-i8-2)*i14+
  1317.                (sqw3*(sqw3-1)/2)*i14;
  1318.     }
  1319.     else if (sqw2+7 == sqEnP && 0 != TbColumn(sqw2)) {
  1320.         // Capture to the left
  1321.         sqw3 = EXCLUDE2(sqw3,sqEnP,sqEmptyEnP)-i8-2;
  1322.         return TbColumn(sqw2)-1+
  1323.                (sqw1-i8)*i14+
  1324.                (sqw3*(sqw3-1)/2)*i14;
  1325.     }
  1326.     else if (sqw2+9 == sqEnP && 7 != TbColumn(sqw2)) {
  1327.         // Capture to the right
  1328.         sqw3 = EXCLUDE2(sqw3,sqEnP,sqEmptyEnP)-i8-2;
  1329.         return TbColumn(sqw2)+7+
  1330.                (sqw1-i8)*i14+
  1331.                (sqw3*(sqw3-1)/2)*i14;
  1332.     }
  1333.     else if (sqw3+7 == sqEnP && 0 != TbColumn(sqw3)) {
  1334.         // Capture to the left
  1335.         sqw2 = sqw2-i8;
  1336.         return TbColumn(sqw3)-1+
  1337.                (sqw1-i8)*i14+
  1338.                (sqw2*(sqw2-1)/2)*i14;
  1339.     }
  1340.     else {
  1341.         // Capture to the right
  1342.         sqw2 = sqw2-i8;
  1343.         return TbColumn(sqw3)+7+
  1344.                (sqw1-i8)*i14+
  1345.                (sqw2*(sqw2-1)/2)*i14;
  1346.     }
  1347. }
  1348.  
  1349. static INLINE unsigned TB_FASTCALL IndEnPassant31B
  1350.     (
  1351.     square  sqw1,
  1352.     square  sqw2,
  1353.     square  sqw3,
  1354.     square  sqb,
  1355.     square  sqEnP
  1356.     )
  1357. {
  1358.     square sqEmptyEnP = sqEnP - 8;
  1359.  
  1360.     if(sqw2 - 8 == sqEnP)
  1361.         SWAP(sqw1, sqw2);
  1362.     if(sqw3 - 8 == sqEnP)
  1363.         SWAP(sqw1, sqw3);
  1364.  
  1365.     assert(sqw1 - 8 == sqEnP);
  1366.  
  1367.     SORT(sqw2, sqw3);
  1368.  
  1369.     if(sqb - 9 == sqEnP && 0 != TbColumn(sqb)) {
  1370.         sqw3 = EXCLUDE4(sqw3,sqw1,sqb,sqEnP,sqEmptyEnP)-i8;
  1371.         return TbColumn(sqb)-1+
  1372.         (EXCLUDE4(sqw2,sqw1,sqb,sqEnP,sqEmptyEnP)-i8)*i14+
  1373.         (sqw3*(sqw3-1)/2)*i14;
  1374.     }
  1375.     else {
  1376.         assert(sqb - 7 == sqEnP && 7 != TbColumn(sqb));
  1377.         sqw3 = EXCLUDE4(sqw3,sqw1,sqb,sqEnP,sqEmptyEnP)-i8;
  1378.         return TbColumn(sqb)+7+
  1379.             (EXCLUDE4(sqw2,sqw1,sqb,sqEnP,sqEmptyEnP)-i8)*i14+
  1380.         (sqw3*(sqw3-1)/2)*i14;
  1381.     }
  1382. }
  1383.  
  1384. // Index calculation functions for different endgame classes
  1385.  
  1386. template <int piw1> class T21
  1387.     {
  1388. public:
  1389.     static INDEX TB_FASTCALL IndCalcW
  1390.         (
  1391.         square  *psqW,
  1392.         square  *psqB,
  1393.         square  sqEnP,
  1394.         int     fInvert
  1395.         )
  1396.         {
  1397.         square sqwk, sqw1, sqbk, sqMask;
  1398.  
  1399.         sqwk = SqFindKing (psqW);
  1400.         sqw1 = SqFindOne  (psqW, piw1);
  1401.         sqbk = SqFindKing (psqB);
  1402.  
  1403.         if (x_piecePawn == piw1)
  1404.             sqMask = rgsqReflectMaskY [sqwk] ^ rgsqReflectInvertMask [fInvert];
  1405.         else
  1406.             sqMask = rgsqReflectMaskYandX [sqwk];
  1407.         sqwk ^= sqMask;
  1408.         sqbk ^= sqMask;
  1409.         sqw1 ^= sqMask;
  1410.  
  1411.         if (x_piecePawn != piw1)
  1412.             {
  1413.             // No pawn
  1414.             if (! FInTriangle (sqwk, sqbk))
  1415.                 {
  1416.                 sqwk = reflect_xy(sqwk);
  1417.                 sqbk = reflect_xy(sqbk);
  1418.                 sqw1 = reflect_xy(sqw1);
  1419.                 };
  1420.             }
  1421.         return TEnumerate1<piw1,x_piecePawn==piw1 ? true : false,false>::Index(sqwk,sqw1,sqbk);
  1422.         }
  1423.  
  1424.     static INDEX TB_FASTCALL IndCalcB
  1425.         (
  1426.         square  *psqW,
  1427.         square  *psqB,
  1428.         square  sqEnP,
  1429.         int     fInvert
  1430.         )
  1431.         {
  1432.         square sqwk, sqw1, sqbk, sqMask;
  1433.  
  1434.         sqwk = SqFindKing (psqW);
  1435.         sqw1 = SqFindOne  (psqW, piw1);
  1436.         sqbk = SqFindKing (psqB);
  1437.  
  1438.         if (x_piecePawn == piw1)
  1439.             sqMask = rgsqReflectMaskY [sqbk] ^ rgsqReflectInvertMask [fInvert];
  1440.         else
  1441.             sqMask = rgsqReflectMaskYandX [sqbk];
  1442.         sqwk ^= sqMask;
  1443.         sqbk ^= sqMask;
  1444.         sqw1 ^= sqMask;
  1445.  
  1446.         if (x_piecePawn == piw1)
  1447.             return TEnumerate1<x_pieceNone,true,true>::Index(sqbk,sqw1,sqwk);
  1448.         else
  1449.             {
  1450.             // No pawn
  1451.             if (! FInTriangle (sqbk, sqwk))
  1452.                 {
  1453.                 sqwk = reflect_xy(sqwk);
  1454.                 sqbk = reflect_xy(sqbk);
  1455.                 sqw1 = reflect_xy(sqw1);
  1456.                 };
  1457.             return IndTriKings(sqbk,sqwk)*i62 + EXCLUDE2(sqw1,sqwk,sqbk);
  1458.             }
  1459.         }
  1460.     };
  1461.  
  1462. template <int piw1, int pib1> class T22
  1463.     {
  1464. public:
  1465.     static INDEX TB_FASTCALL IndCalcW
  1466.         (
  1467.         square  *psqW,
  1468.         square  *psqB,
  1469.         square  sqEnP,
  1470.         int     fInvert
  1471.         )
  1472.         {
  1473.         square sqwk, sqw1, sqbk, sqb1, sqMask;
  1474.  
  1475.         sqwk = SqFindKing (psqW);
  1476.         sqw1 = SqFindOne  (psqW, piw1);
  1477.         sqbk = SqFindKing (psqB);
  1478.         sqb1 = SqFindOne  (psqB, pib1);
  1479.  
  1480.         if (x_piecePawn == pib1)
  1481.             sqMask = rgsqReflectMaskY [sqwk] ^ rgsqReflectInvertMask [fInvert];
  1482.         else
  1483.             sqMask = rgsqReflectMaskYandX [sqwk];
  1484.         sqwk ^= sqMask;
  1485.         sqbk ^= sqMask;
  1486.         sqw1 ^= sqMask;
  1487.         sqb1 ^= sqMask;
  1488.  
  1489.         if (x_piecePawn == pib1)
  1490.             {
  1491.             // There are pawns on the board
  1492.             if (x_piecePawn == piw1)
  1493.                 {
  1494.                 // One white and one black pawn
  1495.                 if (XX == sqEnP)
  1496.                     return  TEnumerate1<x_piecePawn,true,false>::Index(sqwk,sqw1,sqbk)*i47 +
  1497.                             EXCLUDE1(sqb1,sqw1)-i8; // 47
  1498.                 else
  1499.                     return  rgcSinglePawnPresent[x_piecePawn]*i47 +
  1500.                             IndHalfKings(sqwk,sqbk)*i14 +
  1501.                             IndEnPassant11W (sqw1, sqb1, sqEnP ^ sqMask);
  1502.                 }
  1503.             else
  1504.                 // Only black pawn
  1505.                 return  TEnumerate1<piw1,true,false>::Index(sqwk,sqw1,sqbk)*i48 + sqb1-i8;
  1506.             }
  1507.         else
  1508.             {
  1509.             // No pawns at all
  1510.             if (!FInTriangle (sqwk, sqbk))
  1511.                 {
  1512.                 sqwk = reflect_xy(sqwk);
  1513.                 sqbk = reflect_xy(sqbk);
  1514.                 sqw1 = reflect_xy(sqw1);
  1515.                 sqb1 = reflect_xy(sqb1);
  1516.                 };
  1517.             return  TEnumerate1<piw1,false,false>::Index(sqwk,sqw1,sqbk)*i61 +
  1518.                     EXCLUDE3(sqb1,sqwk,sqbk,sqw1);  // 61
  1519.             }
  1520.         }
  1521.  
  1522.     static INDEX TB_FASTCALL IndCalcB
  1523.         (
  1524.         square  *psqW,
  1525.         square  *psqB,
  1526.         square  sqEnP,
  1527.         int     fInvert
  1528.         )
  1529.         {
  1530.         square sqwk, sqw1, sqbk, sqb1, sqMask;
  1531.  
  1532.         sqwk = SqFindKing (psqW);
  1533.         sqw1 = SqFindOne  (psqW, piw1);
  1534.         sqbk = SqFindKing (psqB);
  1535.         sqb1 = SqFindOne  (psqB, pib1);
  1536.  
  1537.         if (x_piecePawn == pib1)
  1538.             sqMask = rgsqReflectMaskY [sqbk] ^ rgsqReflectInvertMask [fInvert];
  1539.         else
  1540.             sqMask = rgsqReflectMaskYandX [sqbk];
  1541.         sqwk ^= sqMask;
  1542.         sqbk ^= sqMask;
  1543.         sqw1 ^= sqMask;
  1544.         sqb1 ^= sqMask;
  1545.  
  1546.         if (x_piecePawn == pib1)
  1547.             {
  1548.             // There are pawns on the board
  1549.             if (x_piecePawn == piw1)
  1550.                 {
  1551.                 // One white and one black pawn
  1552.                 if (XX == sqEnP)
  1553.                     return  TEnumerate1<x_piecePawn,true,true>::Index(sqbk,sqb1,sqwk)*i47 +
  1554.                             EXCLUDE1(sqw1,sqb1)-i8; // 47
  1555.                 else
  1556.                     return  rgcSinglePawnPresent[x_piecePawn]*i47 +
  1557.                             IndHalfKings(sqbk,sqwk)*i14 +
  1558.                             IndEnPassant11B (sqw1, sqb1, sqEnP ^ sqMask);
  1559.                 }
  1560.             }
  1561.         else
  1562.             {
  1563.             // No pawns at all
  1564.             if (!FInTriangle (sqbk, sqwk))
  1565.                 {
  1566.                 sqwk = reflect_xy(sqwk);
  1567.                 sqbk = reflect_xy(sqbk);
  1568.                 sqw1 = reflect_xy(sqw1);
  1569.                 sqb1 = reflect_xy(sqb1);
  1570.                 };
  1571.             }
  1572.         return  (x_piecePawn == pib1 ?  TEnumerate1<pib1,true,true>::Index(sqbk,sqb1,sqwk) :
  1573.                                         TEnumerate1<pib1,false,false>::Index(sqbk,sqb1,sqwk))*i61 +
  1574.                 EXCLUDE3(sqw1,sqwk,sqbk,sqb1);  // 61
  1575.         }
  1576.     };
  1577.  
  1578. template <int piw1, int piw2> class T31
  1579.     {
  1580. public:
  1581.     static INDEX TB_FASTCALL IndCalcW
  1582.         (
  1583.         square  *psqW,
  1584.         square  *psqB,
  1585.         square  sqEnP,
  1586.         int     fInvert
  1587.         )
  1588.         {
  1589.         square sqwk, sqw1, sqw2, sqbk, sqMask;
  1590.  
  1591.         sqwk = SqFindKing (psqW);
  1592.         if (piw1 == piw2)
  1593.             {
  1594.             sqw1 = SqFindFirst  (psqW, piw1);
  1595.             sqw2 = SqFindSecond (psqW, piw2);
  1596.             }
  1597.         else
  1598.             {
  1599.             SqFind2 (psqW, piw1, sqw1, piw2, sqw2);
  1600.             }
  1601.         sqbk = SqFindKing (psqB);
  1602.  
  1603.         if (x_piecePawn == piw2)
  1604.             sqMask = rgsqReflectMaskY [sqwk] ^ rgsqReflectInvertMask [fInvert];
  1605.         else
  1606.             sqMask = rgsqReflectMaskYandX [sqwk];
  1607.         sqwk ^= sqMask;
  1608.         sqbk ^= sqMask;
  1609.         sqw1 ^= sqMask;
  1610.         sqw2 ^= sqMask;
  1611.  
  1612.         if (x_piecePawn != piw2)
  1613.             {
  1614.             // There are no pawns on the board
  1615.             if (!FInTriangle (sqwk, sqbk))
  1616.                 {
  1617.                 sqwk = reflect_xy(sqwk);
  1618.                 sqw1 = reflect_xy(sqw1);
  1619.                 sqw2 = reflect_xy(sqw2);
  1620.                 sqbk = reflect_xy(sqbk);
  1621.                 };
  1622.             }
  1623.         return TEnumerate2<piw1, piw2, x_piecePawn==piw2 ? true : false, false>::Index(sqwk, sqw1, sqw2, sqbk);
  1624.         }
  1625.  
  1626.     static INDEX TB_FASTCALL IndCalcB
  1627.         (
  1628.         square  *psqW,
  1629.         square  *psqB,
  1630.         square  sqEnP,
  1631.         int     fInvert
  1632.         )
  1633.         {
  1634.         square sqwk, sqw1, sqw2, sqbk, sqMask;
  1635.  
  1636.         sqwk = SqFindKing (psqW);
  1637.         if (piw1 == piw2)
  1638.             {
  1639.             sqw1 = SqFindFirst (psqW, piw1);
  1640.             sqw2 = SqFindSecond (psqW, piw2);
  1641.             }
  1642.         else
  1643.             {
  1644.             SqFind2 (psqW, piw1, sqw1, piw2, sqw2);
  1645.             }
  1646.         sqbk = SqFindKing (psqB);
  1647.  
  1648.         if (x_piecePawn == piw2)
  1649.             sqMask = rgsqReflectMaskY [sqbk] ^ rgsqReflectInvertMask [fInvert];
  1650.         else
  1651.             sqMask = rgsqReflectMaskYandX [sqbk];
  1652.         sqwk ^= sqMask;
  1653.         sqbk ^= sqMask;
  1654.         sqw1 ^= sqMask;
  1655.         sqw2 ^= sqMask;
  1656.  
  1657.         if (x_piecePawn == piw2)
  1658.             {
  1659.             // There are pawns on the board
  1660.             if (x_piecePawn == piw1)
  1661.                 // Two white pawns
  1662.                 return  TEnumerate2<x_pieceNone,x_pieceNone,true,true>::Index(sqbk,sqw1,sqw2,sqwk);
  1663.             else
  1664.                 // Only one white pawn
  1665.                 return  TEnumerate1<x_pieceNone,true,true>::Index(sqbk,sqw2,sqwk)*i61 +
  1666.                         EXCLUDE3(sqw1,sqwk,sqbk,sqw2);  // 61
  1667.             }
  1668.         else
  1669.             {
  1670.             // No pawns
  1671.             if (!FInTriangle (sqbk, sqwk))
  1672.                 {
  1673.                 sqwk = reflect_xy(sqwk);
  1674.                 sqw1 = reflect_xy(sqw1);
  1675.                 sqw2 = reflect_xy(sqw2);
  1676.                 sqbk = reflect_xy(sqbk);
  1677.                 };
  1678.             if (piw1 == piw2)
  1679.                 {
  1680.                 SORT (sqw1, sqw2);
  1681.                 sqw2 = EXCLUDE2(sqw2,sqwk,sqbk);                    // 62
  1682.                 return  IndTriKings(sqbk,sqwk)*(i62*i61/2) +
  1683.                         sqw2*(sqw2-1)/2+EXCLUDE2(sqw1,sqwk,sqbk);   // 62*61/2
  1684.                 }
  1685.             else
  1686.                 return  IndTriKings(sqbk,sqwk)*(i62*i61) +
  1687.                         EXCLUDE2(sqw1,sqwk,sqbk)*i61 +  // 62
  1688.                         EXCLUDE3(sqw2,sqwk,sqbk,sqw1);  // 61
  1689.             }
  1690.         }
  1691.     };
  1692.  
  1693. template <int piw1, int piw2, int pib1> class T32
  1694.     {
  1695. public:
  1696.     static INDEX TB_FASTCALL IndCalcW
  1697.         (
  1698.         square  *psqW,
  1699.         square  *psqB,
  1700.         square  sqEnP,
  1701.         int     fInvert
  1702.         )
  1703.         {
  1704.         square sqwk, sqw1, sqw2, sqbk, sqb1, sqMask;
  1705.  
  1706.         sqwk = SqFindKing (psqW);
  1707.         if (piw1 == piw2)
  1708.             {
  1709.             sqw1 = SqFindFirst  (psqW, piw1);
  1710.             sqw2 = SqFindSecond (psqW, piw2);
  1711.             }
  1712.         else
  1713.             {
  1714.             SqFind2 (psqW, piw1, sqw1, piw2, sqw2);
  1715.             }
  1716.         sqbk = SqFindKing (psqB);
  1717.         sqb1 = SqFindOne  (psqB, pib1);
  1718.  
  1719.         if (x_piecePawn == piw2 || x_piecePawn == pib1)
  1720.             sqMask = rgsqReflectMaskY [sqwk] ^ rgsqReflectInvertMask [fInvert];
  1721.         else
  1722.             sqMask = rgsqReflectMaskYandX [sqwk];
  1723.         sqwk ^= sqMask;
  1724.         sqbk ^= sqMask;
  1725.         sqw1 ^= sqMask;
  1726.         sqw2 ^= sqMask;
  1727.         sqb1 ^= sqMask;
  1728.  
  1729.         if (x_piecePawn == piw2 || x_piecePawn == pib1)
  1730.             {
  1731.             // There are pawns on the board
  1732.             if (x_piecePawn == pib1)
  1733.                 {
  1734.                 // Black pawn
  1735.                 if (x_piecePawn == piw1 && x_piecePawn == piw2)
  1736.                     {
  1737.                     // All 3 pieces are pawns
  1738.                     if (XX == sqEnP)
  1739.                         return  TEnumerate2<x_piecePawn,x_piecePawn,true,false>::
  1740.                                     Index(sqwk,sqw1,sqw2,sqbk)*i46+
  1741.                                 EXCLUDE2(sqb1,sqw1,sqw2)-i8;    // 46
  1742.                     else
  1743.                         // En passant capture
  1744.                         return  rgcPairPawnPresent[x_piecePawn][x_piecePawn]*i46 +
  1745.                                 IndHalfKings(sqwk,sqbk)*(i14*i44) +
  1746.                                 IndEnPassant21W (sqw1, sqw2, sqb1, sqEnP ^ sqMask);
  1747.                     }
  1748.                 else if (x_piecePawn == piw2)
  1749.                     {
  1750.                     // One white pawn, one black pawn
  1751.                     if (XX == sqEnP)
  1752.                         return  TEnumerate2<piw1,x_piecePawn,true,false>::
  1753.                                     Index(sqwk,sqw1,sqw2,sqbk)*i47 +
  1754.                                 EXCLUDE1(sqb1,sqw2)-i8; // 47
  1755.                     else
  1756.                         // En passant capture
  1757.                         return  rgcPairPawnPresent[piw1][x_piecePawn]*i47 +
  1758.                                 TEnumerate1<piw1,true,false>::Index(sqwk,sqw1,sqbk)*i14 +
  1759.                                 IndEnPassant11W (sqw2, sqb1, sqEnP ^ sqMask);
  1760.                     }
  1761.                 else
  1762.                     // Only black pawn
  1763.                     return  TEnumerate2<piw1,piw2,true,false>::
  1764.                                 Index(sqwk,sqw1,sqw2,sqbk)*i48 +
  1765.                             sqb1-i8;    // 48
  1766.                 }
  1767.             }
  1768.         else
  1769.             {
  1770.             // No pawns
  1771.             if (!FInTriangle (sqwk, sqbk))
  1772.                 {
  1773.                 sqwk = reflect_xy(sqwk);
  1774.                 sqw1 = reflect_xy(sqw1);
  1775.                 sqw2 = reflect_xy(sqw2);
  1776.                 sqbk = reflect_xy(sqbk);
  1777.                 sqb1 = reflect_xy(sqb1);
  1778.                 };
  1779.             }
  1780.         return  TEnumerate2<piw1,piw2,(x_piecePawn==piw2||x_piecePawn==pib1) ? true : false,false>::
  1781.                     Index(sqwk,sqw1,sqw2,sqbk)*i60 +
  1782.                 EXCLUDE4(sqb1,sqwk,sqbk,sqw1,sqw2); // 60
  1783.         }
  1784.  
  1785.     static INDEX TB_FASTCALL IndCalcB
  1786.         (
  1787.         square  *psqW,
  1788.         square  *psqB,
  1789.         square  sqEnP,
  1790.         int     fInvert
  1791.         )
  1792.         {
  1793.         square sqwk, sqw1, sqw2, sqbk, sqb1, sqMask;
  1794.  
  1795.         sqwk = SqFindKing (psqW);
  1796.         if (piw1 == piw2)
  1797.             {
  1798.             sqw1 = SqFindFirst  (psqW, piw1);
  1799.             sqw2 = SqFindSecond (psqW, piw2);
  1800.             }
  1801.         else
  1802.             {
  1803.             SqFind2 (psqW, piw1, sqw1, piw2, sqw2);
  1804.             }
  1805.         sqbk = SqFindKing (psqB);
  1806.         sqb1 = SqFindOne  (psqB, pib1);
  1807.  
  1808.         if (x_piecePawn == piw2 || x_piecePawn == pib1)
  1809.             sqMask = rgsqReflectMaskY [sqbk] ^ rgsqReflectInvertMask [fInvert];
  1810.         else
  1811.             sqMask = rgsqReflectMaskYandX [sqbk];
  1812.         sqwk ^= sqMask;
  1813.         sqbk ^= sqMask;
  1814.         sqw1 ^= sqMask;
  1815.         sqw2 ^= sqMask;
  1816.         sqb1 ^= sqMask;
  1817.  
  1818.         if (x_piecePawn == piw2 || x_piecePawn == pib1)
  1819.             {
  1820.             // There are pawns on the board
  1821.             if (x_piecePawn == pib1)
  1822.                 {
  1823.                 // Black pawn
  1824.                 if (x_piecePawn == piw1 && x_piecePawn == piw2)
  1825.                     {
  1826.                     // All 3 pieces are pawns
  1827.                     SORT (sqw1, sqw2);
  1828.                     if (XX == sqEnP)
  1829.                         {
  1830.                         sqw2 = EXCLUDE1(sqw2,sqb1)-i8;                  // 47
  1831.                         return  TEnumerate1<x_piecePawn,true,true>::
  1832.                                     Index(sqbk,sqb1,sqwk)*(i47*i46/2) +
  1833.                                 sqw2*(sqw2-1)/2+EXCLUDE1(sqw1,sqb1)-i8; // 47*46/2
  1834.                         }
  1835.                     else
  1836.                         // En passant capture
  1837.                         return  rgcSinglePawnPresent[x_piecePawn]*(i47*i46/2) +
  1838.                                 IndHalfKings(sqbk,sqwk)*(i44*i14) +
  1839.                                 IndEnPassant21B (sqw1, sqw2, sqb1, sqEnP ^ sqMask);
  1840.                     }
  1841.                 else if (x_piecePawn == piw2)
  1842.                     {
  1843.                     // One white pawn, one black pawn
  1844.                     if (XX == sqEnP)
  1845.                         return  TEnumerate1<x_piecePawn,true,true>::
  1846.                                     Index(sqbk,sqb1,sqwk)*(i60*i47) +
  1847.                                 EXCLUDE4(sqw1,sqwk,sqbk,sqw2,sqb1)*i47 +    // 60
  1848.                                 EXCLUDE1(sqw2,sqb1)-i8;                     // 47
  1849.                     else
  1850.                         {
  1851.                         // En passant capture
  1852.                         sqEnP ^= sqMask;
  1853.                         return  rgcSinglePawnPresent[x_piecePawn]*(i60*i47) +
  1854.                                 IndHalfKings(sqbk,sqwk)*(i58*i14) +
  1855.                                 EXCLUDE6(sqw1,sqwk,sqbk,sqw2,sqb1,sqEnP,sqEnP-8)*i14 +  // 58
  1856.                                 IndEnPassant11B (sqw2, sqb1, sqEnP);
  1857.                         }
  1858.                     }
  1859.                 else
  1860.                     {
  1861.                     // Only black pawn
  1862.                     if (piw1 == piw2)
  1863.                         {
  1864.                         // 2 identical white pieces
  1865.                         SORT (sqw1, sqw2);
  1866.                         sqw2 = EXCLUDE3(sqw2,sqwk,sqbk,sqb1);                       // 61
  1867.                         return  TEnumerate1<x_piecePawn,true,true>::
  1868.                                     Index(sqbk,sqb1,sqwk)*(i61*i60/2) +
  1869.                                 sqw2*(sqw2-1)/2 + EXCLUDE3(sqw1,sqwk,sqbk,sqb1);    // 61*60/2
  1870.                         }
  1871.                     return  TEnumerate1<x_piecePawn,true,true>::
  1872.                                 Index(sqbk,sqb1,sqwk)*(i61*i60) +
  1873.                             EXCLUDE3(sqw1,sqwk,sqbk,sqb1)*i60 + // 61
  1874.                             EXCLUDE4(sqw2,sqwk,sqbk,sqw1,sqb1); // 60
  1875.                     }
  1876.                 }
  1877.             else
  1878.                 {
  1879.                 // No black pawn
  1880.                 if (x_piecePawn == piw1)
  1881.                     {
  1882.                     // Only 2 white pawns
  1883.                     SORT (sqw1, sqw2);
  1884.                     sqw2 -= i8;
  1885.                     return  TEnumerate1<pib1,true,true>::
  1886.                                 Index(sqbk,sqb1,sqwk)*(i48*47/2) +
  1887.                             sqw2*(sqw2-1)/2+sqw1-i8;            // 48*47/2
  1888.                     }
  1889.                 else
  1890.                     // Only one white pawn
  1891.                     return  TEnumerate1<pib1,true,true>::
  1892.                                 Index(sqbk,sqb1,sqwk)*(i60*i48) +
  1893.                             EXCLUDE4(sqw1,sqwk,sqbk,sqw2,sqb1)*i48 +    // 60
  1894.                             sqw2-i8;                                    // 48
  1895.                 }
  1896.             }
  1897.         else
  1898.             {
  1899.             // No pawns
  1900.             if (!FInTriangle (sqbk, sqwk))
  1901.                 {
  1902.                 sqwk = reflect_xy(sqwk);
  1903.                 sqw1 = reflect_xy(sqw1);
  1904.                 sqw2 = reflect_xy(sqw2);
  1905.                 sqbk = reflect_xy(sqbk);
  1906.                 sqb1 = reflect_xy(sqb1);
  1907.                 };
  1908.             if (piw1 == piw2)
  1909.                 {
  1910.                 // 2 identical white pieces
  1911.                 SORT (sqw1, sqw2);
  1912.                 sqw2 = EXCLUDE3(sqw2,sqwk,sqbk,sqb1);                   // 61
  1913.                 return  TEnumerate1<pib1,false,false>::
  1914.                             Index(sqbk,sqb1,sqwk)*(i61*i60/2) +
  1915.                         sqw2*(sqw2-1)/2+EXCLUDE3(sqw1,sqwk,sqbk,sqb1);  // 61*60/2
  1916.                 }
  1917.             else
  1918.                 return  TEnumerate1<pib1,false,false>::
  1919.                             Index(sqbk,sqb1,sqwk)*(i61*i60) +
  1920.                         EXCLUDE3(sqw1,sqwk,sqbk,sqb1)*i60 + // 61
  1921.                         EXCLUDE4(sqw2,sqwk,sqbk,sqw1,sqb1); // 60
  1922.             }
  1923.         }
  1924.     };
  1925.  
  1926. #if defined (T41_INCLUDE)
  1927.  
  1928. template <int piw1, int piw2, int piw3> class T41
  1929.     {
  1930. public:
  1931.     static INDEX TB_FASTCALL IndCalcW
  1932.         (
  1933.         square  *psqW,
  1934.         square  *psqB,
  1935.         square  sqEnP,
  1936.         int     fInvert
  1937.         )
  1938.         {
  1939.         square sqwk, sqw1, sqw2, sqw3, sqbk, sqMask;
  1940.  
  1941.         sqwk = SqFindKing (psqW);
  1942.         sqw1 = SqFindFirst (psqW, piw1);
  1943.         if (piw1 == piw2 && piw2 == piw3)
  1944.             {
  1945.             sqw2 = SqFindSecond (psqW, piw2);
  1946.             sqw3 = SqFindThird (psqW, piw3);
  1947.             }
  1948.         else if (piw1 == piw2)
  1949.             {
  1950.             sqw2 = SqFindSecond (psqW, piw2);
  1951.             sqw3 = SqFindFirst (psqW, piw3);
  1952.             }
  1953.         else if (piw2 == piw3)
  1954.             {
  1955.             sqw2 = SqFindFirst (psqW, piw2);
  1956.             sqw3 = SqFindSecond (psqW, piw3);
  1957.             }
  1958.         else
  1959.             {
  1960.             sqw2 = SqFindFirst (psqW, piw2);
  1961.             sqw3 = SqFindFirst (psqW, piw3);
  1962.             }
  1963.         sqbk = SqFindKing (psqB);
  1964.  
  1965.         if (x_piecePawn == piw3)
  1966.             sqMask = rgsqReflectMaskY [sqwk] ^ rgsqReflectInvertMask [fInvert];
  1967.         else
  1968.             sqMask = rgsqReflectMaskYandX [sqwk];
  1969.         sqwk ^= sqMask;
  1970.         sqbk ^= sqMask;
  1971.         sqw1 ^= sqMask;
  1972.         sqw2 ^= sqMask;
  1973.         sqw3 ^= sqMask;
  1974.  
  1975.         if (x_piecePawn != piw3)
  1976.             {
  1977.             // No pawns
  1978.             if (!FInTriangle (sqwk, sqbk))
  1979.                 {
  1980.                 sqwk = reflect_xy(sqwk);
  1981.                 sqw1 = reflect_xy(sqw1);
  1982.                 sqw2 = reflect_xy(sqw2);
  1983.                 sqw3 = reflect_xy(sqw3);
  1984.                 sqbk = reflect_xy(sqbk);
  1985.                 };
  1986.             }
  1987.         return  TEnumerate3<piw1,piw2,piw3,x_piecePawn == piw3,false>::Index(sqwk,sqw1,sqw2,sqw3,sqbk);
  1988.         }
  1989.  
  1990.     static INDEX TB_FASTCALL IndCalcB
  1991.         (
  1992.         square  *psqW,
  1993.         square  *psqB,
  1994.         square  sqEnP,
  1995.         int     fInvert
  1996.         )
  1997.         {
  1998.         square sqwk, sqw1, sqw2, sqw3, sqbk, sqMask;
  1999.  
  2000.         sqwk = SqFindKing (psqW);
  2001.         sqw1 = SqFindFirst (psqW, piw1);
  2002.         if (piw1 == piw2 && piw2 == piw3)
  2003.             {
  2004.             sqw2 = SqFindSecond (psqW, piw2);
  2005.             sqw3 = SqFindThird (psqW, piw3);
  2006.             }
  2007.         else if (piw1 == piw2)
  2008.             {
  2009.             sqw2 = SqFindSecond (psqW, piw2);
  2010.             sqw3 = SqFindFirst (psqW, piw3);
  2011.             }
  2012.         else if (piw2 == piw3)
  2013.             {
  2014.             sqw2 = SqFindFirst (psqW, piw2);
  2015.             sqw3 = SqFindSecond (psqW, piw3);
  2016.             }
  2017.         else
  2018.             {
  2019.             sqw2 = SqFindFirst (psqW, piw2);
  2020.             sqw3 = SqFindFirst (psqW, piw3);
  2021.             }
  2022.         sqbk = SqFindKing (psqB);
  2023.  
  2024.         if (x_piecePawn == piw3)
  2025.             sqMask = rgsqReflectMaskY [sqbk] ^ rgsqReflectInvertMask [fInvert];
  2026.         else
  2027.             sqMask = rgsqReflectMaskYandX [sqbk];
  2028.         sqwk ^= sqMask;
  2029.         sqbk ^= sqMask;
  2030.         sqw1 ^= sqMask;
  2031.         sqw2 ^= sqMask;
  2032.         sqw3 ^= sqMask;
  2033.  
  2034.         if (x_piecePawn == piw3)
  2035.             {
  2036.             // There are pawns on the board
  2037.             if (x_piecePawn == piw1)
  2038.                 // 3 white pawns
  2039.                 return  TEnumerate3<x_pieceNone,x_pieceNone,x_pieceNone,true,true>::
  2040.                             Index(sqbk,sqw1,sqw2,sqw3,sqwk);
  2041.             else if (x_piecePawn == piw2)
  2042.                 // 2 white pawns
  2043.                 return  TEnumerate2<x_pieceNone,x_pieceNone,true,true>::
  2044.                             Index(sqbk,sqw2,sqw3,sqwk)*i60 +
  2045.                         EXCLUDE4(sqw1,sqwk,sqbk,sqw2,sqw3); // 60
  2046.             else if (piw1 == piw2)
  2047.                 {
  2048.                 // 1 pawn, 2 pieces equal
  2049.                 SORT (sqw1, sqw2);
  2050.                 sqw2 = EXCLUDE3(sqw2,sqwk,sqbk,sqw3);                   // 61
  2051.                 return  TEnumerate1<x_pieceNone,true,true>::
  2052.                             Index(sqbk,sqw3,sqwk)*(i61*i60/2) +
  2053.                         sqw2*(sqw2-1)/2+EXCLUDE3(sqw1,sqwk,sqbk,sqw3);  // 61*60/2
  2054.                 }
  2055.             else
  2056.                 // Only one white pawn
  2057.                 return  TEnumerate1<x_pieceNone,true,true>::Index(sqbk,sqw3,sqwk)*i61*i60 +
  2058.                         EXCLUDE3(sqw1,sqwk,sqbk,sqw3)*i60 + // 61
  2059.                         EXCLUDE4(sqw2,sqwk,sqbk,sqw1,sqw3); // 60
  2060.             }
  2061.         else
  2062.             {
  2063.             // No pawns
  2064.             if (!FInTriangle (sqbk, sqwk))
  2065.                 {
  2066.                 sqwk = reflect_xy(sqwk);
  2067.                 sqw1 = reflect_xy(sqw1);
  2068.                 sqw2 = reflect_xy(sqw2);
  2069.                 sqw3 = reflect_xy(sqw3);
  2070.                 sqbk = reflect_xy(sqbk);
  2071.                 };
  2072.             if (piw1 == piw2 && piw2 == piw3)
  2073.                 {
  2074.                 // All 3 pieces equal
  2075.                 SORT (sqw1, sqw2);
  2076.                 SORT (sqw2, sqw3);
  2077.                 SORT (sqw1, sqw2);
  2078.                 sqw3 = EXCLUDE2(sqw3,sqwk,sqbk);    // 62
  2079.                 sqw2 = EXCLUDE2(sqw2,sqwk,sqbk);
  2080.                 return  IndTriKings(sqbk,sqwk)*(i62*i61*i60/6) +
  2081.                         sqw3*(sqw3-1)*(sqw3-2)/6+
  2082.                         sqw2*(sqw2-1)/2+
  2083.                         EXCLUDE2(sqw1,sqwk,sqbk);   // 62*61*60/6
  2084.                 }
  2085.             else if (piw1 == piw2)
  2086.                 {
  2087.                 // 2 major pieces equal
  2088.                 SORT (sqw1, sqw2);
  2089.                 sqw2 = EXCLUDE3(sqw2,sqwk,sqbk,sqw3);                           // 61
  2090.                 return  IndTriKings(sqbk,sqwk)*(i61*i60/2*i62) +
  2091.                         (sqw2*(sqw2-1)/2+EXCLUDE3(sqw1,sqwk,sqbk,sqw3))*i62 +   // 61*60/2
  2092.                         EXCLUDE2(sqw3,sqwk,sqbk);                               // 62
  2093.                 }
  2094.             else if (piw2 == piw3)
  2095.                 {
  2096.                 // 2 minor pieces equal
  2097.                 SORT (sqw2, sqw3);
  2098.                 sqw3 = EXCLUDE3(sqw3,sqwk,sqbk,sqw1);                   // 61
  2099.                 return  IndTriKings(sqbk,sqwk)*(i62*i61*i60/2) +
  2100.                         EXCLUDE2(sqw1,sqwk,sqbk)*(i61*i60/2) +          // 62
  2101.                         sqw3*(sqw3-1)/2+EXCLUDE3(sqw2,sqwk,sqbk,sqw1);  // 61*60/2
  2102.                 }
  2103.             else
  2104.                 return  IndTriKings(sqbk,sqwk)*(i62*i61*i60) +
  2105.                         EXCLUDE2(sqw1,sqwk,sqbk)*(i61*i60) +    // 62
  2106.                         EXCLUDE3(sqw2,sqwk,sqbk,sqw1)*i60 +     // 61
  2107.                         EXCLUDE4(sqw3,sqwk,sqbk,sqw1,sqw2);     // 60
  2108.             }
  2109.         }
  2110.     };
  2111.  
  2112. #endif  // T41
  2113.  
  2114. #if defined (ILLEGAL_POSSIBLE)
  2115.  
  2116. #define CHECK_INF_SINGLE(ind)\
  2117.         if (INF_SINGLE == ind)\
  2118.             return (INDEX) -1;\
  2119.  
  2120. #define CHECK_INF_PAIR(ind)\
  2121.         if (INF_PAIR == ind)\
  2122.             return (INDEX) -1;\
  2123.  
  2124. #define CHECK_INF_TRIPLE(ind)\
  2125.         if (INF_TRIPLE == ind)\
  2126.             return (INDEX) -1;\
  2127.  
  2128. #else
  2129.  
  2130. #define CHECK_INF_SINGLE(ind)
  2131. #define CHECK_INF_PAIR(ind)
  2132. #define CHECK_INF_TRIPLE(ind)
  2133.  
  2134. #endif
  2135.  
  2136. #if defined (T33_INCLUDE)
  2137.  
  2138. template <int piw1, int piw2, int pib1, int pib2> class T33
  2139. {
  2140. public:
  2141.     static INDEX TB_FASTCALL IndCalcW
  2142.         (
  2143.         square  *psqW,
  2144.         square  *psqB,
  2145.         square  sqEnP,
  2146.         int     fInvert
  2147.         )
  2148.     {
  2149.         square   sqwk, sqw1, sqw2, sqbk, sqb1, sqb2, sqMask;
  2150.         unsigned uInd;
  2151.  
  2152.         sqwk = SqFindKing (psqW);
  2153.         if (piw1 == piw2) {
  2154.             sqw1 = SqFindFirst  (psqW, piw1);
  2155.             sqw2 = SqFindSecond (psqW, piw2);
  2156.             }
  2157.         else {
  2158.             SqFind2 (psqW, piw1, sqw1, piw2, sqw2);
  2159.             }
  2160.         sqbk = SqFindKing (psqB);
  2161.         if (pib1 == pib2) {
  2162.             sqb1 = SqFindFirst  (psqB, pib1);
  2163.             sqb2 = SqFindSecond (psqB, pib2);
  2164.             }
  2165.         else {
  2166.             SqFind2 (psqB, pib1, sqb1, pib2, sqb2);
  2167.             }
  2168.  
  2169.         if(x_piecePawn == piw2 || x_piecePawn == pib2)
  2170.             sqMask = rgsqReflectMaskY[sqwk] ^ rgsqReflectInvertMask[fInvert];
  2171.         else
  2172.             sqMask = rgsqReflectMaskYandX[sqwk];
  2173.  
  2174.         sqwk ^= sqMask;
  2175.         sqbk ^= sqMask;
  2176.         sqw1 ^= sqMask;
  2177.         sqw2 ^= sqMask;
  2178.         sqb1 ^= sqMask;
  2179.         sqb2 ^= sqMask;
  2180.  
  2181.         if(x_piecePawn == piw2 || x_piecePawn == pib2) {
  2182.             // There are pawns on the board
  2183.             if(XX == sqEnP) {
  2184.                 // No En Passant possible
  2185.                 uInd = TEnumerate2<piw1,piw2,true,false>::Index(sqwk,sqw1,sqw2,sqbk);
  2186.                 CHECK_INF_PAIR(uInd);
  2187.                 if(x_piecePawn == piw1) {
  2188.                     // all 4 pieces are pawns
  2189.                     SORT(sqb1, sqb2);
  2190.                     sqb2 = EXCLUDE2(sqb2,sqw1,sqw2) - i8;
  2191.                     return uInd*(INDEX)(i46*i45/2) +
  2192.                            sqb2*(sqb2-1)/2 + EXCLUDE2(sqb1,sqw1,sqw2) - i8;
  2193.                 }
  2194.                 else if(x_piecePawn == piw2) {
  2195.                     if(x_piecePawn == pib1) {
  2196.                         // 1 white, 2 black pawns
  2197.                         SORT(sqb1, sqb2);
  2198.                         sqb2 = EXCLUDE1(sqb2,sqw2) - i8;
  2199.                         return uInd*(INDEX)(i47*i46/2) +
  2200.                                sqb2*(sqb2-1)/2 + EXCLUDE1(sqb1,sqw2) - i8;
  2201.                     }
  2202.                     else if(x_piecePawn == pib2) {
  2203.                         // 1 white, 1 black pawn
  2204.                         return uInd*(INDEX)(i59*i47) +
  2205.                                (EXCLUDE1(sqb2,sqw2)-i8)*i59 +
  2206.                                EXCLUDE5(sqb1,sqb2,sqwk,sqw1,sqw2,sqbk);
  2207.                     }
  2208.                     else if(pib2 == pib1) {
  2209.                         // only 1 white pawn, two identical black pieces
  2210.                         SORT(sqb1, sqb2);
  2211.                         sqb2 = EXCLUDE4(sqb2,sqwk,sqw1,sqw2,sqbk);
  2212.                         return uInd*(INDEX)(i60*i59/2) +
  2213.                                sqb2*(sqb2-1)/2 +
  2214.                                EXCLUDE4(sqb1,sqwk,sqw1,sqw2,sqbk);
  2215.                     }
  2216.                     else {
  2217.                         // only 1 white pawn, two different black pieces
  2218.                         return uInd*(INDEX)(i60*i59) +
  2219.                                EXCLUDE4(sqb2,sqwk,sqw1,sqw2,sqbk)*i59 +
  2220.                                EXCLUDE5(sqb1,sqb2,sqwk,sqw1,sqw2,sqbk);
  2221.                     }
  2222.                 }
  2223.                 else if(x_piecePawn == pib1) {
  2224.                     // no white pawns, two black pawns
  2225.                     SORT(sqb1, sqb2);
  2226.                     sqb2 -= i8;
  2227.                     return uInd*(INDEX)(i48*i47/2) +
  2228.                            sqb2*(sqb2-1)/2 + sqb1 - i8;
  2229.                 }
  2230.                 else {
  2231.                     // no white pawns, 1 black pawn
  2232.                     return uInd*(INDEX)(i48*i59) +
  2233.                            (sqb2 - i8)*i59 +
  2234.                            EXCLUDE5(sqb1,sqb2,sqwk,sqw1,sqw2,sqbk);
  2235.                 }
  2236.             }
  2237.             else {
  2238.                 // En Passant possible
  2239.                 sqEnP ^= sqMask;
  2240.                 if(x_piecePawn == piw1) {
  2241.                     // all 4 pieces are pawns
  2242.                     uInd = rgcPairPawnPresent[x_piecePawn][x_piecePawn];
  2243.                     return uInd*(INDEX)(i46*i45/2) +
  2244.                            IndHalfKings(sqwk,sqbk)*(i14*i44*i43) +
  2245.                            IndEnPassant22W(sqw1, sqw2, sqb1, sqb2, sqEnP);
  2246.                 }
  2247.                 else {
  2248.                     assert(x_piecePawn == piw2);
  2249.  
  2250.                     uInd = TEnumerate1<piw1, true, false>::
  2251.                            Index(sqwk,sqw1,sqbk);
  2252.                     CHECK_INF_SINGLE(uInd);
  2253.  
  2254.                     if(x_piecePawn == pib1) {
  2255.                         // 1 white pawn, 2 black pawns
  2256.                         return rgcPairPawnPresent[piw1][x_piecePawn]*((INDEX)(i47*i46/2)) +
  2257.                                (uInd*(i14*i44) +
  2258.                                 IndEnPassant12W(sqw2, sqb1, sqb2, sqEnP));
  2259.                     }
  2260.                     else {
  2261.                         // 1 white pawn, 1 black pawn
  2262.                         assert(x_piecePawn == pib2);
  2263.                         return rgcPairPawnPresent[piw1][x_piecePawn]*((INDEX)(i47*i59))+
  2264.                                (uInd*(i14*i57) +
  2265.                                  EXCLUDE7(sqb1,sqb2,sqwk,sqw1,sqw2,sqbk,sqEnP,sqEnP+8)*i14+
  2266.                                  IndEnPassant11W(sqw2,sqb2,sqEnP));
  2267.                     }
  2268.                 }
  2269.             }
  2270.         }
  2271.         else {
  2272.             // no pawns at all
  2273.             if (!FInTriangle (sqwk, sqbk)) {
  2274.                 sqwk = reflect_xy(sqwk);
  2275.                 sqw1 = reflect_xy(sqw1);
  2276.                 sqw2 = reflect_xy(sqw2);
  2277.                 sqbk = reflect_xy(sqbk);
  2278.                 sqb1 = reflect_xy(sqb1);
  2279.                 sqb2 = reflect_xy(sqb2);
  2280.                 }
  2281.  
  2282.             uInd = TEnumerate2<piw1,piw2,false,false>::Index(sqwk,sqw1,sqw2,sqbk);
  2283.             CHECK_INF_PAIR(uInd);
  2284.             if (pib1 == pib2) {
  2285.                 SORT (sqb1, sqb2);
  2286.                 sqb2 = EXCLUDE4(sqb2,sqwk,sqbk,sqw1,sqw2);
  2287.                 return  uInd*(i60*i59/2) +
  2288.                         sqb2*(sqb2-1)/2+
  2289.                         EXCLUDE4(sqb1,sqwk,sqbk,sqw1,sqw2);
  2290.                 }
  2291.             else {
  2292.                 // Divide by 2 to avoid overflow on the 32-bit systems, later
  2293.                 // add to itself to produce the correct result. Only the final
  2294.                 // addition have to be done using 64-bit arithmetic.
  2295.                 uInd *= (i60*i59/2);
  2296.                 return  ((INDEX) uInd) +
  2297.                           (INDEX) (uInd +
  2298.                             EXCLUDE4(sqb1,sqwk,sqbk,sqw1,sqw2)*i59 +
  2299.                             EXCLUDE5(sqb2,sqwk,sqbk,sqw1,sqw2,sqb1));
  2300.                 }
  2301.             }
  2302.     }
  2303.  
  2304.     static INDEX TB_FASTCALL IndCalcB
  2305.         (
  2306.         square  *psqW,
  2307.         square  *psqB,
  2308.         square  sqEnP,
  2309.         int     fInvert
  2310.         )
  2311.     {
  2312.         square   sqwk, sqw1, sqw2, sqbk, sqb1, sqb2, sqMask;
  2313.         unsigned uInd;
  2314.  
  2315.         sqwk = SqFindKing (psqW);
  2316.         if (piw1 == piw2) {
  2317.             sqw1 = SqFindFirst  (psqW, piw1);
  2318.             sqw2 = SqFindSecond (psqW, piw2);
  2319.             }
  2320.         else {
  2321.             SqFind2 (psqW, piw1, sqw1, piw2, sqw2);
  2322.             }
  2323.         sqbk = SqFindKing (psqB);
  2324.         if (pib1 == pib2) {
  2325.             sqb1 = SqFindFirst  (psqB, pib1);
  2326.             sqb2 = SqFindSecond (psqB, pib2);
  2327.             }
  2328.         else {
  2329.             SqFind2 (psqB, pib1, sqb1, pib2, sqb2);
  2330.             }
  2331.  
  2332.         if(piw2 == x_piecePawn || pib2 == x_piecePawn)
  2333.             sqMask = rgsqReflectMaskY[sqbk] ^ rgsqReflectInvertMask[fInvert];
  2334.         else
  2335.             sqMask = rgsqReflectMaskYandX[sqbk];
  2336.  
  2337.         sqwk ^= sqMask;
  2338.         sqw1 ^= sqMask;
  2339.         sqw2 ^= sqMask;
  2340.         sqbk ^= sqMask;
  2341.         sqb1 ^= sqMask;
  2342.         sqb2 ^= sqMask;
  2343.  
  2344.         if(x_piecePawn == piw2 || x_piecePawn == pib2) {
  2345.             // There are pawns on the board
  2346.             if(XX == sqEnP) {
  2347.                 // No En Passant possible
  2348.                 uInd = TEnumerate2<pib1,pib2,true,true>::Index(sqbk,sqb1,sqb2,sqwk);
  2349.                 CHECK_INF_PAIR(uInd);
  2350.                 if(x_piecePawn == piw1) {
  2351.                     // all 4 pieces are pawns
  2352.                     SORT(sqw1, sqw2);
  2353.                     sqw2 = EXCLUDE2(sqw2,sqb1,sqb2) - i8;
  2354.                     return uInd*(INDEX)(i46*i45/2) +
  2355.                            sqw2*(sqw2-1)/2 + EXCLUDE2(sqw1,sqb1,sqw2) - i8;
  2356.                 }
  2357.                 else if(x_piecePawn == piw2) {
  2358.                     if(x_piecePawn == pib1) {
  2359.                         // 1 white, 2 black pawns
  2360.                         return uInd*(INDEX)(i46*i59) +
  2361.                                (EXCLUDE2(sqw2,sqb1,sqb2)-i8)*i59 +
  2362.                                EXCLUDE5(sqw1,sqw2,sqb1,sqb2,sqwk,sqbk);
  2363.                     }
  2364.                     else if(x_piecePawn == pib2) {
  2365.                         // 1 white, 1 black pawn
  2366.                         return uInd*(INDEX)(i47*i59) +
  2367.                                (EXCLUDE1(sqw2,sqb2)-i8)*i59 +
  2368.                                EXCLUDE5(sqw1,sqw2,sqb1,sqb2,sqwk,sqbk);
  2369.                     }
  2370.                     else {
  2371.                         // only 1 white pawn
  2372.                         return uInd*(INDEX)(i48*i59) +
  2373.                                (sqw2 - i8)*i59 +
  2374.                                EXCLUDE5(sqw1,sqw2,sqb1,sqb2,sqwk,sqbk);
  2375.                     }
  2376.                 }
  2377.                 else if(piw1 == piw2) {
  2378.                     // no white pawns, two identical white pieces
  2379.                     SORT(sqw1, sqw2);
  2380.                     sqw2 = EXCLUDE4(sqw2,sqb1,sqb2,sqwk,sqbk);
  2381.                     return uInd*(INDEX)(i60*i59/2) +
  2382.                            sqw2*(sqw2-1)/2 +
  2383.                            EXCLUDE4(sqw1,sqb1,sqb2,sqwk,sqbk);
  2384.                 }
  2385.                 else {
  2386.                     // no white pawns, two different white pieces
  2387.                     return uInd*(INDEX)(i60*i59) +
  2388.                            EXCLUDE4(sqw2,sqb1,sqb2,sqwk,sqbk)*i59 +
  2389.                            EXCLUDE5(sqw1,sqw2,sqb1,sqb2,sqwk,sqbk);
  2390.                 }
  2391.             }
  2392.             else {
  2393.                 // En Passant possible
  2394.                 sqEnP ^= sqMask;
  2395.                 if(x_piecePawn == piw1) {
  2396.                     // all 4 pieces are pawns
  2397.                     uInd = rgcPairPawnPresent[x_piecePawn][x_piecePawn];
  2398.                     return uInd*(INDEX)(i46*i45/2) +
  2399.                            IndHalfKings(sqbk,sqwk)*(i14*i44*i43) +
  2400.                            IndEnPassant22B(sqw1, sqw2, sqb1, sqb2, sqEnP);
  2401.                 }
  2402.                 else if(x_piecePawn == pib1) {
  2403.                     // 1 white, 2 black pawns
  2404.                     assert(x_piecePawn == piw2);
  2405.                     uInd = rgcPairPawnPresent[x_piecePawn][x_piecePawn];
  2406.                     return uInd*(INDEX)(i46*i59) +
  2407.                            IndHalfKings(sqbk,sqwk)*(i14*i44*i57) +
  2408.                            EXCLUDE7(sqw1,sqw2,sqb1,sqb2,sqbk,sqwk,sqEnP,sqEnP-8)*(i44*i14)+
  2409.                            IndEnPassant12B(sqw2, sqb1, sqb2, sqEnP);
  2410.                 }
  2411.                 else {
  2412.                     // 1 white, 1 black pawn
  2413.                     assert(x_piecePawn == piw2 && x_piecePawn == pib2);
  2414.                     uInd = TEnumerate1<pib1, true, true>::
  2415.                            Index(sqbk,sqb1,sqwk);
  2416.                     CHECK_INF_SINGLE(uInd);
  2417.                     return rgcPairPawnPresent[pib1][x_piecePawn]*((INDEX)(i47*i59)) +
  2418.                            (uInd*(i14*i57) +
  2419.                             EXCLUDE7(sqw1,sqw2,sqb1,sqb2,sqwk,sqbk,sqEnP,sqEnP-8)*i14 +
  2420.                             IndEnPassant11B(sqw2,sqb2,sqEnP));
  2421.                 }
  2422.             }
  2423.         }
  2424.         else {
  2425.             // no pawns at all
  2426.             if (!FInTriangle (sqbk, sqwk)) {
  2427.             sqwk = reflect_xy(sqwk);
  2428.             sqw1 = reflect_xy(sqw1);
  2429.             sqw2 = reflect_xy(sqw2);
  2430.             sqbk = reflect_xy(sqbk);
  2431.             sqb1 = reflect_xy(sqb1);
  2432.             sqb2 = reflect_xy(sqb2);
  2433.             }
  2434.             uInd = TEnumerate2<pib1,pib2,false,false>::Index(sqbk,sqb1,sqb2,sqwk);
  2435.             CHECK_INF_PAIR(uInd);
  2436.             if (piw1 == piw2) {
  2437.             SORT (sqw1, sqw2);
  2438.                 sqw2 = EXCLUDE4(sqw2,sqbk,sqwk,sqb1,sqb2);
  2439.                 return  uInd*(i60*i59/2) +
  2440.                     sqw2*(sqw2-1)/2+
  2441.                         EXCLUDE4(sqw1,sqbk,sqwk,sqb1,sqb2);
  2442.             }
  2443.             else {
  2444.             // Divide by 2 to avoid overflow on the 32-bit systems, later
  2445.             // add to itself to produce the correct result. Only the final
  2446.                 // addition have to be done using 64-bit arithmetic.
  2447.                 uInd *= (i60*i59/2);
  2448.                 return  ((INDEX) uInd) +
  2449.                          (INDEX) (uInd +
  2450.                           EXCLUDE4(sqw1,sqbk,sqwk,sqb1,sqb2)*i59 +
  2451.                            EXCLUDE5(sqw2,sqbk,sqwk,sqb1,sqb2,sqw1));
  2452.             }
  2453.         }
  2454.     }
  2455.  
  2456.     // IndCalcBF should replace IndCalcB for symmetric endgames
  2457.  
  2458.     static INDEX TB_FASTCALL IndCalcBF
  2459.         (
  2460.         square  *psqW,
  2461.         square  *psqB,
  2462.         square  sqEnP,
  2463.         int fInvert
  2464.         )
  2465.     {
  2466.             return IndCalcW(psqB, psqW, sqEnP, !fInvert);
  2467.     }
  2468. };
  2469.  
  2470. #endif  // T33
  2471.  
  2472. #if defined (T42_INCLUDE)
  2473.  
  2474. // TODO: Add code for the TBs with pawns
  2475.  
  2476. template <int piw1, int piw2, int piw3, int pib1> class T42
  2477.     {
  2478. public:
  2479.     static INDEX TB_FASTCALL IndCalcW
  2480.         (
  2481.         square  *psqW,
  2482.         square  *psqB,
  2483.         square  sqEnP,
  2484.         int     fInvert
  2485.         )
  2486.         {
  2487.         unsigned uInd;
  2488.         square sqwk, sqw1, sqw2, sqw3, sqbk, sqb1, sqMask;
  2489.  
  2490.         sqwk = SqFindKing (psqW);
  2491.         sqw1 = SqFindFirst (psqW, piw1);
  2492.         if (piw1 == piw2 && piw2 == piw3)
  2493.             {
  2494.             sqw2 = SqFindSecond (psqW, piw2);
  2495.             sqw3 = SqFindThird (psqW, piw3);
  2496.             }
  2497.         else if (piw1 == piw2)
  2498.             {
  2499.             sqw2 = SqFindSecond (psqW, piw2);
  2500.             sqw3 = SqFindFirst (psqW, piw3);
  2501.             }
  2502.         else if (piw2 == piw3)
  2503.             {
  2504.             sqw2 = SqFindFirst (psqW, piw2);
  2505.             sqw3 = SqFindSecond (psqW, piw3);
  2506.             }
  2507.         else
  2508.             {
  2509.             sqw2 = SqFindFirst (psqW, piw2);
  2510.             sqw3 = SqFindFirst (psqW, piw3);
  2511.             }
  2512.         sqbk = SqFindKing (psqB);
  2513.         sqb1 = SqFindOne  (psqB, pib1);
  2514.  
  2515.         if (x_piecePawn == piw3 || x_piecePawn == pib1)
  2516.             sqMask = rgsqReflectMaskY [sqwk] ^ rgsqReflectInvertMask [fInvert];
  2517.         else
  2518.             sqMask = rgsqReflectMaskYandX [sqwk];
  2519.         sqwk ^= sqMask;
  2520.         sqbk ^= sqMask;
  2521.         sqw1 ^= sqMask;
  2522.         sqw2 ^= sqMask;
  2523.         sqw3 ^= sqMask;
  2524.         sqb1 ^= sqMask;
  2525.  
  2526.         if (x_piecePawn == piw3 || x_piecePawn == pib1)
  2527.             {
  2528.             // There are pawns on the board
  2529.             if (x_piecePawn == pib1)
  2530.                 {
  2531.                 // Black pawn
  2532.                 if (x_piecePawn == piw1)
  2533.                     {
  2534.                     // All 4 pieces are pawns
  2535.                     if (XX == sqEnP)
  2536.                         {
  2537.                         uInd = TEnumerate3<x_piecePawn,x_piecePawn,x_piecePawn,true,false>::
  2538.                                 Index(sqwk,sqw1,sqw2,sqw3,sqbk);
  2539.                         CHECK_INF_TRIPLE(uInd);
  2540.                         return uInd*i45 + EXCLUDE3(sqb1,sqw1,sqw2,sqw3)-i8; // 45
  2541.                         }
  2542.                     else
  2543.                         {
  2544.                         // En passant capture
  2545.                         uInd = rgcTriplePawnPresent[x_piecePawn][x_piecePawn][x_piecePawn];
  2546.                         return  uInd*i45 +
  2547.                                 IndHalfKings(sqwk,sqbk)*(i14*i44*i43/2) +
  2548.                                 IndEnPassant31W (sqw1, sqw2, sqw3, sqb1, sqEnP ^ sqMask);
  2549.                         }
  2550.                     }
  2551.                 else if (x_piecePawn == piw2)
  2552.                     {
  2553.                     // Two white pawns, one black pawn
  2554.                     if (XX == sqEnP)
  2555.                         {
  2556.                         uInd = TEnumerate3<piw1,x_piecePawn,x_piecePawn,true,false>::
  2557.                                 Index(sqwk,sqw1,sqw2,sqw3,sqbk);
  2558.                         CHECK_INF_TRIPLE(uInd);
  2559.                         return uInd*(INDEX)i46 + (EXCLUDE2(sqb1,sqw2,sqw3)-i8);   // 46
  2560.                         }
  2561.                     else
  2562.                         {
  2563.                         // En passant capture
  2564.                         uInd = TEnumerate1<piw1,true,false>::Index(sqwk,sqw1,sqbk);
  2565.                         CHECK_INF_SINGLE(uInd);
  2566.                         return  rgcTriplePawnPresent[piw1][x_piecePawn][x_piecePawn]*(INDEX)i46 +
  2567.                                 (uInd*(i14*i44) + IndEnPassant21W (sqw2, sqw3, sqb1, sqEnP ^ sqMask));
  2568.                         }
  2569.                     }
  2570.                 else if (x_piecePawn == piw3)
  2571.                     {
  2572.                     // One white pawn, one black pawn
  2573.                     if (XX == sqEnP)
  2574.                         {
  2575.                         uInd = TEnumerate3<piw1,piw2,x_piecePawn,true,false>::
  2576.                                 Index(sqwk,sqw1,sqw2,sqw3,sqbk);
  2577.                         CHECK_INF_TRIPLE(uInd);
  2578.                         return  uInd*((INDEX)i47) + (EXCLUDE1(sqb1,sqw3)-i8);    // 47
  2579.                         }
  2580.                     else
  2581.                         {
  2582.                         // En passant capture
  2583.                         uInd = TEnumerate2<piw1,piw2,true,false>::Index(sqwk,sqw1,sqw2,sqbk);
  2584.                         CHECK_INF_PAIR(uInd);
  2585.                         return  rgcTriplePawnPresent[piw1][piw2][x_piecePawn]*(INDEX)i47 +
  2586.                                 (uInd*i14 + IndEnPassant11W (sqw3, sqb1, sqEnP ^ sqMask));
  2587.                         }
  2588.                     }
  2589.                 else
  2590.                     {
  2591.                     // Only black pawn
  2592.                     uInd = TEnumerate3<piw1,piw2,piw3,true,false>::
  2593.                             Index(sqwk,sqw1,sqw2,sqw3,sqbk);
  2594.                     CHECK_INF_TRIPLE(uInd);
  2595.                     return  (uInd*3)*(INDEX)16 + (sqb1-i8); // 48
  2596.                     }
  2597.                 }
  2598.             else
  2599.                 {
  2600.                 // No black pawn
  2601.                 uInd = TEnumerate3<piw1,piw2,piw3,true,false>::
  2602.                     Index(sqwk,sqw1,sqw2,sqw3,sqbk);
  2603.                 CHECK_INF_TRIPLE(uInd);
  2604.                 return uInd*(INDEX)i59 + EXCLUDE5(sqb1,sqwk,sqbk,sqw1,sqw2,sqw3);    // 59
  2605.                 }
  2606.             }
  2607.         else
  2608.             {
  2609.             // No pawns
  2610.             if (!FInTriangle (sqwk, sqbk))
  2611.                 {
  2612.                 sqwk = reflect_xy(sqwk);
  2613.                 sqw1 = reflect_xy(sqw1);
  2614.                 sqw2 = reflect_xy(sqw2);
  2615.                 sqw3 = reflect_xy(sqw3);
  2616.                 sqbk = reflect_xy(sqbk);
  2617.                 sqb1 = reflect_xy(sqb1);
  2618.                 };
  2619.             uInd = TEnumerate3<piw1,piw2,piw3,false,false>::Index(sqwk,sqw1,sqw2,sqw3,sqbk);
  2620.             CHECK_INF_TRIPLE(uInd);
  2621.             return uInd*(INDEX)i59 + EXCLUDE5(sqb1,sqwk,sqbk,sqw1,sqw2,sqw3);   // 59
  2622.             }
  2623.         }
  2624.  
  2625.     static INDEX TB_FASTCALL IndCalcB
  2626.         (
  2627.         square  *psqW,
  2628.         square  *psqB,
  2629.         square  sqEnP,
  2630.         int     fInvert
  2631.         )
  2632.         {
  2633.         unsigned uInd;
  2634.         square sqwk, sqw1, sqw2, sqw3, sqbk, sqb1, sqMask, sqTemp;
  2635.  
  2636.         sqwk = SqFindKing (psqW);
  2637.         sqw1 = SqFindFirst (psqW, piw1);
  2638.         if (piw1 == piw2 && piw2 == piw3)
  2639.             {
  2640.             sqw2 = SqFindSecond (psqW, piw2);
  2641.             sqw3 = SqFindThird (psqW, piw3);
  2642.             }
  2643.         else if (piw1 == piw2)
  2644.             {
  2645.             sqw2 = SqFindSecond (psqW, piw2);
  2646.             sqw3 = SqFindFirst (psqW, piw3);
  2647.             }
  2648.         else if (piw2 == piw3)
  2649.             {
  2650.             sqw2 = SqFindFirst (psqW, piw2);
  2651.             sqw3 = SqFindSecond (psqW, piw3);
  2652.             }
  2653.         else
  2654.             {
  2655.             sqw2 = SqFindFirst (psqW, piw2);
  2656.             sqw3 = SqFindFirst (psqW, piw3);
  2657.             }
  2658.         sqbk = SqFindKing (psqB);
  2659.         sqb1 = SqFindOne  (psqB, pib1);
  2660.  
  2661.         if (x_piecePawn == piw3 || x_piecePawn == pib1)
  2662.             sqMask = rgsqReflectMaskY [sqbk] ^ rgsqReflectInvertMask [fInvert];
  2663.         else
  2664.             sqMask = rgsqReflectMaskYandX [sqbk];
  2665.         sqwk ^= sqMask;
  2666.         sqbk ^= sqMask;
  2667.         sqw1 ^= sqMask;
  2668.         sqw2 ^= sqMask;
  2669.         sqw3 ^= sqMask;
  2670.         sqb1 ^= sqMask;
  2671.  
  2672.         if (x_piecePawn == piw3 || x_piecePawn == pib1)
  2673.             {
  2674.             // There are pawns on the board
  2675.             if (x_piecePawn == pib1)
  2676.                 {
  2677.                 // Black pawn
  2678.                 if (x_piecePawn == piw1)
  2679.                     {
  2680.                     // All 4 pieces are pawns
  2681.                     SORT (sqw1, sqw2);
  2682.                     SORT (sqw2, sqw3);
  2683.                     SORT (sqw1, sqw2);
  2684.                     if (XX == sqEnP)
  2685.                         {
  2686.                         sqw3 = EXCLUDE1(sqw3,sqb1)-i8;                  // 47
  2687.                         sqw2 = EXCLUDE1(sqw2,sqb1)-i8;                  // 47
  2688.                         uInd = TEnumerate1<x_piecePawn,true,true>::Index(sqbk,sqb1,sqwk);
  2689.                         CHECK_INF_SINGLE(uInd);
  2690.                         return  uInd*(i47*i46*i45/6) +
  2691.                                 sqw3*(sqw3-1)*(sqw3-2)/6 +
  2692.                                 sqw2*(sqw2-1)/2 +
  2693.                                 EXCLUDE1(sqw1,sqb1)-i8; // 47*46*45/6
  2694.                         }
  2695.                     else
  2696.                         // En passant capture
  2697.                         return  rgcSinglePawnPresent[x_piecePawn]*(i47*i46*i45/6) +
  2698.                                 IndHalfKings(sqbk,sqwk)*(i44*i43/2*i14) +
  2699.                                 IndEnPassant31B (sqw1, sqw2, sqw3, sqb1, sqEnP ^ sqMask);
  2700.                     }
  2701.                 else if (x_piecePawn == piw2)
  2702.                     {
  2703.                     // Two white pawns, one black pawn
  2704.                     SORT (sqw2, sqw3);
  2705.                     if (XX == sqEnP)
  2706.                         {
  2707.                         sqTemp = EXCLUDE1(sqw3,sqb1)-i8;                    // 47
  2708.                         uInd = TEnumerate1<x_piecePawn,true,true>::
  2709.                                     Index(sqbk,sqb1,sqwk);
  2710.                         CHECK_INF_SINGLE(uInd);
  2711.                         return (uInd*(i59*i47)*(INDEX)(i46/2)) +
  2712.                                 (EXCLUDE5(sqw1,sqwk,sqbk,sqw2,sqw3,sqb1)*(i47*i46/2) +  // 59
  2713.                                  sqTemp*(sqTemp-1)/2 +
  2714.                                  EXCLUDE1(sqw2,sqb1)-i8);   // 47*46/2
  2715.                         }
  2716.                     else
  2717.                         {
  2718.                         // En passant capture
  2719.                         sqEnP ^= sqMask;
  2720.                         uInd = rgcSinglePawnPresent[x_piecePawn];
  2721.                         return (uInd*(i59*i47))*(INDEX)(i46/2) +
  2722.                                 (IndHalfKings(sqbk,sqwk)*(i57*i44*i14) +
  2723.                                  EXCLUDE7(sqw1,sqwk,sqbk,sqw2,sqw3,sqb1,sqEnP,sqEnP-8)*(i44*i14) +  // 57
  2724.                                  IndEnPassant21B (sqw2, sqw3, sqb1, sqEnP));
  2725.                         }
  2726.                     }
  2727.                 else if (x_piecePawn == piw3)
  2728.                     {
  2729.                     // One white pawn, one black pawn
  2730.                     if (piw1 == piw2)
  2731.                         {
  2732.                         // Two identical white pieces
  2733.                         SORT (sqw1, sqw2);
  2734.                         if (XX == sqEnP)
  2735.                             {
  2736.                             sqw2 = EXCLUDE4(sqw2,sqwk,sqbk,sqw3,sqb1);
  2737.                             sqw1 = EXCLUDE4(sqw1,sqwk,sqbk,sqw3,sqb1);
  2738.                             uInd = TEnumerate1<x_piecePawn,true,true>::Index(sqbk,sqb1,sqwk);
  2739.                             CHECK_INF_SINGLE(uInd);
  2740.                             return  (uInd*(i59*i47))*((INDEX)i60/2) +
  2741.                                     ((sqw2*(sqw2-1)/2+sqw1)*i47 +   // 60*59/2
  2742.                                      EXCLUDE1(sqw3,sqb1)-i8);           // 47
  2743.                             }
  2744.                         else
  2745.                             {
  2746.                             // En passant capture
  2747.                             sqEnP ^= sqMask;
  2748.                             sqw2 = EXCLUDE6(sqw2,sqwk,sqbk,sqw3,sqb1,sqEnP,sqEnP-8);
  2749.                             sqw1 = EXCLUDE6(sqw1,sqwk,sqbk,sqw3,sqb1,sqEnP,sqEnP-8);
  2750.                             uInd = rgcSinglePawnPresent[x_piecePawn];
  2751.                             return  (uInd*(i59*i47))*((INDEX)i60/2) +
  2752.                                     (IndHalfKings(sqbk,sqwk)*(i58*i57/2*i14) +
  2753.                                      (sqw2*(sqw2-1)/2+sqw1)*i14 + // 58*57/2
  2754.                                      IndEnPassant11B (sqw3, sqb1, sqEnP));
  2755.                             }
  2756.                         }
  2757.                     else
  2758.                         {
  2759.                         // Two different white pieces
  2760.                         if (XX == sqEnP)
  2761.                             {
  2762.                             uInd = TEnumerate1<x_piecePawn,true,true>::Index(sqbk,sqb1,sqwk);
  2763.                             CHECK_INF_SINGLE(uInd);
  2764.                             return  (uInd*(i59*i47))*((INDEX)i60) +
  2765.                                     (EXCLUDE4(sqw1,sqwk,sqbk,sqw3,sqb1)*i59*i47 +   // 60
  2766.                                      EXCLUDE5(sqw2,sqwk,sqbk,sqw1,sqw3,sqb1)*i47 +  // 59
  2767.                                      EXCLUDE1(sqw3,sqb1)-i8);                       // 47
  2768.                             }
  2769.                         else
  2770.                             {
  2771.                             // En passant capture
  2772.                             sqEnP ^= sqMask;
  2773.                             uInd = rgcSinglePawnPresent[x_piecePawn];
  2774.                             return  (uInd*(i59*i47))*((INDEX)i60) +
  2775.                                     (IndHalfKings(sqbk,sqwk)*(i58*i57*i14) +
  2776.                                      EXCLUDE6(sqw1,sqwk,sqbk,sqw3,sqb1,sqEnP,sqEnP-8)*(i57*i14) +   // 58
  2777.                                      EXCLUDE7(sqw2,sqwk,sqbk,sqw1,sqw3,sqb1,sqEnP,sqEnP-8)*i14 +        // 57
  2778.                                      IndEnPassant11B (sqw3, sqb1, sqEnP));
  2779.                             }
  2780.                         }
  2781.                     }
  2782.                 else
  2783.                     {
  2784.                     // Only black pawn
  2785.                     uInd = TEnumerate1<x_piecePawn,true,true>::Index(sqbk,sqb1,sqwk);
  2786.                     CHECK_INF_SINGLE(uInd);
  2787.                     if (piw1 == piw3)
  2788.                         {
  2789.                         // 3 identical white pieces
  2790.                         SORT (sqw1, sqw2);
  2791.                         SORT (sqw2, sqw3);
  2792.                         SORT (sqw1, sqw2);
  2793.                         sqw1 = EXCLUDE3(sqw1,sqwk,sqbk,sqb1);                       // 61
  2794.                         sqw2 = EXCLUDE3(sqw2,sqwk,sqbk,sqb1);                       // 61
  2795.                         sqw3 = EXCLUDE3(sqw3,sqwk,sqbk,sqb1);                       // 61
  2796.                         return  uInd*(i61*i60*i59/6) +
  2797.                                 sqw3*(sqw3-1)*(sqw3-2)/6 + sqw2*(sqw2-1)/2 + sqw1;  // 61*60*59/6
  2798.                         }
  2799.                     else if (piw1 == piw2)
  2800.                         {
  2801.                         // 2 identical major white pieces
  2802.                         SORT (sqw1, sqw2);
  2803.                         sqw3 = EXCLUDE5(sqw3,sqwk,sqbk,sqw1,sqw2,sqb1);
  2804.                         sqw1 = EXCLUDE3(sqw1,sqwk,sqbk,sqb1);               // 61
  2805.                         sqw2 = EXCLUDE3(sqw2,sqwk,sqbk,sqb1);               // 61
  2806.                         return  (uInd*(i61*i59))*(INDEX)(i60/2) +
  2807.                                 ((sqw2*(sqw2-1)/2 + sqw1)*i59 +             // 61*60/2
  2808.                                  sqw3);                                     // 59
  2809.                         }
  2810.                     else if (piw2 == piw3)
  2811.                         {
  2812.                         // 2 identical minor white pieces
  2813.                         SORT (sqw2, sqw3);
  2814.                         sqw2 = EXCLUDE4(sqw2,sqwk,sqbk,sqw1,sqb1);              // 60
  2815.                         sqw3 = EXCLUDE4(sqw3,sqwk,sqbk,sqw1,sqb1);              // 60
  2816.                         return  (uInd*(i61*i59))*(INDEX)(i60/2) +
  2817.                                 (EXCLUDE3(sqw1,sqwk,sqbk,sqb1)*(i60*i59/2) +    // 61
  2818.                                  sqw3*(sqw3-1)/2 + sqw2);                       // 60*59/2
  2819.                         }
  2820.                     else
  2821.                         {
  2822.                         // All 3 white pieces are different
  2823.                         return  (uInd*(i61*i59))*(INDEX)i60 +
  2824.                                 (EXCLUDE3(sqw1,sqwk,sqbk,sqb1)*(i60*i59) +  // 61
  2825.                                  EXCLUDE4(sqw2,sqwk,sqbk,sqw1,sqb1)*i59 +   // 60
  2826.                                  EXCLUDE5(sqw3,sqwk,sqbk,sqw1,sqw2,sqb1));  // 59
  2827.                         }
  2828.                     }
  2829.                 }
  2830.             else
  2831.                 {
  2832.                 // No black pawn
  2833.                 uInd = TEnumerate1<pib1,true,true>::Index(sqbk,sqb1,sqwk);
  2834.                 CHECK_INF_SINGLE(uInd);
  2835.                 if (x_piecePawn == piw1)
  2836.                     {
  2837.                     // Only 3 white pawns
  2838.                     SORT (sqw1, sqw2);
  2839.                     SORT (sqw2, sqw3);
  2840.                     SORT (sqw1, sqw2);
  2841.                     sqw3 -= i8;
  2842.                     sqw2 -= i8;
  2843.                     return  uInd*(i48*47*i46/6) +
  2844.                             sqw3*(sqw3-1)*(sqw3-2)/6+sqw2*(sqw2-1)/2+sqw1-i8;           // 48*47*46/6
  2845.                     }
  2846.                 else if (x_piecePawn == piw2)
  2847.                     {
  2848.                     // 2 white pawns, one non-pawn
  2849.                     SORT (sqw2, sqw3);
  2850.                     sqTemp = sqw3 - i8;
  2851.                     return  (uInd*(i59*47))*(INDEX)(i48/2) +
  2852.                             (EXCLUDE5(sqw1,sqwk,sqbk,sqb1,sqw2,sqw3)*(i48*i47/2) +
  2853.                              sqTemp*(sqTemp-1)/2+sqw2-i8);          // 48*47/2
  2854.                     }
  2855.                 else if (piw1 == piw2)
  2856.                     {
  2857.                     // One white pawn, 2 identical white pieces
  2858.                     SORT (sqw1, sqw2);
  2859.                     sqw1 = EXCLUDE4(sqw1,sqwk,sqbk,sqb1,sqw3);
  2860.                     sqw2 = EXCLUDE4(sqw2,sqwk,sqbk,sqb1,sqw3);
  2861.                     return  (uInd*(i60*i59/2))*(INDEX)i48 +
  2862.                             ((sqw2*(sqw2-1)/2+sqw1)*i48 +   // 60*59/2
  2863.                              sqw3-i8);                      // 48
  2864.                     }
  2865.                 else
  2866.                     {
  2867.                     // One white pawn, 2 different white pieces
  2868.                     return  (uInd*(i60*i59))*(INDEX)i48 +
  2869.                             (EXCLUDE4(sqw1,sqwk,sqbk,sqb1,sqw3)*(i59*i48) + // 60
  2870.                              EXCLUDE5(sqw2,sqwk,sqbk,sqb1,sqw1,sqw3)*i48 +  // 59
  2871.                              sqw3-i8);                                      // 48
  2872.                     }
  2873.                 }
  2874.             }
  2875.         else
  2876.             {
  2877.             // No pawns
  2878.             if (!FInTriangle (sqbk, sqwk))
  2879.                 {
  2880.                 sqwk = reflect_xy(sqwk);
  2881.                 sqw1 = reflect_xy(sqw1);
  2882.                 sqw2 = reflect_xy(sqw2);
  2883.                 sqw3 = reflect_xy(sqw3);
  2884.                 sqbk = reflect_xy(sqbk);
  2885.                 sqb1 = reflect_xy(sqb1);
  2886.                 };
  2887.             uInd = TEnumerate1<pib1,false,false>::Index(sqbk,sqb1,sqwk);
  2888.             CHECK_INF_SINGLE(uInd);
  2889.             if (piw1 == piw2 && piw2 == piw3)
  2890.                 {
  2891.                 // All 3 pieces equal
  2892.                 SORT (sqw1, sqw2);
  2893.                 SORT (sqw2, sqw3);
  2894.                 SORT (sqw1, sqw2);
  2895.                 sqw3 = EXCLUDE3(sqw3,sqwk,sqbk,sqb1);   // 61
  2896.                 sqw2 = EXCLUDE3(sqw2,sqwk,sqbk,sqb1);
  2897.                 return  uInd*(i61*i60*i59/6) +
  2898.                         sqw3*(sqw3-1)*(sqw3-2)/6+
  2899.                         sqw2*(sqw2-1)/2+
  2900.                         EXCLUDE3(sqw1,sqwk,sqbk,sqb1);  // 61*60*59/6
  2901.                 }
  2902.             else if (piw1 == piw2)
  2903.                 {
  2904.                 // 2 major pieces equal
  2905.                 SORT (sqw1, sqw2);
  2906.                 sqw2 = EXCLUDE4(sqw2,sqwk,sqbk,sqw3,sqb1);                          // 60
  2907.                 return uInd*(i60*i59/2*i61) +
  2908.                         (sqw2*(sqw2-1)/2+EXCLUDE4(sqw1,sqwk,sqbk,sqw3,sqb1))*i61 +  // 60*59/2
  2909.                         EXCLUDE3(sqw3,sqwk,sqbk,sqb1);                              // 61
  2910.                 }
  2911.             else if (piw2 == piw3)
  2912.                 {
  2913.                 // 2 minor pieces equal
  2914.                 SORT (sqw2, sqw3);
  2915.                 sqw3 = EXCLUDE4(sqw3,sqwk,sqbk,sqw1,sqb1);                  // 60
  2916.                 return uInd*(i61*i60*i59/2) +
  2917.                         EXCLUDE3(sqw1,sqwk,sqbk,sqb1)*(i60*i59/2) +         // 62
  2918.                         sqw3*(sqw3-1)/2+EXCLUDE4(sqw2,sqwk,sqbk,sqw1,sqb1); // 60*59/2
  2919.                 }
  2920.             else
  2921.                 {
  2922.                 uInd *= i61*i60*i59/2;
  2923.                 return (INDEX) uInd +
  2924.                        (INDEX) (uInd +
  2925.                                 EXCLUDE3(sqw1,sqwk,sqbk,sqb1)*(i60*i59) +   // 61
  2926.                                 EXCLUDE4(sqw2,sqwk,sqbk,sqw1,sqb1)*i59 +    // 60
  2927.                                 EXCLUDE5(sqw3,sqwk,sqbk,sqw1,sqw2,sqb1));   // 59
  2928.                 }
  2929.             }
  2930.         }
  2931.     };
  2932.  
  2933. #endif  // T42
  2934.  
  2935. #else   // Old SJE schema ------------------------------------------------------
  2936.  
  2937. /* scanning pattern: triangle encoding */
  2938.  
  2939. static const INDEX sptriv[] =
  2940.     {
  2941.      0,  1,  2,  3, -1, -1, -1, -1,
  2942.     -1,  4,  5,  6, -1, -1, -1, -1,
  2943.     -1, -1,  7,  8, -1, -1, -1, -1,
  2944.     -1, -1, -1,  9, -1, -1, -1, -1,
  2945.     -1, -1, -1, -1, -1, -1, -1, -1,
  2946.     -1, -1, -1, -1, -1, -1, -1, -1,
  2947.     -1, -1, -1, -1, -1, -1, -1, -1,
  2948.     -1, -1, -1, -1, -1, -1, -1, -1,
  2949.     };
  2950.  
  2951. /* scanning pattern: queenside flank encoding */
  2952.  
  2953. static const INDEX spqsfv[] =
  2954.     {
  2955.      0,  1,  2,  3, -1, -1, -1, -1,
  2956.      4,  5,  6,  7, -1, -1, -1, -1,
  2957.      8,  9, 10, 11, -1, -1, -1, -1,
  2958.     12, 13, 14, 15, -1, -1, -1, -1,
  2959.     16, 17, 18, 19, -1, -1, -1, -1,
  2960.     20, 21, 22, 23, -1, -1, -1, -1,
  2961.     24, 25, 26, 27, -1, -1, -1, -1,
  2962.     28, 29, 30, 31, -1, -1, -1, -1,
  2963.     };
  2964.  
  2965. /*--> CalcIndex3A: calculate index, mode 3A */
  2966. INLINE INDEX CalcIndex3A
  2967.     (
  2968.     square sq0,
  2969.     square sq1,
  2970.     square sq2
  2971.     )
  2972.     {
  2973.     INDEX index;
  2974.  
  2975.     if (TbRow(sq2) > x_row_4)
  2976.         {
  2977.         sq0 = reflect_x(sq0);
  2978.         sq1 = reflect_x(sq1);
  2979.         sq2 = reflect_x(sq2);
  2980.         };
  2981.  
  2982.     if (TbColumn(sq2) > x_column_d)
  2983.         {
  2984.         sq0 = reflect_y(sq0);
  2985.         sq1 = reflect_y(sq1);
  2986.         sq2 = reflect_y(sq2);
  2987.         };
  2988.  
  2989.     if (TbRow(sq2) > TbColumn(sq2))
  2990.         {
  2991.         sq0 = reflect_xy(sq0);
  2992.         sq1 = reflect_xy(sq1);
  2993.         sq2 = reflect_xy(sq2);
  2994.         };
  2995.  
  2996.     index =
  2997.         sq0 +
  2998.         sq1 * i64 +
  2999.         sptriv [sq2] * i64 * i64;
  3000.  
  3001.     return (index);
  3002.     }
  3003.  
  3004. /*--> CalcIndex3B: calculate index, mode 3B */
  3005. INLINE INDEX CalcIndex3B
  3006.     (
  3007.     square sq0,
  3008.     square sq1,
  3009.     square sq2
  3010.     )
  3011.     {
  3012.     INDEX index;
  3013.  
  3014.     if (TbColumn(sq1) > x_column_d)
  3015.         {
  3016.         sq0 = reflect_y(sq0);
  3017.         sq1 = reflect_y(sq1);
  3018.         sq2 = reflect_y(sq2);
  3019.         };
  3020.  
  3021.     index =
  3022.         sq0 +
  3023.         spqsfv [sq1] * i64 +
  3024.         sq2 * (i64 / 2) * i64;
  3025.  
  3026.     return (index);
  3027.     }
  3028.  
  3029. /*--> CalcIndex4A: calculate index, mode 4A */
  3030. INLINE INDEX CalcIndex4A
  3031.     (
  3032.     square sq0,
  3033.     square sq1,
  3034.     square sq2,
  3035.     square sq3
  3036.     )
  3037.     {
  3038.     INDEX index;
  3039.  
  3040.     if (TbRow(sq3) > x_row_4)
  3041.         {
  3042.         sq0 = reflect_x(sq0);
  3043.         sq1 = reflect_x(sq1);
  3044.         sq2 = reflect_x(sq2);
  3045.         sq3 = reflect_x(sq3);
  3046.         };
  3047.  
  3048.     if (TbColumn(sq3) > x_column_d)
  3049.         {
  3050.         sq0 = reflect_y(sq0);
  3051.         sq1 = reflect_y(sq1);
  3052.         sq2 = reflect_y(sq2);
  3053.         sq3 = reflect_y(sq3);
  3054.         };
  3055.  
  3056.     if (TbRow(sq3) > TbColumn(sq3))
  3057.         {
  3058.         sq0 = reflect_xy(sq0);
  3059.         sq1 = reflect_xy(sq1);
  3060.         sq2 = reflect_xy(sq2);
  3061.         sq3 = reflect_xy(sq3);
  3062.         };
  3063.  
  3064.     index =
  3065.         sq0 +
  3066.         sq1 * i64 +
  3067.         sq2 * i64 * i64 +
  3068.         sptriv [sq3] * i64 * i64 * i64;
  3069.  
  3070.     return (index);
  3071.     }
  3072.  
  3073. /*--> CalcIndex4B: calculate index, mode 4B */
  3074. INLINE INDEX CalcIndex4B
  3075.     (
  3076.     square sq0,
  3077.     square sq1,
  3078.     square sq2,
  3079.     square sq3
  3080.     )
  3081.     {
  3082.     INDEX index;
  3083.  
  3084.     if (TbColumn(sq3) > x_column_d)
  3085.         {
  3086.         sq0 = reflect_y(sq0);
  3087.         sq1 = reflect_y(sq1);
  3088.         sq2 = reflect_y(sq2);
  3089.         sq3 = reflect_y(sq3);
  3090.         };
  3091.  
  3092.     index =
  3093.         sq0 +
  3094.         sq1 * i64 +
  3095.         sq2 * i64 * i64 +
  3096.         spqsfv [sq3] * i64 * i64 * i64;
  3097.  
  3098.     return (index);
  3099.     }
  3100.  
  3101. /*--> CalcIndex4C: calculate index, mode 4C */
  3102. INLINE INDEX CalcIndex4C
  3103.     (
  3104.     square sq0,
  3105.     square sq1,
  3106.     square sq2,
  3107.     square sq3
  3108.     )
  3109.     {
  3110.     INDEX index;
  3111.  
  3112.     if (TbColumn(sq2) > x_column_d)
  3113.         {
  3114.         sq0 = reflect_y(sq0);
  3115.         sq1 = reflect_y(sq1);
  3116.         sq2 = reflect_y(sq2);
  3117.         sq3 = reflect_y(sq3);
  3118.         };
  3119.  
  3120.     index =
  3121.         sq0 +
  3122.         sq1 * i64 +
  3123.         spqsfv [sq2] * i64 * i64 +
  3124.         sq3 * (i64 / 2) * i64 * i64;
  3125.  
  3126.     return (index);
  3127.     }
  3128.  
  3129. /*--> CalcIndex5A: calculate index, mode 5A */
  3130. INLINE INDEX CalcIndex5A
  3131.     (
  3132.     square sq0,
  3133.     square sq1,
  3134.     square sq2,
  3135.     square sq3,
  3136.     square sq4
  3137.     )
  3138.     {
  3139.     INDEX index;
  3140.  
  3141.     if (TbRow(sq4) > x_row_4)
  3142.         {
  3143.         sq0 = reflect_x(sq0);
  3144.         sq1 = reflect_x(sq1);
  3145.         sq2 = reflect_x(sq2);
  3146.         sq3 = reflect_x(sq3);
  3147.         sq4 = reflect_x(sq4);
  3148.         };
  3149.  
  3150.     if (TbColumn(sq4) > x_column_d)
  3151.         {
  3152.         sq0 = reflect_y(sq0);
  3153.         sq1 = reflect_y(sq1);
  3154.         sq2 = reflect_y(sq2);
  3155.         sq3 = reflect_y(sq3);
  3156.         sq4 = reflect_y(sq4);
  3157.         };
  3158.  
  3159.     if (TbRow(sq4) > TbColumn(sq4))
  3160.         {
  3161.         sq0 = reflect_xy(sq0);
  3162.         sq1 = reflect_xy(sq1);
  3163.         sq2 = reflect_xy(sq2);
  3164.         sq3 = reflect_xy(sq3);
  3165.         sq4 = reflect_xy(sq4);
  3166.         };
  3167.  
  3168.     index =
  3169.         sq0 +
  3170.         sq1 * i64 +
  3171.         sq2 * i64 * i64 +
  3172.         sq3 * i64 * i64 * i64 +
  3173.         sptriv [sq4] * i64 * i64 * i64 * i64;
  3174.  
  3175.     return (index);
  3176.     }
  3177.  
  3178. /*--> CalcIndex5B: calculate index, mode 5B */
  3179. INLINE INDEX CalcIndex5B
  3180.     (
  3181.     square sq0,
  3182.     square sq1,
  3183.     square sq2,
  3184.     square sq3,
  3185.     square sq4
  3186.     )
  3187.     {
  3188.     INDEX index;
  3189.  
  3190.     if (TbColumn(sq4) > x_column_d)
  3191.         {
  3192.         sq0 = reflect_y(sq0);
  3193.         sq1 = reflect_y(sq1);
  3194.         sq2 = reflect_y(sq2);
  3195.         sq3 = reflect_y(sq3);
  3196.         sq4 = reflect_y(sq4);
  3197.         };
  3198.  
  3199.     index =
  3200.         sq0 +
  3201.         sq1 * i64 +
  3202.         sq2 * i64 * i64 +
  3203.         sq3 * i64 * i64 * i64 +
  3204.         spqsfv [sq4] * i64 * i64 * i64 * i64;
  3205.  
  3206.     return (index);
  3207.     }
  3208.  
  3209. /*--> CalcIndex5C: calculate index, mode 5C */
  3210. INLINE INDEX CalcIndex5C
  3211.     (
  3212.     square sq0,
  3213.     square sq1,
  3214.     square sq2,
  3215.     square sq3,
  3216.     square sq4
  3217.     )
  3218.     {
  3219.     INDEX index;
  3220.  
  3221.     if (TbColumn(sq3) > x_column_d)
  3222.         {
  3223.         sq0 = reflect_y(sq0);
  3224.         sq1 = reflect_y(sq1);
  3225.         sq2 = reflect_y(sq2);
  3226.         sq3 = reflect_y(sq3);
  3227.         sq4 = reflect_y(sq4);
  3228.         };
  3229.  
  3230.     index =
  3231.         sq0 +
  3232.         sq1 * i64 +
  3233.         sq2 * i64 * i64 +
  3234.         spqsfv [sq3] * i64 * i64 * i64 +
  3235.         sq4 * (i64 / 2) * i64 * i64 * i64;
  3236.  
  3237.     return (index);
  3238.     }
  3239.  
  3240. /*--> CalcIndex5D: calculate index, mode 5D */
  3241. INLINE INDEX CalcIndex5D
  3242.     (
  3243.     square sq0,
  3244.     square sq1,
  3245.     square sq2,
  3246.     square sq3,
  3247.     square sq4
  3248.     )
  3249.     {
  3250.     INDEX index;
  3251.  
  3252.     if (TbColumn(sq2) > x_column_d)
  3253.         {
  3254.         sq0 = reflect_y(sq0);
  3255.         sq1 = reflect_y(sq1);
  3256.         sq2 = reflect_y(sq2);
  3257.         sq3 = reflect_y(sq3);
  3258.         sq4 = reflect_y(sq4);
  3259.         };
  3260.  
  3261.     index =
  3262.         sq0 +
  3263.         sq1 * i64 +
  3264.         spqsfv [sq2] * i64 * i64 +
  3265.         sq3 * (i64 / 2) * i64 * i64 +
  3266.         sq4 * (i64 / 2) * i64 * i64 * i64;
  3267.  
  3268.     return (index);
  3269.     }
  3270.  
  3271. // Calculate index - a lot of functions...
  3272.  
  3273. #define IndCalcW    IndCalc
  3274. #define IndCalcB    IndCalc
  3275.  
  3276. template <int pi> class T21
  3277.     {
  3278. public:
  3279.     static INDEX TB_FASTCALL IndCalc
  3280.         (
  3281.         square  *psqW,
  3282.         square  *psqB,
  3283.         square  sqEnP,
  3284.         int     fInvert
  3285.         )
  3286.         {
  3287.         square sq0, sq1, sq2;
  3288.  
  3289.         sq0 = SqFindKing (psqW);
  3290.         sq1 = SqFindOne  (psqW, pi);
  3291.         sq2 = SqFindKing (psqB);
  3292.  
  3293.         if (x_piecePawn == pi)
  3294.             {
  3295.             if (fInvert)
  3296.                 {
  3297.                 sq0 = reflect_x (sq0);
  3298.                 sq1 = reflect_x (sq1);
  3299.                 sq2 = reflect_x (sq2);
  3300.                 }
  3301.             return CalcIndex3B (sq0, sq1, sq2);
  3302.             }
  3303.         else
  3304.             return CalcIndex3A (sq0, sq1, sq2);
  3305.         }
  3306.     };
  3307.  
  3308. template <int pi1, int pi2> class T22
  3309.     {
  3310. public:
  3311.     static INDEX TB_FASTCALL IndCalc
  3312.         (
  3313.         square  *psqW,
  3314.         square  *psqB,
  3315.         square  sqEnP,
  3316.         int     fInvert
  3317.         )
  3318.         {
  3319.         square sq0, sq1, sq2, sq3;
  3320.  
  3321.         sq0 = SqFindKing (psqW);
  3322.         sq1 = SqFindOne  (psqW, pi1);
  3323.         sq2 = SqFindKing (psqB);
  3324.         sq3 = SqFindOne  (psqB, pi2);
  3325.  
  3326.         if (x_piecePawn == pi1 || x_piecePawn == pi2)
  3327.             {
  3328.             if (fInvert)
  3329.                 {
  3330.                 sq0 = reflect_x (sq0);
  3331.                 sq1 = reflect_x (sq1);
  3332.                 sq2 = reflect_x (sq2);
  3333.                 sq3 = reflect_x (sq3);
  3334.                 }
  3335.             return CalcIndex4B (sq0, sq1, sq2, sq3);
  3336.             }
  3337.         else
  3338.             return CalcIndex4A (sq0, sq1, sq2, sq3);
  3339.         }
  3340.     };
  3341.  
  3342. template <int pi1, int pi2> class T31
  3343.     {
  3344. public:
  3345.     static INDEX TB_FASTCALL IndCalc
  3346.         (
  3347.         square  *psqW,
  3348.         square  *psqB,
  3349.         square  sqEnP,
  3350.         int     fInvert
  3351.         )
  3352.         {
  3353.         square sq0, sq1, sq2, sq3;
  3354.  
  3355.         sq0 = SqFindKing (psqW);
  3356.         sq1 = SqFindFirst (psqW, pi1);
  3357.         if (pi1 == pi2)
  3358.             sq2 = SqFindSecond (psqW, pi2);
  3359.         else
  3360.             sq2 = SqFindFirst (psqW, pi2);
  3361.         sq3 = SqFindKing (psqB);
  3362.  
  3363.         if (x_piecePawn == pi1 || x_piecePawn == pi2)
  3364.             {
  3365.             if (fInvert)
  3366.                 {
  3367.                 sq0 = reflect_x (sq0);
  3368.                 sq1 = reflect_x (sq1);
  3369.                 sq2 = reflect_x (sq2);
  3370.                 sq3 = reflect_x (sq3);
  3371.                 }
  3372.             return CalcIndex4C (sq0, sq1, sq2, sq3);
  3373.             }
  3374.         else
  3375.             return CalcIndex4A (sq0, sq1, sq2, sq3);
  3376.         }
  3377.     };
  3378.  
  3379. template <int pi1, int pi2, int pi3> class T32
  3380.     {
  3381. public:
  3382.     static INDEX TB_FASTCALL IndCalc
  3383.         (
  3384.         square  *psqW,
  3385.         square  *psqB,
  3386.         square  sqEnP,
  3387.         int     fInvert
  3388.         )
  3389.         {
  3390.         square sq0, sq1, sq2, sq3, sq4;
  3391.  
  3392.         sq0 = SqFindKing (psqW);
  3393.         sq1 = SqFindFirst (psqW, pi1);
  3394.         if (pi1 == pi2)
  3395.             sq2 = SqFindSecond (psqW, pi2);
  3396.         else
  3397.             sq2 = SqFindFirst (psqW, pi2);
  3398.         sq3 = SqFindKing (psqB);
  3399.         sq4 = SqFindOne  (psqB, pi3);
  3400.  
  3401.         if (x_piecePawn == pi1 || x_piecePawn == pi2 || x_piecePawn == pi3)
  3402.             {
  3403.             if (fInvert)
  3404.                 {
  3405.                 sq0 = reflect_x (sq0);
  3406.                 sq1 = reflect_x (sq1);
  3407.                 sq2 = reflect_x (sq2);
  3408.                 sq3 = reflect_x (sq3);
  3409.                 sq4 = reflect_x (sq4);
  3410.                 }
  3411.             if (x_piecePawn == pi3)
  3412.                 return CalcIndex5B (sq0, sq1, sq2, sq3, sq4);
  3413.             else
  3414.                 return CalcIndex5D (sq0, sq1, sq2, sq3, sq4);
  3415.             }
  3416.         else
  3417.             return CalcIndex5A (sq0, sq1, sq2, sq3, sq4);
  3418.         }
  3419.     };
  3420.  
  3421. #if defined (T41_INCLUDE)
  3422.  
  3423. template <int pi1, int pi2, int pi3> class T41
  3424.     {
  3425. public:
  3426.     static INDEX TB_FASTCALL IndCalc
  3427.         (
  3428.         square  *psqW,
  3429.         square  *psqB,
  3430.         square  sqEnP,
  3431.         int     fInvert
  3432.         )
  3433.         {
  3434.         square sq0, sq1, sq2, sq3, sq4;
  3435.  
  3436.         sq0 = SqFindKing (psqW);
  3437.         sq1 = SqFindFirst (psqW, pi1);
  3438.         sq2 = SqFindFirst (psqW, pi2);
  3439.         sq3 = SqFindFirst (psqW, pi3);
  3440.         sq4 = SqFindKing (psqB);
  3441.  
  3442.         if (x_piecePawn == pi1 || x_piecePawn == pi2 || x_piecePawn == pi3)
  3443.             {
  3444.             // There are pawns on the board
  3445.             if (fInvert)
  3446.                 {
  3447.                 sq0 = reflect_x (sq0);
  3448.                 sq1 = reflect_x (sq1);
  3449.                 sq2 = reflect_x (sq2);
  3450.                 sq3 = reflect_x (sq3);
  3451.                 sq4 = reflect_x (sq4);
  3452.                 }
  3453.             return CalcIndex5C (sq0, sq1, sq2, sq3, sq4);
  3454.             }
  3455.         else    // No pawns
  3456.             return CalcIndex5A (sq0, sq1, sq2, sq3, sq4);
  3457.         }
  3458.     };
  3459.  
  3460. #endif
  3461.  
  3462. #endif  //----------------------------------------------------------------------
  3463.  
  3464. // All tablebases enumerated
  3465.  
  3466. #define tbid_kk      0
  3467. #define tbid_kpk     1
  3468. #define tbid_knk     2
  3469. #define tbid_kbk     3
  3470. #define tbid_krk     4
  3471. #define tbid_kqk     5
  3472. #define tbid_kpkp    6
  3473. #define tbid_knkp    7
  3474. #define tbid_knkn    8
  3475. #define tbid_kbkp    9
  3476. #define tbid_kbkn   10
  3477. #define tbid_kbkb   11
  3478. #define tbid_krkp   12
  3479. #define tbid_krkn   13
  3480. #define tbid_krkb   14
  3481. #define tbid_krkr   15
  3482. #define tbid_kqkp   16
  3483. #define tbid_kqkn   17
  3484. #define tbid_kqkb   18
  3485. #define tbid_kqkr   19
  3486. #define tbid_kqkq   20
  3487. #define tbid_kppk   21
  3488. #define tbid_knpk   22
  3489. #define tbid_knnk   23
  3490. #define tbid_kbpk   24
  3491. #define tbid_kbnk   25
  3492. #define tbid_kbbk   26
  3493. #define tbid_krpk   27
  3494. #define tbid_krnk   28
  3495. #define tbid_krbk   29
  3496. #define tbid_krrk   30
  3497. #define tbid_kqpk   31
  3498. #define tbid_kqnk   32
  3499. #define tbid_kqbk   33
  3500. #define tbid_kqrk   34
  3501. #define tbid_kqqk   35
  3502. #define tbid_kppkp  36
  3503. #define tbid_kppkn  37
  3504. #define tbid_kppkb  38
  3505. #define tbid_kppkr  39
  3506. #define tbid_kppkq  40
  3507. #define tbid_knpkp  41
  3508. #define tbid_knpkn  42
  3509. #define tbid_knpkb  43
  3510. #define tbid_knpkr  44
  3511. #define tbid_knpkq  45
  3512. #define tbid_knnkp  46
  3513. #define tbid_knnkn  47
  3514. #define tbid_knnkb  48
  3515. #define tbid_knnkr  49
  3516. #define tbid_knnkq  50
  3517. #define tbid_kbpkp  51
  3518. #define tbid_kbpkn  52
  3519. #define tbid_kbpkb  53
  3520. #define tbid_kbpkr  54
  3521. #define tbid_kbpkq  55
  3522. #define tbid_kbnkp  56
  3523. #define tbid_kbnkn  57
  3524. #define tbid_kbnkb  58
  3525. #define tbid_kbnkr  59
  3526. #define tbid_kbnkq  60
  3527. #define tbid_kbbkp  61
  3528. #define tbid_kbbkn  62
  3529. #define tbid_kbbkb  63
  3530. #define tbid_kbbkr  64
  3531. #define tbid_kbbkq  65
  3532. #define tbid_krpkp  66
  3533. #define tbid_krpkn  67
  3534. #define tbid_krpkb  68
  3535. #define tbid_krpkr  69
  3536. #define tbid_krpkq  70
  3537. #define tbid_krnkp  71
  3538. #define tbid_krnkn  72
  3539. #define tbid_krnkb  73
  3540. #define tbid_krnkr  74
  3541. #define tbid_krnkq  75
  3542. #define tbid_krbkp  76
  3543. #define tbid_krbkn  77
  3544. #define tbid_krbkb  78
  3545. #define tbid_krbkr  79
  3546. #define tbid_krbkq  80
  3547. #define tbid_krrkp  81
  3548. #define tbid_krrkn  82
  3549. #define tbid_krrkb  83
  3550. #define tbid_krrkr  84
  3551. #define tbid_krrkq  85
  3552. #define tbid_kqpkp  86
  3553. #define tbid_kqpkn  87
  3554. #define tbid_kqpkb  88
  3555. #define tbid_kqpkr  89
  3556. #define tbid_kqpkq  90
  3557. #define tbid_kqnkp  91
  3558. #define tbid_kqnkn  92
  3559. #define tbid_kqnkb  93
  3560. #define tbid_kqnkr  94
  3561. #define tbid_kqnkq  95
  3562. #define tbid_kqbkp  96
  3563. #define tbid_kqbkn  97
  3564. #define tbid_kqbkb  98
  3565. #define tbid_kqbkr  99
  3566. #define tbid_kqbkq 100
  3567. #define tbid_kqrkp 101
  3568. #define tbid_kqrkn 102
  3569. #define tbid_kqrkb 103
  3570. #define tbid_kqrkr 104
  3571. #define tbid_kqrkq 105
  3572. #define tbid_kqqkp 106
  3573. #define tbid_kqqkn 107
  3574. #define tbid_kqqkb 108
  3575. #define tbid_kqqkr 109
  3576. #define tbid_kqqkq 110
  3577.  
  3578. #if defined (T41_INCLUDE)
  3579. #  define tbid_kpppk    111
  3580. #  define tbid_knppk    112
  3581. #  define tbid_knnpk    113
  3582. #  define tbid_knnnk    114
  3583. #  define tbid_kbppk    115
  3584. #  define tbid_kbnpk    116
  3585. #  define tbid_kbnnk    117
  3586. #  define tbid_kbbpk    118
  3587. #  define tbid_kbbnk    119
  3588. #  define tbid_kbbbk    120
  3589. #  define tbid_krppk    121
  3590. #  define tbid_krnpk    122
  3591. #  define tbid_krnnk    123
  3592. #  define tbid_krbpk    124
  3593. #  define tbid_krbnk    125
  3594. #  define tbid_krbbk    126
  3595. #  define tbid_krrpk    127
  3596. #  define tbid_krrnk    128
  3597. #  define tbid_krrbk    129
  3598. #  define tbid_krrrk    130
  3599. #  define tbid_kqppk    131
  3600. #  define tbid_kqnpk    132
  3601. #  define tbid_kqnnk    133
  3602. #  define tbid_kqbpk    134
  3603. #  define tbid_kqbnk    135
  3604. #  define tbid_kqbbk    136
  3605. #  define tbid_kqrpk    137
  3606. #  define tbid_kqrnk    138
  3607. #  define tbid_kqrbk    139
  3608. #  define tbid_kqrrk    140
  3609. #  define tbid_kqqpk    141
  3610. #  define tbid_kqqnk    142
  3611. #  define tbid_kqqbk    143
  3612. #  define tbid_kqqrk    144
  3613. #  define tbid_kqqqk    145
  3614. #endif
  3615.  
  3616. #if defined (T33_INCLUDE)
  3617. #  if defined (T41_INCLUDE)
  3618. #    define BASE_33 145
  3619. #  else
  3620. #    define BASE_33 110
  3621. #  endif
  3622. #  define tbid_knnknn   (BASE_33 + 1)
  3623. #  define tbid_kbnknn   (BASE_33 + 2)
  3624. #  define tbid_kbbknn   (BASE_33 + 3)
  3625. #  define tbid_kbbkbn   (BASE_33 + 4)
  3626. #  define tbid_kbbkbb   (BASE_33 + 5)
  3627. #  define tbid_krnknn   (BASE_33 + 6)
  3628. #  define tbid_krnkbb   (BASE_33 + 7)
  3629. #  define tbid_krbknn   (BASE_33 + 8)
  3630. #  define tbid_krbkbb   (BASE_33 + 9)
  3631. #  define tbid_krrknn   (BASE_33 + 10)
  3632. #  define tbid_krrkbn   (BASE_33 + 11)
  3633. #  define tbid_krrkbb   (BASE_33 + 12)
  3634. #  define tbid_krrkrn   (BASE_33 + 13)
  3635. #  define tbid_krrkrb   (BASE_33 + 14)
  3636. #  define tbid_krrkrr   (BASE_33 + 15)
  3637. #  define tbid_kqnknn   (BASE_33 + 16)
  3638. #  define tbid_kqnkbb   (BASE_33 + 17)
  3639. #  define tbid_kqnkrr   (BASE_33 + 18)
  3640. #  define tbid_kqbknn   (BASE_33 + 19)
  3641. #  define tbid_kqbkbb   (BASE_33 + 20)
  3642. #  define tbid_kqbkrr   (BASE_33 + 21)
  3643. #  define tbid_kqrknn   (BASE_33 + 22)
  3644. #  define tbid_kqrkbb   (BASE_33 + 23)
  3645. #  define tbid_kqrkrr   (BASE_33 + 24)
  3646. #  define tbid_kqqknn   (BASE_33 + 25)
  3647. #  define tbid_kqqkbn   (BASE_33 + 26)
  3648. #  define tbid_kqqkbb   (BASE_33 + 27)
  3649. #  define tbid_kqqkrn   (BASE_33 + 28)
  3650. #  define tbid_kqqkrb   (BASE_33 + 29)
  3651. #  define tbid_kqqkrr   (BASE_33 + 30)
  3652. #  define tbid_kqqkqn   (BASE_33 + 31)
  3653. #  define tbid_kqqkqb   (BASE_33 + 32)
  3654. #  define tbid_kqqkqr   (BASE_33 + 33)
  3655. #  define tbid_kqqkqq   (BASE_33 + 34)
  3656. #  if defined (T_INDEX64)
  3657. #    define tbid_kbnkbn (BASE_33 + 35)
  3658. #    define tbid_krnkrn (BASE_33 + 36)
  3659. #    define tbid_krbkrb (BASE_33 + 37)
  3660. #    define tbid_kqnkqn (BASE_33 + 38)
  3661. #    define tbid_kqbkqb (BASE_33 + 39)
  3662. #    define tbid_kqrkqr (BASE_33 + 40)
  3663. #    define tbid_krnkbn (BASE_33 + 41)
  3664. #    define tbid_krbkbn (BASE_33 + 42)
  3665. #    define tbid_krbkrn (BASE_33 + 43)
  3666. #    define tbid_kqnkbn (BASE_33 + 44)
  3667. #    define tbid_kqnkrn (BASE_33 + 45)
  3668. #    define tbid_kqnkrb (BASE_33 + 46)
  3669. #    define tbid_kqbkbn (BASE_33 + 47)
  3670. #    define tbid_kqbkrn (BASE_33 + 48)
  3671. #    define tbid_kqbkrb (BASE_33 + 49)
  3672. #    define tbid_kqbkqn (BASE_33 + 50)
  3673. #    define tbid_kqrkbn (BASE_33 + 51)
  3674. #    define tbid_kqrkrn (BASE_33 + 52)
  3675. #    define tbid_kqrkrb (BASE_33 + 53)
  3676. #    define tbid_kqrkqn (BASE_33 + 54)
  3677. #    define tbid_kqrkqb (BASE_33 + 55)
  3678. #    define tbid_kppkpp (BASE_33 + 56)
  3679. #    define tbid_knpkpp (BASE_33 + 57)
  3680. #    define tbid_knpknp (BASE_33 + 58)
  3681. #    define tbid_knnkpp (BASE_33 + 59)
  3682. #    define tbid_knnknp (BASE_33 + 60)
  3683. #    define tbid_kbpkpp (BASE_33 + 61)
  3684. #    define tbid_kbpknp (BASE_33 + 62)
  3685. #    define tbid_kbpknn (BASE_33 + 63)
  3686. #    define tbid_kbpkbp (BASE_33 + 64)
  3687. #    define tbid_kbnkpp (BASE_33 + 65)
  3688. #    define tbid_kbnknp (BASE_33 + 66)
  3689. #    define tbid_kbnkbp (BASE_33 + 67)
  3690. #    define tbid_kbbkpp (BASE_33 + 68)
  3691. #    define tbid_kbbknp (BASE_33 + 69)
  3692. #    define tbid_kbbkbp (BASE_33 + 70)
  3693. #    define tbid_krpkpp (BASE_33 + 71)
  3694. #    define tbid_krpknp (BASE_33 + 72)
  3695. #    define tbid_krpknn (BASE_33 + 73)
  3696. #    define tbid_krpkbp (BASE_33 + 74)
  3697. #    define tbid_krpkbn (BASE_33 + 75)
  3698. #    define tbid_krpkbb (BASE_33 + 76)
  3699. #    define tbid_krpkrp (BASE_33 + 77)
  3700. #    define tbid_krnkpp (BASE_33 + 78)
  3701. #    define tbid_krnknp (BASE_33 + 79)
  3702. #    define tbid_krnkbp (BASE_33 + 80)
  3703. #    define tbid_krnkrp (BASE_33 + 81)
  3704. #    define tbid_krbkpp (BASE_33 + 82)
  3705. #    define tbid_krbknp (BASE_33 + 83)
  3706. #    define tbid_krbkbp (BASE_33 + 84)
  3707. #    define tbid_krbkrp (BASE_33 + 85)
  3708. #    define tbid_krrkpp (BASE_33 + 86)
  3709. #    define tbid_krrknp (BASE_33 + 87)
  3710. #    define tbid_krrkbp (BASE_33 + 88)
  3711. #    define tbid_krrkrp (BASE_33 + 89)
  3712. #    define tbid_kqpkpp (BASE_33 + 90)
  3713. #    define tbid_kqpknp (BASE_33 + 91)
  3714. #    define tbid_kqpknn (BASE_33 + 92)
  3715. #    define tbid_kqpkbp (BASE_33 + 93)
  3716. #    define tbid_kqpkbn (BASE_33 + 94)
  3717. #    define tbid_kqpkbb (BASE_33 + 95)
  3718. #    define tbid_kqpkrp (BASE_33 + 96)
  3719. #    define tbid_kqpkrn (BASE_33 + 97)
  3720. #    define tbid_kqpkrb (BASE_33 + 98)
  3721. #    define tbid_kqpkrr (BASE_33 + 99)
  3722. #    define tbid_kqpkqp (BASE_33 + 100)
  3723. #    define tbid_kqnkpp (BASE_33 + 101)
  3724. #    define tbid_kqnknp (BASE_33 + 102)
  3725. #    define tbid_kqnkbp (BASE_33 + 103)
  3726. #    define tbid_kqnkrp (BASE_33 + 104)
  3727. #    define tbid_kqnkqp (BASE_33 + 105)
  3728. #    define tbid_kqbkpp (BASE_33 + 106)
  3729. #    define tbid_kqbknp (BASE_33 + 107)
  3730. #    define tbid_kqbkbp (BASE_33 + 108)
  3731. #    define tbid_kqbkrp (BASE_33 + 109)
  3732. #    define tbid_kqbkqp (BASE_33 + 110)
  3733. #    define tbid_kqrkpp (BASE_33 + 111)
  3734. #    define tbid_kqrknp (BASE_33 + 112)
  3735. #    define tbid_kqrkbp (BASE_33 + 113)
  3736. #    define tbid_kqrkrp (BASE_33 + 114)
  3737. #    define tbid_kqrkqp (BASE_33 + 115)
  3738. #    define tbid_kqqkpp (BASE_33 + 116)
  3739. #    define tbid_kqqknp (BASE_33 + 117)
  3740. #    define tbid_kqqkbp (BASE_33 + 118)
  3741. #    define tbid_kqqkrp (BASE_33 + 119)
  3742. #    define tbid_kqqkqp (BASE_33 + 120)
  3743. #    define C33 (tbid_kqqkqp - BASE_33)
  3744. #  else
  3745. #    define C33 (tbid_kqqkqq - BASE_33)
  3746. #  endif
  3747. #else
  3748. #  define C33   0
  3749. #endif
  3750.  
  3751. #if defined (T41_INCLUDE)
  3752. #  define BASE_42   (145 + C33)
  3753. #else
  3754. #  define BASE_42   (110 + C33)
  3755. #endif
  3756.  
  3757. #if defined (T42_INCLUDE)
  3758. #  define tbid_knnnkn   (BASE_42 + 1)
  3759. #  define tbid_kbnnkn   (BASE_42 + 2)
  3760. #  define tbid_kbbnkn   (BASE_42 + 3)
  3761. #  define tbid_kbbbkn   (BASE_42 + 4)
  3762. #  define tbid_krnnkn   (BASE_42 + 5)
  3763. #  define tbid_krbbkn   (BASE_42 + 6)
  3764. #  define tbid_krrnkn   (BASE_42 + 7)
  3765. #  define tbid_krrbkn   (BASE_42 + 8)
  3766. #  define tbid_krrrkn   (BASE_42 + 9)
  3767. #  define tbid_kqnnkn   (BASE_42 + 10)
  3768. #  define tbid_kqbbkn   (BASE_42 + 11)
  3769. #  define tbid_kqrrkn   (BASE_42 + 12)
  3770. #  define tbid_kqqnkn   (BASE_42 + 13)
  3771. #  define tbid_kqqbkn   (BASE_42 + 14)
  3772. #  define tbid_kqqrkn   (BASE_42 + 15)
  3773. #  define tbid_kqqqkn   (BASE_42 + 16)
  3774. #  define tbid_knnnkb   (BASE_42 + 17)
  3775. #  define tbid_kbnnkb   (BASE_42 + 18)
  3776. #  define tbid_kbbnkb   (BASE_42 + 19)
  3777. #  define tbid_kbbbkb   (BASE_42 + 20)
  3778. #  define tbid_krnnkb   (BASE_42 + 21)
  3779. #  define tbid_krbbkb   (BASE_42 + 22)
  3780. #  define tbid_krrnkb   (BASE_42 + 23)
  3781. #  define tbid_krrbkb   (BASE_42 + 24)
  3782. #  define tbid_krrrkb   (BASE_42 + 25)
  3783. #  define tbid_kqnnkb   (BASE_42 + 26)
  3784. #  define tbid_kqbbkb   (BASE_42 + 27)
  3785. #  define tbid_kqrrkb   (BASE_42 + 28)
  3786. #  define tbid_kqqnkb   (BASE_42 + 29)
  3787. #  define tbid_kqqbkb   (BASE_42 + 30)
  3788. #  define tbid_kqqrkb   (BASE_42 + 31)
  3789. #  define tbid_kqqqkb   (BASE_42 + 32)
  3790. #  define tbid_knnnkr   (BASE_42 + 33)
  3791. #  define tbid_kbnnkr   (BASE_42 + 34)
  3792. #  define tbid_kbbnkr   (BASE_42 + 35)
  3793. #  define tbid_kbbbkr   (BASE_42 + 36)
  3794. #  define tbid_krnnkr   (BASE_42 + 37)
  3795. #  define tbid_krbbkr   (BASE_42 + 38)
  3796. #  define tbid_krrnkr   (BASE_42 + 39)
  3797. #  define tbid_krrbkr   (BASE_42 + 40)
  3798. #  define tbid_krrrkr   (BASE_42 + 41)
  3799. #  define tbid_kqnnkr   (BASE_42 + 42)
  3800. #  define tbid_kqbbkr   (BASE_42 + 43)
  3801. #  define tbid_kqrrkr   (BASE_42 + 44)
  3802. #  define tbid_kqqnkr   (BASE_42 + 45)
  3803. #  define tbid_kqqbkr   (BASE_42 + 46)
  3804. #  define tbid_kqqrkr   (BASE_42 + 47)
  3805. #  define tbid_kqqqkr   (BASE_42 + 48)
  3806. #  define tbid_knnnkq   (BASE_42 + 49)
  3807. #  define tbid_kbnnkq   (BASE_42 + 50)
  3808. #  define tbid_kbbnkq   (BASE_42 + 51)
  3809. #  define tbid_kbbbkq   (BASE_42 + 52)
  3810. #  define tbid_krnnkq   (BASE_42 + 53)
  3811. #  define tbid_krbbkq   (BASE_42 + 54)
  3812. #  define tbid_krrnkq   (BASE_42 + 55)
  3813. #  define tbid_krrbkq   (BASE_42 + 56)
  3814. #  define tbid_krrrkq   (BASE_42 + 57)
  3815. #  define tbid_kqnnkq   (BASE_42 + 58)
  3816. #  define tbid_kqbbkq   (BASE_42 + 59)
  3817. #  define tbid_kqrrkq   (BASE_42 + 60)
  3818. #  define tbid_kqqnkq   (BASE_42 + 61)
  3819. #  define tbid_kqqbkq   (BASE_42 + 62)
  3820. #  define tbid_kqqrkq   (BASE_42 + 63)
  3821. #  define tbid_kqqqkq   (BASE_42 + 64)
  3822. #  if defined (T_INDEX64)
  3823. #    define tbid_krbnkn (BASE_42 + 65)
  3824. #    define tbid_kqbnkn (BASE_42 + 66)
  3825. #    define tbid_kqrnkn (BASE_42 + 67)
  3826. #    define tbid_kqrbkn (BASE_42 + 68)
  3827. #    define tbid_krbnkb (BASE_42 + 69)
  3828. #    define tbid_kqbnkb (BASE_42 + 70)
  3829. #    define tbid_kqrnkb (BASE_42 + 71)
  3830. #    define tbid_kqrbkb (BASE_42 + 72)
  3831. #    define tbid_krbnkr (BASE_42 + 73)
  3832. #    define tbid_kqbnkr (BASE_42 + 74)
  3833. #    define tbid_kqrnkr (BASE_42 + 75)
  3834. #    define tbid_kqrbkr (BASE_42 + 76)
  3835. #    define tbid_krbnkq (BASE_42 + 77)
  3836. #    define tbid_kqbnkq (BASE_42 + 78)
  3837. #    define tbid_kqrnkq (BASE_42 + 79)
  3838. #    define tbid_kqrbkq (BASE_42 + 80)
  3839.  
  3840. #    define tbid_kpppkp (BASE_42 + 81)
  3841. #    define tbid_knppkp (BASE_42 + 82)
  3842. #    define tbid_knnpkp (BASE_42 + 83)
  3843. #    define tbid_knnnkp (BASE_42 + 84)
  3844. #    define tbid_kbppkp (BASE_42 + 85)
  3845. #    define tbid_kbnpkp (BASE_42 + 86)
  3846. #    define tbid_kbnnkp (BASE_42 + 87)
  3847. #    define tbid_kbbpkp (BASE_42 + 88)
  3848. #    define tbid_kbbnkp (BASE_42 + 89)
  3849. #    define tbid_kbbbkp (BASE_42 + 90)
  3850. #    define tbid_krppkp (BASE_42 + 91)
  3851. #    define tbid_krnpkp (BASE_42 + 92)
  3852. #    define tbid_krnnkp (BASE_42 + 93)
  3853. #    define tbid_krbpkp (BASE_42 + 94)
  3854. #    define tbid_krbnkp (BASE_42 + 95)
  3855. #    define tbid_krbbkp (BASE_42 + 96)
  3856. #    define tbid_krrpkp (BASE_42 + 97)
  3857. #    define tbid_krrnkp (BASE_42 + 98)
  3858. #    define tbid_krrbkp (BASE_42 + 99)
  3859. #    define tbid_krrrkp (BASE_42 + 100)
  3860. #    define tbid_kqppkp (BASE_42 + 101)
  3861. #    define tbid_kqnpkp (BASE_42 + 102)
  3862. #    define tbid_kqnnkp (BASE_42 + 103)
  3863. #    define tbid_kqbpkp (BASE_42 + 104)
  3864. #    define tbid_kqbnkp (BASE_42 + 105)
  3865. #    define tbid_kqbbkp (BASE_42 + 106)
  3866. #    define tbid_kqrpkp (BASE_42 + 107)
  3867. #    define tbid_kqrnkp (BASE_42 + 108)
  3868. #    define tbid_kqrbkp (BASE_42 + 109)
  3869. #    define tbid_kqrrkp (BASE_42 + 110)
  3870. #    define tbid_kqqpkp (BASE_42 + 111)
  3871. #    define tbid_kqqnkp (BASE_42 + 112)
  3872. #    define tbid_kqqbkp (BASE_42 + 113)
  3873. #    define tbid_kqqrkp (BASE_42 + 114)
  3874. #    define tbid_kqqqkp (BASE_42 + 115)
  3875. #    define tbid_kpppkn (BASE_42 + 116)
  3876. #    define tbid_knppkn (BASE_42 + 117)
  3877. #    define tbid_knnpkn (BASE_42 + 118)
  3878. #    define tbid_kbppkn (BASE_42 + 119)
  3879. #    define tbid_kbnpkn (BASE_42 + 120)
  3880. #    define tbid_kbbpkn (BASE_42 + 121)
  3881. #    define tbid_krppkn (BASE_42 + 122)
  3882. #    define tbid_krnpkn (BASE_42 + 123)
  3883. #    define tbid_krbpkn (BASE_42 + 124)
  3884. #    define tbid_krrpkn (BASE_42 + 125)
  3885. #    define tbid_kqppkn (BASE_42 + 126)
  3886. #    define tbid_kqnpkn (BASE_42 + 127)
  3887. #    define tbid_kqbpkn (BASE_42 + 128)
  3888. #    define tbid_kqrpkn (BASE_42 + 129)
  3889. #    define tbid_kqqpkn (BASE_42 + 130)
  3890. #    define tbid_kpppkb (BASE_42 + 131)
  3891. #    define tbid_knppkb (BASE_42 + 132)
  3892. #    define tbid_knnpkb (BASE_42 + 133)
  3893. #    define tbid_kbppkb (BASE_42 + 134)
  3894. #    define tbid_kbnpkb (BASE_42 + 135)
  3895. #    define tbid_kbbpkb (BASE_42 + 136)
  3896. #    define tbid_krppkb (BASE_42 + 137)
  3897. #    define tbid_krnpkb (BASE_42 + 138)
  3898. #    define tbid_krbpkb (BASE_42 + 139)
  3899. #    define tbid_krrpkb (BASE_42 + 140)
  3900. #    define tbid_kqppkb (BASE_42 + 141)
  3901. #    define tbid_kqnpkb (BASE_42 + 142)
  3902. #    define tbid_kqbpkb (BASE_42 + 143)
  3903. #    define tbid_kqrpkb (BASE_42 + 144)
  3904. #    define tbid_kqqpkb (BASE_42 + 145)
  3905. #    define tbid_kpppkr (BASE_42 + 146)
  3906. #    define tbid_knppkr (BASE_42 + 147)
  3907. #    define tbid_knnpkr (BASE_42 + 148)
  3908. #    define tbid_kbppkr (BASE_42 + 149)
  3909. #    define tbid_kbnpkr (BASE_42 + 150)
  3910. #    define tbid_kbbpkr (BASE_42 + 151)
  3911. #    define tbid_krppkr (BASE_42 + 152)
  3912. #    define tbid_krnpkr (BASE_42 + 153)
  3913. #    define tbid_krbpkr (BASE_42 + 154)
  3914. #    define tbid_krrpkr (BASE_42 + 155)
  3915. #    define tbid_kqppkr (BASE_42 + 156)
  3916. #    define tbid_kqnpkr (BASE_42 + 157)
  3917. #    define tbid_kqbpkr (BASE_42 + 158)
  3918. #    define tbid_kqrpkr (BASE_42 + 159)
  3919. #    define tbid_kqqpkr (BASE_42 + 160)
  3920. #    define tbid_kpppkq (BASE_42 + 161)
  3921. #    define tbid_knppkq (BASE_42 + 162)
  3922. #    define tbid_knnpkq (BASE_42 + 163)
  3923. #    define tbid_kbppkq (BASE_42 + 164)
  3924. #    define tbid_kbnpkq (BASE_42 + 165)
  3925. #    define tbid_kbbpkq (BASE_42 + 166)
  3926. #    define tbid_krppkq (BASE_42 + 167)
  3927. #    define tbid_krnpkq (BASE_42 + 168)
  3928. #    define tbid_krbpkq (BASE_42 + 169)
  3929. #    define tbid_krrpkq (BASE_42 + 170)
  3930. #    define tbid_kqppkq (BASE_42 + 171)
  3931. #    define tbid_kqnpkq (BASE_42 + 172)
  3932. #    define tbid_kqbpkq (BASE_42 + 173)
  3933. #    define tbid_kqrpkq (BASE_42 + 174)
  3934. #    define tbid_kqqpkq (BASE_42 + 175)
  3935.  
  3936. #    define C42 175
  3937. #  else
  3938. #    define C42 64
  3939. #  endif
  3940. #endif
  3941.  
  3942. #if defined (T42_INCLUDE)
  3943. #  define cTb   (BASE_42 + C42 + 1)
  3944. #else
  3945. #  define cTb   (BASE_42 + 1)
  3946. #endif
  3947.  
  3948. // Compression
  3949.  
  3950. #include "tbdecode.h"
  3951.  
  3952. #if !defined (CPUS)
  3953. #  define   CPUS    1
  3954. #endif
  3955.  
  3956. #if (CPUS > 1)
  3957.   static    lock_t  lockDecode;
  3958. #endif
  3959. /*extern "C" int TB_CRC_CHECK = 0; */
  3960. int TB_CRC_CHECK = 0;
  3961. static int cCompressed = 0;
  3962. static decode_block *rgpdbDecodeBlocks[CPUS];
  3963.  
  3964. // Information about tablebases
  3965.  
  3966. #define MAX_EXTENTS                 18  /* Maximum # of 2Gb file extents */
  3967.  
  3968. #if defined (T33_INCLUDE) || defined (T42_INCLUDE)
  3969. #  define   MAX_TOTAL_PIECES        6   /* Maximum # of pieces on the board */
  3970. #else
  3971. #  define   MAX_TOTAL_PIECES        5   /* Maximum # of pieces on the board */
  3972. #endif
  3973. #define MAX_NON_KINGS           (MAX_TOTAL_PIECES - 2)
  3974.  
  3975. #if !defined (TB_DIRECTORY_SIZE)
  3976. #  define   TB_DIRECTORY_SIZE       32  /* # of cache buckets */
  3977. #endif
  3978.  
  3979. #if !defined (PFNCALCINDEX_DECLARED)
  3980. typedef INDEX (TB_FASTCALL * PfnCalcIndex) (square *psqW, square *psqB,
  3981.                                          square sqEnP, int fInverse);
  3982. #  define   PFNCALCINDEX_DECLARED
  3983. #endif
  3984.  
  3985. struct CTbCache;
  3986.  
  3987. typedef struct      // Hungarian: tbcb
  3988.     {
  3989. #if (CPUS > 1)
  3990.     lock_t                       m_lock;            // Lock on this cache bucket list
  3991. #endif
  3992.     volatile CTbCache * volatile m_ptbcFirst;   // Cached file chunks in LRU order
  3993.     }
  3994.     CTbCacheBucket;
  3995.  
  3996. typedef struct      // Hungarian: tbd
  3997.     {
  3998.     int             m_iTbId;
  3999.     unsigned int    m_fSymmetric:1;
  4000.     unsigned int    m_f16bit:1;
  4001.     unsigned int    m_fSplit:1;
  4002.     PfnCalcIndex    m_rgpfnCalcIndex[2];
  4003.     char            m_rgchName[MAX_TOTAL_PIECES+1];
  4004.     INDEX           m_rgcbLength[2];
  4005.     char            *m_rgpchFileName[2][MAX_EXTENTS];
  4006. #if (CPUS > 1)
  4007.     lock_t          m_rglockFiles[2];
  4008. #endif
  4009.     FILE            *m_rgfpFiles[2][MAX_EXTENTS];
  4010.     decode_info     *m_rgpdiDecodeInfo[2][MAX_EXTENTS];
  4011.     CTbCacheBucket  *m_prgtbcbBuckets[2];   // Cached file chunks in LRU order
  4012.     BYTE            *m_rgpbRead[2];
  4013.     }
  4014.     CTbDesc;
  4015.  
  4016. #if defined (T_INDEX64) && defined (_MSC_VER)
  4017. #  define   TB(name, fSym, f16bit, fSplit, funW, funB, cbW, cbB)\
  4018.                     { tbid_##name, fSym, f16bit, fSplit, { funW, funB }, #name, { cbW##ui64, cbB##ui64 } },
  4019. #elif defined (T_INDEX64)
  4020. #  define   TB(name, fSym, f16bit, fSplit, funW, funB, cbW, cbB)\
  4021.                     { tbid_##name, fSym, f16bit, fSplit, { funW, funB }, #name, { cbW##llu, cbB##llu } },
  4022. #else
  4023. #  define   TB(name, fSym, f16bit, fSplit, funW, funB, cbW, cbB)\
  4024.                     { tbid_##name, fSym, f16bit, fSplit, { funW, funB }, #name, { cbW##u, cbB##u } },
  4025. #endif
  4026.  
  4027. #define P   x_piecePawn
  4028. #define N   x_pieceKnight
  4029. #define B   x_pieceBishop
  4030. #define R   x_pieceRook
  4031. #define Q   x_pieceQueen
  4032.  
  4033. CTbDesc rgtbdDesc[cTb] =
  4034.     {
  4035.     TB (kk, true, false, false, NULL, NULL, 0, 0)
  4036.  
  4037.     TB (kpk, false, false, false, (T21<P>::IndCalcW), (T21<P>::IndCalcB), 81664, 84012)
  4038.     TB (knk, false, false, false, (T21<N>::IndCalcW), (T21<N>::IndCalcB), 26282, 28644)
  4039.     TB (kbk, false, false, false, (T21<B>::IndCalcW), (T21<B>::IndCalcB), 27243, 28644)
  4040.     TB (krk, false, false, false, (T21<R>::IndCalcW), (T21<R>::IndCalcB), 27030, 28644)
  4041.     TB (kqk, false, false, false, (T21<Q>::IndCalcW), (T21<Q>::IndCalcB), 25629, 28644)
  4042.  
  4043.     TB (kpkp, false, false, false, (T22<P, P>::IndCalcW), (T22<P, P>::IndCalcB), 3863492, 3863492)
  4044.     TB (knkp, false, false, false, (T22<N, P>::IndCalcW), (T22<N, P>::IndCalcB), 4931904, 4981504)
  4045.     TB (knkn, true,  false, false, (T22<N, N>::IndCalcW), (T22<N, N>::IndCalcB), 1603202, 1603202)
  4046.     TB (kbkp, false, false, false, (T22<B, P>::IndCalcW), (T22<B, P>::IndCalcB), 5112000, 4981504)
  4047.     TB (kbkn, false, false, false, (T22<B, N>::IndCalcW), (T22<B, N>::IndCalcB), 1661823, 1603202)
  4048.     TB (kbkb, true,  false, false, (T22<B, B>::IndCalcW), (T22<B, B>::IndCalcB), 1661823, 1661823)
  4049.     TB (krkp, false, false, false, (T22<R, P>::IndCalcW), (T22<R, P>::IndCalcB), 5072736, 4981504)
  4050.     TB (krkn, false, false, false, (T22<R, N>::IndCalcW), (T22<R, N>::IndCalcB), 1649196, 1603202)
  4051.     TB (krkb, false, false, false, (T22<R, B>::IndCalcW), (T22<R, B>::IndCalcB), 1649196, 1661823)
  4052.     TB (krkr, true,  false, false, (T22<R, R>::IndCalcW), (T22<R, R>::IndCalcB), 1649196, 1649196)
  4053.     TB (kqkp, false, false, false, (T22<Q, P>::IndCalcW), (T22<Q, P>::IndCalcB), 4810080, 4981504)
  4054.     TB (kqkn, false, false, false, (T22<Q, N>::IndCalcW), (T22<Q, N>::IndCalcB), 1563735, 1603202)
  4055.     TB (kqkb, false, false, false, (T22<Q, B>::IndCalcW), (T22<Q, B>::IndCalcB), 1563735, 1661823)
  4056.     TB (kqkr, false, false, false, (T22<Q, R>::IndCalcW), (T22<Q, R>::IndCalcB), 1563735, 1649196)
  4057.     TB (kqkq, true,  false, false, (T22<Q, Q>::IndCalcW), (T22<Q, Q>::IndCalcB), 1563735, 1563735)
  4058.     TB (kppk, false, false, false, (T31<P, P>::IndCalcW), (T31<P, P>::IndCalcB), 1806671, 1912372)
  4059.     TB (knpk, false, false, false, (T31<N, P>::IndCalcW), (T31<N, P>::IndCalcB), 4648581, 5124732)
  4060.     TB (knnk, false, false, false, (T31<N, N>::IndCalcW), (T31<N, N>::IndCalcB),  735304,  873642)
  4061.     TB (kbpk, false, false, false, (T31<B, P>::IndCalcW), (T31<B, P>::IndCalcB), 4817128, 5124732)
  4062.     TB (kbnk, false, false, false, (T31<B, N>::IndCalcW), (T31<B, N>::IndCalcB), 1550620, 1747284)
  4063.     TB (kbbk, false, false, false, (T31<B, B>::IndCalcW), (T31<B, B>::IndCalcB),  789885,  873642)
  4064.     TB (krpk, false, false, false, (T31<R, P>::IndCalcW), (T31<R, P>::IndCalcB), 4779530, 5124732)
  4065.     TB (krnk, false, false, false, (T31<R, N>::IndCalcW), (T31<R, N>::IndCalcB), 1538479, 1747284)
  4066.     TB (krbk, false, false, false, (T31<R, B>::IndCalcW), (T31<R, B>::IndCalcB), 1594560, 1747284)
  4067.     TB (krrk, false, false, false, (T31<R, R>::IndCalcW), (T31<R, R>::IndCalcB),  777300,  873642)
  4068.     TB (kqpk, false, false, false, (T31<Q, P>::IndCalcW), (T31<Q, P>::IndCalcB), 4533490, 5124732)
  4069.     TB (kqnk, false, false, false, (T31<Q, N>::IndCalcW), (T31<Q, N>::IndCalcB), 1459616, 1747284)
  4070.     TB (kqbk, false, false, false, (T31<Q, B>::IndCalcW), (T31<Q, B>::IndCalcB), 1512507, 1747284)
  4071.     TB (kqrk, false, false, false, (T31<Q, R>::IndCalcW), (T31<Q, R>::IndCalcB), 1500276, 1747284)
  4072.     TB (kqqk, false, false, false, (T31<Q, Q>::IndCalcW), (T31<Q, Q>::IndCalcB),  698739,  873642)
  4073.  
  4074. #if !defined (KPPKP_16BIT)
  4075.     TB (kppkp, false, false, false, (T32<P, P, P>::IndCalcW), (T32<P, P, P>::IndCalcB),  84219361,  89391280)
  4076. #else
  4077.     TB (kppkp, false, true,  false, (T32<P, P, P>::IndCalcW), (T32<P, P, P>::IndCalcB),  84219361,  89391280)
  4078. #endif
  4079.     TB (kppkn, false, false, false, (T32<P, P, N>::IndCalcW), (T32<P, P, N>::IndCalcB), 108400260, 115899744)
  4080.     TB (kppkb, false, false, false, (T32<P, P, B>::IndCalcW), (T32<P, P, B>::IndCalcB), 108400260, 120132000)
  4081.     TB (kppkr, false, false, false, (T32<P, P, R>::IndCalcW), (T32<P, P, R>::IndCalcB), 108400260, 119209296)
  4082.     TB (kppkq, false, false, false, (T32<P, P, Q>::IndCalcW), (T32<P, P, Q>::IndCalcB), 108400260, 113036880)
  4083.     TB (knpkp, false, false, false, (T32<N, P, P>::IndCalcW), (T32<N, P, P>::IndCalcB), 219921779, 231758952)
  4084.     TB (knpkn, false, false, false, (T32<N, P, N>::IndCalcW), (T32<N, P, N>::IndCalcB), 278914860, 295914240)
  4085.     TB (knpkb, false, false, false, (T32<N, P, B>::IndCalcW), (T32<N, P, B>::IndCalcB), 278914860, 306720000)
  4086.     TB (knpkr, false, false, false, (T32<N, P, R>::IndCalcW), (T32<N, P, R>::IndCalcB), 278914860, 304369920)
  4087.     TB (knpkq, false, false, false, (T32<N, P, Q>::IndCalcW), (T32<N, P, Q>::IndCalcB), 278914860, 288610560)
  4088.     TB (knnkp, false, false, false, (T32<N, N, P>::IndCalcW), (T32<N, N, P>::IndCalcB), 137991648, 149445120)
  4089.     TB (knnkn, false, false, false, (T32<N, N, N>::IndCalcW), (T32<N, N, N>::IndCalcB),  44118240,  48096060)
  4090.     TB (knnkb, false, false, false, (T32<N, N, B>::IndCalcW), (T32<N, N, B>::IndCalcB),  44118240,  49854690)
  4091.     TB (knnkr, false, false, false, (T32<N, N, R>::IndCalcW), (T32<N, N, R>::IndCalcB),  44118240,  49475880)
  4092.     TB (knnkq, false, false, false, (T32<N, N, Q>::IndCalcW), (T32<N, N, Q>::IndCalcB),  44118240,  46912050)
  4093.     TB (kbpkp, false, false, false, (T32<B, P, P>::IndCalcW), (T32<B, P, P>::IndCalcB), 227896016, 231758952)
  4094.     TB (kbpkn, false, false, false, (T32<B, P, N>::IndCalcW), (T32<B, P, N>::IndCalcB), 289027680, 295914240)
  4095.     TB (kbpkb, false, false, false, (T32<B, P, B>::IndCalcW), (T32<B, P, B>::IndCalcB), 289027680, 306720000)
  4096.     TB (kbpkr, false, false, false, (T32<B, P, R>::IndCalcW), (T32<B, P, R>::IndCalcB), 289027680, 304369920)
  4097.     TB (kbpkq, false, false, false, (T32<B, P, Q>::IndCalcW), (T32<B, P, Q>::IndCalcB), 289027680, 288610560)
  4098.     TB (kbnkp, false, false, false, (T32<B, N, P>::IndCalcW), (T32<B, N, P>::IndCalcB), 290989584, 298890240)
  4099.     TB (kbnkn, false, false, false, (T32<B, N, N>::IndCalcW), (T32<B, N, N>::IndCalcB),  93037200,  96192120)
  4100.     TB (kbnkb, false, false, false, (T32<B, N, B>::IndCalcW), (T32<B, N, B>::IndCalcB),  93037200,  99709380)
  4101.     TB (kbnkr, false, false, false, (T32<B, N, R>::IndCalcW), (T32<B, N, R>::IndCalcB),  93037200,  98951760)
  4102.     TB (kbnkq, false, false, false, (T32<B, N, Q>::IndCalcW), (T32<B, N, Q>::IndCalcB),  93037200,  93824100)
  4103.     TB (kbbkp, false, false, false, (T32<B, B, P>::IndCalcW), (T32<B, B, P>::IndCalcB), 148223520, 149445120)
  4104.     TB (kbbkn, false, false, false, (T32<B, B, N>::IndCalcW), (T32<B, B, N>::IndCalcB),  47393100,  48096060)
  4105.     TB (kbbkb, false, false, false, (T32<B, B, B>::IndCalcW), (T32<B, B, B>::IndCalcB),  47393100,  49854690)
  4106.     TB (kbbkr, false, false, false, (T32<B, B, R>::IndCalcW), (T32<B, B, R>::IndCalcB),  47393100,  49475880)
  4107.     TB (kbbkq, false, false, false, (T32<B, B, Q>::IndCalcW), (T32<B, B, Q>::IndCalcB),  47393100,  46912050)
  4108.     TB (krpkp, false, false, false, (T32<R, P, P>::IndCalcW), (T32<R, P, P>::IndCalcB), 226121876, 231758952)
  4109.     TB (krpkn, false, false, false, (T32<R, P, N>::IndCalcW), (T32<R, P, N>::IndCalcB), 286777440, 295914240)
  4110.     TB (krpkb, false, false, false, (T32<R, P, B>::IndCalcW), (T32<R, P, B>::IndCalcB), 286777440, 306720000)
  4111.     TB (krpkr, false, false, false, (T32<R, P, R>::IndCalcW), (T32<R, P, R>::IndCalcB), 286777440, 304369920)
  4112.     TB (krpkq, false, false, false, (T32<R, P, Q>::IndCalcW), (T32<R, P, Q>::IndCalcB), 286777440, 288610560)
  4113.     TB (krnkp, false, false, false, (T32<R, N, P>::IndCalcW), (T32<R, N, P>::IndCalcB), 288692928, 298890240)
  4114.     TB (krnkn, false, false, false, (T32<R, N, N>::IndCalcW), (T32<R, N, N>::IndCalcB),  92308740,  96192120)
  4115.     TB (krnkb, false, false, false, (T32<R, N, B>::IndCalcW), (T32<R, N, B>::IndCalcB),  92308740,  99709380)
  4116.     TB (krnkr, false, false, false, (T32<R, N, R>::IndCalcW), (T32<R, N, R>::IndCalcB),  92308740,  98951760)
  4117.     TB (krnkq, false, false, false, (T32<R, N, Q>::IndCalcW), (T32<R, N, Q>::IndCalcB),  92308740,  93824100)
  4118.     TB (krbkp, false, false, false, (T32<R, B, P>::IndCalcW), (T32<R, B, P>::IndCalcB), 299203200, 298890240)
  4119.     TB (krbkn, false, false, false, (T32<R, B, N>::IndCalcW), (T32<R, B, N>::IndCalcB),  95673600,  96192120)
  4120.     TB (krbkb, false, false, false, (T32<R, B, B>::IndCalcW), (T32<R, B, B>::IndCalcB),  95673600,  99709380)
  4121.     TB (krbkr, false, false, false, (T32<R, B, R>::IndCalcW), (T32<R, B, R>::IndCalcB),  95673600,  98951760)
  4122.     TB (krbkq, false, false, false, (T32<R, B, Q>::IndCalcW), (T32<R, B, Q>::IndCalcB),  95673600,  93824100)
  4123.     TB (krrkp, false, false, false, (T32<R, R, P>::IndCalcW), (T32<R, R, P>::IndCalcB), 145901232, 149445120)
  4124.     TB (krrkn, false, false, false, (T32<R, R, N>::IndCalcW), (T32<R, R, N>::IndCalcB),  46658340,  48096060)
  4125.     TB (krrkb, false, false, false, (T32<R, R, B>::IndCalcW), (T32<R, R, B>::IndCalcB),  46658340,  49854690)
  4126.     TB (krrkr, false, false, false, (T32<R, R, R>::IndCalcW), (T32<R, R, R>::IndCalcB),  46658340,  49475880)
  4127.     TB (krrkq, false, false, false, (T32<R, R, Q>::IndCalcW), (T32<R, R, Q>::IndCalcB),  46658340,  46912050)
  4128.     TB (kqpkp, false, false, false, (T32<Q, P, P>::IndCalcW), (T32<Q, P, P>::IndCalcB), 214481388, 231758952)
  4129.     TB (kqpkn, false, false, false, (T32<Q, P, N>::IndCalcW), (T32<Q, P, N>::IndCalcB), 272015040, 295914240)
  4130.     TB (kqpkb, false, false, false, (T32<Q, P, B>::IndCalcW), (T32<Q, P, B>::IndCalcB), 272015040, 306720000)
  4131.     TB (kqpkr, false, false, false, (T32<Q, P, R>::IndCalcW), (T32<Q, P, R>::IndCalcB), 272015040, 304369920)
  4132.     TB (kqpkq, false, false, false, (T32<Q, P, Q>::IndCalcW), (T32<Q, P, Q>::IndCalcB), 272015040, 288610560)
  4133.     TB (kqnkp, false, false, false, (T32<Q, N, P>::IndCalcW), (T32<Q, N, P>::IndCalcB), 273904512, 298890240)
  4134.     TB (kqnkn, false, false, false, (T32<Q, N, N>::IndCalcW), (T32<Q, N, N>::IndCalcB),  87576960,  96192120)
  4135.     TB (kqnkb, false, false, false, (T32<Q, N, B>::IndCalcW), (T32<Q, N, B>::IndCalcB),  87576960,  99709380)
  4136.     TB (kqnkr, false, false, false, (T32<Q, N, R>::IndCalcW), (T32<Q, N, R>::IndCalcB),  87576960,  98951760)
  4137.     TB (kqnkq, false, false, false, (T32<Q, N, Q>::IndCalcW), (T32<Q, N, Q>::IndCalcB),  87576960,  93824100)
  4138.     TB (kqbkp, false, false, false, (T32<Q, B, P>::IndCalcW), (T32<Q, B, P>::IndCalcB), 283818240, 298890240)
  4139.     TB (kqbkn, false, false, false, (T32<Q, B, N>::IndCalcW), (T32<Q, B, N>::IndCalcB),  90750420,  96192120)
  4140.     TB (kqbkb, false, false, false, (T32<Q, B, B>::IndCalcW), (T32<Q, B, B>::IndCalcB),  90750420,  99709380)
  4141.     TB (kqbkr, false, false, false, (T32<Q, B, R>::IndCalcW), (T32<Q, B, R>::IndCalcB),  90750420,  98951760)
  4142.     TB (kqbkq, false, false, false, (T32<Q, B, Q>::IndCalcW), (T32<Q, B, Q>::IndCalcB),  90750420,  93824100)
  4143.     TB (kqrkp, false, false, false, (T32<Q, R, P>::IndCalcW), (T32<Q, R, P>::IndCalcB), 281568240, 298890240)
  4144.     TB (kqrkn, false, false, false, (T32<Q, R, N>::IndCalcW), (T32<Q, R, N>::IndCalcB),  90038460,  96192120)
  4145.     TB (kqrkb, false, false, false, (T32<Q, R, B>::IndCalcW), (T32<Q, R, B>::IndCalcB),  90038460,  99709380)
  4146.     TB (kqrkr, false, false, false, (T32<Q, R, R>::IndCalcW), (T32<Q, R, R>::IndCalcB),  90038460,  98951760)
  4147.     TB (kqrkq, false, false, false, (T32<Q, R, Q>::IndCalcW), (T32<Q, R, Q>::IndCalcB),  90038460,  93824100)
  4148.     TB (kqqkp, false, false, false, (T32<Q, Q, P>::IndCalcW), (T32<Q, Q, P>::IndCalcB), 131170128, 149445120)
  4149.     TB (kqqkn, false, false, false, (T32<Q, Q, N>::IndCalcW), (T32<Q, Q, N>::IndCalcB),  41944320,  48096060)
  4150.     TB (kqqkb, false, false, false, (T32<Q, Q, B>::IndCalcW), (T32<Q, Q, B>::IndCalcB),  41944320,  49854690)
  4151.     TB (kqqkr, false, false, false, (T32<Q, Q, R>::IndCalcW), (T32<Q, Q, R>::IndCalcB),  41944320,  49475880)
  4152.     TB (kqqkq, false, false, false, (T32<Q, Q, Q>::IndCalcW), (T32<Q, Q, Q>::IndCalcB),  41944320,  46912050)
  4153.  
  4154. #if defined (T41_INCLUDE)
  4155.     TB (kpppk, false, false, false, (T41<P, P, P>::IndCalcW), (T41<P, P, P>::IndCalcB),  26061704,  28388716)
  4156.     TB (knppk, false, false, false, (T41<N, P, P>::IndCalcW), (T41<N, P, P>::IndCalcB), 102898651, 114742320)
  4157.     TB (knnpk, false, false, false, (T41<N, N, P>::IndCalcW), (T41<N, N, P>::IndCalcB), 130135501, 153741960)
  4158.     TB (knnnk, false, false, false, (T41<N, N, N>::IndCalcW), (T41<N, N, N>::IndCalcB),  13486227,  17472840)
  4159.     TB (kbppk, false, false, false, (T41<B, P, P>::IndCalcW), (T41<B, P, P>::IndCalcB), 106602156, 114742320)
  4160.     TB (kbnpk, false, false, false, (T41<B, N, P>::IndCalcW), (T41<B, N, P>::IndCalcB), 274352939, 307483920)
  4161.     TB (kbnnk, false, false, false, (T41<B, N, N>::IndCalcW), (T41<B, N, N>::IndCalcB),  43406294, 52418520)
  4162.     TB (kbbpk, false, false, false, (T41<B, B, P>::IndCalcW), (T41<B, B, P>::IndCalcB), 139715040, 153741960)
  4163.     TB (kbbnk, false, false, false, (T41<B, B, N>::IndCalcW), (T41<B, B, N>::IndCalcB),  44983618,  52418520)
  4164.     TB (kbbbk, false, false, false, (T41<B, B, B>::IndCalcW), (T41<B, B, B>::IndCalcB),  15010230,  17472840)
  4165.     TB (krppk, false, false, false, (T41<R, P, P>::IndCalcW), (T41<R, P, P>::IndCalcB), 105758666, 114742320)
  4166.     TB (krnpk, false, false, false, (T41<R, N, P>::IndCalcW), (T41<R, N, P>::IndCalcB), 272153675, 307483920)
  4167.     TB (krnnk, false, false, false, (T41<R, N, N>::IndCalcW), (T41<R, N, N>::IndCalcB),  43056198,  52418520)
  4168.     TB (krbpk, false, false, false, (T41<R, B, P>::IndCalcW), (T41<R, B, P>::IndCalcB), 281991360, 307483920)
  4169.     TB (krbnk, false, false, false, (T41<R, B, N>::IndCalcW), (T41<R, B, N>::IndCalcB),  90787358, 104837040)
  4170.     TB (krbbk, false, false, false, (T41<R, B, B>::IndCalcW), (T41<R, B, B>::IndCalcB),  46242089,  52418520)
  4171.     TB (krrpk, false, false, false, (T41<R, R, P>::IndCalcW), (T41<R, R, P>::IndCalcB), 137491197, 153741960)
  4172.     TB (krrnk, false, false, false, (T41<R, R, N>::IndCalcW), (T41<R, R, N>::IndCalcB),  44265261,  52418520)
  4173.     TB (krrbk, false, false, false, (T41<R, R, B>::IndCalcW), (T41<R, R, B>::IndCalcB),  45873720,  52418520)
  4174.     TB (krrrk, false, false, false, (T41<R, R, R>::IndCalcW), (T41<R, R, R>::IndCalcB),  14644690,  17472840)
  4175.     TB (kqppk, false, false, false, (T41<Q, P, P>::IndCalcW), (T41<Q, P, P>::IndCalcB), 100347220, 114742320)
  4176.     TB (kqnpk, false, false, false, (T41<Q, N, P>::IndCalcW), (T41<Q, N, P>::IndCalcB), 258294639, 307483920)
  4177.     TB (kqnnk, false, false, false, (T41<Q, N, N>::IndCalcW), (T41<Q, N, N>::IndCalcB),  40873646,  52418520)
  4178.     TB (kqbpk, false, false, false, (T41<Q, B, P>::IndCalcW), (T41<Q, B, P>::IndCalcB), 267576632, 307483920)
  4179.     TB (kqbnk, false, false, false, (T41<Q, B, N>::IndCalcW), (T41<Q, B, N>::IndCalcB),  86166717, 104837040)
  4180.     TB (kqbbk, false, false, false, (T41<Q, B, B>::IndCalcW), (T41<Q, B, B>::IndCalcB),  43879679,  52418520)
  4181.     TB (kqrpk, false, false, false, (T41<Q, R, P>::IndCalcW), (T41<Q, R, P>::IndCalcB), 265421907, 307483920)
  4182.     TB (kqrnk, false, false, false, (T41<Q, R, N>::IndCalcW), (T41<Q, R, N>::IndCalcB),  85470603, 104837040)
  4183.     TB (kqrbk, false, false, false, (T41<Q, R, B>::IndCalcW), (T41<Q, R, B>::IndCalcB),  88557959, 104837040)
  4184.     TB (kqrrk, false, false, false, (T41<Q, R, R>::IndCalcW), (T41<Q, R, R>::IndCalcB),  43157690,  52418520)
  4185.     TB (kqqpk, false, false, false, (T41<Q, Q, P>::IndCalcW), (T41<Q, Q, P>::IndCalcB), 123688859, 153741960)
  4186.     TB (kqqnk, false, false, false, (T41<Q, Q, N>::IndCalcW), (T41<Q, Q, N>::IndCalcB),  39840787,  52418520)
  4187.     TB (kqqbk, false, false, false, (T41<Q, Q, B>::IndCalcW), (T41<Q, Q, B>::IndCalcB),  41270973,  52418520)
  4188.     TB (kqqrk, false, false, false, (T41<Q, Q, R>::IndCalcW), (T41<Q, Q, R>::IndCalcB),  40916820,  52418520)
  4189.     TB (kqqqk, false, false, false, (T41<Q, Q, Q>::IndCalcW), (T41<Q, Q, Q>::IndCalcB),  12479974,  17472840)
  4190. #endif
  4191.  
  4192. #if defined (T33_INCLUDE)
  4193.     TB (knnknn, true,  false, false, (T33<N, N, N, N>::IndCalcW), (T33<N, N, N, N>::IndCalcB),  1301488080,  1301488080)
  4194.     TB (kbnknn, false, false, false, (T33<B, N, N, N>::IndCalcW), (T33<B, N, N, N>::IndCalcB),  2744597400,  2602976160)
  4195.     TB (kbbknn, false, false, false, (T33<B, B, N, N>::IndCalcW), (T33<B, B, N, N>::IndCalcB),  1398096450,  1301488080)
  4196.     TB (kbbkbn, false, false, false, (T33<B, B, B, N>::IndCalcW), (T33<B, B, B, N>::IndCalcB),  2796192900,  2744597400)
  4197.     TB (kbbkbb, true,  false, false, (T33<B, B, B, B>::IndCalcW), (T33<B, B, B, B>::IndCalcB),  1398096450,  1398096450)
  4198.     TB (krnknn, false, true,  false, (T33<R, N, N, N>::IndCalcW), (T33<R, N, N, N>::IndCalcB),  2723107830,  2602976160)
  4199.     TB (krnkbb, false, true,  false, (T33<R, N, B, B>::IndCalcW), (T33<R, N, B, B>::IndCalcB),  2723107830,  2796192900)
  4200.     TB (krbknn, false, true,  false, (T33<R, B, N, N>::IndCalcW), (T33<R, B, N, N>::IndCalcB),  2822371200,  2602976160)
  4201.     TB (krbkbb, false, false, false, (T33<R, B, B, B>::IndCalcW), (T33<R, B, B, B>::IndCalcB),  2822371200,  2796192900)
  4202.     TB (krrknn, false, false, false, (T33<R, R, N, N>::IndCalcW), (T33<R, R, N, N>::IndCalcB),  1376421030,  1301488080)
  4203.     TB (krrkbn, false, false, false, (T33<R, R, B, N>::IndCalcW), (T33<R, R, B, N>::IndCalcB),  2752842060,  2744597400)
  4204.     TB (krrkbb, false, false, false, (T33<R, R, B, B>::IndCalcW), (T33<R, R, B, B>::IndCalcB),  1376421030,  1398096450)
  4205.     TB (krrkrn, false, false, false, (T33<R, R, R, N>::IndCalcW), (T33<R, R, R, N>::IndCalcB),  2752842060,  2723107830)
  4206.     TB (krrkrb, false, false, false, (T33<R, R, R, B>::IndCalcW), (T33<R, R, R, B>::IndCalcB),  2752842060,  2822371200)
  4207.     TB (krrkrr, true,  false, false, (T33<R, R, R, R>::IndCalcW), (T33<R, R, R, R>::IndCalcB),  1376421030,  1376421030)
  4208.     TB (kqnknn, false, false, false, (T33<Q, N, N, N>::IndCalcW), (T33<Q, N, N, N>::IndCalcB),  2583520320,  2602976160)
  4209.     TB (kqnkbb, false, false, false, (T33<Q, N, B, B>::IndCalcW), (T33<Q, N, B, B>::IndCalcB),  2583520320,  2796192900)
  4210.     TB (kqnkrr, false, true,  false, (T33<Q, N, R, R>::IndCalcW), (T33<Q, N, R, R>::IndCalcB),  2583520320,  2752842060)
  4211.     TB (kqbknn, false, false, false, (T33<Q, B, N, N>::IndCalcW), (T33<Q, B, N, N>::IndCalcB),  2677137390,  2602976160)
  4212.     TB (kqbkbb, false, false, false, (T33<Q, B, B, B>::IndCalcW), (T33<Q, B, B, B>::IndCalcB),  2677137390,  2796192900)
  4213.     TB (kqbkrr, false, false, false, (T33<Q, B, R, R>::IndCalcW), (T33<Q, B, R, R>::IndCalcB),  2677137390,  2752842060)
  4214.     TB (kqrknn, false, false, false, (T33<Q, R, N, N>::IndCalcW), (T33<Q, R, N, N>::IndCalcB),  2656134570,  2602976160)
  4215.     TB (kqrkbb, false, false, false, (T33<Q, R, B, B>::IndCalcW), (T33<Q, R, B, B>::IndCalcB),  2656134570,  2796192900)
  4216.     TB (kqrkrr, false, false, false, (T33<Q, R, R, R>::IndCalcW), (T33<Q, R, R, R>::IndCalcB),  2656134570,  2752842060)
  4217.     TB (kqqknn, false, false, false, (T33<Q, Q, N, N>::IndCalcW), (T33<Q, Q, N, N>::IndCalcB),  1237357440,  1301488080)
  4218.     TB (kqqkbn, false, false, false, (T33<Q, Q, B, N>::IndCalcW), (T33<Q, Q, B, N>::IndCalcB),  2474714880,  2744597400)
  4219.     TB (kqqkbb, false, false, false, (T33<Q, Q, B, B>::IndCalcW), (T33<Q, Q, B, B>::IndCalcB),  1237357440,  1398096450)
  4220.     TB (kqqkrn, false, false, false, (T33<Q, Q, R, N>::IndCalcW), (T33<Q, Q, R, N>::IndCalcB),  2474714880,  2723107830)
  4221.     TB (kqqkrb, false, false, false, (T33<Q, Q, R, B>::IndCalcW), (T33<Q, Q, R, B>::IndCalcB),  2474714880,  2822371200)
  4222.     TB (kqqkrr, false, false, false, (T33<Q, Q, R, R>::IndCalcW), (T33<Q, Q, R, R>::IndCalcB),  1237357440,  1376421030)
  4223.     TB (kqqkqn, false, false, false, (T33<Q, Q, Q, N>::IndCalcW), (T33<Q, Q, Q, N>::IndCalcB),  2474714880,  2583520320)
  4224.     TB (kqqkqb, false, false, false, (T33<Q, Q, Q, B>::IndCalcW), (T33<Q, Q, Q, B>::IndCalcB),  2474714880,  2677137390)
  4225.     TB (kqqkqr, false, false, false, (T33<Q, Q, Q, R>::IndCalcW), (T33<Q, Q, Q, R>::IndCalcB),  2474714880,  2656134570)
  4226.     TB (kqqkqq, true,  false, false, (T33<Q, Q, Q, Q>::IndCalcW), (T33<Q, Q, Q, Q>::IndCalcB),  1237357440,  1237357440)
  4227. #if defined (T_INDEX64)
  4228.     TB (kbnkbn, true,  false, false, (T33<B, N, B, N>::IndCalcW), (T33<B, N, B, N>::IndCalcB),  5489194800,  5489194800)
  4229.     TB (krnkrn, true,  false, false, (T33<R, N, R, N>::IndCalcW), (T33<R, N, R, N>::IndCalcB),  5446215660,  5446215660)
  4230.     TB (krbkrb, true,  false, false, (T33<R, B, R, B>::IndCalcW), (T33<R, B, R, B>::IndCalcB),  5644742400,  5644742400)
  4231.     TB (kqnkqn, true,  false, false, (T33<Q, N, Q, N>::IndCalcW), (T33<Q, N, Q, N>::IndCalcB),  5167040640,  5167040640)
  4232.     TB (kqbkqb, true,  false, false, (T33<Q, B, Q, B>::IndCalcW), (T33<Q, B, Q, B>::IndCalcB),  5354274780,  5354274780)
  4233.     TB (kqrkqr, true,  false, false, (T33<Q, R, Q, R>::IndCalcW), (T33<Q, R, Q, R>::IndCalcB),  5312269140,  5312269140)
  4234.     TB (krnkbn, false, true,  true,  (T33<R, N, B, N>::IndCalcW), (T33<R, N, B, N>::IndCalcB),  5446215660,  5489194800)
  4235.     TB (krbkbn, false, false, true,  (T33<R, B, B, N>::IndCalcW), (T33<R, B, B, N>::IndCalcB),  5644742400,  5489194800)
  4236.     TB (krbkrn, false, false, false, (T33<R, B, R, N>::IndCalcW), (T33<R, B, R, N>::IndCalcB),  5644742400,  5446215660)
  4237.     TB (kqnkbn, false, false, false, (T33<Q, N, B, N>::IndCalcW), (T33<Q, N, B, N>::IndCalcB),  5167040640,  5489194800)
  4238.     TB (kqnkrn, false, false, true,  (T33<Q, N, R, N>::IndCalcW), (T33<Q, N, R, N>::IndCalcB),  5167040640,  5446215660)
  4239.     TB (kqnkrb, false, false, true,  (T33<Q, N, R, B>::IndCalcW), (T33<Q, N, R, B>::IndCalcB),  5167040640,  5644742400)
  4240.     TB (kqbkbn, false, false, false, (T33<Q, B, B, N>::IndCalcW), (T33<Q, B, B, N>::IndCalcB),  5354274780,  5489194800)
  4241.     TB (kqbkrn, false, false, true,  (T33<Q, B, R, N>::IndCalcW), (T33<Q, B, R, N>::IndCalcB),  5354274780,  5446215660)
  4242.     TB (kqbkrb, false, false, true,  (T33<Q, B, R, B>::IndCalcW), (T33<Q, B, R, B>::IndCalcB),  5354274780,  5644742400)
  4243.     TB (kqbkqn, false, false, false, (T33<Q, B, Q, N>::IndCalcW), (T33<Q, B, Q, N>::IndCalcB),  5354274780,  5167040640)
  4244.     TB (kqrkbn, false, false, false, (T33<Q, R, B, N>::IndCalcW), (T33<Q, R, B, N>::IndCalcB),  5312269140,  5489194800)
  4245.     TB (kqrkrn, false, false, false, (T33<Q, R, R, N>::IndCalcW), (T33<Q, R, R, N>::IndCalcB),  5312269140,  5446215660)
  4246.     TB (kqrkrb, false, false, false, (T33<Q, R, R, B>::IndCalcW), (T33<Q, R, R, B>::IndCalcB),  5312269140,  5644742400)
  4247.     TB (kqrkqn, false, false, false, (T33<Q, R, Q, N>::IndCalcW), (T33<Q, R, Q, N>::IndCalcB),  5312269140,  5167040640)
  4248.     TB (kqrkqb, false, false, false, (T33<Q, R, Q, B>::IndCalcW), (T33<Q, R, Q, B>::IndCalcB),  5312269140,  5354274780)
  4249.  
  4250.     TB (kppkpp, true,  true,  false, (T33<P, P, P, P>::IndCalcW), (T33<P, P, P, P>::IndCalcBF),  1917741812,  1917741812)
  4251.     TB (knpkpp, false, true,  true,  (T33<N, P, P, P>::IndCalcW), (T33<N, P, P, P>::IndCalcB),   5088408829,  4966717366)
  4252.     TB (knpknp, true,  false, true,  (T33<N, P, N, P>::IndCalcW), (T33<N, P, N, P>::IndCalcBF), 12972508017, 12972508017)
  4253.     TB (knnkpp, false, true,  false, (T33<N, N, P, P>::IndCalcW), (T33<N, N, P, P>::IndCalcB),   3242803728,  3197807670)
  4254.     TB (knnknp, false, true,  true,  (T33<N, N, N, P>::IndCalcW), (T33<N, N, N, P>::IndCalcB),   8141507232,  8227988370)
  4255.     TB (kbpkpp, false, true,  true,  (T33<B, P, P, P>::IndCalcW), (T33<B, P, P, P>::IndCalcB),   5272919368,  4966717366)
  4256.     TB (kbpknp, false, true,  true,  (T33<B, P, N, P>::IndCalcW), (T33<B, P, N, P>::IndCalcB),  13442882944, 12972508017)
  4257.     TB (kbpknn, false, true,  true,  (T33<B, P, N, N>::IndCalcW), (T33<B, P, N, N>::IndCalcB),   8526316560,  8141507232)
  4258.     TB (kbpkbp, true,  false, true,  (T33<B, P, B, P>::IndCalcW), (T33<B, P, B, P>::IndCalcBF), 13442882944, 13442882944)
  4259.     TB (kbnkpp, false, true,  true,  (T33<B, N, P, P>::IndCalcW), (T33<B, N, P, P>::IndCalcB),   6838255224,  6395615340)
  4260.     TB (kbnknp, false, true,  true,  (T33<B, N, N, P>::IndCalcW), (T33<B, N, N, P>::IndCalcB),  17168385456, 16455976740)
  4261.     TB (kbnkbp, false, false, true,  (T33<B, N, B, P>::IndCalcW), (T33<B, N, B, P>::IndCalcB),  17168385456, 17052633120)
  4262.     TB (kbbkpp, false, false, false, (T33<B, B, P, P>::IndCalcW), (T33<B, B, P, P>::IndCalcB),   3483252720,  3197807670)
  4263.     TB (kbbknp, false, true,  true,  (T33<B, B, N, P>::IndCalcW), (T33<B, B, N, P>::IndCalcB),   8745187680,  8227988370)
  4264.     TB (kbbkbp, false, false, true,  (T33<B, B, B, P>::IndCalcW), (T33<B, B, B, P>::IndCalcB),   8745187680,  8526316560)
  4265.     TB (krpkpp, false, true,  true,  (T33<R, P, P, P>::IndCalcW), (T33<R, P, P, P>::IndCalcB),   5231873656,  4966717366)
  4266.     TB (krpknp, false, true,  true,  (T33<R, P, N, P>::IndCalcW), (T33<R, P, N, P>::IndCalcB),  13338233184, 12972508017)
  4267.     TB (krpknn, false, true,  true,  (T33<R, P, N, N>::IndCalcW), (T33<R, P, N, N>::IndCalcB),   8459934480,  8141507232)
  4268.     TB (krpkbp, false, true,  true,  (T33<R, P, B, P>::IndCalcW), (T33<R, P, B, P>::IndCalcB),  13338233184, 13442882944)
  4269.     TB (krpkbn, false, true,  true,  (T33<R, P, B, N>::IndCalcW), (T33<R, P, B, N>::IndCalcB),  16919868960, 17168385456)
  4270.     TB (krpkbb, false, true,  true,  (T33<R, P, B, B>::IndCalcW), (T33<R, P, B, B>::IndCalcB),   8459934480,  8745187680)
  4271.     TB (krpkrp, true,  false, true,  (T33<R, P, R, P>::IndCalcW), (T33<R, P, R, P>::IndCalcBF), 13338233184, 13338233184)
  4272.     TB (krnkpp, false, true,  true,  (T33<R, N, P, P>::IndCalcW), (T33<R, N, P, P>::IndCalcB),   6784283808,  6395615340)
  4273.     TB (krnknp, false, true,  true,  (T33<R, N, N, P>::IndCalcW), (T33<R, N, N, P>::IndCalcB),  17032882752, 16455976740)
  4274.     TB (krnkbp, false, true,  true,  (T33<R, N, B, P>::IndCalcW), (T33<R, N, B, P>::IndCalcB),  17032882752, 17052633120)
  4275.     TB (krnkrp, false, false, true,  (T33<R, N, R, P>::IndCalcW), (T33<R, N, R, P>::IndCalcB),  17032882752, 16919868906)
  4276.     TB (krbkpp, false, true,  true,  (T33<R, B, P, P>::IndCalcW), (T33<R, B, P, P>::IndCalcB),   7031275200,  6395615340)
  4277.     TB (krbknp, false, true,  true,  (T33<R, B, N, P>::IndCalcW), (T33<R, B, N, P>::IndCalcB),  17652988800, 16455976740)
  4278.     TB (krbkbp, false, false, true,  (T33<R, B, B, P>::IndCalcW), (T33<R, B, B, P>::IndCalcB),  17652988800, 17052633120)
  4279.     TB (krbkrp, false, false, true,  (T33<R, B, R, P>::IndCalcW), (T33<R, B, R, P>::IndCalcB),  17652988800, 16919868906)
  4280.     TB (krrkpp, false, true,  false, (T33<R, R, P, P>::IndCalcW), (T33<R, R, P, P>::IndCalcB),   3428678952,  3197807670)
  4281.     TB (krrknp, false, true,  true,  (T33<R, R, N, P>::IndCalcW), (T33<R, R, N, P>::IndCalcB),   8608504032,  8227988370)
  4282.     TB (krrkbp, false, false, true,  (T33<R, R, B, P>::IndCalcW), (T33<R, R, B, P>::IndCalcB),   8608504032,  8526316560)
  4283.     TB (krrkrp, false, false, true,  (T33<R, R, R, P>::IndCalcW), (T33<R, R, R, P>::IndCalcB),   8608504032,  8459934426)
  4284.     TB (kqpkpp, false, true,  true,  (T33<Q, P, P, P>::IndCalcW), (T33<Q, P, P, P>::IndCalcB),   4962533664,  4966717366)
  4285.     TB (kqpknp, false, false, true,  (T33<Q, P, N, P>::IndCalcW), (T33<Q, P, N, P>::IndCalcB),  12651597608, 12972508017)
  4286.     TB (kqpknn, false, false, true,  (T33<Q, P, N, N>::IndCalcW), (T33<Q, P, N, N>::IndCalcB),   8024443680,  8141507232)
  4287.     TB (kqpkbp, false, false, true,  (T33<Q, P, B, P>::IndCalcW), (T33<Q, P, B, P>::IndCalcB),  12651597608, 13442882944)
  4288.     TB (kqpkbn, false, false, true,  (T33<Q, P, B, N>::IndCalcW), (T33<Q, P, B, N>::IndCalcB),  16048887360, 17168385456)
  4289.     TB (kqpkbb, false, false, true,  (T33<Q, P, B, B>::IndCalcW), (T33<Q, P, B, B>::IndCalcB),   8024443680,  8745187680)
  4290.     TB (kqpkrp, false, false, true,  (T33<Q, P, R, P>::IndCalcW), (T33<Q, P, R, P>::IndCalcB),  12651597608, 13338233184)
  4291.     TB (kqpkrn, false, false, true,  (T33<Q, P, R, N>::IndCalcW), (T33<Q, P, R, N>::IndCalcB),  16048887360, 17032882752)
  4292.     TB (kqpkrb, false, true,  true,  (T33<Q, P, R, B>::IndCalcW), (T33<Q, P, R, B>::IndCalcB),  16048887360, 17652988800)
  4293.     TB (kqpkrr, false, true,  true,  (T33<Q, P, R, R>::IndCalcW), (T33<Q, P, R, R>::IndCalcB),   8024443680,  8608504032)
  4294.     TB (kqpkqp, true,  true,  true,  (T33<Q, P, Q, P>::IndCalcW), (T33<Q, P, Q, P>::IndCalcBF), 12651597608, 12651597608)
  4295.     TB (kqnkpp, false, true,  true,  (T33<Q, N, P, P>::IndCalcW), (T33<Q, N, P, P>::IndCalcB),   6436756032,  6395615340)
  4296.     TB (kqnknp, false, false, true,  (T33<Q, N, N, P>::IndCalcW), (T33<Q, N, N, P>::IndCalcB),  16160366208, 16455976740)
  4297.     TB (kqnkbp, false, false, true,  (T33<Q, N, B, P>::IndCalcW), (T33<Q, N, B, P>::IndCalcB),  16160366208, 17052633120)
  4298.     TB (kqnkrp, false, false, true,  (T33<Q, N, R, P>::IndCalcW), (T33<Q, N, R, P>::IndCalcB),  16160366208, 16919868906)
  4299.     TB (kqnkqp, false, true,  true,  (T33<Q, N, Q, P>::IndCalcW), (T33<Q, N, Q, P>::IndCalcB),  16160366208, 16048887306)
  4300.     TB (kqbkpp, false, false, true,  (T33<Q, B, P, P>::IndCalcW), (T33<Q, B, P, P>::IndCalcB),   6669728640,  6395615340)
  4301.     TB (kqbknp, false, false, true,  (T33<Q, B, N, P>::IndCalcW), (T33<Q, B, N, P>::IndCalcB),  16745276160, 16455976740)
  4302.     TB (kqbkbp, false, false, true,  (T33<Q, B, B, P>::IndCalcW), (T33<Q, B, B, P>::IndCalcB),  16745276160, 17052633120)
  4303.     TB (kqbkrp, false, false, true,  (T33<Q, B, R, P>::IndCalcW), (T33<Q, B, R, P>::IndCalcB),  16745276160, 16919868906)
  4304.     TB (kqbkqp, false, true,  true,  (T33<Q, B, Q, P>::IndCalcW), (T33<Q, B, Q, P>::IndCalcB),  16745276160, 16048887306)
  4305.     TB (kqrkpp, false, false, true,  (T33<Q, R, P, P>::IndCalcW), (T33<Q, R, P, P>::IndCalcB),   6616853640,  6395615340)
  4306.     TB (kqrknp, false, false, true,  (T33<Q, R, N, P>::IndCalcW), (T33<Q, R, N, P>::IndCalcB),  16612871664, 16455976740)
  4307.     TB (kqrkbp, false, false, true,  (T33<Q, R, B, P>::IndCalcW), (T33<Q, R, B, P>::IndCalcB),  16612871664, 17052633120)
  4308.     TB (kqrkrp, false, false, true,  (T33<Q, R, R, P>::IndCalcW), (T33<Q, R, R, P>::IndCalcB),  16612871664, 16919868906)
  4309.     TB (kqrkqp, false, true,  true,  (T33<Q, R, Q, P>::IndCalcW), (T33<Q, R, Q, P>::IndCalcB),  16612871664, 16048887306)
  4310.     TB (kqqkpp, false, false, false, (T33<Q, Q, P, P>::IndCalcW), (T33<Q, Q, P, P>::IndCalcB),   3082498008,  3197807670)
  4311.     TB (kqqknp, false, false, true,  (T33<Q, Q, N, P>::IndCalcW), (T33<Q, Q, N, P>::IndCalcB),   7739363232,  8227988370)
  4312.     TB (kqqkbp, false, false, true,  (T33<Q, Q, B, P>::IndCalcW), (T33<Q, Q, B, P>::IndCalcB),   7739363232,  8526316560)
  4313.     TB (kqqkrp, false, false, true,  (T33<Q, Q, R, P>::IndCalcW), (T33<Q, Q, R, P>::IndCalcB),   7739363232,  8459934426)
  4314.     TB (kqqkqp, false, false, true,  (T33<Q, Q, Q, P>::IndCalcW), (T33<Q, Q, Q, P>::IndCalcB),   7739363232,  8024443626)
  4315. #endif  // T_INDEX64
  4316. #endif  // T33_INCLUDE
  4317.  
  4318. #if defined (T42_INCLUDE)
  4319.     TB (knnnkn, false, false, false, (T42<N, N, N, N>::IndCalcW), (T42<N, N, N, N>::IndCalcB),  795687393,  945889180)
  4320.     TB (kbnnkn, false, false, false, (T42<B, N, N, N>::IndCalcW), (T42<B, N, N, N>::IndCalcB), 2560971346, 2837667540)
  4321.     TB (kbbnkn, false, false, false, (T42<B, B, N, N>::IndCalcW), (T42<B, B, N, N>::IndCalcB), 2654033462, 2837667540)
  4322.     TB (kbbbkn, false, false, false, (T42<B, B, B, N>::IndCalcW), (T42<B, B, B, N>::IndCalcB),  885603570,  945889180)
  4323.     TB (krnnkn, false, false, false, (T42<R, N, N, N>::IndCalcW), (T42<R, N, N, N>::IndCalcB), 2540315682, 2837667540)
  4324.     TB (krbbkn, false, false, false, (T42<R, B, B, N>::IndCalcW), (T42<R, B, B, N>::IndCalcB), 2728283251, 2837667540)
  4325.     TB (krrnkn, false, false, false, (T42<R, R, N, N>::IndCalcW), (T42<R, R, N, N>::IndCalcB), 2611650399, 2837667540)
  4326.     TB (krrbkn, false, false, false, (T42<R, R, B, N>::IndCalcW), (T42<R, R, B, N>::IndCalcB), 2706549480, 2837667540)
  4327.     TB (krrrkn, false, false, false, (T42<R, R, R, N>::IndCalcW), (T42<R, R, R, N>::IndCalcB),  864592254,  945889180)
  4328.     TB (kqnnkn, false, false, false, (T42<Q, N, N, N>::IndCalcW), (T42<Q, N, N, N>::IndCalcB), 2411545114, 2837667540)
  4329.     TB (kqbbkn, false, false, false, (T42<Q, B, B, N>::IndCalcW), (T42<Q, B, B, N>::IndCalcB), 2588901061, 2837667540)
  4330.     TB (kqrrkn, false, false, false, (T42<Q, R, R, N>::IndCalcW), (T42<Q, R, R, N>::IndCalcB), 2547484064, 2837667540)
  4331.     TB (kqqnkn, false, false, false, (T42<Q, Q, N, N>::IndCalcW), (T42<Q, Q, N, N>::IndCalcB), 2350606433, 2837667540)
  4332.     TB (kqqbkn, false, false, false, (T42<Q, Q, B, N>::IndCalcW), (T42<Q, Q, B, N>::IndCalcB), 2434987407, 2837667540)
  4333.     TB (kqqrkn, false, false, false, (T42<Q, Q, R, N>::IndCalcW), (T42<Q, Q, R, N>::IndCalcB), 2415271436, 2837667540)
  4334.     TB (kqqqkn, false, false, false, (T42<Q, Q, Q, N>::IndCalcW), (T42<Q, Q, Q, N>::IndCalcB),  736854363,  945889180)
  4335.     TB (knnnkb, false, false, false, (T42<N, N, N, B>::IndCalcW), (T42<N, N, N, B>::IndCalcB),  795687393,  980475570)
  4336.     TB (kbnnkb, false, false, false, (T42<B, N, N, B>::IndCalcW), (T42<B, N, N, B>::IndCalcB), 2560971346, 2941426710)
  4337.     TB (kbbnkb, false, false, false, (T42<B, B, N, B>::IndCalcW), (T42<B, B, N, B>::IndCalcB), 2654033462, 2941426710)
  4338.     TB (kbbbkb, false, false, false, (T42<B, B, B, B>::IndCalcW), (T42<B, B, B, B>::IndCalcB),  885603570,  980475570)
  4339.     TB (krnnkb, false, false, false, (T42<R, N, N, B>::IndCalcW), (T42<R, N, N, B>::IndCalcB), 2540315682, 2941426710)
  4340.     TB (krbbkb, false, false, false, (T42<R, B, B, B>::IndCalcW), (T42<R, B, B, B>::IndCalcB), 2728283251, 2941426710)
  4341.     TB (krrnkb, false, false, false, (T42<R, R, N, B>::IndCalcW), (T42<R, R, N, B>::IndCalcB), 2611650399, 2941426710)
  4342.     TB (krrbkb, false, false, false, (T42<R, R, B, B>::IndCalcW), (T42<R, R, B, B>::IndCalcB), 2706549480, 2941426710)
  4343.     TB (krrrkb, false, false, false, (T42<R, R, R, B>::IndCalcW), (T42<R, R, R, B>::IndCalcB),  864592254,  980475570)
  4344.     TB (kqnnkb, false, false, false, (T42<Q, N, N, B>::IndCalcW), (T42<Q, N, N, B>::IndCalcB), 2411545114, 2941426710)
  4345.     TB (kqbbkb, false, false, false, (T42<Q, B, B, B>::IndCalcW), (T42<Q, B, B, B>::IndCalcB), 2588901061, 2941426710)
  4346.     TB (kqrrkb, false, false, false, (T42<Q, R, R, B>::IndCalcW), (T42<Q, R, R, B>::IndCalcB), 2547484064, 2941426710)
  4347.     TB (kqqnkb, false, false, false, (T42<Q, Q, N, B>::IndCalcW), (T42<Q, Q, N, B>::IndCalcB), 2350606433, 2941426710)
  4348.     TB (kqqbkb, false, false, false, (T42<Q, Q, B, B>::IndCalcW), (T42<Q, Q, B, B>::IndCalcB), 2434987407, 2941426710)
  4349.     TB (kqqrkb, false, false, false, (T42<Q, Q, R, B>::IndCalcW), (T42<Q, Q, R, B>::IndCalcB), 2415271436, 2941426710)
  4350.     TB (kqqqkb, false, false, false, (T42<Q, Q, Q, B>::IndCalcW), (T42<Q, Q, Q, B>::IndCalcB),  736854363,  980475570)
  4351.     TB (knnnkr, false, false, false, (T42<N, N, N, R>::IndCalcW), (T42<N, N, N, R>::IndCalcB),  795687393,  973025640)
  4352.     TB (kbnnkr, false, false, false, (T42<B, N, N, R>::IndCalcW), (T42<B, N, N, R>::IndCalcB), 2560971346, 2919076920)
  4353.     TB (kbbnkr, false, false, false, (T42<B, B, N, R>::IndCalcW), (T42<B, B, N, R>::IndCalcB), 2654033462, 2919076920)
  4354.     TB (kbbbkr, false, false, false, (T42<B, B, B, R>::IndCalcW), (T42<B, B, B, R>::IndCalcB),  885603570,  973025640)
  4355.     TB (krnnkr, false, false, false, (T42<R, N, N, R>::IndCalcW), (T42<R, N, N, R>::IndCalcB), 2540315682, 2919076920)
  4356.     TB (krbbkr, false, false, false, (T42<R, B, B, R>::IndCalcW), (T42<R, B, B, R>::IndCalcB), 2728283251, 2919076920)
  4357.     TB (krrnkr, false, false, false, (T42<R, R, N, R>::IndCalcW), (T42<R, R, N, R>::IndCalcB), 2611650399, 2919076920)
  4358.     TB (krrbkr, false, false, false, (T42<R, R, B, R>::IndCalcW), (T42<R, R, B, R>::IndCalcB), 2706549480, 2919076920)
  4359.     TB (krrrkr, false, false, false, (T42<R, R, R, R>::IndCalcW), (T42<R, R, R, R>::IndCalcB),  864592254,  973025640)
  4360.     TB (kqnnkr, false, false, false, (T42<Q, N, N, R>::IndCalcW), (T42<Q, N, N, R>::IndCalcB), 2411545114, 2919076920)
  4361.     TB (kqbbkr, false, false, false, (T42<Q, B, B, R>::IndCalcW), (T42<Q, B, B, R>::IndCalcB), 2588901061, 2919076920)
  4362.     TB (kqrrkr, false, false, false, (T42<Q, R, R, R>::IndCalcW), (T42<Q, R, R, R>::IndCalcB), 2547484064, 2919076920)
  4363.     TB (kqqnkr, false, false, false, (T42<Q, Q, N, R>::IndCalcW), (T42<Q, Q, N, R>::IndCalcB), 2350606433, 2919076920)
  4364.     TB (kqqbkr, false, false, false, (T42<Q, Q, B, R>::IndCalcW), (T42<Q, Q, B, R>::IndCalcB), 2434987407, 2919076920)
  4365.     TB (kqqrkr, false, false, false, (T42<Q, Q, R, R>::IndCalcW), (T42<Q, Q, R, R>::IndCalcB), 2415271436, 2919076920)
  4366.     TB (kqqqkr, false, false, false, (T42<Q, Q, Q, R>::IndCalcW), (T42<Q, Q, Q, R>::IndCalcB),  736854363,  973025640)
  4367.     TB (knnnkq, false, false, false, (T42<N, N, N, Q>::IndCalcW), (T42<N, N, N, Q>::IndCalcB),  795687393,  922603650)
  4368.     TB (kbnnkq, false, false, false, (T42<B, N, N, Q>::IndCalcW), (T42<B, N, N, Q>::IndCalcB), 2560971346, 2767810950)
  4369.     TB (kbbnkq, false, false, false, (T42<B, B, N, Q>::IndCalcW), (T42<B, B, N, Q>::IndCalcB), 2654033462, 2767810950)
  4370.     TB (kbbbkq, false, false, false, (T42<B, B, B, Q>::IndCalcW), (T42<B, B, B, Q>::IndCalcB),  885603570,  922603650)
  4371.     TB (krnnkq, false, false, false, (T42<R, N, N, Q>::IndCalcW), (T42<R, N, N, Q>::IndCalcB), 2540315682, 2767810950)
  4372.     TB (krbbkq, false, false, false, (T42<R, B, B, Q>::IndCalcW), (T42<R, B, B, Q>::IndCalcB), 2728283251, 2767810950)
  4373.     TB (krrnkq, false, false, false, (T42<R, R, N, Q>::IndCalcW), (T42<R, R, N, Q>::IndCalcB), 2611650399, 2767810950)
  4374.     TB (krrbkq, false, false, false, (T42<R, R, B, Q>::IndCalcW), (T42<R, R, B, Q>::IndCalcB), 2706549480, 2767810950)
  4375.     TB (krrrkq, false, false, false, (T42<R, R, R, Q>::IndCalcW), (T42<R, R, R, Q>::IndCalcB),  864592254,  922603650)
  4376.     TB (kqnnkq, false, false, false, (T42<Q, N, N, Q>::IndCalcW), (T42<Q, N, N, Q>::IndCalcB), 2411545114, 2767810950)
  4377.     TB (kqbbkq, false, false, false, (T42<Q, B, B, Q>::IndCalcW), (T42<Q, B, B, Q>::IndCalcB), 2588901061, 2767810950)
  4378.     TB (kqrrkq, false, false, false, (T42<Q, R, R, Q>::IndCalcW), (T42<Q, R, R, Q>::IndCalcB), 2547484064, 2767810950)
  4379.     TB (kqqnkq, false, false, false, (T42<Q, Q, N, Q>::IndCalcW), (T42<Q, Q, N, Q>::IndCalcB), 2350606433, 2767810950)
  4380.     TB (kqqbkq, false, false, false, (T42<Q, Q, B, Q>::IndCalcW), (T42<Q, Q, B, Q>::IndCalcB), 2434987407, 2767810950)
  4381.     TB (kqqrkq, false, false, false, (T42<Q, Q, R, Q>::IndCalcW), (T42<Q, Q, R, Q>::IndCalcB), 2415271436, 2767810950)
  4382.     TB (kqqqkq, false, false, false, (T42<Q, Q, Q, Q>::IndCalcW), (T42<Q, Q, Q, Q>::IndCalcB),  736854363,  922603650)
  4383. #if defined (T_INDEX64)
  4384.     TB (krbnkn, false, false, false, (T42<R, B, N, N>::IndCalcW), (T42<R, B, N, N>::IndCalcB), 5356454122, 5675335080)
  4385.     TB (kqbnkn, false, false, false, (T42<Q, B, N, N>::IndCalcW), (T42<Q, B, N, N>::IndCalcB), 5083836303, 5675335080)
  4386.     TB (kqrnkn, false, false, false, (T42<Q, R, N, N>::IndCalcW), (T42<Q, R, N, N>::IndCalcB), 5042765577, 5675335080)
  4387.     TB (kqrbkn, false, false, false, (T42<Q, R, B, N>::IndCalcW), (T42<Q, R, B, N>::IndCalcB), 5224919581, 5675335080)
  4388.     TB (krbnkb, false, false, false, (T42<R, B, N, B>::IndCalcW), (T42<R, B, N, B>::IndCalcB), 5356454122, 5882853420)
  4389.     TB (kqbnkb, false, false, false, (T42<Q, B, N, B>::IndCalcW), (T42<Q, B, N, B>::IndCalcB), 5083836303, 5882853420)
  4390.     TB (kqrnkb, false, false, false, (T42<Q, R, N, B>::IndCalcW), (T42<Q, R, N, B>::IndCalcB), 5042765577, 5882853420)
  4391.     TB (kqrbkb, false, false, false, (T42<Q, R, B, B>::IndCalcW), (T42<Q, R, B, B>::IndCalcB), 5224919581, 5882853420)
  4392.     TB (krbnkr, false, false, false, (T42<R, B, N, R>::IndCalcW), (T42<R, B, N, R>::IndCalcB), 5356454122, 5838153840)
  4393.     TB (kqbnkr, false, false, false, (T42<Q, B, N, R>::IndCalcW), (T42<Q, B, N, R>::IndCalcB), 5083836303, 5838153840)
  4394.     TB (kqrnkr, false, false, false, (T42<Q, R, N, R>::IndCalcW), (T42<Q, R, N, R>::IndCalcB), 5042765577, 5838153840)
  4395.     TB (kqrbkr, false, false, false, (T42<Q, R, B, R>::IndCalcW), (T42<Q, R, B, R>::IndCalcB), 5224919581, 5838153840)
  4396.     TB (krbnkq, false, false, false, (T42<R, B, N, Q>::IndCalcW), (T42<R, B, N, Q>::IndCalcB), 5356454122, 5535621900)
  4397.     TB (kqbnkq, false, false, true,  (T42<Q, B, N, Q>::IndCalcW), (T42<Q, B, N, Q>::IndCalcB), 5083836303, 5535621900)
  4398.     TB (kqrnkq, false, false, false, (T42<Q, R, N, Q>::IndCalcW), (T42<Q, R, N, Q>::IndCalcB), 5042765577, 5535621900)
  4399.     TB (kqrbkq, false, false, false, (T42<Q, R, B, Q>::IndCalcW), (T42<Q, R, B, Q>::IndCalcB), 5224919581, 5535621900)
  4400.  
  4401.     TB (kpppkp, false, true,  false, (T42<P, P, P, P>::IndCalcW), (T42<P, P, P, P>::IndCalcB),  1196695343,  1348100424)
  4402.     TB (knppkp, false, true,  true,  (T42<N, P, P, P>::IndCalcW), (T42<N, P, P, P>::IndCalcB),  4796630713,  5271860528)
  4403.     TB (knnpkp, false, false, true,  (T42<N, N, P, P>::IndCalcW), (T42<N, N, P, P>::IndCalcB),  6156616111,  6835422612)
  4404.     TB (knnnkp, false, false, false, (T42<N, N, N, P>::IndCalcW), (T42<N, N, N, P>::IndCalcB),  2531022144,  2939087360)
  4405.     TB (kbppkp, false, true,  true,  (T42<B, P, P, P>::IndCalcW), (T42<B, P, P, P>::IndCalcB),  4969303175,  5271860528)
  4406.     TB (kbnpkp, false, true,  true,  (T42<B, N, P, P>::IndCalcW), (T42<B, N, P, P>::IndCalcB), 12979462304, 13670845224)
  4407.     TB (kbnnkp, false, false, true,  (T42<B, N, N, P>::IndCalcW), (T42<B, N, N, P>::IndCalcB),  8146120416,  8817262080)
  4408.     TB (kbbpkp, false, true,  true,  (T42<B, B, P, P>::IndCalcW), (T42<B, B, P, P>::IndCalcB),  6609838740,  6835422612)
  4409.     TB (kbbnkp, false, false, true,  (T42<B, B, N, P>::IndCalcW), (T42<B, B, N, P>::IndCalcB),  8441899104,  8817262080)
  4410.     TB (kbbbkp, false, false, false, (T42<B, B, B, P>::IndCalcW), (T42<B, B, B, P>::IndCalcB),  2816801280,  2939087360)
  4411.     TB (krppkp, false, true,  true,  (T42<R, P, P, P>::IndCalcW), (T42<R, P, P, P>::IndCalcB),  4929998839,  5271860528)
  4412.     TB (krnpkp, false, true,  true,  (T42<R, N, P, P>::IndCalcW), (T42<R, N, P, P>::IndCalcB), 12875424829, 13670845224)
  4413.     TB (krnnkp, false, false, true,  (T42<R, N, N, P>::IndCalcW), (T42<R, N, N, P>::IndCalcB),  8079921360,  8817262080)
  4414.     TB (krbpkp, false, true,  true,  (T42<R, B, P, P>::IndCalcW), (T42<R, B, P, P>::IndCalcB), 13340861520, 13670845224)
  4415.     TB (krbnkp, false, false, true,  (T42<R, B, N, P>::IndCalcW), (T42<R, B, N, P>::IndCalcB), 17036639904, 17634524160)
  4416.     TB (krbbkp, false, false, true,  (T42<R, B, B, P>::IndCalcW), (T42<R, B, B, P>::IndCalcB),  8677177872,  8817262080)
  4417.     TB (krrpkp, false, true,  true,  (T42<R, R, P, P>::IndCalcW), (T42<R, R, P, P>::IndCalcB),  6504899238,  6835422612)
  4418.     TB (krrnkp, false, false, true,  (T42<R, R, N, P>::IndCalcW), (T42<R, R, N, P>::IndCalcB),  8306047872,  8817262080)
  4419.     TB (krrbkp, false, false, true,  (T42<R, R, B, P>::IndCalcW), (T42<R, R, B, P>::IndCalcB),  8607504960,  8817262080)
  4420.     TB (krrrkp, false, false, false, (T42<R, R, R, P>::IndCalcW), (T42<R, R, R, P>::IndCalcB),  2749283520,  2939087360)
  4421.     TB (kqppkp, false, true,  true,  (T42<Q, P, P, P>::IndCalcW), (T42<Q, P, P, P>::IndCalcB),  4677701571,  5271860528)
  4422.     TB (kqnpkp, false, true,  true,  (T42<Q, N, P, P>::IndCalcW), (T42<Q, N, P, P>::IndCalcB), 12219736849, 13670845224)
  4423.     TB (kqnnkp, false, false, true,  (T42<Q, N, N, P>::IndCalcW), (T42<Q, N, N, P>::IndCalcB),  7670559696,  8817262080)
  4424.     TB (kqbpkp, false, true,  true,  (T42<Q, B, P, P>::IndCalcW), (T42<Q, B, P, P>::IndCalcB), 12658882024, 13670845224)
  4425.     TB (kqbnkp, false, false, true,  (T42<Q, B, N, P>::IndCalcW), (T42<Q, B, N, P>::IndCalcB), 16170070752, 17634524160)
  4426.     TB (kqbbkp, false, false, true,  (T42<Q, B, B, P>::IndCalcW), (T42<Q, B, B, P>::IndCalcB),  8234170512,  8817262080)
  4427.     TB (kqrpkp, false, false, true,  (T42<Q, R, P, P>::IndCalcW), (T42<Q, R, P, P>::IndCalcB), 12557225406, 13670845224)
  4428.     TB (kqrnkp, false, false, true,  (T42<Q, R, N, P>::IndCalcW), (T42<Q, R, N, P>::IndCalcB), 16038464256, 17634524160)
  4429.     TB (kqrbkp, false, false, true,  (T42<Q, R, B, P>::IndCalcW), (T42<Q, R, B, P>::IndCalcB), 16617170832, 17634524160)
  4430.     TB (kqrrkp, false, false, true,  (T42<Q, R, R, P>::IndCalcW), (T42<Q, R, R, P>::IndCalcB),  8101097520,  8817262080)
  4431.     TB (kqqpkp, false, false, true,  (T42<Q, Q, P, P>::IndCalcW), (T42<Q, Q, P, P>::IndCalcB),  5851888362,  6835422612)
  4432.     TB (kqqnkp, false, false, true,  (T42<Q, Q, N, P>::IndCalcW), (T42<Q, Q, N, P>::IndCalcB),  7476276864,  8817262080)
  4433.     TB (kqqbkp, false, false, true,  (T42<Q, Q, B, P>::IndCalcW), (T42<Q, Q, B, P>::IndCalcB),  7744392000,  8817262080)
  4434.     TB (kqqrkp, false, false, true,  (T42<Q, Q, R, P>::IndCalcW), (T42<Q, Q, R, P>::IndCalcB),  7680886080,  8817262080)
  4435.     TB (kqqqkp, false, false, false, (T42<Q, Q, Q, P>::IndCalcW), (T42<Q, Q, Q, P>::IndCalcB),  2343300048,  2939087360)
  4436.     TB (kpppkn, false, false, false, (T42<P, P, P, N>::IndCalcW), (T42<P, P, P, N>::IndCalcB),  1537640536,  1777129408)
  4437.     TB (knppkn, false, false, true,  (T42<N, P, P, N>::IndCalcW), (T42<N, P, P, N>::IndCalcB),  6071020409,  6838084896)
  4438.     TB (knnpkn, false, false, true,  (T42<N, N, P, N>::IndCalcW), (T42<N, N, P, N>::IndCalcB),  7677994559,  8729470080)
  4439.     TB (kbppkn, false, false, true,  (T42<B, P, P, N>::IndCalcW), (T42<B, P, P, N>::IndCalcB),  6289527204,  6838084896)
  4440.     TB (kbnpkn, false, false, true,  (T42<B, N, P, N>::IndCalcW), (T42<B, N, P, N>::IndCalcB), 16186823401, 17458940160)
  4441.     TB (kbbpkn, false, false, true,  (T42<B, B, P, N>::IndCalcW), (T42<B, B, P, N>::IndCalcB),  8243187360,  8729470080)
  4442.     TB (krppkn, false, false, true,  (T42<R, P, P, N>::IndCalcW), (T42<R, P, P, N>::IndCalcB),  6239761412,  6838084896)
  4443.     TB (krnpkn, false, false, true,  (T42<R, N, P, N>::IndCalcW), (T42<R, N, P, N>::IndCalcB), 16057066825, 17458940160)
  4444.     TB (krbpkn, false, false, true,  (T42<R, B, P, N>::IndCalcW), (T42<R, B, P, N>::IndCalcB), 16637490240, 17458940160)
  4445.     TB (krrpkn, false, false, true,  (T42<R, R, P, N>::IndCalcW), (T42<R, R, P, N>::IndCalcB),  8112305064,  8729470080)
  4446.     TB (kqppkn, false, false, true,  (T42<Q, P, P, N>::IndCalcW), (T42<Q, P, P, N>::IndCalcB),  5920486098,  6838084896)
  4447.     TB (kqnpkn, false, false, true,  (T42<Q, N, P, N>::IndCalcW), (T42<Q, N, P, N>::IndCalcB), 15239383701, 17458940160)
  4448.     TB (kqbpkn, false, false, true,  (T42<Q, B, P, N>::IndCalcW), (T42<Q, B, P, N>::IndCalcB), 15787021288, 17458940160)
  4449.     TB (kqrpkn, false, false, true,  (T42<Q, R, P, N>::IndCalcW), (T42<Q, R, P, N>::IndCalcB), 15660230819, 17458940160)
  4450.     TB (kqqpkn, false, false, true,  (T42<Q, Q, P, N>::IndCalcW), (T42<Q, Q, P, N>::IndCalcB),  7297961576,  8729470080)
  4451.     TB (kpppkb, false, false, false, (T42<P, P, P, B>::IndCalcW), (T42<P, P, P, B>::IndCalcB),  1537640536,  1842024000)
  4452.     TB (knppkb, false, false, true,  (T42<N, P, P, B>::IndCalcW), (T42<N, P, P, B>::IndCalcB),  6071020409,  7087788000)
  4453.     TB (knnpkb, false, false, true,  (T42<N, N, P, B>::IndCalcW), (T42<N, N, P, B>::IndCalcB),  7677994559,  9048240000)
  4454.     TB (kbppkb, false, false, true,  (T42<B, P, P, B>::IndCalcW), (T42<B, P, P, B>::IndCalcB),  6289527204,  7087788000)
  4455.     TB (kbnpkb, false, false, true,  (T42<B, N, P, B>::IndCalcW), (T42<B, N, P, B>::IndCalcB), 16186823401, 18096480000)
  4456.     TB (kbbpkb, false, false, true,  (T42<B, B, P, B>::IndCalcW), (T42<B, B, P, B>::IndCalcB),  8243187360,  9048240000)
  4457.     TB (krppkb, false, false, true,  (T42<R, P, P, B>::IndCalcW), (T42<R, P, P, B>::IndCalcB),  6239761412,  7087788000)
  4458.     TB (krnpkb, false, false, true,  (T42<R, N, P, B>::IndCalcW), (T42<R, N, P, B>::IndCalcB), 16057066825, 18096480000)
  4459.     TB (krbpkb, false, false, true,  (T42<R, B, P, B>::IndCalcW), (T42<R, B, P, B>::IndCalcB), 16637490240, 18096480000)
  4460.     TB (krrpkb, false, false, true,  (T42<R, R, P, B>::IndCalcW), (T42<R, R, P, B>::IndCalcB),  8112305064,  9048240000)
  4461.     TB (kqppkb, false, false, true,  (T42<Q, P, P, B>::IndCalcW), (T42<Q, P, P, B>::IndCalcB),  5920486098,  7087788000)
  4462.     TB (kqnpkb, false, false, true,  (T42<Q, N, P, B>::IndCalcW), (T42<Q, N, P, B>::IndCalcB), 15239383701, 18096480000)
  4463.     TB (kqbpkb, false, false, true,  (T42<Q, B, P, B>::IndCalcW), (T42<Q, B, P, B>::IndCalcB), 15787021288, 18096480000)
  4464.     TB (kqrpkb, false, false, true,  (T42<Q, R, P, B>::IndCalcW), (T42<Q, R, P, B>::IndCalcB), 15660230819, 18096480000)
  4465.     TB (kqqpkb, false, false, true,  (T42<Q, Q, P, B>::IndCalcW), (T42<Q, Q, P, B>::IndCalcB),  7297961576,  9048240000)
  4466.     TB (kpppkr, false, false, false, (T42<P, P, P, R>::IndCalcW), (T42<P, P, P, R>::IndCalcB),  1537640536,  1827875872)
  4467.     TB (knppkr, false, false, true,  (T42<N, P, P, R>::IndCalcW), (T42<N, P, P, R>::IndCalcB),  6071020409,  7033481568)
  4468.     TB (knnpkr, false, false, true,  (T42<N, N, P, R>::IndCalcW), (T42<N, N, P, R>::IndCalcB),  7677994559,  8978912640)
  4469.     TB (kbppkr, false, true,  true,  (T42<B, P, P, R>::IndCalcW), (T42<B, P, P, R>::IndCalcB),  6289527204,  7033481568)
  4470.     TB (kbnpkr, false, true,  true,  (T42<B, N, P, R>::IndCalcW), (T42<B, N, P, R>::IndCalcB), 16186823401, 17957825280)
  4471.     TB (kbbpkr, false, true,  true,  (T42<B, B, P, R>::IndCalcW), (T42<B, B, P, R>::IndCalcB),  8243187360,  8978912640)
  4472.     TB (krppkr, false, false, true,  (T42<R, P, P, R>::IndCalcW), (T42<R, P, P, R>::IndCalcB),  6239761412,  7033481568)
  4473.     TB (krnpkr, false, false, true,  (T42<R, N, P, R>::IndCalcW), (T42<R, N, P, R>::IndCalcB), 16057066825, 17957825280)
  4474.     TB (krbpkr, false, false, true,  (T42<R, B, P, R>::IndCalcW), (T42<R, B, P, R>::IndCalcB), 16637490240, 17957825280)
  4475.     TB (krrpkr, false, false, true,  (T42<R, R, P, R>::IndCalcW), (T42<R, R, P, R>::IndCalcB),  8112305064,  8978912640)
  4476.     TB (kqppkr, false, false, true,  (T42<Q, P, P, R>::IndCalcW), (T42<Q, P, P, R>::IndCalcB),  5920486098,  7033481568)
  4477.     TB (kqnpkr, false, false, true,  (T42<Q, N, P, R>::IndCalcW), (T42<Q, N, P, R>::IndCalcB), 15239383701, 17957825280)
  4478.     TB (kqbpkr, false, false, true,  (T42<Q, B, P, R>::IndCalcW), (T42<Q, B, P, R>::IndCalcB), 15787021288, 17957825280)
  4479.     TB (kqrpkr, false, false, true,  (T42<Q, R, P, R>::IndCalcW), (T42<Q, R, P, R>::IndCalcB), 15660230819, 17957825280)
  4480.     TB (kqqpkr, false, false, true,  (T42<Q, Q, P, R>::IndCalcW), (T42<Q, Q, P, R>::IndCalcB),  7297961576,  8978912640)
  4481.     TB (kpppkq, false, true,  false, (T42<P, P, P, Q>::IndCalcW), (T42<P, P, P, Q>::IndCalcB),  1537640536,  1733232160)
  4482.     TB (knppkq, false, true,  true,  (T42<N, P, P, Q>::IndCalcW), (T42<N, P, P, Q>::IndCalcB),  6071020409,  6669309024)
  4483.     TB (knnpkq, false, false, true,  (T42<N, N, P, Q>::IndCalcW), (T42<N, N, P, Q>::IndCalcB),  7677994559,  8514011520)
  4484.     TB (kbppkq, false, true,  true,  (T42<B, P, P, Q>::IndCalcW), (T42<B, P, P, Q>::IndCalcB),  6289527204,  6669309024)
  4485.     TB (kbnpkq, false, true,  true,  (T42<B, N, P, Q>::IndCalcW), (T42<B, N, P, Q>::IndCalcB), 16186823401, 17028023040)
  4486.     TB (kbbpkq, false, true,  true,  (T42<B, B, P, Q>::IndCalcW), (T42<B, B, P, Q>::IndCalcB),  8243187360,  8514011520)
  4487.     TB (krppkq, false, true,  true,  (T42<R, P, P, Q>::IndCalcW), (T42<R, P, P, Q>::IndCalcB),  6239761412,  6669309024)
  4488.     TB (krnpkq, false, true,  true,  (T42<R, N, P, Q>::IndCalcW), (T42<R, N, P, Q>::IndCalcB), 16057066825, 17028023040)
  4489.     TB (krbpkq, false, true,  true,  (T42<R, B, P, Q>::IndCalcW), (T42<R, B, P, Q>::IndCalcB), 16637490240, 17028023040)
  4490.     TB (krrpkq, false, true,  true,  (T42<R, R, P, Q>::IndCalcW), (T42<R, R, P, Q>::IndCalcB),  8112305064,  8514011520)
  4491.     TB (kqppkq, false, true,  true,  (T42<Q, P, P, Q>::IndCalcW), (T42<Q, P, P, Q>::IndCalcB),  5920486098,  6669309024)
  4492.     TB (kqnpkq, false, true,  true,  (T42<Q, N, P, Q>::IndCalcW), (T42<Q, N, P, Q>::IndCalcB), 15239383701, 17028023040)
  4493.     TB (kqbpkq, false, true,  true,  (T42<Q, B, P, Q>::IndCalcW), (T42<Q, B, P, Q>::IndCalcB), 15787021288, 17028023040)
  4494.     TB (kqrpkq, false, true,  true,  (T42<Q, R, P, Q>::IndCalcW), (T42<Q, R, P, Q>::IndCalcB), 15660230819, 17028023040)
  4495.     TB (kqqpkq, false, false, true,  (T42<Q, Q, P, Q>::IndCalcW), (T42<Q, Q, P, Q>::IndCalcB),  7297961576,  8514011520)
  4496.  
  4497. #endif
  4498. #endif
  4499.     };
  4500.  
  4501. #undef  P
  4502. #undef  N
  4503. #undef  B
  4504. #undef  R
  4505. #undef  Q
  4506.  
  4507. //  Helper structure
  4508. //  Used to classify on-board position
  4509.  
  4510. union CUTbReference     // Hungarian: utbr
  4511.     {
  4512.     int             m_iDesc;            // Negative if have to inverse
  4513.     int             m_cPieces;
  4514.     CUTbReference   *m_utbReference;
  4515.     };
  4516.  
  4517. //  Root of the search tree
  4518.  
  4519. static CUTbReference rgutbReference [MAX_NON_KINGS + 2];
  4520.  
  4521. // Convert TB name (e.g. KQKR) into set of counters
  4522.  
  4523. static const char *PchSetHalfCounters
  4524.     (
  4525.     int         *piCounters,
  4526.     const char  *pch
  4527.     )
  4528.     {
  4529.     memset (piCounters, 0, 5 * sizeof (int));
  4530.     while ('\0' != *pch && 'k' != *pch)
  4531.         {
  4532.         piece pi;
  4533.  
  4534.         pi = x_piecePawn;   // To make compiler happy
  4535.         switch (*pch)
  4536.             {
  4537.         case 'p':
  4538.             pi = x_piecePawn;
  4539.             break;
  4540.         case 'n':
  4541.             pi = x_pieceKnight;
  4542.             break;
  4543.         case 'b':
  4544.             pi = x_pieceBishop;
  4545.             break;
  4546.         case 'r':
  4547.             pi = x_pieceRook;
  4548.             break;
  4549.         case 'q':
  4550.             pi = x_pieceQueen;
  4551.             break;
  4552.         default:
  4553.             assert (0);
  4554.             }
  4555.         piCounters [pi-1] ++;
  4556.         pch ++;
  4557.         }
  4558.         return pch;
  4559.     };
  4560.  
  4561. static void VSetCounters
  4562.     (
  4563.     int         *piCounters,
  4564.     const char  *pch
  4565.     )
  4566.     {
  4567.     assert ('k' == *pch);
  4568.     pch = PchSetHalfCounters (piCounters, pch+1);
  4569.     assert ('k' == *pch);
  4570.     pch = PchSetHalfCounters (piCounters+5, pch+1);
  4571.     assert ('\0' == *pch);
  4572.     }
  4573.  
  4574. //  Following functions return TB index
  4575. //  They differ by input arguments
  4576.  
  4577. extern "C" int IDescFindFromCounters
  4578.     (
  4579.     int *piCount
  4580.     )
  4581.     {
  4582.     CUTbReference *putbr = rgutbReference;
  4583.  
  4584.     if (piCount[0] > putbr->m_cPieces)
  4585.         goto not_found;
  4586.     putbr = putbr[1 + piCount[0]].m_utbReference;
  4587.     if (piCount[1] > putbr->m_cPieces)
  4588.         goto not_found;
  4589.     putbr = putbr[1 + piCount[1]].m_utbReference;
  4590.     if (piCount[2] > putbr->m_cPieces)
  4591.         goto not_found;
  4592.     putbr = putbr[1 + piCount[2]].m_utbReference;
  4593.     if (piCount[3] > putbr->m_cPieces)
  4594.         goto not_found;
  4595.     putbr = putbr[1 + piCount[3]].m_utbReference;
  4596.     if (piCount[4] > putbr->m_cPieces)
  4597.         goto not_found;
  4598.     putbr = putbr[1 + piCount[4]].m_utbReference;
  4599.     if (piCount[5] > putbr->m_cPieces)
  4600.         goto not_found;
  4601.     putbr = putbr[1 + piCount[5]].m_utbReference;
  4602.     if (piCount[6] > putbr->m_cPieces)
  4603.         goto not_found;
  4604.     putbr = putbr[1 + piCount[6]].m_utbReference;
  4605.     if (piCount[7] > putbr->m_cPieces)
  4606.         goto not_found;
  4607.     putbr = putbr[1 + piCount[7]].m_utbReference;
  4608.     if (piCount[8] > putbr->m_cPieces)
  4609.         goto not_found;
  4610.     putbr = putbr[1 + piCount[8]].m_utbReference;
  4611.     if (piCount[9] <= putbr->m_cPieces)
  4612.         return putbr[1 + piCount[9]].m_iDesc;
  4613. not_found:
  4614.     return 0;
  4615.     }
  4616.  
  4617. int IDescFind
  4618.     (
  4619.     square  *p_piW, // IN | Pointer to array of white pieces (king excluded)
  4620.     square  *p_piB, // IN | Pointer to array of black pieces (king excluded)
  4621.     int     cWhite, // IN | Counter of white pieces (king excluded)
  4622.     int     cBlack  // IN | Counter of black pieces (king excluded)
  4623.     )
  4624.     {
  4625.     int rgiCount[10];
  4626.  
  4627.     // Set pieces counters
  4628.     rgiCount[0] =
  4629.     rgiCount[1] =
  4630.     rgiCount[2] =
  4631.     rgiCount[3] =
  4632.     rgiCount[4] =
  4633.     rgiCount[5] =
  4634.     rgiCount[6] =
  4635.     rgiCount[7] =
  4636.     rgiCount[8] =
  4637.     rgiCount[9] = 0;
  4638.     while (cWhite)
  4639.         {
  4640.         rgiCount[(*p_piW)-1] ++;
  4641.         p_piW ++;
  4642.         cWhite --;
  4643.         }
  4644.     while (cBlack)
  4645.         {
  4646.         rgiCount[5-1+(*p_piB)] ++;
  4647.         p_piB ++;
  4648.         cBlack --;
  4649.         }
  4650.     return IDescFindFromCounters (rgiCount);
  4651.     }
  4652.  
  4653. int IDescFindByName
  4654.     (
  4655.     char    *pchName
  4656.     )
  4657.     {
  4658.     int rgiCount[10];
  4659.  
  4660.     VSetCounters (rgiCount, pchName);
  4661.     return IDescFindFromCounters (rgiCount);
  4662.     }
  4663.  
  4664. //-----------------------------------------------------------------------------
  4665. //
  4666. //  Function used during initialization
  4667.  
  4668. //  Set of functions to create search table
  4669.  
  4670. static CUTbReference *PutbrCreateSubtable
  4671.     (
  4672.     int cPieces,    //  IN | # of pieces ramaining on board
  4673.     int iDepth      //  IN | Recursion depth (# of piece classes left)
  4674.     )
  4675.     {
  4676.     CUTbReference *putbr;
  4677.  
  4678.     putbr = (CUTbReference *) PvMalloc ((cPieces + 2) * sizeof (CUTbReference));
  4679.     putbr[0].m_cPieces = cPieces;
  4680.     if (0 == iDepth)
  4681.         {
  4682.         for (int i = 0; i <= cPieces; i ++)
  4683.             putbr[i+1].m_iDesc = 0;
  4684.         }
  4685.     else
  4686.         {
  4687.         for (int i = 0; i <= cPieces; i ++)
  4688.             putbr[i+1].m_utbReference = PutbrCreateSubtable (cPieces-i, iDepth-1);
  4689.         }
  4690.     return putbr;
  4691.     }
  4692.  
  4693. static bool fTbTableCreated = false;
  4694.  
  4695. static void VCreateEmptyTbTable (void)
  4696.     {
  4697.     if (fTbTableCreated)
  4698.         return;
  4699.     fTbTableCreated = true;
  4700.     rgutbReference[0].m_cPieces = MAX_NON_KINGS;
  4701.     for (int i = 0; i <= MAX_NON_KINGS; i ++)
  4702.         rgutbReference[i+1].m_utbReference = PutbrCreateSubtable (MAX_NON_KINGS - i, 8);
  4703.     }
  4704.  
  4705. // Insert TB (e.g. KQKR) into search table
  4706.  
  4707. static bool FRegisterHalf
  4708.     (
  4709.     int     iTb,
  4710.     int     *piCount
  4711.     )
  4712.     {
  4713.     CUTbReference   *putbr;
  4714.  
  4715.     putbr = rgutbReference;
  4716.     for (int i = 0; i < 9; i ++)
  4717.         {
  4718.         if (piCount[i] > putbr->m_cPieces)
  4719.             return false;
  4720.         putbr = putbr[1 + piCount[i]].m_utbReference;
  4721.         }
  4722.     if (piCount[9] > putbr->m_cPieces)
  4723.         return false;
  4724.     putbr[1 + piCount[9]].m_iDesc = iTb;
  4725.     return true;
  4726.     }
  4727.  
  4728. // Insert TB (both, e.g. KQKR and KRKQ) into search table
  4729.  
  4730. static bool FRegisterTb
  4731.     (
  4732.     CTbDesc *ptbDesc
  4733.     )
  4734.     {
  4735.     int     rgiCount[10];
  4736.     bool    fInserted;
  4737.  
  4738.     VSetCounters (rgiCount, ptbDesc->m_rgchName);
  4739.     fInserted = FRegisterHalf (ptbDesc->m_iTbId, rgiCount);
  4740.     if (fInserted)
  4741.         {
  4742.         if (ptbDesc->m_fSymmetric)
  4743.             return true;
  4744.         for (int i = 0; i < 5; i ++)
  4745.             {
  4746.             int iTemp;
  4747.  
  4748.             iTemp = rgiCount[i];
  4749.             rgiCount[i] = rgiCount[i+5];
  4750.             rgiCount[i+5] = iTemp;
  4751.             }
  4752.         fInserted = FRegisterHalf (-ptbDesc->m_iTbId, rgiCount);
  4753.         assert (fInserted);
  4754.         }
  4755.     return fInserted;
  4756.     }
  4757.  
  4758. // File mapping - Win32 code only
  4759.  
  4760. #if defined (_WIN32) || defined(_WIN64)
  4761.  
  4762. static BYTE * PbMapFileForRead
  4763.     (
  4764.     char    *szName,
  4765.     HANDLE  *phFile,
  4766.     HANDLE  *phFileMapping
  4767.     )
  4768.     {
  4769.     HANDLE  hFile;
  4770.     HANDLE  hFileMapping;
  4771.     LPVOID  lpFileBase;
  4772.  
  4773.     hFile = CreateFile (szName, GENERIC_READ, FILE_SHARE_READ,
  4774.                         NULL, OPEN_EXISTING,
  4775.                         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL);
  4776.     if (INVALID_HANDLE_VALUE == hFile)
  4777.         {
  4778.         printf("*** Couldn't open file %s with CreateFile()\n", szName);
  4779.         exit (1);
  4780.         }
  4781.     hFileMapping = CreateFileMapping (hFile, NULL, PAGE_READONLY, 0, 0, NULL);
  4782.     if (0 == hFileMapping)
  4783.         {
  4784.         CloseHandle (hFile);
  4785.         printf ("*** Couldn't open file %s mapping with CreateFileMapping()\n", szName);
  4786.         exit (1);
  4787.         }
  4788.     lpFileBase = MapViewOfFile (hFileMapping, FILE_MAP_READ, 0, 0, 0);
  4789.     if (0 == lpFileBase)
  4790.         {
  4791.         CloseHandle (hFileMapping);
  4792.         CloseHandle (hFile);
  4793.         printf ("*** Couldn't map view of file %s with MapViewOfFile()\n", szName);
  4794.         exit (1);
  4795.         }
  4796.     if (NULL != phFile)
  4797.         *phFile = hFile;
  4798.     if (NULL != phFileMapping)
  4799.         *phFileMapping = hFileMapping;
  4800.     return (BYTE*) lpFileBase;
  4801.     }
  4802.  
  4803. static void VUnmapFile
  4804.     (
  4805.     BYTE    *pbFileBase,
  4806.     HANDLE  hFile,
  4807.     HANDLE  hFileMapping
  4808.     )
  4809.     {
  4810.     BOOL fFailed;
  4811.  
  4812.     fFailed = (0 == UnmapViewOfFile (pbFileBase)) |
  4813.               (0 == CloseHandle (hFileMapping)) |
  4814.               (0 == CloseHandle (hFile));
  4815.     if (fFailed)
  4816.         {
  4817.         printf ("*** Couldn't unmap file\n");
  4818.         exit (1);
  4819.         }
  4820.     }
  4821.  
  4822. #endif
  4823.  
  4824. //-----------------------------------------------------------------------------
  4825. //
  4826. //  TB caching
  4827.  
  4828. #if !defined (TB_CB_CACHE_CHUNK)
  4829. #define TB_CB_CACHE_CHUNK           8192 /* Must be power of 2 */
  4830. #define LOG2_TB_CB_CACHE_CHUNK      13
  4831. #endif
  4832.  
  4833. #define TB_CHUNK(index)             ((index) >> LOG2_TB_CB_CACHE_CHUNK)
  4834. #define TB_OFFSET(index)            ((index) % TB_CB_CACHE_CHUNK)
  4835. #define TB_DIRECTORY_ENTRY(chunk)   ((chunk) % TB_DIRECTORY_SIZE)
  4836.  
  4837. #define WIDE_TB_CHUNK(index)        ((index) >> (LOG2_TB_CB_CACHE_CHUNK-1))
  4838. #define WIDE_TB_OFFSET(index)       ((index) % (TB_CB_CACHE_CHUNK/2))*2
  4839.  
  4840. struct CTbCache         //Hungarian: tbc
  4841.     {
  4842.     int volatile                m_iTb;
  4843.     color volatile              m_color;
  4844.     unsigned volatile           m_indChunk;
  4845.     volatile CTbCache *volatile m_ptbcNext;     // Next element in double-linked general LRU list
  4846.     volatile CTbCache *volatile m_ptbcPrev;     // Previous element in double-linked general LRU list
  4847.     volatile CTbCache *volatile m_ptbcTbNext;   // Next element in double-linked cache bucket LRU list
  4848.     volatile CTbCache *volatile m_ptbcTbPrev;   // Previous element in double-linked cache bucket LRU list
  4849.     BYTE                        *m_pbData;
  4850.     };
  4851.  
  4852. static CTbCache *ptbcTbCache;   // Cache memory
  4853. static ULONG    ctbcTbCache;    // Cache size (in entries)
  4854.  
  4855. static volatile CTbCache * volatile ptbcHead;       // Head of that list
  4856. static volatile CTbCache * volatile ptbcTail;       // Last element in that list
  4857. static volatile CTbCache * volatile ptbcFree;       // First free cache header
  4858.  
  4859. static INLINE void VTbCloseFile
  4860.     (
  4861.     int     iTb,
  4862.     color   side
  4863.     )
  4864.     {
  4865.     for (int iExtent = 0; iExtent < MAX_EXTENTS; iExtent ++) {
  4866.         if (NULL != rgtbdDesc[iTb].m_rgfpFiles[side][iExtent])
  4867.             {
  4868.             Lock (rgtbdDesc[iTb].m_rglockFiles[side]);
  4869.             if (NULL != rgtbdDesc[iTb].m_rgfpFiles[side][iExtent])
  4870.                 {
  4871.                 fclose (rgtbdDesc[iTb].m_rgfpFiles[side][iExtent]);
  4872.                 rgtbdDesc[iTb].m_rgfpFiles[side][iExtent] = NULL;
  4873.                 }
  4874.             Unlock (rgtbdDesc[iTb].m_rglockFiles[side]);
  4875.             }
  4876.         }
  4877.     }
  4878.  
  4879. extern "C" void VTbCloseFiles (void)
  4880.     {
  4881.     // Initialized?
  4882.     if (0 == ctbcTbCache)
  4883.         return;
  4884.  
  4885.     // Walk through TB cache and close all opened files
  4886.     for (int iTb = 1; iTb < cTb; iTb ++)
  4887.         {
  4888.         VTbCloseFile (iTb, x_colorWhite);
  4889.         VTbCloseFile (iTb, x_colorBlack);
  4890.         }
  4891.     }
  4892.  
  4893. void VTbClearCache (void)
  4894.     {
  4895.     CTbCacheBucket  *prgtbcbBuckets;
  4896.     CTbCache *ptbc;
  4897.     BYTE *pb;
  4898.     ULONG i;
  4899.  
  4900.     // Initialized?
  4901.     if (0 == ctbcTbCache)
  4902.         return;
  4903.     VTbCloseFiles();
  4904.    
  4905.     // Initialize all lists
  4906.     pb = (BYTE *) & ptbcTbCache [ctbcTbCache];
  4907.     for (i = 0, ptbc = ptbcTbCache; i < ctbcTbCache; i ++, ptbc ++)
  4908.         {
  4909.         ptbc->m_pbData = pb + i*(TB_CB_CACHE_CHUNK+32+4);
  4910.         ptbc->m_ptbcTbPrev =
  4911.         ptbc->m_ptbcTbNext =
  4912.         ptbc->m_ptbcPrev = NULL;
  4913.         ptbc->m_ptbcNext = (ptbc + 1);
  4914.         }
  4915.     ptbc[-1].m_ptbcNext = NULL;
  4916.  
  4917.     // Clear references from TBs
  4918.     for (int iTb = 1; iTb < cTb; iTb ++)
  4919.         {
  4920.         for (color sd=x_colorWhite; sd <= x_colorBlack; sd ++)
  4921.             {
  4922.             prgtbcbBuckets = rgtbdDesc[iTb].m_prgtbcbBuckets[sd];
  4923.             if (NULL != prgtbcbBuckets)
  4924.                 {
  4925. #if (CPUS > 1)
  4926.                 for (i = 0; i < TB_DIRECTORY_SIZE; i ++)
  4927.                     LockFree (prgtbcbBuckets[i].m_lock);
  4928. #endif
  4929.                 memset (prgtbcbBuckets, 0, TB_DIRECTORY_SIZE * sizeof (CTbCacheBucket));
  4930. #if (CPUS > 1)
  4931.                 for (i = 0; i < TB_DIRECTORY_SIZE; i ++)
  4932.                     LockInit (prgtbcbBuckets[i].m_lock);
  4933. #endif
  4934.                 }
  4935.             }
  4936.         }
  4937.  
  4938.     // Set globals
  4939.     ptbcHead = ptbcTail = NULL;
  4940.     ptbcFree = ptbcTbCache;
  4941.     }
  4942.  
  4943. extern "C" int FTbSetCacheSize
  4944.     (
  4945.     void    *pv,
  4946.     ULONG   cbSize
  4947.     )
  4948.     {
  4949.     VTbCloseFiles();
  4950.     ctbcTbCache = 0;
  4951.     ptbcHead = NULL;
  4952.     if (cbSize < sizeof (CTbCache))
  4953.         return false;
  4954.     ptbcTbCache = (CTbCache*) pv;
  4955.     ctbcTbCache = cbSize / (sizeof (CTbCache) + TB_CB_CACHE_CHUNK+32+4);
  4956.     VTbClearCache();
  4957.     return true;
  4958.     }
  4959.  
  4960. // Table registered
  4961.  
  4962. INLINE int FRegisteredExtent
  4963.     (
  4964.     int     iTb,
  4965.     color   side,
  4966.     int     iExtent
  4967.     )
  4968.     {
  4969.     if (rgtbdDesc[iTb].m_fSymmetric)
  4970.         side = x_colorWhite;
  4971.     return (NULL != rgtbdDesc[iTb].m_rgpchFileName[side][iExtent]);
  4972.     }
  4973.  
  4974. INLINE int FRegistered
  4975.     (
  4976.     int     iTb,
  4977.     color   side
  4978.     )
  4979.     {
  4980.     int iExtent, cExtents;
  4981.     INDEX cBytes;
  4982.  
  4983.     if (rgtbdDesc[iTb].m_fSplit)
  4984.         {
  4985.         cBytes = rgtbdDesc[iTb].m_rgcbLength[side];
  4986.         if (rgtbdDesc[iTb].m_f16bit)
  4987.             cBytes *= 2;
  4988.         cExtents = (int) (cBytes >> 31) + 1;
  4989.         }
  4990.     else
  4991.         cExtents = 1;
  4992.     for (iExtent = 0; iExtent < cExtents; iExtent ++)
  4993.         {
  4994.         if (FRegisteredExtent (iTb, side, iExtent))
  4995.             return true;
  4996.         }
  4997.     return false;
  4998.     }
  4999.  
  5000. extern "C" int FRegisteredFun
  5001.     (
  5002.     int     iTb,
  5003.     color   side
  5004.     )
  5005.     {
  5006.     return FRegistered (iTb, side);
  5007.     }
  5008.  
  5009. // Return function that calculates the necessary index:
  5010.  
  5011. #define PfnIndCalc(iTb, side)   (rgtbdDesc[iTb].m_rgpfnCalcIndex[side])
  5012. extern "C" PfnCalcIndex PfnIndCalcFun
  5013.     (
  5014.     int     iTb,
  5015.     color   side
  5016.     )
  5017.     {
  5018.     return PfnIndCalc (iTb, side);
  5019.     }
  5020.  
  5021. // Read whole file into memory
  5022.  
  5023. extern "C" int FReadTableToMemory
  5024.     (
  5025.     int     iTb,    // IN | Tablebase
  5026.     color   side,   // IN | Side to move
  5027.     BYTE    *pb     // IN | Either buffer or NULL
  5028.     )
  5029.     {
  5030.     char    *pszName;
  5031.     INDEX   cb;
  5032.     FILE    *fp;
  5033.  
  5034.     if (rgtbdDesc[iTb].m_fSymmetric)
  5035.         side = x_colorWhite;
  5036.     if (!FRegistered (iTb, side))
  5037.         return false;
  5038.     if (rgtbdDesc[iTb].m_fSplit)
  5039.         return false;
  5040.     for (int iExtent = 0; iExtent < MAX_EXTENTS; iExtent ++)
  5041.         {
  5042.         if (NULL != rgtbdDesc[iTb].m_rgpdiDecodeInfo[side][iExtent])
  5043.             return false;
  5044.         }
  5045.     if (NULL != rgtbdDesc[iTb].m_rgpbRead[side])
  5046.         return true;
  5047.     pszName = rgtbdDesc[iTb].m_rgpchFileName[side][0];
  5048.     fp = fopen (pszName, "rb");
  5049.     if (NULL == fp)
  5050.         return false;
  5051.  
  5052.     // Find database size
  5053. #if defined (NEW)
  5054.     cb = rgtbdDesc[iTb].m_rgcbLength[side];
  5055.     if (0 == cb)
  5056.         {
  5057. #endif
  5058.         if (0 != fseek (fp, 0L, SEEK_END))
  5059.             {
  5060.             printf ("*** Seek in %s failed\n", pszName);
  5061.             exit (1);
  5062.             }
  5063.         cb = ftell (fp);
  5064.         if (-1 == (int) cb)
  5065.             {
  5066.             printf ("*** Cannot find length of %s\n", pszName);
  5067.             exit (1);
  5068.             }
  5069.         if (0 != fseek (fp, 0L, SEEK_SET))
  5070.             {
  5071.             printf ("*** Seek in %s failed\n", pszName);
  5072.             exit (1);
  5073.             }
  5074. #if defined (NEW)
  5075.         }
  5076. #if defined (T33_INCLUDE) || defined (KPPKP_16BIT)
  5077.     else if (rgtbdDesc[iTb].m_f16bit)
  5078.         {
  5079.         if ((size_t) cb != cb)   // Overflow
  5080.             {
  5081.             printf ("*** %s too big to read into memory\n", pszName);
  5082.             exit (1);
  5083.             }
  5084.         }
  5085. #endif
  5086. #endif
  5087.    
  5088.     // If buffer not specified, allocate memory for it
  5089.     if (NULL == pb)
  5090.         pb = (BYTE*) PvMalloc ((size_t) cb); // Pierre-Marie Baty -- added type cast
  5091.  
  5092.     // Read file into memory
  5093.     if (cb != (INDEX) fread (pb, 1, (size_t) cb, fp)) // Pierre-Marie Baty -- added type cast
  5094.         {
  5095.         printf ("*** Read from %s failed\n", pszName);
  5096.         exit (1);
  5097.         }
  5098.     fclose (fp);
  5099.  
  5100.     // All done
  5101.     rgtbdDesc[iTb].m_rgpbRead[side] = pb;
  5102.     return true;
  5103.     }
  5104.  
  5105. #if defined (_WIN32) || defined(_WIN64)
  5106.  
  5107. // Map whole file into memory
  5108.  
  5109. extern "C" int FMapTableToMemory
  5110.     (
  5111.     int     iTb,    // IN | Tablebase
  5112.     color   side    // IN | Side to move
  5113.     )
  5114.     {
  5115.     char *pszName;
  5116.  
  5117.     if (rgtbdDesc[iTb].m_fSymmetric)
  5118.         side = x_colorWhite;
  5119.     if (!FRegistered (iTb, side))
  5120.         return false;
  5121.     if (rgtbdDesc[iTb].m_fSplit)
  5122.         return false;
  5123.     for (int iExtent = 0; iExtent < MAX_EXTENTS; iExtent ++)
  5124.         {
  5125.         if (NULL != rgtbdDesc[iTb].m_rgpdiDecodeInfo[side][iExtent])
  5126.             return false;
  5127.         }
  5128.     pszName = rgtbdDesc[iTb].m_rgpchFileName[side][0];
  5129.     if (NULL == rgtbdDesc[iTb].m_rgpbRead[side])
  5130.         {
  5131.         rgtbdDesc[iTb].m_rgpbRead[side] = PbMapFileForRead (pszName, NULL, NULL);
  5132.         if (fVerbose)
  5133.             printf ("%s mapped\n", pszName);
  5134.         }
  5135.     return true;
  5136.     }
  5137.  
  5138. // Map whole file into memory
  5139.  
  5140. int FMapTableToMemory
  5141.     (
  5142.     int     iTb,            // IN  | Tablebase
  5143.     color   side,           // IN  | Side to move
  5144.     HANDLE  *phFile,        // OUT | File handle will be written here
  5145.     HANDLE  *phFileMapping  // OUT | File mapping handle will be written here
  5146.     )
  5147.     {
  5148.     char *pszName;
  5149.  
  5150.     if (rgtbdDesc[iTb].m_fSymmetric)
  5151.         side = x_colorWhite;
  5152.     if (!FRegistered (iTb, side))
  5153.         return false;
  5154.     if (rgtbdDesc[iTb].m_fSplit)
  5155.         return false;
  5156.     pszName = rgtbdDesc[iTb].m_rgpchFileName[side][0];
  5157.     if (NULL == rgtbdDesc[iTb].m_rgpbRead[side])
  5158.         {
  5159.         rgtbdDesc[iTb].m_rgpbRead[side] = PbMapFileForRead (pszName, phFile, phFileMapping);
  5160.         if (fVerbose)
  5161.             printf ("%s mapped\n", pszName);
  5162.         }
  5163.     return true;
  5164.     }
  5165.  
  5166. // Unmap whole file from memory
  5167.  
  5168. int FUnMapTableFromMemory
  5169.     (
  5170.     int     iTb,            // IN | Tablebase
  5171.     color   side,           // IN | Side to move
  5172.     HANDLE  hFile,          // IN | File handle will be written here
  5173.     HANDLE  hFileMapping    // IN | File mapping handle will be written here
  5174.     )
  5175.     {
  5176.     char *pszName;
  5177.  
  5178.     if (rgtbdDesc[iTb].m_fSymmetric)
  5179.         side = x_colorWhite;
  5180.     if (!FRegistered (iTb, side))
  5181.         return false;
  5182.     if (rgtbdDesc[iTb].m_fSplit)
  5183.         return false;
  5184.     pszName = rgtbdDesc[iTb].m_rgpchFileName[side][0];
  5185.     if (NULL != rgtbdDesc[iTb].m_rgpbRead[side])
  5186.         {
  5187.         VUnmapFile (rgtbdDesc[iTb].m_rgpbRead[side], hFile, hFileMapping);
  5188.         rgtbdDesc[iTb].m_rgpbRead[side] = NULL;
  5189.         if (fVerbose)
  5190.             printf ("%s unmapped\n", pszName);
  5191.         }
  5192.     return true;
  5193.     }
  5194.  
  5195. #endif
  5196.  
  5197. // Probe TB - lower level (not exportable) function
  5198.  
  5199. static int TB_FASTCALL TbtProbeTable
  5200.     (
  5201.     int      iTb,
  5202.     color    side,
  5203.     unsigned indChunk,
  5204.     unsigned indInChunk
  5205.     )
  5206.     {
  5207.     CTbDesc *ptbd;
  5208.     int iDirectory, iExtent, iPhysicalChunk;
  5209.     volatile CTbCache * ptbc;
  5210.     volatile CTbCache * ptbcTbFirst;
  5211.     const char *pszFileName;
  5212.  
  5213.     ptbd = & rgtbdDesc[iTb];
  5214.     iDirectory = TB_DIRECTORY_ENTRY (indChunk);
  5215.  
  5216.     // Head of the cache bucket LRU list
  5217.     Lock (ptbd->m_prgtbcbBuckets[side][iDirectory].m_lock);
  5218.     ptbcTbFirst = ptbd->m_prgtbcbBuckets[side][iDirectory].m_ptbcFirst;
  5219.  
  5220.     // First, search entry in the cache
  5221.     for (ptbc = ptbcTbFirst; NULL != ptbc; ptbc = ptbc->m_ptbcTbNext)
  5222.         {
  5223.         if (indChunk == ptbc->m_indChunk)
  5224.             {
  5225.             // Found - move cache entry to the head of the general LRU list
  5226.             Lock (lockLRU);
  5227.             if (ptbc != ptbcHead)
  5228.                 {
  5229.                 // Remove it from its current position
  5230.                 ptbc->m_ptbcPrev->m_ptbcNext = ptbc->m_ptbcNext;
  5231.                 if (NULL == ptbc->m_ptbcNext)
  5232.                     ptbcTail = ptbc->m_ptbcPrev;
  5233.                 else
  5234.                     ptbc->m_ptbcNext->m_ptbcPrev = ptbc->m_ptbcPrev;
  5235.                 // Insert it at the head
  5236.                 ptbc->m_ptbcPrev = NULL;
  5237.                 ptbc->m_ptbcNext = ptbcHead;
  5238.                 ptbcHead->m_ptbcPrev = ptbc;
  5239.                 ptbcHead = ptbc;
  5240.                 }
  5241.             Unlock (lockLRU);
  5242.             // Move cache entry to the head of the cache bucket LRU list
  5243.             if (ptbc != ptbcTbFirst)
  5244.                 {
  5245.                 // Remove it from list
  5246.                 ptbc->m_ptbcTbPrev->m_ptbcTbNext = ptbc->m_ptbcTbNext;
  5247.                 if (NULL != ptbc->m_ptbcTbNext)
  5248.                     ptbc->m_ptbcTbNext->m_ptbcTbPrev = ptbc->m_ptbcTbPrev;
  5249.                 // Insert it at head
  5250.                 ptbc->m_ptbcTbPrev = NULL;
  5251.                 ptbc->m_ptbcTbNext = ptbcTbFirst;
  5252.                 ptbcTbFirst->m_ptbcTbPrev = ptbc;
  5253.                 ptbd->m_prgtbcbBuckets[side][iDirectory].m_ptbcFirst = ptbc;
  5254.                 }
  5255.             int tb;
  5256.  
  5257.             tb = (tb_t) (ptbc->m_pbData[(ULONG)indInChunk]);
  5258.             Unlock (ptbd->m_prgtbcbBuckets[side][iDirectory].m_lock);
  5259.             return tb;
  5260.             }
  5261.         }
  5262.     // Not in the cache - have to read it from disk.
  5263.     // I decided to write simple code - so sometimes it's possible that
  5264.     // 2 threads will simultaneously read exactly the same chunk into 2
  5265.     // different cache entries. In that case, all subsequent cache probes
  5266.     // will hit the first cache entry, so the second one will 'drift' to
  5267.     // the end of general LRU list and will be reused.
  5268.  
  5269.     // Unlock cache bucket, so other threads can continue execution
  5270.     Unlock (ptbd->m_prgtbcbBuckets[side][iDirectory].m_lock);
  5271.     // First, find cache entry we can use
  5272.     Lock (lockLRU);
  5273.     // Get it either from a free list, or reuse last element of the LRU list
  5274.     if (NULL != ptbcFree)
  5275.         {
  5276.         ptbc = ptbcFree;
  5277.         ptbcFree = ptbc->m_ptbcNext;
  5278.         Unlock (lockLRU);
  5279.         }
  5280.     else
  5281.         {
  5282.         unsigned iTailDirectory;
  5283.         int      iTailTb;
  5284.         color    colorTail;
  5285.  
  5286.         assert (NULL != ptbcTail);
  5287. #if (CPUS > 1)
  5288.         // "Optimistic" model - assuming that there is low content
  5289.         // (not hundreds of threads)
  5290.         for (;;)
  5291.             {
  5292.             ptbc = ptbcTail;
  5293.             iTailTb = ptbc->m_iTb;
  5294.             iTailDirectory = TB_DIRECTORY_ENTRY (ptbc->m_indChunk);
  5295.             colorTail = ptbc->m_color;
  5296.             // To avoid deadlocks, have to first acquire cache buckets lock,
  5297.             // and only then general LRU lock. So, free general LRU lock and
  5298.             // acquire 2 locks in a proper order.
  5299.             Unlock (lockLRU);
  5300.             Lock (rgtbdDesc[iTailTb].m_prgtbcbBuckets[colorTail][iTailDirectory].m_lock);
  5301.             Lock (lockLRU);
  5302.             // Have structures been modified while we re-acquired locks?
  5303.             // (to be more precise, it's Ok, if structures were modified,
  5304.             // but cache entry again become the last element of the list,
  5305.             // and TB, color, and cache bucket did not changed, so we locked
  5306.             // proper locks).
  5307.             if (ptbc == ptbcTail && ptbc->m_iTb == iTailTb &&
  5308.                 ptbc->m_color == colorTail &&
  5309.                 TB_DIRECTORY_ENTRY (ptbc->m_indChunk) == iTailDirectory)
  5310.                 break;
  5311.             // Sorry - try once again...
  5312.             Unlock (rgtbdDesc[iTailTb].m_prgtbcbBuckets[colorTail][iTailDirectory].m_lock);
  5313.             }
  5314. #else
  5315.         ptbc = ptbcTail;
  5316.         iTailTb = ptbc->m_iTb;
  5317.         iTailDirectory = TB_DIRECTORY_ENTRY (ptbc->m_indChunk);
  5318.         colorTail = ptbc->m_color;
  5319. #endif
  5320.  
  5321.         // Remove cache entry from the general LRU list
  5322.         ptbcTail = ptbc->m_ptbcPrev;
  5323.         if (NULL == ptbcTail)
  5324.             ptbcHead = NULL;
  5325.         else
  5326.             ptbcTail->m_ptbcNext = NULL;
  5327.         Unlock (lockLRU);
  5328.        
  5329.         // Remove it from cache bucket list
  5330.         if (NULL != ptbc->m_ptbcTbNext)
  5331.             ptbc->m_ptbcTbNext->m_ptbcTbPrev = ptbc->m_ptbcTbPrev;
  5332.         if (NULL == ptbc->m_ptbcTbPrev)
  5333.             rgtbdDesc[iTailTb].m_prgtbcbBuckets[colorTail][iTailDirectory].m_ptbcFirst = ptbc->m_ptbcTbNext;
  5334.         else
  5335.             ptbc->m_ptbcTbPrev->m_ptbcTbNext = ptbc->m_ptbcTbNext;
  5336.         Unlock (rgtbdDesc[iTailTb].m_prgtbcbBuckets[colorTail][iTailDirectory].m_lock);
  5337.         }
  5338.  
  5339.     // Ok, now we have "orphan" cache entry - it's excluded from all lists,
  5340.     // so other threads will never touch it.
  5341.     ptbc->m_iTb = iTb;
  5342.     ptbc->m_color = side;
  5343.     ptbc->m_indChunk = indChunk;
  5344.  
  5345.     // Now read it from the disk
  5346.     FILE    *fp;
  5347.     size_t  cb;
  5348.  
  5349.     // First, check: is necessary file opened?
  5350.     // As files are not thread-safe, lock file
  5351.     Lock (ptbd->m_rglockFiles[side]);
  5352.     if (ptbd->m_fSplit)
  5353.         {
  5354.         iExtent = indChunk >> (31 - LOG2_TB_CB_CACHE_CHUNK);
  5355.         iPhysicalChunk = indChunk - (iExtent << (31 - LOG2_TB_CB_CACHE_CHUNK));
  5356.         }
  5357.     else
  5358.         {
  5359.         iExtent = 0;
  5360.         iPhysicalChunk = indChunk;
  5361.         }
  5362.     fp = ptbd->m_rgfpFiles[side][iExtent];
  5363.     if (NULL == fp)
  5364.         {
  5365.         // Not - try to open it
  5366.         pszFileName = ptbd->m_rgpchFileName[side][iExtent];
  5367.         if (NULL != pszFileName)
  5368.             {
  5369.             fp = fopen (pszFileName, "rb");
  5370.             if (NULL == fp)
  5371.                 {
  5372.                 // Failed. Close all the opened files and retry
  5373.                 Unlock (ptbd->m_rglockFiles[side]);
  5374.                 VTbCloseFiles ();
  5375.                 Lock (ptbd->m_rglockFiles[side]);
  5376.                 // Theoretically, it's possible that other threads opened a lot of
  5377.                 // files in the interval between VTbCloseFiles() and Lock(). If
  5378.                 // so, we'll fail - I don't like to have one more global lock
  5379.                 // especially for file open, at least not in first version.
  5380.                 // Problem can happen only on systems with small limit of
  5381.                 // simultaneously open files and high number of threads - unlikely
  5382.                 // combination.
  5383.                 fp = ptbd->m_rgfpFiles[side][iExtent];
  5384.                 if (NULL == fp)
  5385.                     {
  5386.                     fp = fopen (pszFileName, "rb");
  5387.                     if (NULL == fp)
  5388.                         {
  5389. #if defined (STOP_ON_ERROR)
  5390.                         printf ("*** Unable to open file %s\n", pszFileName);
  5391.                         fflush (stdout);
  5392.                         exit(1);
  5393. #endif
  5394.                         goto ERROR_LABEL;
  5395.                         }
  5396.                     }
  5397.                 }
  5398.             ptbd->m_rgfpFiles[side][iExtent] = fp;
  5399.             }
  5400.         else
  5401.             goto ERROR_LABEL;
  5402.         }
  5403.  
  5404.     // File opened. Now seek and read necessary chunk
  5405.     if (NULL == ptbd->m_rgpdiDecodeInfo[side][iExtent])
  5406.         {
  5407.         long lPos;
  5408.         int  iResult;
  5409.  
  5410.         lPos = (long) (iPhysicalChunk*TB_CB_CACHE_CHUNK);
  5411. #if defined (T33_INCLUDE) || defined (T42_INCLUDE)
  5412.         if (lPos < 0)
  5413.             {
  5414.             iResult = fseek (fp, 0L, SEEK_SET);
  5415.             if (iResult)
  5416.                 {
  5417. #if defined (STOP_ON_ERROR)
  5418.                 printf ("*** Unable to seek file %s offset %08X\n",
  5419.                         pszFileName, 0);
  5420.                 fflush (stdout);
  5421.                 exit(1);
  5422. #endif
  5423.                 goto ERROR_LABEL;
  5424.                 }
  5425.             do
  5426.                 {
  5427.                 iResult = fseek (fp, 0x40000000, SEEK_CUR);
  5428.                 if (iResult)
  5429.                     {
  5430. #if defined (STOP_ON_ERROR)
  5431.                     printf ("*** Unable to seek file %s offset %08X\n",
  5432.                             pszFileName, 0x40000000);
  5433.                     fflush (stdout);
  5434.                     exit(1);
  5435. #endif
  5436.                     goto ERROR_LABEL;
  5437.                     }
  5438.                 lPos -= 0x40000000;
  5439.                 } while (lPos < 0);
  5440.             iResult = fseek (fp, lPos, SEEK_CUR);
  5441.             }
  5442.         else
  5443. #endif
  5444.             iResult = fseek (fp, lPos, SEEK_SET);
  5445.         // Read uncompressed file
  5446.         if (iResult)
  5447.             {
  5448. #if defined (STOP_ON_ERROR)
  5449.             printf ("*** Unable to seek file %s offset %08X\n",
  5450.                     pszFileName, lPos);
  5451.             fflush (stdout);
  5452.             exit(1);
  5453. #endif
  5454.             goto ERROR_LABEL;
  5455.             }
  5456.         cb = fread (ptbc->m_pbData, 1, TB_CB_CACHE_CHUNK, fp);
  5457.         if (cb != TB_CB_CACHE_CHUNK)
  5458.             {
  5459.             // Could not read TB_CB_CACHE_CHUNK - check for error
  5460.             if (ferror (fp) || ((size_t) -1 == cb))
  5461.                 {
  5462. #if defined (STOP_ON_ERROR)
  5463.                 printf ("*** Read error, file %s\n", pszFileName);
  5464.                 fflush (stdout);
  5465.                 exit(1);
  5466. #endif
  5467.                 goto ERROR_LABEL;
  5468.                 }
  5469.             }
  5470.         Unlock (ptbd->m_rglockFiles[side]);
  5471.         }
  5472.     else
  5473.         {
  5474.         // Read compressed file
  5475.         int fWasError;
  5476.         decode_block    *block;
  5477.         decode_info     *info = ptbd->m_rgpdiDecodeInfo[side][iExtent];
  5478.  
  5479. #if (CPUS > 1)
  5480.         // Find free decode block
  5481.         decode_block    **pBlock;
  5482.  
  5483.         Lock (lockDecode);
  5484.         pBlock = rgpdbDecodeBlocks;
  5485.         while (NULL == *pBlock)
  5486.             pBlock ++;
  5487.         block = *pBlock;
  5488.         *pBlock = NULL;
  5489.         Unlock (lockDecode);
  5490. #else
  5491.         block = rgpdbDecodeBlocks[0];
  5492. #endif
  5493.  
  5494.         // Initialize decode block and read chunk
  5495.         fWasError = 0 != comp_init_block (block, TB_CB_CACHE_CHUNK, ptbc->m_pbData) ||
  5496.                     0 != comp_read_block (block, info, fp, iPhysicalChunk);
  5497.        
  5498.         // Release lock on file, so other threads can proceed with that file
  5499.         Unlock (ptbd->m_rglockFiles[side]);
  5500.  
  5501.         // Decompress chunk
  5502.         if (!fWasError)
  5503.             fWasError |= (0 != comp_decode_and_check_crc (block, info, block->orig.size, TB_CRC_CHECK));
  5504.  
  5505.         // Release block
  5506. #if (CPUS > 1)
  5507.         Lock (lockDecode);
  5508.         *pBlock = block;
  5509.         Unlock (lockDecode);
  5510. #endif
  5511.  
  5512.         // Read Ok?
  5513.         if (fWasError)
  5514.             {
  5515. #if defined (STOP_ON_ERROR)
  5516.             printf ("*** Decompression error, file %s\n", pszFileName);
  5517.             fflush (stdout);
  5518.             exit(1);
  5519. #endif
  5520.             goto ERROR_LABEL_2;
  5521.             }
  5522.         }
  5523.  
  5524.     // Read - now acquire locks and insert cache entry in both lists
  5525.     Lock (ptbd->m_prgtbcbBuckets[side][iDirectory].m_lock);
  5526.     Lock (lockLRU);
  5527.  
  5528.     // Insert cache entry into general LRU list
  5529.     ptbc->m_ptbcPrev = NULL;
  5530.     ptbc->m_ptbcNext = ptbcHead;
  5531.     if (NULL == ptbcHead)
  5532.         ptbcTail = ptbc;
  5533.     else
  5534.         ptbcHead->m_ptbcPrev = ptbc;
  5535.     ptbcHead = ptbc;
  5536.  
  5537.     // Insert cache entry into cache bucket LRU list
  5538.     ptbc->m_ptbcTbPrev = NULL;
  5539.     ptbc->m_ptbcTbNext = ptbd->m_prgtbcbBuckets[side][iDirectory].m_ptbcFirst;
  5540.     if (NULL != ptbc->m_ptbcTbNext)
  5541.         ptbc->m_ptbcTbNext->m_ptbcTbPrev = ptbc;
  5542.     ptbd->m_prgtbcbBuckets[side][iDirectory].m_ptbcFirst = ptbc;
  5543.  
  5544.     // All done
  5545.     int tb;
  5546.  
  5547.     tb = (tb_t) (ptbc->m_pbData[indInChunk]);
  5548.     // Release locks
  5549.     Unlock (ptbd->m_prgtbcbBuckets[side][iDirectory].m_lock);
  5550.     Unlock (lockLRU);
  5551.     return tb;
  5552.  
  5553.     // I/O error. Here I don't want to halt the program, because that can
  5554.     // happen in the middle of the important game. Just return failure.
  5555. ERROR_LABEL:
  5556.     Unlock (ptbd->m_rglockFiles[side]);
  5557. ERROR_LABEL_2:
  5558.     Lock (lockLRU);
  5559.     ptbd->m_rgpchFileName[side][iExtent] = NULL;
  5560.     ptbc->m_ptbcNext = ptbcFree;
  5561.     ptbcFree = ptbc;
  5562.     Unlock (lockLRU);
  5563.     return L_bev_broken;
  5564.     }
  5565.  
  5566. // Probe TB - upper level function
  5567.  
  5568. // 16-bit version (recommended)
  5569.  
  5570. #define FOutOfBound(iTb, side, indOffset)\
  5571.         (tbid_kppkp == iTb && x_colorBlack == side &&\
  5572.          (indOffset == 0x0362BC7C || indOffset == 0x0362DE44 || indOffset == 0x03637648 ||\
  5573.           indOffset == 0x03639810 || indOffset == 0x038D4F29 || indOffset == 0x040A2CAB ||\
  5574.           indOffset == 0x043C778C))
  5575.  
  5576. extern "C" int TB_FASTCALL L_TbtProbeTable
  5577.     (
  5578.     int     iTb,
  5579.     color   side,
  5580.     INDEX   indOffset
  5581.     )
  5582.     {
  5583.     int tbtScore;
  5584.     CTbDesc *ptbd;
  5585.  
  5586.     assert (iTb > 0 && iTb < cTb);
  5587.     ptbd = & rgtbdDesc[iTb];
  5588.     if (ptbd->m_fSymmetric)
  5589.         side = x_colorWhite;
  5590.  
  5591.     // Entire file read/mapped to memory?
  5592.     if (NULL != ptbd->m_rgpbRead[side])
  5593.         {
  5594. #if defined (KPPKP_16BIT)
  5595.         if (!ptbd->m_f16bit)
  5596.             {
  5597.             tbtScore = (tb_t) ptbd->m_rgpbRead[side][indOffset];
  5598.             return S_to_L (tbtScore);
  5599.             }
  5600.         else
  5601.             return (((int) (((signed char) ptbd->m_rgpbRead[side][indOffset*2+1]))) << 8) +
  5602.                     ptbd->m_rgpbRead[side][indOffset*2];
  5603. #elif defined (T33_INCLUDE)
  5604.         if (!ptbd->m_f16bit)
  5605.             {
  5606.             if (FOutOfBound (iTb, side, indOffset))
  5607.                 return -32639;
  5608.             else
  5609.                 {
  5610.                 tbtScore = (tb_t) ptbd->m_rgpbRead[side][indOffset];
  5611.                 return S_to_L (tbtScore);
  5612.                 }
  5613.             }
  5614.         else
  5615.             return (((int) (((signed char) ptbd->m_rgpbRead[side][indOffset*2+1]))) << 8) +
  5616.                     ptbd->m_rgpbRead[side][indOffset*2];
  5617. #else
  5618.         if (FOutOfBound (iTb, side, indOffset))
  5619.             return -32639;
  5620.         else
  5621.             {
  5622.             tbtScore = (tb_t) ptbd->m_rgpbRead[side][indOffset];
  5623.             return S_to_L (tbtScore);
  5624.             }
  5625. #endif
  5626.         }
  5627.  
  5628.     // Cache initialized? TB registered?
  5629.     if (0 == ctbcTbCache || NULL == ptbd->m_prgtbcbBuckets[side])
  5630.         return L_bev_broken;
  5631.  
  5632. #if defined (T33_INCLUDE) || defined (T42_INCLUDE)
  5633.     if (ptbd->m_f16bit)
  5634.         {
  5635.         // Inefficient, but very simple, code
  5636.         int iLo;
  5637.         int iHi;
  5638.        
  5639.         iLo = TbtProbeTable (iTb, side, (unsigned) WIDE_TB_CHUNK (indOffset), (unsigned) WIDE_TB_OFFSET (indOffset));
  5640.         iHi = TbtProbeTable (iTb, side, (unsigned) WIDE_TB_CHUNK (indOffset), (unsigned) WIDE_TB_OFFSET (indOffset)+1);
  5641.         tbtScore = (L_bev_broken == iLo || L_bev_broken == iHi) ? L_bev_broken : ((iHi << 8) + (iLo & 0xFF));
  5642.         }
  5643.     else
  5644.         {
  5645. #if !defined (KPPKP_16BIT)
  5646.         if (FOutOfBound (iTb, side, indOffset))
  5647.             return -32639;
  5648. #endif
  5649.         tbtScore = TbtProbeTable (iTb, side, (unsigned) TB_CHUNK (indOffset), (unsigned) TB_OFFSET (indOffset));
  5650.         tbtScore = L_bev_broken == tbtScore ? L_bev_broken : S_to_L (tbtScore);
  5651.         }
  5652. #elif !defined (KPPKP_16BIT)
  5653.     if (FOutOfBound (iTb, side, indOffset))
  5654.         return -32639;
  5655.     tbtScore = TbtProbeTable (iTb, side, (unsigned) TB_CHUNK (indOffset), (unsigned) TB_OFFSET (indOffset));
  5656.     tbtScore = L_bev_broken == tbtScore ? L_bev_broken : S_to_L (tbtScore);
  5657. #else
  5658.     if (tbid_kppkp != iTb)
  5659.         {
  5660.         // All tables but kppkp are 8-bit tables
  5661.         tbtScore = TbtProbeTable (iTb, side, (unsigned) TB_CHUNK (indOffset), (unsigned) TB_OFFSET (indOffset));
  5662.         tbtScore = L_bev_broken == tbtScore ? L_bev_broken : S_to_L (tbtScore);
  5663.         }
  5664.     else
  5665.         {
  5666.         // Special handling of kppkp - it's 16-bit table
  5667.         // Inefficient, but very simple, code
  5668.         int iLo;
  5669.         int iHi;
  5670.        
  5671.         iLo = TbtProbeTable (iTb, side, (unsigned) WIDE_TB_CHUNK (indOffset), (unsigned) WIDE_TB_OFFSET (indOffset));
  5672.         iHi = TbtProbeTable (iTb, side, (unsigned) WIDE_TB_CHUNK (indOffset), (unsigned) WIDE_TB_OFFSET (indOffset)+1);
  5673.         tbtScore = (L_bev_broken == iLo || L_bev_broken == iHi) ? L_bev_broken : ((iHi << 8) + (iLo & 0xFF));
  5674.         }
  5675. #endif
  5676.     return tbtScore;
  5677.     }
  5678.  
  5679. //-----------------------------------------------------------------------------
  5680. //
  5681. //  Global initialization
  5682.  
  5683. // TODO: Check size of split tables, too
  5684.  
  5685. static void VCheckSize
  5686.     (
  5687.     int     iTb,
  5688.     color   side,
  5689.     int     iExtent,
  5690.     INDEX   cb,
  5691.     char    *rgchTbName
  5692.     )
  5693.     {
  5694. #if defined (NEW)
  5695.     INDEX   cbOk1, cbOk2;
  5696.  
  5697.     if (0 == rgtbdDesc[iTb].m_rgcbLength[side])
  5698.         return;
  5699.  
  5700.     cbOk1 = rgtbdDesc[iTb].m_rgcbLength[side];
  5701.     cbOk2 = cbOk1;
  5702. #if defined (T_INDEX64)
  5703.     if (rgtbdDesc[iTb].m_fSplit)
  5704.         {
  5705.         cbOk1 = (1uLL << (rgtbdDesc[iTb].m_f16bit ? 30 : 31)); // Pierre-Marie Baty -- added type cast
  5706.         cbOk2 = cbOk2 % (1uLL << (rgtbdDesc[iTb].m_f16bit ? 30 : 31)); // Pierre-Marie Baty -- added type cast
  5707.         }
  5708. #endif
  5709.  
  5710.     if (cb != cbOk1 && cb != cbOk2)
  5711.         {
  5712.         printf ("*** %s corrupted "
  5713.                 DEC_INDEX_FORMAT " " DEC_INDEX_FORMAT " " DEC_INDEX_FORMAT "\n", // Pierre-Marie Baty -- added spaces for preprocessor
  5714.                 rgchTbName, cbOk1, cbOk2, cb);
  5715.         exit (1);
  5716.         }
  5717. #endif
  5718.     }
  5719.  
  5720.  
  5721. #if defined (_WIN32) || defined (_WIN64)
  5722. int     iDrivesMap;
  5723. BOOL    rgfAccessed[26];
  5724. BOOL    rgfNotReady[26];
  5725. #endif
  5726.  
  5727. static int FCheckExtentExistance
  5728.     (
  5729.     char    *pszPath,
  5730.     int     iTb,
  5731.     color   side,
  5732.     int     iExtent
  5733.     )
  5734.     {
  5735.     FILE            *fp;
  5736.     char            *pchCopy;
  5737.     const char      *pchExt = PchExt (side);
  5738.     char            rgchTbName[1024];
  5739.     char            rgchExtent[4];
  5740.     CTbCacheBucket  *prgtbcbBuckets;
  5741.     INDEX           cb;
  5742.     decode_info     *comp_info = NULL;
  5743.  
  5744.     if (FRegisteredExtent (iTb, side, iExtent) || NULL != rgtbdDesc[iTb].m_rgpbRead[side])
  5745.         return true;
  5746.  
  5747. #if defined (_WIN32) || defined (_WIN64)
  5748.     // Do not repeatedely probe device that is not ready
  5749.     // (i.e. unmapped disk or CD-ROM that does not contain the disk).
  5750.     if (NULL != pszPath && 0 != pszPath[0] && ':' == pszPath[1])
  5751.         {
  5752.         int  iDrive;
  5753.         char szRoot[5];
  5754.         WIN32_FIND_DATA fd;
  5755.         HANDLE hResult;
  5756.  
  5757.         iDrive = tolower(pszPath[0]) - 'a';
  5758.         if (iDrive >= 0 && iDrive < 26)
  5759.             {
  5760.             if (rgfNotReady[iDrive])
  5761.                 return false;
  5762.             if (!rgfAccessed[iDrive])
  5763.                 {
  5764.                 if (iDrivesMap && 0 == (iDrivesMap & (1 << iDrive)))
  5765.                     return false;
  5766.                 szRoot[0] = pszPath[0];
  5767.                 szRoot[1] = pszPath[1];
  5768.                 szRoot[2] = '\\';
  5769.                 szRoot[3] = '*';
  5770.                 szRoot[4] = 0;
  5771.                 hResult = FindFirstFile (szRoot, &fd);
  5772.                 if (INVALID_HANDLE_VALUE == hResult)
  5773.                     {
  5774.                     if (ERROR_NOT_READY == GetLastError())
  5775.                         {
  5776.                         rgfNotReady[iDrive] = true;
  5777.                         return false;
  5778.                         }
  5779.                     }
  5780.                 else
  5781.                     FindClose (hResult);
  5782.                 rgfAccessed[iDrive] = true;
  5783.                 }
  5784.             }
  5785.         }
  5786. #endif
  5787.  
  5788.     strcpy (rgchTbName, pszPath);
  5789.     if (0 != pszPath[0] && DELIMITER[0] != pszPath[strlen(pszPath)-1])
  5790.         strcat (rgchTbName, DELIMITER);
  5791.     strcat (rgchTbName, rgtbdDesc[iTb].m_rgchName);
  5792.     if (rgtbdDesc[iTb].m_fSplit)
  5793.         {
  5794.         rgchExtent[0] = '.';
  5795.         if (iExtent >= 10)
  5796.             rgchExtent[1] = (char) (iExtent + 'a' - 10);
  5797.         else
  5798.             rgchExtent[1] = (char) (iExtent + '0');
  5799.         rgchExtent[2] = '\0';
  5800.         strcat (rgchTbName, rgchExtent);
  5801.         }
  5802.     strcat (rgchTbName, pchExt);
  5803.     cOpenFilesAttempts ++;
  5804.     fp = fopen (rgchTbName, "rb");
  5805.     //printf (">>> Opening %s\n", rgchTbName);
  5806.     cOpenFilesSuceed += (NULL != fp);
  5807. #if !defined (NEW) && !defined (_WIN32) && !defined(_WIN64)
  5808.     // For case-sensitive systems, have to try once more
  5809.     if (NULL == fp)
  5810.         {
  5811.         for (int i = strchr(rgchTbName,'.')-rgchTbName-1; i>=0 && isalpha(rgchTbName[i]); i--)
  5812.             rgchTbName[i] = toupper (rgchTbName[i]);
  5813.         cOpenFilesAttempts ++;
  5814.         fp = fopen (rgchTbName, "rb");
  5815.         //printf (">>> Opening %s\n", rgchTbName);
  5816.         cOpenFilesSuceed += (NULL != fp);
  5817.         }
  5818. #endif
  5819.     if (NULL != fp)
  5820.         {
  5821.         // Found uncompressed table
  5822.         if (rgtbdDesc[iTb].m_f16bit ||
  5823.             ((int)(cb = rgtbdDesc[iTb].m_rgcbLength[side])) < 0 ||
  5824.             cb != (unsigned) cb)
  5825.             {
  5826.             // Do not check the length for too large files
  5827.             cb = rgtbdDesc[iTb].m_rgcbLength[side];
  5828.             }
  5829.         else
  5830.             {
  5831.             if (0 != fseek (fp, 0L, SEEK_END))
  5832.                 {
  5833.                 printf ("*** Seek in %s failed\n", rgchTbName);
  5834.                 exit (1);
  5835.                 }
  5836.             cb = (INDEX) ftell (fp);
  5837.             VCheckSize (iTb, side, iExtent, cb, rgchTbName);
  5838.             }
  5839.         }
  5840.     else
  5841.         {
  5842.         // Check for compressed table.
  5843.         // First, check for kxykz.nb?.emd
  5844.         strcat (rgchTbName, ".emd");
  5845.         cOpenFilesAttempts ++;
  5846.         fp = fopen (rgchTbName, "rb");
  5847.         //printf (">>> Opening %s\n", rgchTbName);
  5848.         cOpenFilesSuceed += (NULL != fp);
  5849.         if ((NULL == fp) && !rgtbdDesc[iTb].m_fSplit)
  5850.             {
  5851.             // Check for kxykz_nb?.emd
  5852.             rgchTbName [strlen(rgchTbName)-8] = '_';
  5853.             cOpenFilesAttempts ++;
  5854.             fp = fopen (rgchTbName, "rb");
  5855.             //printf (">>> Opening %s\n", rgchTbName);
  5856.             cOpenFilesSuceed += (NULL != fp);
  5857.             }
  5858.         if ((NULL == fp) && !rgtbdDesc[iTb].m_fSplit)
  5859.             {
  5860.             // Check for kxykz_nb?_emd
  5861.             rgchTbName [strlen(rgchTbName)-4] = '_';
  5862.             cOpenFilesAttempts ++;
  5863.             fp = fopen (rgchTbName, "rb");
  5864.             //printf (">>> Opening %s\n", rgchTbName);
  5865.             cOpenFilesSuceed += (NULL != fp);
  5866.             }
  5867. #if defined (T41_INCLUDE)
  5868.         if ((NULL == fp) && (iTb <= tbid_kqqqk))
  5869. #else
  5870.         if ((NULL == fp) && (iTb <= tbid_kqqkq))
  5871. #endif
  5872.             {
  5873.             // Check for kxykznb?.emd (8+3 format)
  5874.             int cch;
  5875.            
  5876.             rgchTbName [strlen(rgchTbName)-4] = '.';
  5877.             cch = strlen (rgchTbName);
  5878.             memmove (rgchTbName+cch-8, rgchTbName+cch-7, 8);
  5879.             cOpenFilesAttempts ++;
  5880.             fp = fopen (rgchTbName, "rb");
  5881.             //printf (">>> Opening %s\n", rgchTbName);
  5882.             cOpenFilesSuceed += (NULL != fp);
  5883.             }
  5884.         if (NULL == fp)
  5885.             return false;
  5886.         cCompressed ++;
  5887.         int iResult = comp_open_file (&comp_info, fp, TB_CRC_CHECK);
  5888.         if (0 != iResult)
  5889.             {
  5890.             printf ("*** Unable to read %s - ", rgchTbName);
  5891.             switch (iResult & 0xFF)
  5892.                 {
  5893.             case COMP_ERR_READ:
  5894.                 printf ("read error\n");
  5895.                 break;
  5896.             case COMP_ERR_NOMEM:
  5897.                 printf ("out of memory\n");
  5898.                 break;
  5899.             case COMP_ERR_BROKEN:
  5900.                 printf ("file broken\n");
  5901.                 break;
  5902.             default:
  5903.                 printf ("error %d\n", iResult);
  5904.                 break;
  5905.                 }
  5906.             exit (1);
  5907.             }
  5908.         if (comp_info->block_size != TB_CB_CACHE_CHUNK)
  5909.             {
  5910.             printf ("*** %s: Unsupported block size %d\n", rgchTbName, comp_info->block_size);
  5911.             exit (1);
  5912.             }
  5913.         if (rgtbdDesc[iTb].m_f16bit)
  5914.             {
  5915.             cb = ((INDEX)comp_info->block_size/2)*(comp_info->n_blk-1) +
  5916.                   (INDEX)comp_info->last_block_size/2;
  5917.             VCheckSize (iTb, side, iExtent, cb, rgchTbName);
  5918.             }
  5919.         else
  5920.             {
  5921.             cb = ((INDEX)comp_info->block_size)*(comp_info->n_blk-1) +
  5922.                  (INDEX)comp_info->last_block_size;
  5923.             VCheckSize (iTb, side, iExtent, cb, rgchTbName);
  5924.             }
  5925.  
  5926. #if 0
  5927.         block = rgpdbDecodeBlocks[0];
  5928.         if (NULL == block)
  5929.             {
  5930.             int iResult = comp_alloc_block (&rgpdbDecodeBlocks[0], TB_CB_CACHE_CHUNK);
  5931.             if (0 != iResult)
  5932.                 {
  5933.                 printf ("*** Cannot allocate decode block: error code %d\n", iResult);
  5934.                 exit (1);
  5935.                 }
  5936.             block = rgpdbDecodeBlocks[0];
  5937.             }
  5938.         // Initialize decode block and read chunk
  5939.         fWasError = 0 != comp_init_block (block, TB_CB_CACHE_CHUNK, rgbBuffer) ||
  5940.                     0 != comp_read_block (block, comp_info, fp, TB_CHUNK (cb-1)) ||
  5941.                     0 != comp_decode_and_check_crc (block, comp_info, block->orig.size, TB_CRC_CHECK);
  5942.         if (fWasError)
  5943.             {
  5944.             printf ("*** Sanity check on %s failed\n", rgchTbName);
  5945.             exit (1);
  5946.             }
  5947. #endif
  5948.         }
  5949.  
  5950.     fclose (fp);
  5951.     if (FRegisterTb (& (rgtbdDesc[iTb])))
  5952.         {
  5953.         pchCopy = (char*) PvMalloc (strlen(rgchTbName)+1);
  5954.         strcpy (pchCopy, rgchTbName);
  5955.         free (rgtbdDesc[iTb].m_rgpchFileName[side][iExtent]);
  5956.         rgtbdDesc[iTb].m_rgpchFileName[side][iExtent] = pchCopy;
  5957.         if (NULL == rgtbdDesc[iTb].m_prgtbcbBuckets[side])
  5958.             {
  5959.             prgtbcbBuckets = (CTbCacheBucket*) PvMalloc (TB_DIRECTORY_SIZE*sizeof(CTbCacheBucket));
  5960.             memset (prgtbcbBuckets, 0, TB_DIRECTORY_SIZE*sizeof(CTbCacheBucket));
  5961. #if (CPUS > 1)
  5962.             for (int i = 0; i < TB_DIRECTORY_SIZE; i ++)
  5963.                 LockInit (prgtbcbBuckets[i].m_lock);
  5964. #endif
  5965.             rgtbdDesc[iTb].m_prgtbcbBuckets[side] = prgtbcbBuckets;
  5966.             if (fVerbose)
  5967.                 printf ("%s registered\n", pchCopy);
  5968.             }
  5969.         else
  5970.             {
  5971.             if (fVerbose)
  5972.                 printf ("%s found\n", pchCopy);
  5973.             }
  5974.         rgtbdDesc[iTb].m_rgpdiDecodeInfo[side][iExtent] = comp_info;
  5975.         return true;
  5976.         }
  5977.     else
  5978.         {
  5979.         printf ("*** Unable to register %s\n", rgchTbName);
  5980.         exit (1);
  5981.         }
  5982.     return false;
  5983.     }
  5984.  
  5985. int FCheckExistance
  5986.     (
  5987.     char    *pszPath,
  5988.     int     iTb,
  5989.     color   side
  5990.     )
  5991.     {
  5992.     int  fFound;
  5993.     int  cExtents;
  5994.     INDEX cBytes;
  5995.  
  5996.     if (rgtbdDesc[iTb].m_fSplit)
  5997.         {
  5998.         cBytes = rgtbdDesc[iTb].m_rgcbLength[side];
  5999.         if (rgtbdDesc[iTb].m_f16bit)
  6000.             cBytes *= 2;
  6001.         cExtents = (int) (cBytes >> 31) + 1;
  6002.         }
  6003.     else
  6004.         cExtents = 1;
  6005.     fFound = false;
  6006.     for (int iExtent = 0; iExtent < cExtents; iExtent++)
  6007.         {
  6008.         if (!FCheckExtentExistance (pszPath, iTb, side, iExtent))
  6009.             break;
  6010.         fFound = true;
  6011.         }
  6012.     return fFound;
  6013.     }
  6014.  
  6015. extern "C" int IInitializeTb
  6016.     (
  6017.     char *pszPath
  6018.     )
  6019.     {
  6020.     char    szTemp[1024];
  6021.     color   sd;
  6022.     int     iTb, iMaxTb, iExtent, i;
  6023.     CTbCacheBucket  *prgtbcbBuckets;
  6024.  
  6025. #if defined (_WIN32) || defined (_WIN64)
  6026.     // For Windows, get bit map of ready devices
  6027.     iDrivesMap = GetLogicalDrives();
  6028.     memset (rgfAccessed, 0, sizeof(rgfAccessed));
  6029.     memset (rgfNotReady, 0, sizeof(rgfNotReady));
  6030. #endif
  6031.  
  6032.     cOpenFilesAttempts = cOpenFilesSuceed = 0;
  6033.     cbAllocated = cbEGTBCompBytes = 0;
  6034.     // If there are open files, close those
  6035.     VTbCloseFiles ();
  6036. #if (CPUS > 1)
  6037.     // Init all locks
  6038.     LockInit (lockLRU);
  6039.     LockInit (lockDecode);
  6040.     for (iTb = 1; iTb < cTb; iTb ++)
  6041.         {
  6042.         LockInit (rgtbdDesc[iTb].m_rglockFiles[x_colorWhite]);
  6043.         LockInit (rgtbdDesc[iTb].m_rglockFiles[x_colorBlack]);
  6044.         }
  6045. #endif
  6046. #if defined (NEW)
  6047.     // Create enumeration tables
  6048.     VInitEnumerations ();
  6049. #endif
  6050.     // Create empty TB search table
  6051.     VCreateEmptyTbTable ();
  6052.     // Free memory from TB table
  6053.     for (iTb = 1; iTb < cTb; iTb ++)
  6054.         {
  6055.         for (sd = x_colorWhite; sd <= x_colorBlack; sd = (color) (sd + 1))
  6056.             {
  6057.             if (NULL != rgtbdDesc[iTb].m_prgtbcbBuckets[sd] &&
  6058.                 NULL == rgtbdDesc[iTb].m_rgpbRead[sd])
  6059.                 {
  6060.                 prgtbcbBuckets = rgtbdDesc[iTb].m_prgtbcbBuckets[sd];
  6061. #if (CPUS > 1)
  6062.                 for (i = 0; i < TB_DIRECTORY_SIZE; i ++)
  6063.                     LockFree (prgtbcbBuckets[i].m_lock);
  6064. #endif
  6065.                 free (prgtbcbBuckets);
  6066.                 rgtbdDesc[iTb].m_prgtbcbBuckets[sd] = NULL;
  6067.                 }
  6068.             for (iExtent = 0; iExtent < MAX_EXTENTS; iExtent ++)
  6069.                 {
  6070.                 if (NULL != rgtbdDesc[iTb].m_rgpchFileName[sd][iExtent])
  6071.                     {
  6072.                     free (rgtbdDesc[iTb].m_rgpchFileName[sd][iExtent]);
  6073.                     rgtbdDesc[iTb].m_rgpchFileName[sd][iExtent] = NULL;
  6074.                     }
  6075.                 if (NULL != rgtbdDesc[iTb].m_rgpdiDecodeInfo[sd][iExtent])
  6076.                     {
  6077.                     free (rgtbdDesc[iTb].m_rgpdiDecodeInfo[sd][iExtent]);
  6078.                     rgtbdDesc[iTb].m_rgpdiDecodeInfo[sd][iExtent] = NULL;
  6079.                     }
  6080.                 }
  6081.             }
  6082.         }
  6083.     // Free compressed blocks
  6084.     for (i = 0; i < CPUS; i ++)
  6085.         {
  6086.         if (NULL != rgpdbDecodeBlocks[i])
  6087.             {
  6088.             free (rgpdbDecodeBlocks[i]);
  6089.             rgpdbDecodeBlocks[i] = NULL;
  6090.             }
  6091.         }
  6092.  
  6093.     if(pszPath == NULL)
  6094.         return 0;
  6095.  
  6096.     // Search for existing TBs
  6097.     iMaxTb = 0;
  6098.     for (;;)
  6099.         {
  6100.         for (i = 0; pszPath[i] != '\0' && pszPath[i] != ',' && pszPath[i] != ';'
  6101. #if !defined (_WIN32) && !defined (__MWERKS__) && !defined(_WIN64)
  6102.              && pszPath[i] != ':'
  6103. #endif
  6104.              ; i ++)
  6105.             {
  6106.             szTemp[i] = pszPath[i];
  6107.             }
  6108.         szTemp[i] = '\0';
  6109.         for (iTb = 1; iTb < cTb; iTb ++)
  6110.             {
  6111.             if (FCheckExistance (szTemp, iTb, x_colorWhite))
  6112.                 {
  6113.                 if (iTb > iMaxTb)
  6114.                     iMaxTb = iTb;
  6115.                 }
  6116.         if (! rgtbdDesc[iTb].m_fSymmetric && FCheckExistance (szTemp, iTb, x_colorBlack))
  6117.                 {
  6118.                 if (iTb > iMaxTb)
  6119.                     iMaxTb = iTb;
  6120.                 }
  6121.             }
  6122.         pszPath += i;
  6123.         if ('\0' == *pszPath)
  6124.             break;
  6125.         pszPath ++;
  6126.         }
  6127.    
  6128.     // If there were compressed files, have to allocate buffer(s)
  6129.     if (0 != cCompressed)
  6130.         {
  6131.         for (i = 0; i < CPUS; i ++)
  6132.             {
  6133.             if (NULL == rgpdbDecodeBlocks[i])
  6134.                 {
  6135.                 int iResult = comp_alloc_block (&rgpdbDecodeBlocks[i], TB_CB_CACHE_CHUNK);
  6136.                 if (0 != iResult)
  6137.                     {
  6138.                     printf ("*** Cannot allocate decode block: error code %d\n", iResult);
  6139.                     exit (1);
  6140.                     }
  6141.                 }
  6142.             }
  6143.         if (fVerbose)
  6144.             printf ("Allocated %dKb for decompression tables, indices, and buffers.\n",
  6145.                     (cbEGTBCompBytes+1023)/1024);
  6146.         }
  6147.  
  6148.     if (fVerbose)
  6149.         printf ("Tried to open %d files. Opened %d files.\n",
  6150.                 cOpenFilesAttempts, cOpenFilesSuceed);
  6151.     // All done!
  6152. #if defined T33_INCLUDE
  6153.     if (iMaxTb >= tbid_knnknn)
  6154.         return 6;
  6155. #elif defined (T42_INCLUDE)
  6156.     if (iMaxTb >= tbid_knnnkn)
  6157.         return 6;
  6158. #endif
  6159.     if (iMaxTb >= tbid_kppkp)
  6160.         return 5;
  6161.     if (iMaxTb >= tbid_kpkp)
  6162.         return 4;
  6163.     if (iMaxTb >= tbid_kpk)
  6164.         return 3;
  6165.     return 0;
  6166.     }
  6167.