Computer Chess Club Archives


Search

Terms

Messages

Subject: Crafty hackers needed. long post

Author: ERIQ

Date: 10:40:20 08/02/03


I have been trying to get crafty 19.3 working using gcc 3.3 compiler it seems to
me that this compiler is very picky. The gcc 2.95 gives warnings but finishes
compile of crafty. Need help to fix or make more proper egtb.o file. I've
included here both the output of last try & the egtb.cpp file:

Script started on Sat Aug  2 13:24:51 2003
{eriq@osiris} ~/Crafty> gmake -j4

gmake freebsd
gmake[1]: Entering directory `/home/eriq/Crafty'
gmake target=FreeBSD \
	CC=gcc33 CXX=g++33 \
	CFLAGS=' -fomit-frame-pointer -march=i686 -O3 -Wall' \
	CXFLAGS= \
	LDFLAGS= \
	opt=' -DCOMPACT_ATTACKS -DUSE_ATTACK_FUNCTIONS \
	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST' \
	asm=X86-elf.o \
	crafty-make
gmake[2]: Entering directory `/home/eriq/Crafty'
gmake[3]: Entering directory `/home/eriq/Crafty'
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c searchr.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c search.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c thread.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c searchmp.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c repeat.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c next.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c nexte.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c nextr.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c history.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c quiesce.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c evaluate.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c movgen.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c make.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c unmake.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c hash.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c attacks.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c swap.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c boolean.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c utility.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c valid.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c probe.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c book.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c data.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c drawn.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c edit.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c epd.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c epdglue.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c init.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c input.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c interupt.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c iterate.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c main.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c option.c
option.c: In function `Option':
option.c:762: warning: unused variable `i'gcc33 -fomit-frame-pointer -march=i686
-O3 -Wall -DCOMPACT_ATTACKS -DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A
-DUSE_ASSEMBLY_B -DFAST -DFreeBSD -c output.c

option.c:3224: warning: dereferencing type-punned pointer will break
strict-aliasing rules
option.c:3683: warning: dereferencing type-punned pointer will break
strict-aliasing rulesgcc33 -fomit-frame-pointer -march=i686 -O3 -Wall
-DCOMPACT_ATTACKS -DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B
-DFAST -DFreeBSD -c phase.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c ponder.c

gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c preeval.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c resign.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c root.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c learn.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c setboard.c
learn.c: In function `LearnBook':
learn.c:304: warning: dereferencing type-punned pointer will break
strict-aliasing rulesgcc33 -fomit-frame-pointer -march=i686 -O3 -Wall
-DCOMPACT_ATTACKS -DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B
-DFAST -DFreeBSD -c test.c

gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c testepd.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c time.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c validate.c
learn.c: In function `LearnImportPosition':
learn.c:982: warning: dereferencing type-punned pointer will break
strict-aliasing rules
learn.c: In function `LearnPosition':
learn.c:1108: warning: dereferencing type-punned pointer will break
strict-aliasing rules
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c annotate.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c analyze.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c evtest.c
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c bench.c
g++33 -c  -DCOMPACT_ATTACKS -DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A
-DUSE_ASSEMBLY_B -DFAST -DFreeBSD egtb.cpp
gcc33 -fomit-frame-pointer -march=i686 -O3 -Wall -DCOMPACT_ATTACKS
-DUSE_ATTACK_FUNCTIONS 	     -DUSE_ASSEMBLY_A -DUSE_ASSEMBLY_B -DFAST -DFreeBSD
-c dgt.c
egtb.cpp:100:1: warning: "LockInit" redefined
sed -e '/ _/s// /' -e '/^_/s///' -e 's/ALIGN/16/' X86.s > X86-elf.S
In file included from egtb.cpp:61:
lock.h:192:1: gcc33 -c X86-elf.S
warning: this is the location of the previous definition
egtb.cpp:101:1: warning: "Lock" redefined
lock.h:194:1: warning: this is the location of the previous definition
egtb.cpp:102:1: warning: "Unlock" redefined
lock.h:195:1: warning: this is the location of the previous definition
egtb.cpp:4304: warning: `TB_CRC_CHECK' initialized and declared `extern'
gcc33  -o crafty searchr.o search.o thread.o searchmp.o repeat.o next.o nexte.o
nextr.o history.o quiesce.o evaluate.o movgen.o make.o unmake.o hash.o attacks.o
swap.o boolean.o utility.o valid.o probe.o book.o data.o drawn.o edit.o epd.o
epdglue.o init.o input.o interupt.o iterate.o main.o option.o output.o phase.o
ponder.o preeval.o resign.o root.o learn.o setboard.o test.o testepd.o time.o
validate.o annotate.o analyze.o evtest.o bench.o egtb.o dgt.o X86-elf.o -lm
egtb.o(.eh_frame+0x11): undefined reference to `__gxx_personality_v0'
collect2: ld returned 1 exit status
gmake[3]: *** [crafty] Error 1
gmake[3]: Leaving directory `/home/eriq/Crafty'
gmake[2]: *** [crafty-make] Error 2
gmake[2]: Leaving directory `/home/eriq/Crafty'
gmake[1]: *** [freebsd] Error 2
gmake[1]: Leaving directory `/home/eriq/Crafty'
gmake: *** [default] Error 2
{eriq@osiris} ~/Crafty> exitr  [K

exit

Script done on Sat Aug  2 13:25:46 2003

and here is the egtb.cpp:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#if defined(SMP) && defined(MUTEX)
#include <pthread.h>
#endif
#if defined(_WIN32)
#include <windows.h>
#endif

#define SANITY_CHECK 1

#define T41_INCLUDE
#define T42_INCLUDE
#define T33_INCLUDE
#define T_INDEX64
#define  NEW
#define  XX  127

#if !defined(SMP) && !defined(SUN)
#define  lock_t int
#endif

#if defined (T_INDEX64) && defined (_MSC_VER)
    typedef unsigned __int64	INDEX;
#elif defined (T_INDEX64)
    typedef unsigned long long INDEX;
#else
    typedef unsigned long	INDEX;
#endif

typedef unsigned int square;

typedef  int  color;
#define  x_colorWhite    0
#define  x_colorBlack    1
#define  x_colorNeutral  2

typedef  int  piece;
#define  x_pieceNone     0
#define  x_piecePawn     1
#define  x_pieceKnight   2
#define  x_pieceBishop   3
#define  x_pieceRook     4
#define  x_pieceQueen    5
#define  x_pieceKing     6

/*
  Macro that fetches positions of pieces
*/

#define  C_PIECES  3  /* Maximum # of pieces of one color OTB */

#define  SqFindKing(psq)       (psq[C_PIECES*(x_pieceKing-1)])
#define  SqFindOne(psq, pi)    (psq[C_PIECES*(pi-1)])
#define  SqFindFirst(psq, pi)  (psq[C_PIECES*(pi-1)])
#define  SqFindSecond(psq, pi) (psq[C_PIECES*(pi-1)+1])
#define  SqFindThird(psq, pi)  (psq[C_PIECES*(pi-1)+2])

#include "lock.h"

/*
  All defined, now include probing code
*/

/* -------------------------------------------------------------------- */
/*                                                                      */
/*              Probe chess endgame database ("tablebase")              */
/*                                                                      */
/*               Copyright (c) 1998--2001 Eugene Nalimov                */
/*                                                                      */
/* The code listed below should not be used in any product (software or */
/* hardware,  commercial or not,  and so on) without written permission */
/* from the author.                                                     */
/*                                                                      */
/* -------------------------------------------------------------------- */

#if defined (_WIN32) || defined(_WIN64)
#  include <windows.h>
#endif

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#if !defined (DEBUG) && !defined(EBUG)
#  define	NDEBUG
#endif
#include <assert.h>

// SMP stuff

#if defined (CPUS) && !defined (SMP) && (CPUS > 1)
#  error Cannot use CPUS > 1 without SMP defined
#endif

#if defined (SMP)
static	lock_t	lockLRU;
#else
#  define LockInit(x)
#  define Lock(x)
#  define Unlock(x)
#endif

// Declarations

typedef unsigned	char BYTE;
typedef unsigned	long ULONG;
typedef	signed		char tb_t;

#if !defined (COLOR_DECLARED)
typedef	int	color;
#  define	x_colorWhite	0
#  define	x_colorBlack	1
#  define	x_colorNeutral	2
#  define COLOR_DECLARED
#endif

#if !defined (PIECES_DECLARED)
typedef	int	piece;
#  define	x_pieceNone		0
#  define	x_piecePawn		1
#  define	x_pieceKnight	2
#  define	x_pieceBishop	3
#  define	x_pieceRook		4
#  define	x_pieceQueen	5
#  define	x_pieceKing		6
#  define PIECES_DECLARED
#endif

#if !defined (SqFind2)
#
define	SqFind2(psq,pi1,sq1,pi2,sq2)	sq1=SqFindFirst(psq,pi1);sq2=SqFindFirst(psq,pi2);
#endif

// Machine and compiler-specific declarations

#if defined (_MSC_VER)

#  undef	TB_CDECL
#  define	TB_CDECL	__cdecl
#  define	TB_FASTCALL	__fastcall
#  if _MSC_VER >= 1200
#    define	INLINE		__forceinline
#  endif

#else

#  define	TB_CDECL
#  define	TB_FASTCALL

#endif

#if !defined (INLINE)
#  define	INLINE	inline
#endif

// Printf formats

#if defined (T_INDEX64) && defined (_MSC_VER)
#   define HEX_INDEX_FORMAT "%016I64X"
#   define DEC_INDEX_FORMAT "%I64u"
#elif defined (T_INDEX64)
#   define HEX_INDEX_FORMAT "%016llX"
#   define DEC_INDEX_FORMAT "%llu"
#else
#   define HEX_INDEX_FORMAT "%08X"
#   define DEC_INDEX_FORMAT "%lu"
#endif

// Directory delimiter

#if defined (_WIN32) || defined(_WIN64)
#   define DELIMITER   "\\"
#elif defined (__MWERKS__)
#   define DELIMITER   ":"
#else
#   define DELIMITER   "/"
#endif


// Some constants from SJE program

#define pageL 256

/* tablebase byte entry semispan length */

#define tbbe_ssL ((pageL - 4) / 2)

/* tablebase signed byte entry values */

#define bev_broken  (tbbe_ssL + 1)  /* illegal or busted */

#define bev_mi1     tbbe_ssL        /* mate in 1 move */
#define bev_mimin   1               /* mate in 126 moves */

#define bev_draw    0               /* draw */

#define bev_limax   (-1)            /* mated in 125 moves */
#define bev_li0     (-tbbe_ssL)     /* mated in 0 moves */

#define	bev_limaxx	(-tbbe_ssL - 1)	/* mated in 126 moves */
#define	bev_miminx	(-tbbe_ssL - 2)	/* mate in 127 moves */

// Some constants for 16-bit tables

#define L_pageL 65536

/* tablebase short entry semispan length */

#define L_tbbe_ssL ((L_pageL - 4) / 2)

/* tablebase signed short entry values */

#define L_bev_broken  (L_tbbe_ssL + 1)		/* illegal or busted */

#define L_bev_mi1     L_tbbe_ssL			/* mate in 1 move */
#define L_bev_mimin   1						/* mate in 32766 moves */

#define L_bev_draw    0						/* draw */

#define L_bev_limax   (-1)					/* mated in 32765 moves */
#define L_bev_li0     (-L_tbbe_ssL)			/* mated in 0 moves */

#define	L_bev_limaxx	(-L_tbbe_ssL - 1)	/* mated in 32766 moves */
#define	L_bev_miminx	(-L_tbbe_ssL - 2)	/* mate in 32767 moves */

// Convertion from 8-bit to 16-bit score
// UNDONE: Maybe implement via lookup table?

#define	S_to_L(tbt)\
	(\
	 (0 == tbt) ? 0:\
	 (tbt > 0) ? (bev_broken != tbt ? tbt + 32640 : L_bev_broken):\
	 (tbt >= bev_li0) ? tbt - 32640:\
	 (bev_limaxx == tbt) ? -32640:\
	 /*bev_miminx == tbt*/  32640\
	)

// Constants

#define	i8	((unsigned) 8)
#define	i14	((unsigned) 14)
#define	i42	((unsigned) 42)
#define	i43	((unsigned) 43)
#define	i44	((unsigned) 44)
#define	i45	((unsigned) 45)
#define	i46	((unsigned) 46)
#define	i47	((unsigned) 47)
#define	i48	((unsigned) 48)
#define	i57	((unsigned) 57)
#define	i58	((unsigned) 58)
#define	i59	((unsigned) 59)
#define	i60	((unsigned) 60)
#define	i61	((unsigned) 61)
#define	i62	((unsigned) 62)
#define	i63	((unsigned) 63)
#define	i64	((unsigned) 64)

#define x_row_1 0
#define x_row_2 1
#define x_row_3 2
#define x_row_4 3
#define x_row_5 4
#define x_row_6 5
#define x_row_7 6
#define x_row_8 7

#define x_column_a 0
#define x_column_b 1
#define x_column_c 2
#define x_column_d 3
#define x_column_e 4
#define x_column_f 5
#define x_column_g 6
#define x_column_h 7

/* reflection macros */

#define reflect_x(sq) ((sq) ^ 0x38)
#define reflect_y(sq) ((sq) ^ 0x07)
#define reflect_xy(sq) rgsqReflectXY[sq]

static const square rgsqReflectXY [] =
{
  0,  8, 16, 24, 32, 40, 48, 56,
  1,  9, 17, 25, 33, 41, 49, 57,
  2, 10, 18, 26, 34, 42, 50, 58,
  3, 11, 19, 27, 35, 43, 51, 59,
  4, 12, 20, 28, 36, 44, 52, 60,
  5, 13, 21, 29, 37, 45, 53, 61,
  6, 14, 22, 30, 38, 46, 54, 62,
  7, 15, 23, 31, 39, 47, 55, 63,
};

static const square rgsqReflectMaskY [] =
{
 0, 0, 0, 0, 7, 7, 7, 7,
 0, 0, 0, 0, 7, 7, 7, 7,
 0, 0, 0, 0, 7, 7, 7, 7,
 0, 0, 0, 0, 7, 7, 7, 7,
 0, 0, 0, 0, 7, 7, 7, 7,
 0, 0, 0, 0, 7, 7, 7, 7,
 0, 0, 0, 0, 7, 7, 7, 7,
 0, 0, 0, 0, 7, 7, 7, 7,
};

static const square rgsqReflectMaskYandX [] =
{
 0, 0, 0, 0, 7, 7, 7, 7,
 0, 0, 0, 0, 7, 7, 7, 7,
 0, 0, 0, 0, 7, 7, 7, 7,
 0, 0, 0, 0, 7, 7, 7, 7,
 0x38, 0x38, 0x38, 0x38, 0x38+7, 0x38+7, 0x38+7, 0x38+7,
 0x38, 0x38, 0x38, 0x38, 0x38+7, 0x38+7, 0x38+7, 0x38+7,
 0x38, 0x38, 0x38, 0x38, 0x38+7, 0x38+7, 0x38+7, 0x38+7,
 0x38, 0x38, 0x38, 0x38, 0x38+7, 0x38+7, 0x38+7, 0x38+7,
};

static const square rgsqReflectInvertMask[] = { 0, 0x38 };

/* useful macros */

#define	TbRow(sq)				((sq) >> 3)
#define	TbColumn(sq)			((sq) & 7)

#if defined (NEW)
#  define	PchExt(side) ((x_colorWhite == side) ? ".nbw" : ".nbb")
#else
#  define	PchExt(side) ((x_colorWhite == side) ? ".tbw" : ".tbb")
#endif

// Verbose levels

static bool		fPrint = false;		// Print some technical statistics
static bool		fVerbose = false;	// Print additional information

// Malloc that checks for out-of-memory condition

static size_t	cbAllocated;

static void* PvMalloc
	(
	size_t cb
	)
	{
	void	*pv;

	pv = malloc (cb);
	if (NULL == pv)
		{
		printf ("*** Cannot allocate %d bytes of memory\n", cb);
		exit (1);
		}
	cbAllocated += cb;
	return pv;
	}

#if defined (NEW)	// New index schema ----------------------------------------

// 'Invalid' value have to be large, so index
// of invalid position will be very large, too.

#define	INF	4000

// Enumeration: valid positions with 2 kings on board; white king restricted to
// a1-d1-d4 triangle; also, if it's at a1-d4 half-diagonal, then black king
// must be in a1-h1-h8 triangle

static const short rgsTriKings [64 * 64] =
{
 INF, INF,   0,   1,   2,   3,   4,   5, INF, INF,   6,   7,   8,   9,  10,  11,
 INF, INF,  12,  13,  14,  15,  16,  17, INF, INF, INF,  18,  19,  20,  21,  22,
 INF, INF, INF, INF,  23,  24,  25,  26, INF, INF, INF, INF, INF,  27,  28,  29,
 INF, INF, INF, INF, INF, INF,  30,  31, INF, INF, INF, INF, INF, INF, INF,  32,
 INF, INF, INF,  33,  34,  35,  36,  37, INF, INF, INF,  38,  39,  40,  41,  42,
  43,  44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,
  59,  60,  61,  62,  63,  64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,
  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,
  91, INF, INF, INF,  92,  93,  94,  95,  96, INF, INF, INF,  97,  98,  99, 100,
 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,
 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,
 149, 150, INF, INF, INF, 151, 152, 153, 154, 155, INF, INF, INF, 156, 157, 158,
 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174,
 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190,
 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, 207, 208, 209, 210, 211, INF, INF, INF, 212, 213, 214, 215, 216,
 INF, INF, INF, 217, 218, 219, 220, 221, INF, INF, INF, 222, 223, 224, 225, 226,
 INF, INF, INF, INF, 227, 228, 229, 230, INF, INF, INF, INF, INF, 231, 232, 233,
 INF, INF, INF, INF, INF, INF, 234, 235, INF, INF, INF, INF, INF, INF, INF, 236,
 237, INF, INF, INF, 238, 239, 240, 241, 242, INF, INF, INF, 243, 244, 245, 246,
 247, INF, INF, INF, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259,
 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275,
 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291,
 292, 293, INF, INF, INF, 294, 295, 296, 297, 298, INF, INF, INF, 299, 300, 301,
 302, 303, INF, INF, INF, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330,
 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 347, 348, 349, 350, 351, 352, 353, 354, INF, INF, INF, INF, 355, 356, 357, 358,
 INF, INF, INF, INF, 359, 360, 361, 362, INF, INF, INF, INF, 363, 364, 365, 366,
 INF, INF, INF, INF, 367, 368, 369, 370, INF, INF, INF, INF, INF, 371, 372, 373,
 INF, INF, INF, INF, INF, INF, 374, 375, INF, INF, INF, INF, INF, INF, INF, 376,
 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, INF, INF, INF, 387, 388, 389,
 390, 391, INF, INF, INF, 392, 393, 394, 395, 396, INF, INF, INF, 397, 398, 399,
 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415,
 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 432, 433, 434, 435, 436, 437, 438, 439, INF, 440, 441, 442, 443, 444, 445, 446,
 INF, INF, INF, INF, INF, 447, 448, 449, INF, INF, INF, INF, INF, 450, 451, 452,
 INF, INF, INF, INF, INF, 453, 454, 455, INF, INF, INF, INF, INF, 456, 457, 458,
 INF, INF, INF, INF, INF, INF, 459, 460, INF, INF, INF, INF, INF, INF, INF, 461,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
};

// Enumeration: all valid positions with 2 kings on board when white king
// restricted to left half of the board

static const short rgsHalfKings [64 * 64] =
{
 INF, INF,   0,   1,   2,   3,   4,   5, INF, INF,   6,   7,   8,   9,  10,  11,
  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,
  28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,
  44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,
 INF, INF, INF,  60,  61,  62,  63,  64, INF, INF, INF,  65,  66,  67,  68,  69,
  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,
  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  98,  99, 100, 101,
 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
 118, INF, INF, INF, 119, 120, 121, 122, 123, INF, INF, INF, 124, 125, 126, 127,
 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
 176, 177, INF, INF, INF, 178, 179, 180, 181, 182, INF, INF, INF, 183, 184, 185,
 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201,
 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217,
 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, 234, 235, 236, 237, 238, 239, INF, INF, 240, 241, 242, 243, 244, 245,
 INF, INF, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259,
 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275,
 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291,
 INF, INF, INF, 292, 293, 294, 295, 296, INF, INF, INF, 297, 298, 299, 300, 301,
 INF, INF, INF, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330,
 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346,
 347, INF, INF, INF, 348, 349, 350, 351, 352, INF, INF, INF, 353, 354, 355, 356,
 357, INF, INF, INF, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369,
 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385,
 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401,
 402, 403, INF, INF, INF, 404, 405, 406, 407, 408, INF, INF, INF, 409, 410, 411,
 412, 413, INF, INF, INF, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424,
 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440,
 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 457, 458, 459, 460, 461, 462, 463, 464, INF, INF, 465, 466, 467, 468, 469, 470,
 INF, INF, 471, 472, 473, 474, 475, 476, INF, INF, 477, 478, 479, 480, 481, 482,
 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498,
 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514,
 515, 516, 517, 518, 519, 520, 521, 522, INF, INF, INF, 523, 524, 525, 526, 527,
 INF, INF, INF, 528, 529, 530, 531, 532, INF, INF, INF, 533, 534, 535, 536, 537,
 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553,
 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569,
 570, 571, 572, 573, 574, 575, 576, 577, 578, INF, INF, INF, 579, 580, 581, 582,
 583, INF, INF, INF, 584, 585, 586, 587, 588, INF, INF, INF, 589, 590, 591, 592,
 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608,
 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624,
 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, INF, INF, INF, 635, 636, 637,
 638, 639, INF, INF, INF, 640, 641, 642, 643, 644, INF, INF, INF, 645, 646, 647,
 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663,
 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695,
 INF, INF, 696, 697, 698, 699, 700, 701, INF, INF, 702, 703, 704, 705, 706, 707,
 INF, INF, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721,
 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737,
 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753,
 INF, INF, INF, 754, 755, 756, 757, 758, INF, INF, INF, 759, 760, 761, 762, 763,
 INF, INF, INF, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776,
 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792,
 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808,
 809, INF, INF, INF, 810, 811, 812, 813, 814, INF, INF, INF, 815, 816, 817, 818,
 819, INF, INF, INF, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831,
 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847,
 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863,
 864, 865, INF, INF, INF, 866, 867, 868, 869, 870, INF, INF, INF, 871, 872, 873,
 874, 875, INF, INF, INF, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886,
 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918,
 919, 920, 921, 922, 923, 924, 925, 926, INF, INF, 927, 928, 929, 930, 931, 932,
 INF, INF, 933, 934, 935, 936, 937, 938, INF, INF, 939, 940, 941, 942, 943, 944,
 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960,
 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976,
 977, 978, 979, 980, 981, 982, 983, 984, INF, INF, INF, 985, 986, 987, 988, 989,
 INF, INF, INF, 990, 991, 992, 993, 994, INF, INF, INF, 995, 996, 997, 998, 999,
1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,
1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,
1032,1033,1034,1035,1036,1037,1038,1039,1040, INF, INF, INF,1041,1042,1043,1044,
1045, INF, INF, INF,1046,1047,1048,1049,1050, INF, INF, INF,1051,1052,1053,1054,
1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,
1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,
1087,1088,1089,1090,1091,1092,1093,1094,1095,1096, INF, INF, INF,1097,1098,1099,
1100,1101, INF, INF, INF,1102,1103,1104,1105,1106, INF, INF, INF,1107,1108,1109,
1110,1111,1112,1113,1114,1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
1126,1127,1128,1129,1130,1131,1132,1133,1134,1135,1136,1137,1138,1139,1140,1141,
1142,1143,1144,1145,1146,1147,1148,1149,1150,1151,1152,1153,1154,1155,1156,1157,
 INF, INF,1158,1159,1160,1161,1162,1163, INF, INF,1164,1165,1166,1167,1168,1169,
 INF, INF,1170,1171,1172,1173,1174,1175,1176,1177,1178,1179,1180,1181,1182,1183,
1184,1185,1186,1187,1188,1189,1190,1191,1192,1193,1194,1195,1196,1197,1198,1199,
1200,1201,1202,1203,1204,1205,1206,1207,1208,1209,1210,1211,1212,1213,1214,1215,
 INF, INF, INF,1216,1217,1218,1219,1220, INF, INF, INF,1221,1222,1223,1224,1225,
 INF, INF, INF,1226,1227,1228,1229,1230,1231,1232,1233,1234,1235,1236,1237,1238,
1239,1240,1241,1242,1243,1244,1245,1246,1247,1248,1249,1250,1251,1252,1253,1254,
1255,1256,1257,1258,1259,1260,1261,1262,1263,1264,1265,1266,1267,1268,1269,1270,
1271, INF, INF, INF,1272,1273,1274,1275,1276, INF, INF, INF,1277,1278,1279,1280,
1281, INF, INF, INF,1282,1283,1284,1285,1286,1287,1288,1289,1290,1291,1292,1293,
1294,1295,1296,1297,1298,1299,1300,1301,1302,1303,1304,1305,1306,1307,1308,1309,
1310,1311,1312,1313,1314,1315,1316,1317,1318,1319,1320,1321,1322,1323,1324,1325,
1326,1327, INF, INF, INF,1328,1329,1330,1331,1332, INF, INF, INF,1333,1334,1335,
1336,1337, INF, INF, INF,1338,1339,1340,1341,1342,1343,1344,1345,1346,1347,1348,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
1349,1350,1351,1352,1353,1354,1355,1356,1357,1358,1359,1360,1361,1362,1363,1364,
1365,1366,1367,1368,1369,1370,1371,1372,1373,1374,1375,1376,1377,1378,1379,1380,
1381,1382,1383,1384,1385,1386,1387,1388, INF, INF,1389,1390,1391,1392,1393,1394,
 INF, INF,1395,1396,1397,1398,1399,1400, INF, INF,1401,1402,1403,1404,1405,1406,
1407,1408,1409,1410,1411,1412,1413,1414,1415,1416,1417,1418,1419,1420,1421,1422,
1423,1424,1425,1426,1427,1428,1429,1430,1431,1432,1433,1434,1435,1436,1437,1438,
1439,1440,1441,1442,1443,1444,1445,1446, INF, INF, INF,1447,1448,1449,1450,1451,
 INF, INF, INF,1452,1453,1454,1455,1456, INF, INF, INF,1457,1458,1459,1460,1461,
1462,1463,1464,1465,1466,1467,1468,1469,1470,1471,1472,1473,1474,1475,1476,1477,
1478,1479,1480,1481,1482,1483,1484,1485,1486,1487,1488,1489,1490,1491,1492,1493,
1494,1495,1496,1497,1498,1499,1500,1501,1502, INF, INF, INF,1503,1504,1505,1506,
1507, INF, INF, INF,1508,1509,1510,1511,1512, INF, INF, INF,1513,1514,1515,1516,
1517,1518,1519,1520,1521,1522,1523,1524,1525,1526,1527,1528,1529,1530,1531,1532,
1533,1534,1535,1536,1537,1538,1539,1540,1541,1542,1543,1544,1545,1546,1547,1548,
1549,1550,1551,1552,1553,1554,1555,1556,1557,1558, INF, INF, INF,1559,1560,1561,
1562,1563, INF, INF, INF,1564,1565,1566,1567,1568, INF, INF, INF,1569,1570,1571,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,1585,1586,1587,
1588,1589,1590,1591,1592,1593,1594,1595,1596,1597,1598,1599,1600,1601,1602,1603,
1604,1605,1606,1607,1608,1609,1610,1611,1612,1613,1614,1615,1616,1617,1618,1619,
 INF, INF,1620,1621,1622,1623,1624,1625, INF, INF,1626,1627,1628,1629,1630,1631,
1632,1633,1634,1635,1636,1637,1638,1639,1640,1641,1642,1643,1644,1645,1646,1647,
1648,1649,1650,1651,1652,1653,1654,1655,1656,1657,1658,1659,1660,1661,1662,1663,
1664,1665,1666,1667,1668,1669,1670,1671,1672,1673,1674,1675,1676,1677,1678,1679,
 INF, INF, INF,1680,1681,1682,1683,1684, INF, INF, INF,1685,1686,1687,1688,1689,
1690,1691,1692,1693,1694,1695,1696,1697,1698,1699,1700,1701,1702,1703,1704,1705,
1706,1707,1708,1709,1710,1711,1712,1713,1714,1715,1716,1717,1718,1719,1720,1721,
1722,1723,1724,1725,1726,1727,1728,1729,1730,1731,1732,1733,1734,1735,1736,1737,
1738, INF, INF, INF,1739,1740,1741,1742,1743, INF, INF, INF,1744,1745,1746,1747,
1748,1749,1750,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,
1764,1765,1766,1767,1768,1769,1770,1771,1772,1773,1774,1775,1776,1777,1778,1779,
1780,1781,1782,1783,1784,1785,1786,1787,1788,1789,1790,1791,1792,1793,1794,1795,
1796,1797, INF, INF, INF,1798,1799,1800,1801,1802, INF, INF, INF,1803,1804,1805,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
 INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF,
};

// Useful macro and enumeration tables

#define	IndTriKings(sqk1,sqk2)	((unsigned) rgsTriKings[sqk1*64+sqk2])
#define	IndHalfKings(sqk1,sqk2)	((unsigned) rgsHalfKings[sqk1*64+sqk2])

static const bool rgfTriangle[64] =
{
	 true,  true,  true,  true,  false, false, false, false,
	 false, true,  true,  true,  false, false, false, false,
	 false, false, true,  true,  false, false, false, false,
	 false, false, false, true,  false, false, false, false,
	 false, false, false, false, false, false, false, false,
	 false, false, false, false, false, false, false, false,
	 false, false, false, false, false, false, false, false,
	 false, false, false, false, false, false, false, false,
};

static const bool rgfNotDiagonal[64] =
{
	 false, true,  true,  true,  true,  true,  true,  true,
	 true,  false, true,  true,  true,  true,  true,  true,
	 true,  true,  false, true,  true,  true,  true,  true,
	 true,  true,  true,  false, true,  true,  true,  true,
	 true,  true,  true,  true,  false, true,  true,  true,
	 true,  true,  true,  true,  true,  false, true,  true,
	 true,  true,  true,  true,  true,  true,  false, true,
	 true,  true,  true,  true,  true,  true,  true,  false,
};

static const bool rgfInLargeTriangle[64] =
{
	 true,  true,  true,  true,  true,  true,  true,  true,
	 false, true,  true,  true,  true,  true,  true,  true,
	 false, false, true,  true,  true,  true,  true,  true,
	 false, false, false, true,  true,  true,  true,  true,
	 false, false, false, false, true,  true,  true,  true,
	 false, false, false, false, false, true,  true,  true,
	 false, false, false, false, false, false, true,  true,
	 false, false, false, false, false, false, false, true,
};

#define	FInTriangle(sqwk,sqbk)	(rgfTriangle[sqwk] &
(rgfNotDiagonal[sqwk]|rgfInLargeTriangle[sqbk]))

// Sort pieces

#define	SORT(sq1,sq2)	if (sq1>sq2) { square sqTmp; sqTmp=sq1; sq1=sq2;
sq2=sqTmp; }

// Exclude occupied squares

#define	EXCLUDE1(sq,sq1)						 (sq-(sq>sq1))
#define	EXCLUDE2(sq,sq1,sq2)					 (sq-((sq>sq1)+(sq>sq2)))
#define	EXCLUDE3(sq,sq1,sq2,sq3)				 (sq-((sq>sq1)+(sq>sq2)+(sq>sq3)))
#define	EXCLUDE4(sq,sq1,sq2,sq3,sq4)
(sq-((sq>sq1)+(sq>sq2)+(sq>sq3)+(sq>sq4)))
#define	EXCLUDE5(sq,sq1,sq2,sq3,sq4,sq5)
(sq-((sq>sq1)+(sq>sq2)+(sq>sq3)+(sq>sq4)+(sq>sq5)))
#define	EXCLUDE6(sq,sq1,sq2,sq3,sq4,sq5,sq6)
(sq-((sq>sq1)+(sq>sq2)+(sq>sq3)+(sq>sq4)+(sq>sq5)+(sq>sq6)))
#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)))

// Calculate index - a lot of functions...

// Enumeration tables

static BYTE		*rgprgsqPiece[6];	// Enumeration for each piece (0 - black pawn)
									// For each position of the King, all legal squares
									// of the opposite piece enumerated
static BYTE		rgcLegal[6][64];	// # of enumerated positions for each piece and
each
									// location of enemy king

// Enumerations - indexed by [piece] and [kings enumeration].
// In each table for each [piece] and [king enumeration] we store # of
preceeding positions.

static ULONG	*rgprgulSinglePawnless[6];
static ULONG	*rgprgulPairPawnless[6][6];
#if defined (T41_INCLUDE) || defined (T42_INCLUDE)
  static ULONG	*rgprgulTriplePawnless[6][6][6];
#endif
static ULONG	*rgprgulSinglePawnPresent[6];
static ULONG	*rgprgulPairPawnPresent[6][6];
#if defined (T41_INCLUDE) || defined (T42_INCLUDE)
  static ULONG	*rgprgulTriplePawnPresent[6][6][6];
#endif

// Total # of enumerated positions

static ULONG	rgcSinglePawnPresent[6];
static ULONG	rgcSinglePawnless[6];
static ULONG	rgcPairPawnPresent[6][6];
static ULONG	rgcPairPawnless[6][6];
#if defined (T41_INCLUDE) || defined (T42_INCLUDE)
  static ULONG	rgcTriplePawnPresent[6][6][6];
  static ULONG	rgcTriplePawnless[6][6][6];
#endif

// Infinities. Have to be larger than any legal enumeration yet small enough
// so there will be no overflow when combining them with remaining pieces.

#define	INF_SINGLE	(110000)
#define	INF_PAIR	(6500000)
#define	INF_TRIPLE	(500000000)

// Initialize squares and counters table for one piece.
// Piece can be x_pieceNone - that means 'pawn of the wrong color', e.g. KPK
BTM.

static void VInitSquaresTable
	(
	piece	pi,
	BYTE	*prgsqPiece,
	BYTE	*prgcLegal
	)
	{
	int	sqLo, sqHi;

	memset (prgsqPiece, -1, 64*64);
	sqLo = 0;
	sqHi = 64;
	if (pi <= x_piecePawn)
		{
		sqLo = 8;
		sqHi = 56;
		}
	for (int sqKing = 0; sqKing < 64; sqKing ++)
		{
		int	iPiece;

		iPiece = 0;
		for (int sq = sqLo; sq < sqHi; sq ++)
			{
			if (sq == sqKing)
				continue;
			switch (pi)
				{
			case x_piecePawn:
				if (
					0 != TbColumn (sq) && sqKing == sq+7 ||
					7 != TbColumn (sq) && sqKing == sq+9
				   )
				   continue;
				break;
			case x_pieceKnight:
				if (
					TbRow (sq) >= 2 && TbColumn (sq) >= 1 && sqKing == sq-17 ||
					TbRow (sq) >= 2 && TbColumn (sq) <= 6 && sqKing == sq-15 ||
					TbRow (sq) >= 1 && TbColumn (sq) >= 2 && sqKing == sq-10 ||
					TbRow (sq) >= 1 && TbColumn (sq) <= 5 && sqKing == sq-6 ||
					TbRow (sq) <= 6 && TbColumn (sq) >= 2 && sqKing == sq+6 ||
					TbRow (sq) <= 6 && TbColumn (sq) <= 5 && sqKing == sq+10 ||
					TbRow (sq) <= 5 && TbColumn (sq) >= 1 && sqKing == sq+15 ||
					TbRow (sq) <= 5 && TbColumn (sq) <= 6 && sqKing == sq+17
				   )
					continue;
				break;
			case x_pieceBishop:
				if (
					0 != TbRow (sq) && 0 != TbColumn (sq) && sqKing == sq-9 ||
					0 != TbRow (sq) && 7 != TbColumn (sq) && sqKing == sq-7 ||
					7 != TbRow (sq) && 0 != TbColumn (sq) && sqKing == sq+7 ||
					7 != TbRow (sq) && 7 != TbColumn (sq) && sqKing == sq+9
				   )
					continue;
				break;
			case x_pieceRook:
				if (
					0 != TbColumn (sq) && sqKing == sq-1 ||
					7 != TbColumn (sq) && sqKing == sq+1 ||
					0 != TbRow (sq) && sqKing == sq-8 ||
					7 != TbRow (sq) && sqKing == sq+8
				   )
					continue;
				break;
			case x_pieceQueen:
				if (
					0 != TbColumn (sq) && sqKing == sq-1 ||
					7 != TbColumn (sq) && sqKing == sq+1 ||
					0 != TbRow (sq) && sqKing == sq-8 ||
					7 != TbRow (sq) && sqKing == sq+8 ||
					0 != TbRow (sq) && 0 != TbColumn (sq) && sqKing == sq-9 ||
					0 != TbRow (sq) && 7 != TbColumn (sq) && sqKing == sq-7 ||
					7 != TbRow (sq) && 0 != TbColumn (sq) && sqKing == sq+7 ||
					7 != TbRow (sq) && 7 != TbColumn (sq) && sqKing == sq+9
				   )
					continue;
				break;
				}
			prgsqPiece[sqKing*64+sq] = (BYTE) iPiece;
			iPiece ++;
			}
		prgcLegal[sqKing] = (BYTE) iPiece;
		}
	}

// Initialize enumeration table for single piece

static void VInitSingle
	(
	ULONG		*prgIndex,
	const short	*prgsKings,
	const BYTE	*prgcLegal,
	const BYTE	*prgsqPiece,
	ULONG		*pcEnumeration
	)
	{
	ULONG iIndex;

	iIndex = 0;
	for (int sqKing1 = 0; sqKing1 < 64; sqKing1 ++)
		for (int sqKing2 = 0; sqKing2 < 64; sqKing2 ++)
			{
			if (INF != prgsKings[sqKing1*64+sqKing2])
				{
				prgIndex[prgsKings[sqKing1*64+sqKing2]] = iIndex;
				iIndex += prgcLegal[sqKing2] - ((BYTE) -1 !=
prgsqPiece[sqKing2*64+sqKing1]);
				}
			}
	*pcEnumeration = iIndex;
	}

// Initialize enumeration table for pair of pieces

static void VInitPair
	(
	ULONG		*prgIndex,
	const short	*prgsKings,
	const BYTE	*prgcLegal1,
	const BYTE	*prgsqPiece1,
	const BYTE	*prgcLegal2,
	const BYTE	*prgsqPiece2,
	ULONG		*pcEnumeration
	)
	{
	ULONG iIndex;
	ULONG cPositions1, cPositions2;

	iIndex = 0;
	for (int sqKing1 = 0; sqKing1 < 64; sqKing1 ++)
		for (int sqKing2 = 0; sqKing2 < 64; sqKing2 ++)
			{
			if (INF != prgsKings[sqKing1*64+sqKing2])
				{
				prgIndex[prgsKings[sqKing1*64+sqKing2]] = iIndex;
				cPositions1 = prgcLegal1[sqKing2] - ((BYTE) -1 !=
prgsqPiece1[sqKing2*64+sqKing1]);
				if (prgcLegal1 == prgcLegal2)
					iIndex += cPositions1*(cPositions1-1)/2;
				else
					{
					cPositions2 = prgcLegal2[sqKing2] - ((BYTE) -1 !=
prgsqPiece2[sqKing2*64+sqKing1]);
					iIndex += cPositions1*cPositions2;
					}
				}
			}
	*pcEnumeration = iIndex;
	}

#if defined (T41_INCLUDE) || defined (T42_INCLUDE)

// Initialize enumeration table for triple piece

static void VInitTriple
	(
	ULONG		*prgIndex,
	const short	*prgsKings,
	const BYTE	*prgcLegal1,
	const BYTE	*prgsqPiece1,
	const BYTE	*prgcLegal2,
	const BYTE	*prgsqPiece2,
	const BYTE	*prgcLegal3,
	const BYTE	*prgsqPiece3,
	ULONG		*pcEnumeration
	)
	{
	ULONG iIndex;
	ULONG cPositions1, cPositions2, cPositions3;

	iIndex = 0;
	for (int sqKing1 = 0; sqKing1 < 64; sqKing1 ++)
		for (int sqKing2 = 0; sqKing2 < 64; sqKing2 ++)
			{
			if (INF != prgsKings[sqKing1*64+sqKing2])
				{
				prgIndex[prgsKings[sqKing1*64+sqKing2]] = iIndex;
				cPositions1 = prgcLegal1[sqKing2] - ((BYTE) -1 !=
prgsqPiece1[sqKing2*64+sqKing1]);
				if (prgcLegal1 == prgcLegal2 && prgcLegal2 == prgcLegal3)
					iIndex += cPositions1*(cPositions1-1)*(cPositions1-2)/6;
				else if (prgcLegal1 == prgcLegal2)
					{
					cPositions3 = prgcLegal3[sqKing2] - ((BYTE) -1 !=
prgsqPiece3[sqKing2*64+sqKing1]);
					iIndex += cPositions1*(cPositions1-1)/2*cPositions3;
					}
				else if (prgcLegal2 == prgcLegal3)
					{
					cPositions2 = prgcLegal2[sqKing2] - ((BYTE) -1 !=
prgsqPiece2[sqKing2*64+sqKing1]);
					iIndex += cPositions1*cPositions2*(cPositions2-1)/2;
					}
				else
					{
					cPositions2 = prgcLegal2[sqKing2] - ((BYTE) -1 !=
prgsqPiece2[sqKing2*64+sqKing1]);
					cPositions3 = prgcLegal3[sqKing2] - ((BYTE) -1 !=
prgsqPiece3[sqKing2*64+sqKing1]);
					iIndex += cPositions1*cPositions2*cPositions3;
					}
				}
			}
	*pcEnumeration = iIndex;
	}

#endif

// Initialize all Enumeration tables

static bool fEnumerationInitted = false;

static void VInitEnumerations (void)
	{
	piece	pi1;
	piece	pi2;
#if defined (T41_INCLUDE) || defined (T42_INCLUDE)
	piece	pi3;
#endif

	if (fEnumerationInitted)
		return;
	fEnumerationInitted = true;
	// Initialize square tables
	for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
		{
		rgprgsqPiece[pi1] = (BYTE *) PvMalloc (64*64);
		VInitSquaresTable (pi1, rgprgsqPiece[pi1], rgcLegal[pi1]);
		}

	for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
		{
		// Initialize enumeration tables for single piece
		rgprgulSinglePawnPresent[pi1] = (ULONG *) PvMalloc (1806*sizeof (ULONG));
		VInitSingle (rgprgulSinglePawnPresent[pi1], rgsHalfKings,
					 rgcLegal[pi1], rgprgsqPiece[pi1], &rgcSinglePawnPresent[pi1]);
		if (pi1 > x_piecePawn)
			{
			rgprgulSinglePawnless[pi1] = (ULONG *) PvMalloc (462*sizeof (ULONG));
			VInitSingle (rgprgulSinglePawnless[pi1], rgsTriKings,
						 rgcLegal[pi1], rgprgsqPiece[pi1], &rgcSinglePawnless[pi1]);
			}
		// Initialize enumeration tables for pair of pieces
		for (pi2 = (x_pieceNone == pi1 ? x_pieceNone : x_piecePawn); pi2 <= pi1; pi2 =
(piece) (pi2 + 1))
			{
			rgprgulPairPawnPresent[pi1][pi2] = (ULONG *) PvMalloc (1806*sizeof (ULONG));
			VInitPair (rgprgulPairPawnPresent[pi1][pi2], rgsHalfKings,
					   rgcLegal[pi1], rgprgsqPiece[pi1], rgcLegal[pi2], rgprgsqPiece[pi2],
					   &rgcPairPawnPresent[pi1][pi2]);
			if (pi1 > x_piecePawn && pi2 > x_piecePawn)
				{
				rgprgulPairPawnless[pi1][pi2] = (ULONG *) PvMalloc (462*sizeof (ULONG));
				VInitPair (rgprgulPairPawnless[pi1][pi2], rgsTriKings,
						   rgcLegal[pi1], rgprgsqPiece[pi1], rgcLegal[pi2], rgprgsqPiece[pi2],
						   &rgcPairPawnless[pi1][pi2]);
				}
#if defined (T41_INCLUDE) || defined (T42_INCLUDE)
			// Initialize enumeration tables for three pieces
			for (pi3 = (x_pieceNone == pi1 ? x_pieceNone : x_piecePawn); pi3 <= pi2; pi3
= (piece) (pi3 + 1))
				{
				if (pi1 <= x_piecePawn || pi2 <= x_piecePawn || pi3 <= x_piecePawn)
					{
					rgprgulTriplePawnPresent[pi1][pi2][pi3] = (ULONG *) PvMalloc (1806*sizeof
(ULONG));
					VInitTriple (rgprgulTriplePawnPresent[pi1][pi2][pi3], rgsHalfKings,
								 rgcLegal[pi1], rgprgsqPiece[pi1],
								 rgcLegal[pi2], rgprgsqPiece[pi2],
								 rgcLegal[pi3], rgprgsqPiece[pi3],
								 &rgcTriplePawnPresent[pi1][pi2][pi3]);
					}
				else
					{
					rgprgulTriplePawnless[pi1][pi2][pi3] = (ULONG *) PvMalloc (462*sizeof
(ULONG));
					VInitTriple (rgprgulTriplePawnless[pi1][pi2][pi3], rgsTriKings,
						rgcLegal[pi1], rgprgsqPiece[pi1],
						rgcLegal[pi2], rgprgsqPiece[pi2],
						rgcLegal[pi3], rgprgsqPiece[pi3],
						&rgcTriplePawnless[pi1][pi2][pi3]);
#if defined (T42_INCLUDE)
					rgprgulTriplePawnPresent[pi1][pi2][pi3] = (ULONG *) PvMalloc (1806*sizeof
(ULONG));
					VInitTriple (rgprgulTriplePawnPresent[pi1][pi2][pi3], rgsHalfKings,
								 rgcLegal[pi1], rgprgsqPiece[pi1],
								 rgcLegal[pi2], rgprgsqPiece[pi2],
								 rgcLegal[pi3], rgprgsqPiece[pi3],
								 &rgcTriplePawnPresent[pi1][pi2][pi3]);
#endif
					}
				}
#endif
			}
		}

	// All done!
	if (fPrint)
		{
		for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
			printf ("%c - %d enumerated positions\n", "pPNBRQ"[pi1],
rgcSinglePawnPresent[pi1]);
		for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
			{
			if (0 != rgcSinglePawnless[pi1])
				printf ("pawnless %c - %d enumerated positions\n", "pPNBRQ"[pi1],
rgcSinglePawnless[pi1]);
			}
		for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
			for (pi2 = x_pieceNone; pi2 <= pi1; pi2 = (piece) (pi2 + 1))
				{
				if (0 != rgcPairPawnPresent[pi1][pi2])
					printf ("%c%c - %d enumerated positions\n", "pPNBRQ"[pi1], "pPNBRQ"[pi2],
							rgcPairPawnPresent[pi1][pi2]);
				}
		for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
			for (pi2 = x_pieceNone; pi2 <= pi1; pi2 = (piece) (pi2 + 1))
				{
				if (0 != rgcPairPawnless[pi1][pi2])
					printf ("pawnless %c%c - %d enumerated positions\n", "pPNBRQ"[pi1],
"pPNBRQ"[pi2],
							rgcPairPawnless[pi1][pi2]);
				}
#if defined (T41_INCLUDE) || defined (T42_INCLUDE)
		for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
			for (pi2 = x_pieceNone; pi2 <= pi1; pi2 = (piece) (pi2 + 1))
				for (pi3 = x_pieceNone; pi3 <= pi2; pi3 = (piece) (pi3 + 1))
					{
					if (0 != rgcTriplePawnPresent[pi1][pi2][pi3])
						printf ("%c%c%c - %d enumerated positions\n",
								"pPNBRQ"[pi1], "pPNBRQ"[pi2], "pPNBRQ"[pi3],
								rgcTriplePawnPresent[pi1][pi2][pi3]);
					}
		for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
			for (pi2 = x_pieceNone; pi2 <= pi1; pi2 = (piece) (pi2 + 1))
				for (pi3 = x_pieceNone; pi3 <= pi2; pi3 = (piece) (pi3 + 1))
					{
					if (0 != rgcTriplePawnless[pi1][pi2][pi3])
						printf ("pawnless %c%c%c - %d enumerated positions\n",
								"pPNBRQ"[pi1], "pPNBRQ"[pi2], "pPNBRQ"[pi3],
								rgcTriplePawnless[pi1][pi2][pi3]);
					}
#endif
		printf ("\nAllocated %dk\n\n", (cbAllocated + 1023)/1024);
		}
	}

// Return enumeration of 2 kings and single piece

template <int piw1, bool fPawns, bool fInvert> class TEnumerate1
	{
public:
	static INLINE unsigned TB_FASTCALL Index
		(
		square	sqwk,
		square	sqw1,
		square	sqbk
		)
		{
		unsigned ind;
		ULONG	 ulKings;

		// For black pawn invert the board
		if (piw1 <= x_piecePawn && fInvert)
			{
			sqwk = reflect_x(sqwk);
			sqw1 = reflect_x(sqw1);
			sqbk = reflect_x(sqbk);
			}

		// Get enumerated square
		ind = rgprgsqPiece[piw1][sqbk*64+sqw1];
#if defined (ILLEGAL_POSSIBLE)
		if ((BYTE) -1 == ind)
			return INF_SINGLE;
#endif
		// Get enumerated position of both kings
		if (fPawns)
			ulKings = rgsHalfKings[sqwk*64+sqbk];	// 0..1805
		else
			ulKings = rgsTriKings[sqwk*64+sqbk];	// 0..461
#if defined (ILLEGAL_POSSIBLE)
		if (INF == ulKings)
			return INF_SINGLE;
#endif
		// Can we remove one extra square?
		if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk]))
			ind -= (sqw1 > sqwk);
		// Add enumerated square to the # of the preceeding positions
		return ind + (fPawns ? rgprgulSinglePawnPresent[piw1][ulKings] :
rgprgulSinglePawnless[piw1][ulKings]);
		}
	};

// Return enumeration of 2 kings and 2 pieces

template <int piw1, int piw2, bool fPawns, bool fInvert> class TEnumerate2
	{
public:
	static INLINE unsigned TB_FASTCALL Index
		(
		square	sqwk,
		square	sqw1,
		square	sqw2,
		square	sqbk
		)
		{
		unsigned ind1, ind2, cInd2;
		ULONG	 ulKings;

		// For black pawn invert the board
		if (piw2 <= x_piecePawn && fInvert)
			{
			sqwk = reflect_x(sqwk);
			sqw1 = reflect_x(sqw1);
			sqw2 = reflect_x(sqw2);
			sqbk = reflect_x(sqbk);
			}

		// Get enumerated squares for both pieces
		if (piw1 == piw2)
			SORT (sqw1, sqw2);
		ind1 = rgprgsqPiece[piw1][sqbk*64+sqw1];
		ind2 = rgprgsqPiece[piw2][sqbk*64+sqw2];
#if defined (ILLEGAL_POSSIBLE)
		if ((BYTE) -1 == ind1 || (BYTE) -1 == ind2)
			return INF_PAIR;
#endif
		// Get enumerated position of both kings
		if (fPawns)
			ulKings = rgsHalfKings[sqwk*64+sqbk];	// 0..1805
		else
			ulKings = rgsTriKings[sqwk*64+sqbk];	// 0..461
#if defined (ILLEGAL_POSSIBLE)
		if (INF == ulKings)
			return INF_PAIR;
#endif
		if (piw1 == piw2)
			{
			// Can we remove one extra square?
			if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk]))
				{
				ind1 -= (sqw1 > sqwk);
				ind2 -= (sqw2 > sqwk);
				}
			// Add enumerated squares to the # of the preceeding positions
			return	ind2*(ind2-1)/2 + ind1 +
					(fPawns ? rgprgulPairPawnPresent[piw1][piw2][ulKings] :
rgprgulPairPawnless[piw1][piw2][ulKings]);
			}
		else
			{
			// Can we remove WK square from 1st piece Enumeration?
			if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk]))
				ind1 -= (sqw1 > sqwk);
			// Get # of enumerated positions of 2nd piece
			cInd2 = rgcLegal[piw2][sqbk];
			// Can we remove WK square from 2nd piece Enumeration?
			if ((piw2>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw2][sqbk*64+sqwk]))
				{
				cInd2 --;
				ind2 -= (sqw2 > sqwk);
				}
			// Add enumerated square to the # of the preceeding positions
			return cInd2*ind1 + ind2 + (fPawns ?
rgprgulPairPawnPresent[piw1][piw2][ulKings] :
rgprgulPairPawnless[piw1][piw2][ulKings]);
			}
		}
	};

#if defined (T41_INCLUDE) || defined (T42_INCLUDE)

// Return enumeration of 2 kings and 3 pieces

template <int piw1, int piw2, int piw3, bool fPawns, bool fInvert> class
TEnumerate3
	{
public:
	static INLINE unsigned TB_FASTCALL Index
		(
		square	sqwk,
		square	sqw1,
		square	sqw2,
		square	sqw3,
		square	sqbk
		)
		{
		unsigned ind1, ind2, ind3, cInd1, cInd2, cInd3;
		ULONG	 ulKings;

		// For black pawn invert the board
		if (piw3 <= x_piecePawn && fInvert)
			{
			sqwk = reflect_x(sqwk);
			sqw1 = reflect_x(sqw1);
			sqw2 = reflect_x(sqw2);
			sqw3 = reflect_x(sqw3);
			sqbk = reflect_x(sqbk);
			}

		// Get enumerated squares for all pieces
		if (piw1 == piw2 && piw1 == piw3)
			{
			SORT (sqw1, sqw2);
			SORT (sqw2, sqw3);
			SORT (sqw1, sqw2);
			}
		else if (piw1 == piw2)
			{
			SORT (sqw1, sqw2);
			}
		else if (piw2 == piw3)
			{
			SORT (sqw2, sqw3);
			}
		ind1 = rgprgsqPiece[piw1][sqbk*64+sqw1];
		ind2 = rgprgsqPiece[piw2][sqbk*64+sqw2];
		ind3 = rgprgsqPiece[piw3][sqbk*64+sqw3];
#if defined (ILLEGAL_POSSIBLE)
		if ((BYTE) -1 == ind1 || (BYTE) -1 == ind2 || (BYTE) -1 == ind3)
			return INF_TRIPLE;
#endif
		// Get enumerated position of both kings
		if (fPawns)
			ulKings = rgsHalfKings[sqwk*64+sqbk];	// 0..1805
		else
			ulKings = rgsTriKings[sqwk*64+sqbk];	// 0..461
#if defined (ILLEGAL_POSSIBLE)
		if (INF == ulKings)
			return INF_TRIPLE;
#endif
		if (piw1 == piw2 && piw2 == piw3)
			{
			// Can we remove one extra square?
			if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk]))
				{
				ind1 -= (sqw1 > sqwk);
				ind2 -= (sqw2 > sqwk);
				ind3 -= (sqw3 > sqwk);
				}
			// Add enumerated squares to the # of the preceeding positions
			return	ind3*(ind3-1)*(ind3-2)/6 + ind2*(ind2-1)/2 + ind1 +
					(fPawns ? rgprgulTriplePawnPresent[piw1][piw2][piw3][ulKings] :
							  rgprgulTriplePawnless[piw1][piw2][piw3][ulKings]);
			}
		else if (piw1 == piw2)
			{
			// Can we remove one extra square?
			if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk]))
				{
				ind1 -= (sqw1 > sqwk);
				ind2 -= (sqw2 > sqwk);
				}
			// Get # of enumerated positions of 3rd piece
			cInd3 = rgcLegal[piw3][sqbk];
			// Can we remove WK square from 3rd piece Enumeration?
			if ((piw3>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw3][sqbk*64+sqwk]))
				{
				cInd3 --;
				ind3 -= (sqw3 > sqwk);
				}
			// Add enumerated squares to the # of the preceeding positions
			return	(ind2*(ind2-1)/2 + ind1)*cInd3 + ind3 +
					(fPawns ? rgprgulTriplePawnPresent[piw1][piw2][piw3][ulKings] :
							  rgprgulTriplePawnless[piw1][piw2][piw3][ulKings]);
			}
		else if (piw2 == piw3)
			{
			// Can we remove one extra square?
			if ((piw2>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw2][sqbk*64+sqwk]))
				{
				ind2 -= (sqw2 > sqwk);
				ind3 -= (sqw3 > sqwk);
				}
			// Get # of enumerated positions of 1st piece
			cInd1 = rgcLegal[piw1][sqbk];
			// Can we remove WK square from 3rd piece Enumeration?
			if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk]))
				{
				cInd1 --;
				ind1 -= (sqw1 > sqwk);
				}
			// Add enumerated squares to the # of the preceeding positions
			return	(ind3*(ind3-1)/2 + ind2)*cInd1 + ind1 +
					(fPawns ? rgprgulTriplePawnPresent[piw1][piw2][piw3][ulKings] :
							  rgprgulTriplePawnless[piw1][piw2][piw3][ulKings]);
			}
		else
			{
			// Can we remove WK square from 1st piece Enumeration?
			if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk]))
				ind1 -= (sqw1 > sqwk);
			// Get # of enumerated positions of 2nd piece
			cInd2 = rgcLegal[piw2][sqbk];
			// Can we remove WK square from 2nd piece Enumeration?
			if ((piw2>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw2][sqbk*64+sqwk]))
				{
				cInd2 --;
				ind2 -= (sqw2 > sqwk);
				}
			// Get # of enumerated positions of 3rd piece
			cInd3 = rgcLegal[piw3][sqbk];
			// Can we remove WK square from 3rd piece Enumeration?
			if ((piw3>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw3][sqbk*64+sqwk]))
				{
				cInd3 --;
				ind3 -= (sqw3 > sqwk);
				}
			// Add enumerated square to the # of the preceeding positions
			return	cInd3*(cInd2*ind1 + ind2) + ind3 +
					(fPawns ? rgprgulTriplePawnPresent[piw1][piw2][piw3][ulKings] :
							  rgprgulTriplePawnless[piw1][piw2][piw3][ulKings]);
			}
		}
	};

#endif

// Enumerate en passant captures

static INLINE unsigned TB_FASTCALL IndEnPassant11W
	(
	square	sqw,
	square	sqb,
	square	sqEnP
	)
	{
	assert (sqb+8 == sqEnP);
	if (sqw+7 == sqEnP)
		// Capture to the left
		return	(sqw&7)-1;
	else
		{
		// Capture to the right
		assert (sqw+9 == sqEnP);
		return	(sqw&7)+7;
		}
	}

static INLINE unsigned TB_FASTCALL IndEnPassant11B
	(
	square	sqw,
	square	sqb,
	square	sqEnP
	)
	{
	assert (sqw-8 == sqEnP);
	if (sqb-9 == sqEnP)
		// Capture to the left
		return (sqb&7)-1;
	else
		{
		// Capture to the right
		assert (sqb-7 == sqEnP);
		return (sqb&7)+7;
		}
	}

static INLINE unsigned TB_FASTCALL IndEnPassant21W
	(
	square	sqw1,
	square	sqw2,
	square	sqb,
	square	sqEnP
	)
	{
	assert (sqb+8 == sqEnP);
	SORT (sqw1, sqw2);
	if (sqw1+7 == sqEnP && 0 != TbColumn(sqw1))
		// Capture to the left
		return (sqw1&7)-1+(EXCLUDE3(sqw2,sqb,sqEnP,sqEnP+8)-i8-1)*i14;
	else if (sqw1+9 == sqEnP && 7 != TbColumn(sqw1))
		// Capture to the right
		return (sqw1&7)+7+(EXCLUDE3(sqw2,sqb,sqEnP,sqEnP+8)-i8-1)*i14;
	else if (sqw2+7 == sqEnP && 0 != TbColumn(sqw2))
		// Capture to the left
		return (sqw2&7)-1+(EXCLUDE3(sqw1,sqb,sqEnP,sqEnP+8)-i8)*i14;
	else
		{
		// Capture to the right
		assert (sqw2+9 == sqEnP && 7 != TbColumn(sqw2));
		return (sqw2&7)+7+(EXCLUDE3(sqw1,sqb,sqEnP,sqEnP+8)-i8)*i14;
		}
	}

static INLINE unsigned TB_FASTCALL IndEnPassant21B
	(
	square	sqw1,
	square	sqw2,
	square	sqb,
	square	sqEnP
	)
	{
	assert (sqw1 < sqw2);	// Must be already sorted
	if (sqb-9 == sqEnP && 0 != TbColumn(sqb))
		// Capture to the left
		if (sqw1-8 == sqEnP)
			return (sqb&7)-1+(EXCLUDE3(sqw2,sqb,sqEnP,sqEnP-8)-i8-1)*i14;
		else
			{
			assert (sqw2-8 == sqEnP);
			return (sqb&7)-1+(EXCLUDE3(sqw1,sqb,sqEnP,sqEnP-8)-i8)*i14;
			}
	else
		{
		// Capture to the right
		assert (sqb-7 == sqEnP && 7 != TbColumn(sqb));
		if (sqw1-8 == sqEnP)
			return (sqb&7)+7+(EXCLUDE3(sqw2,sqb,sqEnP,sqEnP-8)-i8-1)*i14;
		else
			{
			assert (sqw2-8 == sqEnP);
			return (sqb&7)+7+(EXCLUDE3(sqw1,sqb,sqEnP,sqEnP-8)-i8)*i14;
			}
		}
	}

// 14*43*42

static INLINE unsigned TB_FASTCALL IndEnPassant22W
	(
	square	sqw1,
	square	sqw2,
	square	sqb1,
	square	sqb2,
	square	sqEnP
	)
	{
	square sqEmptyEnP;

	assert (sqb1+8 == sqEnP || sqb2+8 == sqEnP);
	SORT (sqw1, sqw2);
	SORT (sqb1, sqb2);
	sqEmptyEnP = sqEnP+8;
	if (sqb1+8 == sqEnP)
		{
		if (sqw1+7 == sqEnP && 0 != TbColumn(sqw1))
			// Capture to the left
			return (sqw1&7)-1+
				   (EXCLUDE3(sqw2,sqb1,sqEnP,sqEmptyEnP)-i8-1)*i14+
				   (EXCLUDE4(sqb2,sqw1,sqw2,sqEnP,sqEmptyEnP)-i8-1)*i14*i43;
		else if (sqw1+9 == sqEnP && 7 != TbColumn(sqw1))
			// Capture to the right
			return (sqw1&7)+7+
				   (EXCLUDE3(sqw2,sqb1,sqEnP,sqEmptyEnP)-i8-1)*i14+
				   (EXCLUDE4(sqb2,sqw1,sqw2,sqEnP,sqEmptyEnP)-i8-1)*i14*i43;
		else if (sqw2+7 == sqEnP && 0 != TbColumn(sqw2))
			// Capture to the left
			return (sqw2&7)-1+
				   (EXCLUDE3(sqw1,sqb1,sqEnP,sqEmptyEnP)-i8)*i14+
				   (EXCLUDE4(sqb2,sqw1,sqw2,sqEnP,sqEmptyEnP)-i8-1)*i14*i43;
		else
			{
			assert (sqw2+9 == sqEnP && 7 != TbColumn(sqw2));
			// Capture to the right
			return (sqw2&7)+7+
				   (EXCLUDE3(sqw1,sqb1,sqEnP,sqEmptyEnP)-i8)*i14+
				   (EXCLUDE4(sqb2,sqw1,sqw2,sqEnP,sqEmptyEnP)-i8-1)*i14*i43;
			}
		}
	else
		{
		assert (sqb2+8 == sqEnP);
		if (sqw1+7 == sqEnP && 0 != TbColumn(sqw1))
			// Capture to the left
			return (sqw1&7)-1+
				   (EXCLUDE3(sqw2,sqb2,sqEnP,sqEmptyEnP)-i8-1)*i14+
				   (EXCLUDE4(sqb1,sqw1,sqw2,sqEnP,sqEmptyEnP)-i8)*i14*i43;
		else if (sqw1+9 == sqEnP && 7 != TbColumn(sqw1))
			// Capture to the right
			return (sqw1&7)+7+
				   (EXCLUDE3(sqw2,sqb2,sqEnP,sqEmptyEnP)-i8-1)*i14+
				   (EXCLUDE4(sqb1,sqw1,sqw2,sqEnP,sqEmptyEnP)-i8)*i14*i43;
		else if (sqw2+7 == sqEnP && 0 != TbColumn(sqw2))
			// Capture to the left
			return (sqw2&7)-1+
				   (EXCLUDE3(sqw1,sqb2,sqEnP,sqEmptyEnP)-i8)*i14+
				   (EXCLUDE4(sqb1,sqw1,sqw2,sqEnP,sqEmptyEnP)-i8)*i14*i43;
		else
			{
			assert (sqw2+9 == sqEnP && 7 != TbColumn(sqw2));
			// Capture to the right
			return (sqw2&7)+7+
				   (EXCLUDE3(sqw1,sqb2,sqEnP,sqEmptyEnP)-i8)*i14+
				   (EXCLUDE4(sqb1,sqw1,sqw2,sqEnP,sqEmptyEnP)-i8)*i14*i43;
			}
		}
	}

// 14*43*42

static INLINE unsigned TB_FASTCALL IndEnPassant22B
	(
	square	sqw1,
	square	sqw2,
	square	sqb1,
	square	sqb2,
	square	sqEnP
	)
	{
	square sqEmptyEnP;

	assert (sqw1-8 == sqEnP || sqw2-8 == sqEnP);
	SORT (sqw1, sqw2);
	SORT (sqb1, sqb2);
	sqEmptyEnP = sqEnP-8;
	if (sqw1-8 == sqEnP)
		{
		if (sqb1-9 == sqEnP && 0 != TbColumn(sqb1))
			// Capture to the left
			return (sqb1&7)+7+
				   (EXCLUDE3(sqb2,sqw1,sqEnP,sqEmptyEnP)-i8-1)*i14+
				   (EXCLUDE4(sqw2,sqb1,sqb2,sqEnP,sqEmptyEnP)-i8-1)*i14*i43;
		else if (sqb1-7 == sqEnP && 7 != TbColumn(sqb1))
			// Capture to the right
			return (sqb1&7)-1+
				   (EXCLUDE3(sqb2,sqw1,sqEnP,sqEmptyEnP)-i8-1)*i14+
				   (EXCLUDE4(sqw2,sqb1,sqb2,sqEnP,sqEmptyEnP)-i8-1)*i14*i43;
		else if (sqb2-9 == sqEnP && 0 != TbColumn(sqb2))
			// Capture to the left
			return (sqb2&7)+7+
				   (EXCLUDE3(sqb1,sqw1,sqEnP,sqEmptyEnP)-i8)*i14+
				   (EXCLUDE4(sqw2,sqb1,sqb2,sqEnP,sqEmptyEnP)-i8-1)*i14*i43;
		else
			{
			assert (sqb2-7 == sqEnP && 7 != TbColumn(sqb2));
			// Capture to the right
			return (sqb2&7)-1+
				   (EXCLUDE3(sqb1,sqw1,sqEnP,sqEmptyEnP)-i8)*i14+
				   (EXCLUDE4(sqw2,sqb1,sqb2,sqEnP,sqEmptyEnP)-i8-1)*i14*i43;
			}
		}
	else
		{
		assert (sqw2-8 == sqEnP);
		if (sqb1-9 == sqEnP && 0 != TbColumn(sqb1))
			// Capture to the left
			return (sqb1&7)+7+
				   (EXCLUDE3(sqb2,sqw2,sqEnP,sqEmptyEnP)-i8-1)*i14+
				   (EXCLUDE4(sqw1,sqb1,sqb2,sqEnP,sqEmptyEnP)-i8)*i14*i43;
		else if (sqb1-7 == sqEnP && 7 != TbColumn(sqb1))
			// Capture to the right
			return (sqb1&7)-1+
				   (EXCLUDE3(sqb2,sqw2,sqEnP,sqEmptyEnP)-i8-1)*i14+
				   (EXCLUDE4(sqw1,sqb1,sqb2,sqEnP,sqEmptyEnP)-i8)*i14*i43;
		else if (sqb2-9 == sqEnP && 0 != TbColumn(sqb2))
			// Capture to the left
			return (sqb2&7)+7+
				   (EXCLUDE3(sqb1,sqw2,sqEnP,sqEmptyEnP)-i8)*i14+
				   (EXCLUDE4(sqw1,sqb1,sqb2,sqEnP,sqEmptyEnP)-i8)*i14*i43;
		else
			{
			assert (sqb2-7 == sqEnP && 7 != TbColumn(sqb2));
			// Capture to the right
			return (sqb2&7)-1+
				   (EXCLUDE3(sqb1,sqw2,sqEnP,sqEmptyEnP)-i8)*i14+
				   (EXCLUDE4(sqw1,sqb1,sqb2,sqEnP,sqEmptyEnP)-i8)*i14*i43;
			}
		}
	}

// 14*43*42/2

static INLINE unsigned TB_FASTCALL IndEnPassant31W
	(
	square	sqw1,
	square	sqw2,
	square	sqw3,
	square	sqb,
	square	sqEnP
	)
	{
	square sqEmptyEnP;

	assert (sqb+8 == sqEnP);
	SORT (sqw1, sqw2);
	SORT (sqw2, sqw3);
	SORT (sqw1, sqw2);
	sqEmptyEnP = sqEnP+8;
	if (sqw1+7 == sqEnP && 0 != TbColumn(sqw1))
        {
		// Capture to the left
        sqw3 = EXCLUDE3(sqw3,sqb,sqEnP,sqEmptyEnP)-i8-2;
		return (sqw1&7)-1+
               (EXCLUDE3(sqw2,sqb,sqEnP,sqEmptyEnP)-i8-1)*i14+
               (sqw3*(sqw3-1))*(i14*i43);
        }
	else if (sqw1+9 == sqEnP && 7 != TbColumn(sqw1))
        {
		// Capture to the right
        sqw3 = EXCLUDE3(sqw3,sqb,sqEnP,sqEmptyEnP)-i8-2;
		return (sqw1&7)+7+
               (EXCLUDE3(sqw2,sqb,sqEnP,sqEmptyEnP)-i8-1)*i14+
               (sqw3*(sqw3-1))*(i14*i43);
        }
	else if (sqw2+7 == sqEnP && 0 != TbColumn(sqw2))
        {
		// Capture to the left
        sqw3 = EXCLUDE3(sqw3,sqb,sqEnP,sqEmptyEnP)-i8-2;
		return (sqw2&7)-1+
               (EXCLUDE3(sqw1,sqb,sqEnP,sqEmptyEnP)-i8)*i14+
               (sqw3*(sqw3-1))*(i14*i43);
        }
	else if (sqw2+9 == sqEnP && 7 != TbColumn(sqw2))
        {
		// Capture to the right
        sqw3 = EXCLUDE3(sqw3,sqb,sqEnP,sqEmptyEnP)-i8-2;
		return (sqw2&7)+7+
               (EXCLUDE3(sqw1,sqb,sqEnP,sqEmptyEnP)-i8)*i14+
               (sqw3*(sqw3-1))*(i14*i43);
        }
	else if (sqw3+7 == sqEnP && 0 != TbColumn(sqw3))
        {
		// Capture to the left
        sqw2 = EXCLUDE3(sqw2,sqb,sqEnP,sqEmptyEnP)-i8-1;
		return (sqw3&7)-1+
               (EXCLUDE3(sqw1,sqb,sqEnP,sqEmptyEnP)-i8)*i14+
               (sqw2*(sqw2-1))*(i14*i43);
        }
	else
		{
		// Capture to the right
		assert (sqw3+9 == sqEnP && 7 != TbColumn(sqw3));
        sqw2 = EXCLUDE3(sqw2,sqb,sqEnP,sqEmptyEnP)-i8-1;
		return (sqw3&7)+7+
               (EXCLUDE3(sqw1,sqb,sqEnP,sqEmptyEnP)-i8)*i14+
               (sqw2*(sqw2-1))*(i14*i43);
		}
	}

// 14*43*42/2

static INLINE unsigned TB_FASTCALL IndEnPassant31B
	(
	square	sqw1,
	square	sqw2,
	square	sqw3,
	square	sqb,
	square	sqEnP
	)
	{
	square sqEmptyEnP;

	assert (sqw1 < sqw2);	// Must be already sorted
	assert (sqw2 < sqw3);
	sqEmptyEnP = sqEnP-8;
	if (sqb-9 == sqEnP && 0 != TbColumn(sqb))
		// Capture to the left
        if (sqw1-8 == sqEnP) {
            sqw3 = EXCLUDE3(sqw3,sqb,sqEnP,sqEmptyEnP)-i8-2;
		    return (sqb&7)-1+
                   (EXCLUDE3(sqw2,sqb,sqEnP,sqEmptyEnP)-i8-1)*i14+
                   (sqw3*(sqw3-1))*(i14*i43);
            }
		else if (sqw2-8 == sqEnP)
            {
            sqw3 = EXCLUDE3(sqw3,sqb,sqEnP,sqEmptyEnP)-i8-2;
			return (sqb&7)-1+
                   (EXCLUDE3(sqw1,sqb,sqEnP,sqEmptyEnP)-i8)*i14+
                   (sqw3*(sqw3-1))*(i14*i43);
            }
        else
			{
			assert (sqw3-8 == sqEnP);
            sqw2 = EXCLUDE3(sqw2,sqb,sqEnP,sqEmptyEnP)-i8-1;
			return (sqb&7)-1+
                   (EXCLUDE3(sqw1,sqb,sqEnP,sqEmptyEnP)-i8)*i14+
                   (sqw2*(sqw2-1))*(i14*i43);
			}
	else
		{
		// Capture to the right
		assert (sqb-7 == sqEnP && 7 != TbColumn(sqb));
		if (sqw1-8 == sqEnP)
            {
            sqw3 = EXCLUDE3(sqw3,sqb,sqEnP,sqEmptyEnP)-i8-2;
			return (sqb&7)+7+
                   (EXCLUDE3(sqw2,sqb,sqEnP,sqEmptyEnP)-i8-1)*i14+
                   (sqw3*(sqw3-1))*(i14*i43);
            }
		else if (sqw2-8 == sqEnP)
			{
			assert (sqw2-8 == sqEnP);
            sqw3 = EXCLUDE3(sqw3,sqb,sqEnP,sqEmptyEnP)-i8-2;
			return (sqb&7)+7+
                   (EXCLUDE3(sqw1,sqb,sqEnP,sqEmptyEnP)-i8)*i14+
                   (sqw3*(sqw3-1))*(i14*i43);
			}
		else
			{
			assert (sqw3-8 == sqEnP);
            sqw2 = EXCLUDE3(sqw2,sqb,sqEnP,sqEmptyEnP)-i8-1;
			return (sqb&7)+7+
                   (EXCLUDE3(sqw1,sqb,sqEnP,sqEmptyEnP)-i8)*i14+
                   (sqw2*(sqw2-1))*(i14*i43);
			}
		}
	}

// Index calculation functions for different endgame classes

template <int piw1> class T21
	{
public:
	static INDEX TB_FASTCALL IndCalcW
		(
		square	*psqW,
		square	*psqB,
		square	sqEnP,
		int		fInvert
		)
		{
		square sqwk, sqw1, sqbk, sqMask;

		sqwk = SqFindKing (psqW);
		sqw1 = SqFindOne  (psqW, piw1);
		sqbk = SqFindKing (psqB);

		if (x_piecePawn == piw1)
			sqMask = rgsqReflectMaskY [sqwk] ^ rgsqReflectInvertMask [fInvert];
		else
			sqMask = rgsqReflectMaskYandX [sqwk];
		sqwk ^= sqMask;
		sqbk ^= sqMask;
		sqw1 ^= sqMask;

		if (x_piecePawn != piw1)
			{
			// No pawn
			if (! FInTriangle (sqwk, sqbk))
				{
				sqwk = reflect_xy(sqwk);
				sqbk = reflect_xy(sqbk);
				sqw1 = reflect_xy(sqw1);
				};
			}
		return TEnumerate1<piw1,x_piecePawn==piw1 ? true :
false,false>::Index(sqwk,sqw1,sqbk);
		}

	static INDEX TB_FASTCALL IndCalcB
		(
		square	*psqW,
		square	*psqB,
		square	sqEnP,
		int		fInvert
		)
		{
		square sqwk, sqw1, sqbk, sqMask;

		sqwk = SqFindKing (psqW);
		sqw1 = SqFindOne  (psqW, piw1);
		sqbk = SqFindKing (psqB);

		if (x_piecePawn == piw1)
			sqMask = rgsqReflectMaskY [sqbk] ^ rgsqReflectInvertMask [fInvert];
		else
			sqMask = rgsqReflectMaskYandX [sqbk];
		sqwk ^= sqMask;
		sqbk ^= sqMask;
		sqw1 ^= sqMask;

		if (x_piecePawn == piw1)
			return TEnumerate1<x_pieceNone,true,true>::Index(sqbk,sqw1,sqwk);
		else
			{
			// No pawn
			if (! FInTriangle (sqbk, sqwk))
				{
				sqwk = reflect_xy(sqwk);
				sqbk = reflect_xy(sqbk);
				sqw1 = reflect_xy(sqw1);
				};
			return IndTriKings(sqbk,sqwk)*i62 + EXCLUDE2(sqw1,sqwk,sqbk);
			}
		}
	};

template <int piw1, int pib1> class T22
	{
public:
	static INDEX TB_FASTCALL IndCalcW
		(
		square	*psqW,
		square	*psqB,
		square	sqEnP,
		int		fInvert
		)
		{
		square sqwk, sqw1, sqbk, sqb1, sqMask;

		sqwk = SqFindKing (psqW);
		sqw1 = SqFindOne  (psqW, piw1);
		sqbk = SqFindKing (psqB);
		sqb1 = SqFindOne  (psqB, pib1);

		if (x_piecePawn == pib1)
			sqMask = rgsqReflectMaskY [sqwk] ^ rgsqReflectInvertMask [fInvert];
		else
			sqMask = rgsqReflectMaskYandX [sqwk];
		sqwk ^= sqMask;
		sqbk ^= sqMask;
		sqw1 ^= sqMask;
		sqb1 ^= sqMask;

		if (x_piecePawn == pib1)
			{
			// There are pawns on the board
			if (x_piecePawn == piw1)
				{
				// One white and one black pawn
				if (XX == sqEnP)
					return	TEnumerate1<x_piecePawn,true,false>::Index(sqwk,sqw1,sqbk)*i47 +
							EXCLUDE1(sqb1,sqw1)-i8;	// 47
				else
					return	rgcSinglePawnPresent[x_piecePawn]*i47 +
							IndHalfKings(sqwk,sqbk)*i14 +
							IndEnPassant11W (sqw1, sqb1, sqEnP ^ sqMask);
				}
			else
				// Only black pawn
				return	TEnumerate1<piw1,true,false>::Index(sqwk,sqw1,sqbk)*i48 + sqb1-i8;
			}
		else
			{
			// No pawns at all
			if (!FInTriangle (sqwk, sqbk))
				{
				sqwk = reflect_xy(sqwk);
				sqbk = reflect_xy(sqbk);
				sqw1 = reflect_xy(sqw1);
				sqb1 = reflect_xy(sqb1);
				};
			return	TEnumerate1<piw1,false,false>::Index(sqwk,sqw1,sqbk)*i61 +
					EXCLUDE3(sqb1,sqwk,sqbk,sqw1);	// 61
			}
		}

	static INDEX TB_FASTCALL IndCalcB
		(
		square	*psqW,
		square	*psqB,
		square	sqEnP,
		int		fInvert
		)
		{
		square sqwk, sqw1, sqbk, sqb1, sqMask;

		sqwk = SqFindKing (psqW);
		sqw1 = SqFindOne  (psqW, piw1);
		sqbk = SqFindKing (psqB);
		sqb1 = SqFindOne  (psqB, pib1);

		if (x_piecePawn == pib1)
			sqMask = rgsqReflectMaskY [sqbk] ^ rgsqReflectInvertMask [fInvert];
		else
			sqMask = rgsqReflectMaskYandX [sqbk];
		sqwk ^= sqMask;
		sqbk ^= sqMask;
		sqw1 ^= sqMask;
		sqb1 ^= sqMask;

		if (x_piecePawn == pib1)
			{
			// There are pawns on the board
			if (x_piecePawn == piw1)
				{
				// One white and one black pawn
				if (XX == sqEnP)
					return	TEnumerate1<x_piecePawn,true,true>::Index(sqbk,sqb1,sqwk)*i47 +
							EXCLUDE1(sqw1,sqb1)-i8;	// 47
				else
					return	rgcSinglePawnPresent[x_piecePawn]*i47 +
							IndHalfKings(sqbk,sqwk)*i14 +
							IndEnPassant11B (sqw1, sqb1, sqEnP ^ sqMask);
				}
			}
		else
			{
			// No pawns at all
			if (!FInTriangle (sqbk, sqwk))
				{
				sqwk = reflect_xy(sqwk);
				sqbk = reflect_xy(sqbk);
				sqw1 = reflect_xy(sqw1);
				sqb1 = reflect_xy(sqb1);
				};
			}
		return	(x_piecePawn == pib1
?	TEnumerate1<pib1,true,true>::Index(sqbk,sqb1,sqwk) :
										TEnumerate1<pib1,false,false>::Index(sqbk,sqb1,sqwk))*i61 +
				EXCLUDE3(sqw1,sqwk,sqbk,sqb1);	// 61
		}
	};

template <int piw1, int piw2> class T31
	{
public:
	static INDEX TB_FASTCALL IndCalcW
		(
		square	*psqW,
		square	*psqB,
		square	sqEnP,
		int		fInvert
		)
		{
		square sqwk, sqw1, sqw2, sqbk, sqMask;

		sqwk = SqFindKing (psqW);
		if (piw1 == piw2)
			{
			sqw1 = SqFindFirst  (psqW, piw1);
			sqw2 = SqFindSecond (psqW, piw2);
			}
		else
			{
			SqFind2 (psqW, piw1, sqw1, piw2, sqw2);
			}
		sqbk = SqFindKing (psqB);

		if (x_piecePawn == piw2)
			sqMask = rgsqReflectMaskY [sqwk] ^ rgsqReflectInvertMask [fInvert];
		else
			sqMask = rgsqReflectMaskYandX [sqwk];
		sqwk ^= sqMask;
		sqbk ^= sqMask;
		sqw1 ^= sqMask;
		sqw2 ^= sqMask;

		if (x_piecePawn != piw2)
			{
			// There are no pawns on the board
			if (!FInTriangle (sqwk, sqbk))
				{
				sqwk = reflect_xy(sqwk);
				sqw1 = reflect_xy(sqw1);
				sqw2 = reflect_xy(sqw2);
				sqbk = reflect_xy(sqbk);
				};
			}
		return TEnumerate2<piw1, piw2, x_piecePawn==piw2 ? true : false,
false>::Index(sqwk, sqw1, sqw2, sqbk);
		}

	static INDEX TB_FASTCALL IndCalcB
		(
		square	*psqW,
		square	*psqB,
		square	sqEnP,
		int		fInvert
		)
		{
		square sqwk, sqw1, sqw2, sqbk, sqMask;

		sqwk = SqFindKing (psqW);
		if (piw1 == piw2)
			{
			sqw1 = SqFindFirst (psqW, piw1);
			sqw2 = SqFindSecond (psqW, piw2);
			}
		else
			{
			SqFind2 (psqW, piw1, sqw1, piw2, sqw2);
			}
		sqbk = SqFindKing (psqB);

		if (x_piecePawn == piw2)
			sqMask = rgsqReflectMaskY [sqbk] ^ rgsqReflectInvertMask [fInvert];
		else
			sqMask = rgsqReflectMaskYandX [sqbk];
		sqwk ^= sqMask;
		sqbk ^= sqMask;
		sqw1 ^= sqMask;
		sqw2 ^= sqMask;

		if (x_piecePawn == piw2)
			{
			// There are pawns on the board
			if (x_piecePawn == piw1)
				// Two white pawns
				return	TEnumerate2<x_pieceNone,x_pieceNone,true,true>::Index(sqbk,sqw1,sqw2,sqwk);
			else
				// Only one white pawn
				return	TEnumerate1<x_pieceNone,true,true>::Index(sqbk,sqw2,sqwk)*i61 +
						EXCLUDE3(sqw1,sqwk,sqbk,sqw2);	// 61
			}
		else
			{
			// No pawns
			if (!FInTriangle (sqbk, sqwk))
				{
				sqwk = reflect_xy(sqwk);
				sqw1 = reflect_xy(sqw1);
				sqw2 = reflect_xy(sqw2);
				sqbk = reflect_xy(sqbk);
				};
			if (piw1 == piw2)
				{
				SORT (sqw1, sqw2);
				sqw2 = EXCLUDE2(sqw2,sqwk,sqbk);					// 62
				return	IndTriKings(sqbk,sqwk)*(i62*i61/2) +
						sqw2*(sqw2-1)/2+EXCLUDE2(sqw1,sqwk,sqbk);	// 62*61/2
				}
			else
				return	IndTriKings(sqbk,sqwk)*(i62*i61) +
						EXCLUDE2(sqw1,sqwk,sqbk)*i61 +	// 62
						EXCLUDE3(sqw2,sqwk,sqbk,sqw1);	// 61
			}
		}
	};

template <int piw1, int piw2, int pib1> class T32
	{
public:
	static INDEX TB_FASTCALL IndCalcW
		(
		square	*psqW,
		square	*psqB,
		square	sqEnP,
		int		fInvert
		)
		{
		square sqwk, sqw1, sqw2, sqbk, sqb1, sqMask;

		sqwk = SqFindKing (psqW);
		if (piw1 == piw2)
			{
			sqw1 = SqFindFirst  (psqW, piw1);
			sqw2 = SqFindSecond (psqW, piw2);
			}
		else
			{
			SqFind2 (psqW, piw1, sqw1, piw2, sqw2);
			}
		sqbk = SqFindKing (psqB);
		sqb1 = SqFindOne  (psqB, pib1);

		if (x_piecePawn == piw2 || x_piecePawn == pib1)
			sqMask = rgsqReflectMaskY [sqwk] ^ rgsqReflectInvertMask [fInvert];
		else
			sqMask = rgsqReflectMaskYandX [sqwk];
		sqwk ^= sqMask;
		sqbk ^= sqMask;
		sqw1 ^= sqMask;
		sqw2 ^= sqMask;
		sqb1 ^= sqMask;

		if (x_piecePawn == piw2 || x_piecePawn == pib1)
			{
			// There are pawns on the board
			if (x_piecePawn == pib1)
				{
				// Black pawn
				if (x_piecePawn == piw1 && x_piecePawn == piw2)
					{
					// All 3 pieces are pawns
					if (XX == sqEnP)
						return	TEnumerate2<x_piecePawn,x_piecePawn,true,false>::
									Index(sqwk,sqw1,sqw2,sqbk)*i46+
								EXCLUDE2(sqb1,sqw1,sqw2)-i8;	// 46
					else
						// En passant capture
						return	rgcPairPawnPresent[x_piecePawn][x_piecePawn]*i46 +
								IndHalfKings(sqwk,sqbk)*(i14*i44) +
								IndEnPassant21W (sqw1, sqw2, sqb1, sqEnP ^ sqMask);
					}
				else if (x_piecePawn == piw2)
					{
					// One white pawn, one black pawn
					if (XX == sqEnP)
						return	TEnumerate2<piw1,x_piecePawn,true,false>::
									Index(sqwk,sqw1,sqw2,sqbk)*i47 +
								EXCLUDE1(sqb1,sqw2)-i8;	// 47
					else
						// En passant capture
						return	rgcPairPawnPresent[piw1][x_piecePawn]*i47 +
								TEnumerate1<piw1,true,false>::Index(sqwk,sqw1,sqbk)*i14 +
								IndEnPassant11W (sqw2, sqb1, sqEnP ^ sqMask);
					}
				else
					// Only black pawn
					return	TEnumerate2<piw1,piw2,true,false>::
								Index(sqwk,sqw1,sqw2,sqbk)*i48 +
							sqb1-i8;	// 48
				}
			}
		else
			{
			// No pawns
			if (!FInTriangle (sqwk, sqbk))
				{
				sqwk = reflect_xy(sqwk);
				sqw1 = reflect_xy(sqw1);
				sqw2 = reflect_xy(sqw2);
				sqbk = reflect_xy(sqbk);
				sqb1 = reflect_xy(sqb1);
				};
			}
		return	TEnumerate2<piw1,piw2,(x_piecePawn==piw2||x_piecePawn==pib1) ? true :
false,false>::
					Index(sqwk,sqw1,sqw2,sqbk)*i60 +
				EXCLUDE4(sqb1,sqwk,sqbk,sqw1,sqw2);	// 60
		}

	static INDEX TB_FASTCALL IndCalcB
		(
		square	*psqW,
		square	*psqB,
		square	sqEnP,
		int		fInvert
		)
		{
		square sqwk, sqw1, sqw2, sqbk, sqb1, sqMask;

		sqwk = SqFindKing (psqW);
		if (piw1 == piw2)
			{
			sqw1 = SqFindFirst  (psqW, piw1);
			sqw2 = SqFindSecond (psqW, piw2);
			}
		else
			{
			SqFind2 (psqW, piw1, sqw1, piw2, sqw2);
			}
		sqbk = SqFindKing (psqB);
		sqb1 = SqFindOne  (psqB, pib1);

		if (x_piecePawn == piw2 || x_piecePawn == pib1)
			sqMask = rgsqReflectMaskY [sqbk] ^ rgsqReflectInvertMask [fInvert];
		else
			sqMask = rgsqReflectMaskYandX [sqbk];
		sqwk ^= sqMask;
		sqbk ^= sqMask;
		sqw1 ^= sqMask;
		sqw2 ^= sqMask;
		sqb1 ^= sqMask;

		if (x_piecePawn == piw2 || x_piecePawn == pib1)
			{
			// There are pawns on the board
			if (x_piecePawn == pib1)
				{
				// Black pawn
				if (x_piecePawn == piw1 && x_piecePawn == piw2)
					{
					// All 3 pieces are pawns
					SORT (sqw1, sqw2);
					if (XX == sqEnP)
						{
						sqw2 = EXCLUDE1(sqw2,sqb1)-i8;					// 47
						return	TEnumerate1<x_piecePawn,true,true>::
									Index(sqbk,sqb1,sqwk)*(i47*i46/2) +
								sqw2*(sqw2-1)/2+EXCLUDE1(sqw1,sqb1)-i8;	// 47*46/2
						}
					else
						// En passant capture
						return	rgcSinglePawnPresent[x_piecePawn]*(i47*i46/2) +
								IndHalfKings(sqbk,sqwk)*(i44*i14) +
								IndEnPassant21B (sqw1, sqw2, sqb1, sqEnP ^ sqMask);
					}
				else if (x_piecePawn == piw2)
					{
					// One white pawn, one black pawn
					if (XX == sqEnP)
						return	TEnumerate1<x_piecePawn,true,true>::
									Index(sqbk,sqb1,sqwk)*(i60*i47) +
								EXCLUDE4(sqw1,sqwk,sqbk,sqw2,sqb1)*i47 +	// 60
								EXCLUDE1(sqw2,sqb1)-i8;						// 47
					else
						{
						// En passant capture
						sqEnP ^= sqMask;
						return	rgcSinglePawnPresent[x_piecePawn]*(i60*i47) +
								IndHalfKings(sqbk,sqwk)*(i58*i14) +
								EXCLUDE6(sqw1,sqwk,sqbk,sqw2,sqb1,sqEnP,sqEnP-8)*i14 +	// 58
								IndEnPassant11B (sqw2, sqb1, sqEnP);
						}
					}
				else
					{
					// Only black pawn
					if (piw1 == piw2)
						{
						// 2 identical white pieces
						SORT (sqw1, sqw2);
						sqw2 = EXCLUDE3(sqw2,sqwk,sqbk,sqb1);						// 61
						return	TEnumerate1<x_piecePawn,true,true>::
									Index(sqbk,sqb1,sqwk)*(i61*i60/2) +
								sqw2*(sqw2-1)/2 + EXCLUDE3(sqw1,sqwk,sqbk,sqb1);	// 61*60/2
						}
					return	TEnumerate1<x_piecePawn,true,true>::
								Index(sqbk,sqb1,sqwk)*(i61*i60) +
							EXCLUDE3(sqw1,sqwk,sqbk,sqb1)*i60 +	// 61
							EXCLUDE4(sqw2,sqwk,sqbk,sqw1,sqb1);	// 60
					}
				}
			else
				{
				// No black pawn
				if (x_piecePawn == piw1)
					{
					// Only 2 white pawns
					SORT (sqw1, sqw2);
					sqw2 -= i8;
					return	TEnumerate1<pib1,true,true>::
								Index(sqbk,sqb1,sqwk)*(i48*47/2) +
							sqw2*(sqw2-1)/2+sqw1-i8;			// 48*47/2
					}
				else
					// Only one white pawn
					return	TEnumerate1<pib1,true,true>::
								Index(sqbk,sqb1,sqwk)*(i60*i48) +
							EXCLUDE4(sqw1,sqwk,sqbk,sqw2,sqb1)*i48 +	// 60
							sqw2-i8;									// 48
				}
			}
		else
			{
			// No pawns
			if (!FInTriangle (sqbk, sqwk))
				{
				sqwk = reflect_xy(sqwk);
				sqw1 = reflect_xy(sqw1);
				sqw2 = reflect_xy(sqw2);
				sqbk = reflect_xy(sqbk);
				sqb1 = reflect_xy(sqb1);
				};
			if (piw1 == piw2)
				{
				// 2 identical white pieces
				SORT (sqw1, sqw2);
				sqw2 = EXCLUDE3(sqw2,sqwk,sqbk,sqb1);					// 61
				return	TEnumerate1<pib1,false,false>::
							Index(sqbk,sqb1,sqwk)*(i61*i60/2) +
						sqw2*(sqw2-1)/2+EXCLUDE3(sqw1,sqwk,sqbk,sqb1);	// 61*60/2
				}
			else
				return	TEnumerate1<pib1,false,false>::
							Index(sqbk,sqb1,sqwk)*(i61*i60) +
						EXCLUDE3(sqw1,sqwk,sqbk,sqb1)*i60 +	// 61
						EXCLUDE4(sqw2,sqwk,sqbk,sqw1,sqb1);	// 60
			}
		}
	};

#if defined (T41_INCLUDE)

template <int piw1, int piw2, int piw3> class T41
	{
public:
	static INDEX TB_FASTCALL IndCalcW
		(
		square	*psqW,
		square	*psqB,
		square	sqEnP,
		int		fInvert
		)
		{
		square sqwk, sqw1, sqw2, sqw3, sqbk, sqMask;

		sqwk = SqFindKing (psqW);
		sqw1 = SqFindFirst (psqW, piw1);
		if (piw1 == piw2 && piw2 == piw3)
			{
			sqw2 = SqFindSecond (psqW, piw2);
			sqw3 = SqFindThird (psqW, piw3);
			}
		else if (piw1 == piw2)
			{
			sqw2 = SqFindSecond (psqW, piw2);
			sqw3 = SqFindFirst (psqW, piw3);
			}
		else if (piw2 == piw3)
			{
			sqw2 = SqFindFirst (psqW, piw2);
			sqw3 = SqFindSecond (psqW, piw3);
			}
		else
			{
			sqw2 = SqFindFirst (psqW, piw2);
			sqw3 = SqFindFirst (psqW, piw3);
			}
		sqbk = SqFindKing (psqB);

		if (x_piecePawn == piw3)
			sqMask = rgsqReflectMaskY [sqwk] ^ rgsqReflectInvertMask [fInvert];
		else
			sqMask = rgsqReflectMaskYandX [sqwk];
		sqwk ^= sqMask;
		sqbk ^= sqMask;
		sqw1 ^= sqMask;
		sqw2 ^= sqMask;
		sqw3 ^= sqMask;

		if (x_piecePawn != piw3)
			{
			// No pawns
			if (!FInTriangle (sqwk, sqbk))
				{
				sqwk = reflect_xy(sqwk);
				sqw1 = reflect_xy(sqw1);
				sqw2 = reflect_xy(sqw2);
				sqw3 = reflect_xy(sqw3);
				sqbk = reflect_xy(sqbk);
				};
			}
		return	TEnumerate3<piw1,piw2,piw3,x_piecePawn ==
piw3,false>::Index(sqwk,sqw1,sqw2,sqw3,sqbk);
		}

	static INDEX TB_FASTCALL IndCalcB
		(
		square	*psqW,
		square	*psqB,
		square	sqEnP,
		int		fInvert
		)
		{
		square sqwk, sqw1, sqw2, sqw3, sqbk, sqMask;

		sqwk = SqFindKing (psqW);
		sqw1 = SqFindFirst (psqW, piw1);
		if (piw1 == piw2 && piw2 == piw3)
			{
			sqw2 = SqFindSecond (psqW, piw2);
			sqw3 = SqFindThird (psqW, piw3);
			}
		else if (piw1 == piw2)
			{
			sqw2 = SqFindSecond (psqW, piw2);
			sqw3 = SqFindFirst (psqW, piw3);
			}
		else if (piw2 == piw3)
			{
			sqw2 = SqFindFirst (psqW, piw2);
			sqw3 = SqFindSecond (psqW, piw3);
			}
		else
			{
			sqw2 = SqFindFirst (psqW, piw2);
			sqw3 = SqFindFirst (psqW, piw3);
			}
		sqbk = SqFindKing (psqB);

		if (x_piecePawn == piw3)
			sqMask = rgsqReflectMaskY [sqbk] ^ rgsqReflectInvertMask [fInvert];
		else
			sqMask = rgsqReflectMaskYandX [sqbk];
		sqwk ^= sqMask;
		sqbk ^= sqMask;
		sqw1 ^= sqMask;
		sqw2 ^= sqMask;
		sqw3 ^= sqMask;

		if (x_piecePawn == piw3)
			{
			// There are pawns on the board
			if (x_piecePawn == piw1)
				// 3 white pawns
				return	TEnumerate3<x_pieceNone,x_pieceNone,x_pieceNone,true,true>::
							Index(sqbk,sqw1,sqw2,sqw3,sqwk);
			else if (x_piecePawn == piw2)
				// 2 white pawns
				return	TEnumerate2<x_pieceNone,x_pieceNone,true,true>::
							Index(sqbk,sqw2,sqw3,sqwk)*i60 +
						EXCLUDE4(sqw1,sqwk,sqbk,sqw2,sqw3);	// 60
			else if (piw1 == piw2)
				{
				// 1 pawn, 2 pieces equal
				SORT (sqw1, sqw2);
				sqw2 = EXCLUDE3(sqw2,sqwk,sqbk,sqw3);					// 61
				return	TEnumerate1<x_pieceNone,true,true>::
							Index(sqbk,sqw3,sqwk)*(i61*i60/2) +
						sqw2*(sqw2-1)/2+EXCLUDE3(sqw1,sqwk,sqbk,sqw3);	// 61*60/2
				}
			else
				// Only one white pawn
				return	TEnumerate1<x_pieceNone,true,true>::Index(sqbk,sqw3,sqwk)*i61*i60 +
						EXCLUDE3(sqw1,sqwk,sqbk,sqw3)*i60 +	// 61
						EXCLUDE4(sqw2,sqwk,sqbk,sqw1,sqw3);	// 60
			}
		else
			{
			// No pawns
			if (!FInTriangle (sqbk, sqwk))
				{
				sqwk = reflect_xy(sqwk);
				sqw1 = reflect_xy(sqw1);
				sqw2 = reflect_xy(sqw2);
				sqw3 = reflect_xy(sqw3);
				sqbk = reflect_xy(sqbk);
				};
			if (piw1 == piw2 && piw2 == piw3)
				{
				// All 3 pieces equal
				SORT (sqw1, sqw2);
				SORT (sqw2, sqw3);
				SORT (sqw1, sqw2);
				sqw3 = EXCLUDE2(sqw3,sqwk,sqbk);	// 62
				sqw2 = EXCLUDE2(sqw2,sqwk,sqbk);
				return	IndTriKings(sqbk,sqwk)*(i62*i61*i60/6) +
						sqw3*(sqw3-1)*(sqw3-2)/6+
						sqw2*(sqw2-1)/2+
						EXCLUDE2(sqw1,sqwk,sqbk);	// 62*61*60/6
				}
			else if (piw1 == piw2)
				{
				// 2 major pieces equal
				SORT (sqw1, sqw2);
				sqw2 = EXCLUDE3(sqw2,sqwk,sqbk,sqw3);							// 61
				return	IndTriKings(sqbk,sqwk)*(i61*i60/2*i62) +
						(sqw2*(sqw2-1)/2+EXCLUDE3(sqw1,sqwk,sqbk,sqw3))*i62 +	// 61*60/2
						EXCLUDE2(sqw3,sqwk,sqbk);								// 62
				}
			else if (piw2 == piw3)
				{
				// 2 minor pieces equal
				SORT (sqw2, sqw3);
				sqw3 = EXCLUDE3(sqw3,sqwk,sqbk,sqw1);					// 61
				return	IndTriKings(sqbk,sqwk)*(i62*i61*i60/2) +
						EXCLUDE2(sqw1,sqwk,sqbk)*(i61*i60/2) +			// 62
						sqw3*(sqw3-1)/2+EXCLUDE3(sqw2,sqwk,sqbk,sqw1);	// 61*60/2
				}
			else
				return	IndTriKings(sqbk,sqwk)*(i62*i61*i60) +
						EXCLUDE2(sqw1,sqwk,sqbk)*(i61*i60) +	// 62
						EXCLUDE3(sqw2,sqwk,sqbk,sqw1)*i60 +		// 61
						EXCLUDE4(sqw3,sqwk,sqbk,sqw1,sqw2);		// 60
			}
		}
	};

#endif	// T41

#if defined (ILLEGAL_POSSIBLE)

#define CHECK_INF_SINGLE(ind)\
		if (INF_SINGLE == ind)\
			return (INDEX) -1;\

#define CHECK_INF_PAIR(ind)\
		if (INF_PAIR == ind)\
			return (INDEX) -1;\

#define CHECK_INF_TRIPLE(ind)\
		if (INF_TRIPLE == ind)\
			return (INDEX) -1;\

#else

#define CHECK_INF_SINGLE(ind)
#define CHECK_INF_PAIR(ind)
#define CHECK_INF_TRIPLE(ind)

#endif

#if defined (T33_INCLUDE)

// TODO: Add code for the TBs with pawns

template <int piw1, int piw2, int pib1, int pib2> class T33
	{
public:
	static INDEX TB_FASTCALL IndCalcW
		(
		square	*psqW,
		square	*psqB,
		square	sqEnP,
		int		fInvert
		)
		{
		square   sqwk, sqw1, sqw2, sqbk, sqb1, sqb2, sqMask;
		unsigned ind;

		sqwk = SqFindKing (psqW);
		if (piw1 == piw2)
			{
			sqw1 = SqFindFirst  (psqW, piw1);
			sqw2 = SqFindSecond (psqW, piw2);
			}
		else
			{
			SqFind2 (psqW, piw1, sqw1, piw2, sqw2);
			}
		sqbk = SqFindKing (psqB);
		if (pib1 == pib2)
			{
			sqb1 = SqFindFirst  (psqB, pib1);
			sqb2 = SqFindSecond (psqB, pib2);
			}
		else
			{
			SqFind2 (psqB, pib1, sqb1, pib2, sqb2);
			}

		sqMask = rgsqReflectMaskYandX [sqwk];
		sqwk ^= sqMask;
		sqbk ^= sqMask;
		sqw1 ^= sqMask;
		sqw2 ^= sqMask;
		sqb1 ^= sqMask;
		sqb2 ^= sqMask;

		if (!FInTriangle (sqwk, sqbk))
			{
			sqwk = reflect_xy(sqwk);
			sqw1 = reflect_xy(sqw1);
			sqw2 = reflect_xy(sqw2);
			sqbk = reflect_xy(sqbk);
			sqb1 = reflect_xy(sqb1);
			sqb2 = reflect_xy(sqb2);
			}
		ind = TEnumerate2<piw1,piw2,false,false>::Index(sqwk,sqw1,sqw2,sqbk);
        CHECK_INF_PAIR(ind);
		if (pib1 == pib2)
			{
			SORT (sqb1, sqb2);
			sqb2 = EXCLUDE4(sqb2,sqwk,sqbk,sqw1,sqw2);	// 60
			return	ind*(i60*i59/2) +
					sqb2*(sqb2-1)/2+
					EXCLUDE4(sqb1,sqwk,sqbk,sqw1,sqw2);	// 60*59/2
			}
		else
            {
            // Divide by 2 to avoid overflow on the 32-bit systems, later
            // add to itself to produce the correct result. Only the final
            // addition have to be done using 64-bit arithmetic.
            ind *= i60*i59/2;
            return  ((INDEX) ind) +
			        (INDEX) (ind +
					         EXCLUDE4(sqb1,sqwk,sqbk,sqw1,sqw2)*i59 +	// 60
					         EXCLUDE5(sqb2,sqwk,sqbk,sqw1,sqw2,sqb1));	// 59
            }
		}

	static INDEX TB_FASTCALL IndCalcB
		(
		square	*psqW,
		square	*psqB,
		square	sqEnP,
		int		fInvert
		)
		{
		square   sqwk, sqw1, sqw2, sqbk, sqb1, sqb2, sqMask;
		unsigned ind;

		sqwk = SqFindKing (psqW);
		if (piw1 == piw2)
			{
			sqw1 = SqFindFirst  (psqW, piw1);
			sqw2 = SqFindSecond (psqW, piw2);
			}
		else
			{
			SqFind2 (psqW, piw1, sqw1, piw2, sqw2);
			}
		sqbk = SqFindKing (psqB);
		if (pib1 == pib2)
			{
			sqb1 = SqFindFirst  (psqB, pib1);
			sqb2 = SqFindSecond (psqB, pib2);
			}
		else
			{
			SqFind2 (psqB, pib1, sqb1, pib2, sqb2);
			}

		assert (x_piecePawn != piw2 && x_piecePawn != pib2);
		sqMask = rgsqReflectMaskYandX [sqbk];
		sqwk ^= sqMask;
		sqbk ^= sqMask;
		sqw1 ^= sqMask;
		sqw2 ^= sqMask;
		sqb1 ^= sqMask;
		sqb2 ^= sqMask;

		if (!FInTriangle (sqbk, sqwk))
			{
			sqwk = reflect_xy(sqwk);
			sqw1 = reflect_xy(sqw1);
			sqw2 = reflect_xy(sqw2);
			sqbk = reflect_xy(sqbk);
			sqb1 = reflect_xy(sqb1);
			sqb2 = reflect_xy(sqb2);
			}
		ind = TEnumerate2<pib1,pib2,false,false>::Index(sqbk,sqb1,sqb2,sqwk);
        CHECK_INF_PAIR(ind);
		if (piw1 == piw2)
			{
			SORT (sqw1, sqw2);
			sqw2 = EXCLUDE4(sqw2,sqbk,sqwk,sqb1,sqb2);	// 60
			return	ind*(i60*i59/2) +
					sqw2*(sqw2-1)/2+
					EXCLUDE4(sqw1,sqbk,sqwk,sqb1,sqb2);	// 60*59/2
			}
		else
            {
            // Divide by 2 to avoid overflow on the 32-bit systems, later
            // add to itself to produce the correct result. Only the final
            // addition has to be done using 64-bit arithmetic.
            ind *= i60*i59/2;
			return	((INDEX) ind) +
                    (INDEX) (ind +
					         EXCLUDE4(sqw1,sqbk,sqwk,sqb1,sqb2)*i59 +	// 60
					         EXCLUDE5(sqw2,sqbk,sqwk,sqb1,sqb2,sqw1));	// 59
            }
		}
	};

#endif	// T33

#if defined (T42_INCLUDE)

// TODO: Add code for the TBs with pawns

template <int piw1, int piw2, int piw3, int pib1> class T42
	{
public:
	static INDEX TB_FASTCALL IndCalcW
		(
		square	*psqW,
		square	*psqB,
		square	sqEnP,
		int		fInvert
		)
		{
        unsigned uInd;
		square sqwk, sqw1, sqw2, sqw3, sqbk, sqb1, sqMask;

		sqwk = SqFindKing (psqW);
		sqw1 = SqFindFirst (psqW, piw1);
		if (piw1 == piw2 && piw2 == piw3)
			{
			sqw2 = SqFindSecond (psqW, piw2);
			sqw3 = SqFindThird (psqW, piw3);
			}
		else if (piw1 == piw2)
			{
			sqw2 = SqFindSecond (psqW, piw2);
			sqw3 = SqFindFirst (psqW, piw3);
			}
		else if (piw2 == piw3)
			{
			sqw2 = SqFindFirst (psqW, piw2);
			sqw3 = SqFindSecond (psqW, piw3);
			}
		else
			{
			sqw2 = SqFindFirst (psqW, piw2);
			sqw3 = SqFindFirst (psqW, piw3);
			}
 		sqbk = SqFindKing (psqB);
		sqb1 = SqFindOne  (psqB, pib1);

		if (x_piecePawn == piw3 || x_piecePawn == pib1)
			sqMask = rgsqReflectMaskY [sqwk] ^ rgsqReflectInvertMask [fInvert];
		else
			sqMask = rgsqReflectMaskYandX [sqwk];
		sqwk ^= sqMask;
		sqbk ^= sqMask;
		sqw1 ^= sqMask;
		sqw2 ^= sqMask;
		sqw3 ^= sqMask;
		sqb1 ^= sqMask;

		if (x_piecePawn == piw3 || x_piecePawn == pib1)
			{
			// There are pawns on the board
			if (x_piecePawn == pib1)
				{
				// Black pawn
				if (x_piecePawn == piw1)
					{
					// All 4 pieces are pawns
					if (XX == sqEnP)
                        {
						uInd = TEnumerate3<x_piecePawn,x_piecePawn,x_piecePawn,true,false>::
                                Index(sqwk,sqw1,sqw2,sqw3,sqbk);
                        CHECK_INF_TRIPLE(uInd);
						return uInd*i45 + EXCLUDE3(sqb1,sqw1,sqw2,sqw3)-i8;	// 45
                        }
					else
                        {
						// En passant capture
                        uInd =
rgcTriplePawnPresent[x_piecePawn][x_piecePawn][x_piecePawn];
						return	uInd*i45 +
								IndHalfKings(sqwk,sqbk)*(i14*i43*i42/2) +
								IndEnPassant31W (sqw1, sqw2, sqw3, sqb1, sqEnP ^ sqMask);
                        }
					}
				else if (x_piecePawn == piw2)
					{
					// Two white pawns, one black pawn
					if (XX == sqEnP)
                        {
						uInd = TEnumerate3<piw1,x_piecePawn,x_piecePawn,true,false>::
                                Index(sqwk,sqw1,sqw2,sqw3,sqbk);
                        CHECK_INF_TRIPLE(uInd);
						return uInd*(INDEX)i46 + (EXCLUDE2(sqb1,sqw2,sqw3)-i8);   // 46
                        }
					else
                        {
						// En passant capture
						uInd = TEnumerate1<piw1,true,false>::Index(sqwk,sqw1,sqbk);
                        CHECK_INF_SINGLE(uInd);
						return	rgcTriplePawnPresent[piw1][x_piecePawn][x_piecePawn]*(INDEX)i46 +
								(uInd*(i14*i44) + IndEnPassant21W (sqw2, sqw3, sqb1, sqEnP ^ sqMask));
                        }
					}
				else if (x_piecePawn == piw3)
					{
					// One white pawn, one black pawn
					if (XX == sqEnP)
                        {
						uInd = TEnumerate3<piw1,piw2,x_piecePawn,true,false>::
							    Index(sqwk,sqw1,sqw2,sqw3,sqbk);
                        CHECK_INF_TRIPLE(uInd);
						return	uInd*((INDEX)i47) + (EXCLUDE1(sqb1,sqw3)-i8);    // 47
                        }
					else
                        {
						// En passant capture
				        uInd =
TEnumerate2<piw1,piw2,true,false>::Index(sqwk,sqw1,sqw2,sqbk);
                        CHECK_INF_PAIR(uInd);
						return	rgcTriplePawnPresent[piw1][piw2][x_piecePawn]*(INDEX)i47 +
								(uInd*i14 + IndEnPassant11W (sqw3, sqb1, sqEnP ^ sqMask));
                        }
					}
				else
                    {
					// Only black pawn
					uInd = TEnumerate3<piw1,piw2,piw3,true,false>::
						    Index(sqwk,sqw1,sqw2,sqw3,sqbk);
                    CHECK_INF_TRIPLE(uInd);
					return	(uInd*3)*(INDEX)16 + (sqb1-i8);	// 48
                    }
				}
			else
				{
				// No black pawn
           		uInd = TEnumerate3<piw1,piw2,piw3,true,false>::
					Index(sqwk,sqw1,sqw2,sqw3,sqbk);
                CHECK_INF_TRIPLE(uInd);
           		return uInd*(INDEX)i59 + EXCLUDE5(sqb1,sqwk,sqbk,sqw1,sqw2,sqw3);
 // 59
                }
			}
		else
			{
			// No pawns
			if (!FInTriangle (sqwk, sqbk))
				{
				sqwk = reflect_xy(sqwk);
				sqw1 = reflect_xy(sqw1);
				sqw2 = reflect_xy(sqw2);
				sqw3 = reflect_xy(sqw3);
				sqbk = reflect_xy(sqbk);
				sqb1 = reflect_xy(sqb1);
				};
			uInd =
TEnumerate3<piw1,piw2,piw3,false,false>::Index(sqwk,sqw1,sqw2,sqw3,sqbk);
            CHECK_INF_TRIPLE(uInd);
			return uInd*(INDEX)i59 + EXCLUDE5(sqb1,sqwk,sqbk,sqw1,sqw2,sqw3);	// 59
			}
		}

	static INDEX TB_FASTCALL IndCalcB
		(
		square	*psqW,
		square	*psqB,
		square	sqEnP,
		int		fInvert
		)
		{
        unsigned uInd;
		square sqwk, sqw1, sqw2, sqw3, sqbk, sqb1, sqMask, sqTemp;

		sqwk = SqFindKing (psqW);
		sqw1 = SqFindFirst (psqW, piw1);
		if (piw1 == piw2 && piw2 == piw3)
			{
			sqw2 = SqFindSecond (psqW, piw2);
			sqw3 = SqFindThird (psqW, piw3);
			}
		else if (piw1 == piw2)
			{
			sqw2 = SqFindSecond (psqW, piw2);
			sqw3 = SqFindFirst (psqW, piw3);
			}
		else if (piw2 == piw3)
			{
			sqw2 = SqFindFirst (psqW, piw2);
			sqw3 = SqFindSecond (psqW, piw3);
			}
		else
			{
			sqw2 = SqFindFirst (psqW, piw2);
			sqw3 = SqFindFirst (psqW, piw3);
			}
 		sqbk = SqFindKing (psqB);
		sqb1 = SqFindOne  (psqB, pib1);

		if (x_piecePawn == piw3 || x_piecePawn == pib1)
			sqMask = rgsqReflectMaskY [sqbk] ^ rgsqReflectInvertMask [fInvert];
		else
			sqMask = rgsqReflectMaskYandX [sqbk];
		sqwk ^= sqMask;
		sqbk ^= sqMask;
		sqw1 ^= sqMask;
		sqw2 ^= sqMask;
		sqw3 ^= sqMask;
		sqb1 ^= sqMask;

		if (x_piecePawn == piw3 || x_piecePawn == pib1)
			{
			// There are pawns on the board
			if (x_piecePawn == pib1)
				{
				// Black pawn
				if (x_piecePawn == piw1)
					{
					// All 4 pieces are pawns
					SORT (sqw1, sqw2);
					SORT (sqw2, sqw3);
					SORT (sqw1, sqw2);
					if (XX == sqEnP)
						{
						sqw3 = EXCLUDE1(sqw3,sqb1)-i8;					// 47
						sqw2 = EXCLUDE1(sqw2,sqb1)-i8;					// 47
						uInd = TEnumerate1<x_piecePawn,true,true>::Index(sqbk,sqb1,sqwk);
		                CHECK_INF_SINGLE(uInd);
						return	uInd*(i47*i46*i45/6) +
								sqw3*(sqw3-1)*(sqw3-2)/6 +
								sqw2*(sqw2-1)/2 +
								EXCLUDE1(sqw1,sqb1)-i8;	// 47*46*45/6
						}
					else
						// En passant capture
						return	rgcSinglePawnPresent[x_piecePawn]*(i47*i46*i45/6) +
								IndHalfKings(sqbk,sqwk)*(i44*i43/2*i14) +
								IndEnPassant31B (sqw1, sqw2, sqw3, sqb1, sqEnP ^ sqMask);
					}
				else if (x_piecePawn == piw2)
					{
					// Two white pawns, one black pawn
					SORT (sqw2, sqw3);
					if (XX == sqEnP)
						{
						sqTemp = EXCLUDE1(sqw3,sqb1)-i8;					// 47
						uInd = TEnumerate1<x_piecePawn,true,true>::
									Index(sqbk,sqb1,sqwk);
		                CHECK_INF_SINGLE(uInd);
						return (uInd*(i59*i47)*(INDEX)(i46/2)) +
							    (EXCLUDE5(sqw1,sqwk,sqbk,sqw2,sqw3,sqb1)*(i47*i46/2) +	// 59
								 sqTemp*(sqTemp-1)/2 +
								 EXCLUDE1(sqw2,sqb1)-i8);	// 47*46/2
						}
					else
						{
						// En passant capture
						sqEnP ^= sqMask;
                        uInd = rgcSinglePawnPresent[x_piecePawn];
						return (uInd*(i59*i47))*(INDEX)(i46/2) +
								(IndHalfKings(sqbk,sqwk)*(i57*i44*i14) +
								 EXCLUDE7(sqw1,sqwk,sqbk,sqw2,sqw3,sqb1,sqEnP,sqEnP-8)*(i44*i14) +	// 57
								 IndEnPassant21B (sqw2, sqw3, sqb1, sqEnP));
						}
					}
				else if (x_piecePawn == piw3)
					{
					// One white pawn, one black pawn
					if (piw1 == piw2)
						{
						// Two identical white pieces
						SORT (sqw1, sqw2);
						if (XX == sqEnP)
							{
							sqw2 = EXCLUDE4(sqw2,sqwk,sqbk,sqw3,sqb1);
							sqw1 = EXCLUDE4(sqw1,sqwk,sqbk,sqw3,sqb1);
							uInd = TEnumerate1<x_piecePawn,true,true>::Index(sqbk,sqb1,sqwk);
    		                CHECK_INF_SINGLE(uInd);
							return	(uInd*(i59*i47))*((INDEX)i60/2) +
									((sqw2*(sqw2-1)/2+sqw1)*i47 +	// 60*59/2
									 EXCLUDE1(sqw3,sqb1)-i8);			// 47
							}
						else
							{
							// En passant capture
							sqEnP ^= sqMask;
							sqw2 = EXCLUDE6(sqw2,sqwk,sqbk,sqw3,sqb1,sqEnP,sqEnP-8);
							sqw1 = EXCLUDE6(sqw1,sqwk,sqbk,sqw3,sqb1,sqEnP,sqEnP-8);
							uInd = rgcSinglePawnPresent[x_piecePawn];
							return	(uInd*(i59*i47))*((INDEX)i60/2) +
									(IndHalfKings(sqbk,sqwk)*(i58*i57/2*i14) +
									 (sqw2*(sqw2-1)/2+sqw1)*i14 + // 58*57/2
									 IndEnPassant11B (sqw3, sqb1, sqEnP));
							}
						}
					else
						{
						// Two different white pieces
						if (XX == sqEnP)
                            {
							uInd = TEnumerate1<x_piecePawn,true,true>::Index(sqbk,sqb1,sqwk);
    		                CHECK_INF_SINGLE(uInd);
							return	(uInd*(i59*i47))*((INDEX)i60) +
									(EXCLUDE4(sqw1,sqwk,sqbk,sqw3,sqb1)*i59*i47 +	// 60
									 EXCLUDE5(sqw2,sqwk,sqbk,sqw1,sqw3,sqb1)*i47 +	// 59
									 EXCLUDE1(sqw3,sqb1)-i8);                       // 47
                            }
						else
							{
							// En passant capture
							sqEnP ^= sqMask;
                            uInd = rgcSinglePawnPresent[x_piecePawn];
							return	(uInd*(i59*i47))*((INDEX)i60) +
									(IndHalfKings(sqbk,sqwk)*(i58*i57*i14) +
									 EXCLUDE6(sqw1,sqwk,sqbk,sqw3,sqb1,sqEnP,sqEnP-8)*(i57*i14) +	// 58
									 EXCLUDE7(sqw2,sqwk,sqbk,sqw2,sqw3,sqb1,sqEnP,sqEnP-8)*i14 +		// 57
									 IndEnPassant11B (sqw3, sqb1, sqEnP));
							}
						}
					}
				else
					{
					// Only black pawn
					uInd = TEnumerate1<x_piecePawn,true,true>::Index(sqbk,sqb1,sqwk);
                    CHECK_INF_SINGLE(uInd);
					if (piw1 == piw3)
						{
						// 3 identical white pieces
						SORT (sqw1, sqw2);
						SORT (sqw2, sqw3);
						SORT (sqw1, sqw2);
						sqw1 = EXCLUDE3(sqw1,sqwk,sqbk,sqb1);						// 61
						sqw2 = EXCLUDE3(sqw2,sqwk,sqbk,sqb1);						// 61
						sqw3 = EXCLUDE3(sqw3,sqwk,sqbk,sqb1);						// 61
						return	uInd*(i61*i60*i59/6) +
								sqw3*(sqw3-1)*(sqw3-2)/6 + sqw2*(sqw2-1)/2 + sqw1;	// 61*60*59/6
						}
					else if (piw1 == piw2)
						{
						// 2 identical major white pieces
						SORT (sqw1, sqw2);
                        sqw3 = EXCLUDE5(sqw3,sqwk,sqbk,sqw1,sqw2,sqb1);
						sqw1 = EXCLUDE3(sqw1,sqwk,sqbk,sqb1);				// 61
						sqw2 = EXCLUDE3(sqw2,sqwk,sqbk,sqb1);				// 61
						return	(uInd*(i61*i59))*(INDEX)(i60/2) +
								((sqw2*(sqw2-1)/2 + sqw1)*i59 +	            // 61*60/2
								 sqw3);	                                    // 59
						}
					else if (piw2 == piw3)
						{
						// 2 identical minor white pieces
						SORT (sqw2, sqw3);
						sqw2 = EXCLUDE4(sqw2,sqwk,sqbk,sqw1,sqb1);			    // 60
						sqw3 = EXCLUDE4(sqw3,sqwk,sqbk,sqw1,sqb1);			    // 60
						return	(uInd*(i61*i59))*(INDEX)(i60/2) +
								(EXCLUDE3(sqw1,sqwk,sqbk,sqb1)*(i60*i59/2) +	// 61
								 sqw3*(sqw3-1)/2 + sqw2);						// 60*59/2
						}
					else
						{
						// All 3 white pieces are different
						return	(uInd*(i61*i59))*(INDEX)i60 +
								(EXCLUDE3(sqw1,sqwk,sqbk,sqb1)*(i60*i59) +	// 61
								 EXCLUDE4(sqw2,sqwk,sqbk,sqw1,sqb1)*i59 +	// 60
								 EXCLUDE5(sqw3,sqwk,sqbk,sqw1,sqw2,sqb1));	// 59
						}
					}
				}
			else
				{
				// No black pawn
				uInd = TEnumerate1<pib1,true,true>::Index(sqbk,sqb1,sqwk);
                CHECK_INF_SINGLE(uInd);
				if (x_piecePawn == piw1)
					{
					// Only 3 white pawns
					SORT (sqw1, sqw2);
					SORT (sqw2, sqw3);
					SORT (sqw1, sqw2);
					sqw3 -= i8;
					sqw2 -= i8;
					return	uInd*(i48*47*i46/6) +
							sqw3*(sqw3-1)*(sqw3-2)/6+sqw2*(sqw2-1)/2+sqw1-i8;			// 48*47*46/6
					}
				else if (x_piecePawn == piw2)
					{
					// 2 white pawns, one non-pawn
					SORT (sqw2, sqw3);
					sqTemp = sqw3 - i8;
					return	(uInd*(i59*47))*(INDEX)(i48/2) +
							(EXCLUDE5(sqw1,sqwk,sqbk,sqb1,sqw2,sqw3)*(i48*i47/2) +
							 sqTemp*(sqTemp-1)/2+sqw2-i8);			// 48*47/2
					}
				else if (piw1 == piw2)
					{
					// One white pawn, 2 identical white pieces
					SORT (sqw1, sqw2);
					sqw1 = EXCLUDE4(sqw1,sqwk,sqbk,sqb1,sqw3);
					sqw2 = EXCLUDE4(sqw2,sqwk,sqbk,sqb1,sqw3);
					return	(uInd*(i60*i59/2))*(INDEX)i48 +
							((sqw2*(sqw2-1)/2+sqw1)*i48 +	// 60*59/2
							 sqw3-i8);						// 48
					}
				else
                    {
					// One white pawn, 2 different white pieces
					return	(uInd*(i60*i59))*(INDEX)i48 +
							(EXCLUDE4(sqw1,sqwk,sqbk,sqb1,sqw3)*(i59*i48) +	// 60
							 EXCLUDE5(sqw2,sqwk,sqbk,sqb1,sqw1,sqw3)*i48 +	// 59
							 sqw3-i8);										// 48
                    }
				}
			}
		else
			{
			// No pawns
			if (!FInTriangle (sqbk, sqwk))
				{
				sqwk = reflect_xy(sqwk);
				sqw1 = reflect_xy(sqw1);
				sqw2 = reflect_xy(sqw2);
				sqw3 = reflect_xy(sqw3);
				sqbk = reflect_xy(sqbk);
				sqb1 = reflect_xy(sqb1);
				};
			uInd = TEnumerate1<pib1,false,false>::Index(sqbk,sqb1,sqwk);
			CHECK_INF_SINGLE(uInd);
			if (piw1 == piw2 && piw2 == piw3)
				{
				// All 3 pieces equal
				SORT (sqw1, sqw2);
				SORT (sqw2, sqw3);
				SORT (sqw1, sqw2);
				sqw3 = EXCLUDE3(sqw3,sqwk,sqbk,sqb1);	// 61
				sqw2 = EXCLUDE3(sqw2,sqwk,sqbk,sqb1);
				return	uInd*(i61*i60*i59/6) +
						sqw3*(sqw3-1)*(sqw3-2)/6+
						sqw2*(sqw2-1)/2+
						EXCLUDE3(sqw1,sqwk,sqbk,sqb1);	// 61*60*59/6
				}
			else if (piw1 == piw2)
				{
				// 2 major pieces equal
				SORT (sqw1, sqw2);
				sqw2 = EXCLUDE4(sqw2,sqwk,sqbk,sqw3,sqb1);							// 60
				return uInd*(i60*i59/2*i61) +
						(sqw2*(sqw2-1)/2+EXCLUDE4(sqw1,sqwk,sqbk,sqw3,sqb1))*i61 +	// 60*59/2
						EXCLUDE3(sqw3,sqwk,sqbk,sqb1);								// 61
				}
			else if (piw2 == piw3)
				{
				// 2 minor pieces equal
				SORT (sqw2, sqw3);
				sqw3 = EXCLUDE4(sqw3,sqwk,sqbk,sqw1,sqb1);					// 60
				return uInd*(i61*i60*i59/2) +
						EXCLUDE3(sqw1,sqwk,sqbk,sqb1)*(i60*i59/2) +			// 62
						sqw3*(sqw3-1)/2+EXCLUDE4(sqw2,sqwk,sqbk,sqw1,sqb1);	// 60*59/2
				}
			else
				{
				uInd *= i61*i60*i59/2;
				return (INDEX) uInd +
					   (INDEX) (uInd +
								EXCLUDE3(sqw1,sqwk,sqbk,sqb1)*(i60*i59) +	// 61
								EXCLUDE4(sqw2,sqwk,sqbk,sqw1,sqb1)*i59 +	// 60
								EXCLUDE5(sqw3,sqwk,sqbk,sqw1,sqw2,sqb1));	// 59
				}
			}
		}
	};

#endif	// T42

#else	// Old SJE schema ------------------------------------------------------

/* scanning pattern: triangle encoding */

static const INDEX sptriv[] =
	{
	 0,  1,  2,  3, -1, -1, -1, -1,
	-1,  4,  5,  6, -1, -1, -1, -1,
	-1, -1,  7,  8, -1, -1, -1, -1,
	-1, -1, -1,  9, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1,
	};

/* scanning pattern: queenside flank encoding */

static const INDEX spqsfv[] =
	{
	 0,  1,  2,  3, -1, -1, -1, -1,
	 4,  5,  6,  7, -1, -1, -1, -1,
	 8,  9, 10, 11, -1, -1, -1, -1,
	12, 13, 14, 15, -1, -1, -1, -1,
	16, 17, 18, 19, -1, -1, -1, -1,
	20, 21, 22, 23, -1, -1, -1, -1,
	24, 25, 26, 27, -1, -1, -1, -1,
	28, 29, 30, 31, -1, -1, -1, -1,
	};

/*--> CalcIndex3A: calculate index, mode 3A */
INLINE INDEX CalcIndex3A
	(
	square sq0,
	square sq1,
	square sq2
	)
	{
	INDEX index;

	if (TbRow(sq2) > x_row_4)
		{
		sq0 = reflect_x(sq0);
		sq1 = reflect_x(sq1);
		sq2 = reflect_x(sq2);
		};

	if (TbColumn(sq2) > x_column_d)
		{
		sq0 = reflect_y(sq0);
		sq1 = reflect_y(sq1);
		sq2 = reflect_y(sq2);
		};

	if (TbRow(sq2) > TbColumn(sq2))
		{
		sq0 = reflect_xy(sq0);
		sq1 = reflect_xy(sq1);
		sq2 = reflect_xy(sq2);
		};

	index =
		sq0 +
		sq1 * i64 +
		sptriv [sq2] * i64 * i64;

	return (index);
	}

/*--> CalcIndex3B: calculate index, mode 3B */
INLINE INDEX CalcIndex3B
	(
	square sq0,
	square sq1,
	square sq2
	)
	{
	INDEX index;

	if (TbColumn(sq1) > x_column_d)
		{
		sq0 = reflect_y(sq0);
		sq1 = reflect_y(sq1);
		sq2 = reflect_y(sq2);
		};

	index =
		sq0 +
		spqsfv [sq1] * i64 +
		sq2 * (i64 / 2) * i64;

	return (index);
	}

/*--> CalcIndex4A: calculate index, mode 4A */
INLINE INDEX CalcIndex4A
	(
	square sq0,
	square sq1,
	square sq2,
	square sq3
	)
	{
	INDEX index;

	if (TbRow(sq3) > x_row_4)
		{
		sq0 = reflect_x(sq0);
		sq1 = reflect_x(sq1);
		sq2 = reflect_x(sq2);
		sq3 = reflect_x(sq3);
		};

	if (TbColumn(sq3) > x_column_d)
		{
		sq0 = reflect_y(sq0);
		sq1 = reflect_y(sq1);
		sq2 = reflect_y(sq2);
		sq3 = reflect_y(sq3);
		};

	if (TbRow(sq3) > TbColumn(sq3))
		{
		sq0 = reflect_xy(sq0);
		sq1 = reflect_xy(sq1);
		sq2 = reflect_xy(sq2);
		sq3 = reflect_xy(sq3);
		};

	index =
		sq0 +
		sq1 * i64 +
		sq2 * i64 * i64 +
		sptriv [sq3] * i64 * i64 * i64;

	return (index);
	}

/*--> CalcIndex4B: calculate index, mode 4B */
INLINE INDEX CalcIndex4B
	(
	square sq0,
	square sq1,
	square sq2,
	square sq3
	)
	{
	INDEX index;

	if (TbColumn(sq3) > x_column_d)
		{
		sq0 = reflect_y(sq0);
		sq1 = reflect_y(sq1);
		sq2 = reflect_y(sq2);
		sq3 = reflect_y(sq3);
		};

	index =
		sq0 +
		sq1 * i64 +
		sq2 * i64 * i64 +
		spqsfv [sq3] * i64 * i64 * i64;

	return (index);
	}

/*--> CalcIndex4C: calculate index, mode 4C */
INLINE INDEX CalcIndex4C
	(
	square sq0,
	square sq1,
	square sq2,
	square sq3
	)
	{
	INDEX index;

	if (TbColumn(sq2) > x_column_d)
		{
		sq0 = reflect_y(sq0);
		sq1 = reflect_y(sq1);
		sq2 = reflect_y(sq2);
		sq3 = reflect_y(sq3);
		};

	index =
		sq0 +
		sq1 * i64 +
		spqsfv [sq2] * i64 * i64 +
		sq3 * (i64 / 2) * i64 * i64;

	return (index);
	}

/*--> CalcIndex5A: calculate index, mode 5A */
INLINE INDEX CalcIndex5A
	(
	square sq0,
	square sq1,
	square sq2,
	square sq3,
	square sq4
	)
	{
	INDEX index;

	if (TbRow(sq4) > x_row_4)
		{
		sq0 = reflect_x(sq0);
		sq1 = reflect_x(sq1);
		sq2 = reflect_x(sq2);
		sq3 = reflect_x(sq3);
		sq4 = reflect_x(sq4);
		};

	if (TbColumn(sq4) > x_column_d)
		{
		sq0 = reflect_y(sq0);
		sq1 = reflect_y(sq1);
		sq2 = reflect_y(sq2);
		sq3 = reflect_y(sq3);
		sq4 = reflect_y(sq4);
		};

	if (TbRow(sq4) > TbColumn(sq4))
		{
		sq0 = reflect_xy(sq0);
		sq1 = reflect_xy(sq1);
		sq2 = reflect_xy(sq2);
		sq3 = reflect_xy(sq3);
		sq4 = reflect_xy(sq4);
		};

	index =
		sq0 +
		sq1 * i64 +
		sq2 * i64 * i64 +
		sq3 * i64 * i64 * i64 +
		sptriv [sq4] * i64 * i64 * i64 * i64;

	return (index);
	}

/*--> CalcIndex5B: calculate index, mode 5B */
INLINE INDEX CalcIndex5B
	(
	square sq0,
	square sq1,
	square sq2,
	square sq3,
	square sq4
	)
	{
	INDEX index;

	if (TbColumn(sq4) > x_column_d)
		{
		sq0 = reflect_y(sq0);
		sq1 = reflect_y(sq1);
		sq2 = reflect_y(sq2);
		sq3 = reflect_y(sq3);
		sq4 = reflect_y(sq4);
		};

	index =
		sq0 +
		sq1 * i64 +
		sq2 * i64 * i64 +
		sq3 * i64 * i64 * i64 +
		spqsfv [sq4] * i64 * i64 * i64 * i64;

	return (index);
	}

/*--> CalcIndex5C: calculate index, mode 5C */
INLINE INDEX CalcIndex5C
	(
	square sq0,
	square sq1,
	square sq2,
	square sq3,
	square sq4
	)
	{
	INDEX index;

	if (TbColumn(sq3) > x_column_d)
		{
		sq0 = reflect_y(sq0);
		sq1 = reflect_y(sq1);
		sq2 = reflect_y(sq2);
		sq3 = reflect_y(sq3);
		sq4 = reflect_y(sq4);
		};

	index =
		sq0 +
		sq1 * i64 +
		sq2 * i64 * i64 +
		spqsfv [sq3] * i64 * i64 * i64 +
		sq4 * (i64 / 2) * i64 * i64 * i64;

	return (index);
	}

/*--> CalcIndex5D: calculate index, mode 5D */
INLINE INDEX CalcIndex5D
	(
	square sq0,
	square sq1,
	square sq2,
	square sq3,
	square sq4
	)
	{
	INDEX index;

	if (TbColumn(sq2) > x_column_d)
		{
		sq0 = reflect_y(sq0);
		sq1 = reflect_y(sq1);
		sq2 = reflect_y(sq2);
		sq3 = reflect_y(sq3);
		sq4 = reflect_y(sq4);
		};

	index =
		sq0 +
		sq1 * i64 +
		spqsfv [sq2] * i64 * i64 +
		sq3 * (i64 / 2) * i64 * i64 +
		sq4 * (i64 / 2) * i64 * i64 * i64;

	return (index);
	}

// Calculate index - a lot of functions...

#define	IndCalcW	IndCalc
#define	IndCalcB	IndCalc

template <int pi> class T21
	{
public:
	static INDEX TB_FASTCALL IndCalc
		(
		square	*psqW,
		square	*psqB,
		square	sqEnP,
		int		fInvert
		)
		{
		square sq0, sq1, sq2;

		sq0 = SqFindKing (psqW);
		sq1 = SqFindOne  (psqW, pi);
		sq2 = SqFindKing (psqB);

		if (x_piecePawn == pi)
			{
			if (fInvert)
				{
				sq0 = reflect_x (sq0);
				sq1 = reflect_x (sq1);
				sq2 = reflect_x (sq2);
				}
			return CalcIndex3B (sq0, sq1, sq2);
			}
		else
			return CalcIndex3A (sq0, sq1, sq2);
		}
	};

template <int pi1, int pi2> class T22
	{
public:
	static INDEX TB_FASTCALL IndCalc
		(
		square	*psqW,
		square	*psqB,
		square	sqEnP,
		int		fInvert
		)
		{
		square sq0, sq1, sq2, sq3;

		sq0 = SqFindKing (psqW);
		sq1 = SqFindOne  (psqW, pi1);
		sq2 = SqFindKing (psqB);
		sq3 = SqFindOne  (psqB, pi2);

		if (x_piecePawn == pi1 || x_piecePawn == pi2)
			{
			if (fInvert)
				{
				sq0 = reflect_x (sq0);
				sq1 = reflect_x (sq1);
				sq2 = reflect_x (sq2);
				sq3 = reflect_x (sq3);
				}
			return CalcIndex4B (sq0, sq1, sq2, sq3);
			}
		else
			return CalcIndex4A (sq0, sq1, sq2, sq3);
		}
	};

template <int pi1, int pi2> class T31
	{
public:
	static INDEX TB_FASTCALL IndCalc
		(
		square	*psqW,
		square	*psqB,
		square	sqEnP,
		int		fInvert
		)
		{
		square sq0, sq1, sq2, sq3;

		sq0 = SqFindKing (psqW);
		sq1 = SqFindFirst (psqW, pi1);
		if (pi1 == pi2)
			sq2 = SqFindSecond (psqW, pi2);
		else
			sq2 = SqFindFirst (psqW, pi2);
		sq3 = SqFindKing (psqB);

		if (x_piecePawn == pi1 || x_piecePawn == pi2)
			{
			if (fInvert)
				{
				sq0 = reflect_x (sq0);
				sq1 = reflect_x (sq1);
				sq2 = reflect_x (sq2);
				sq3 = reflect_x (sq3);
				}
			return CalcIndex4C (sq0, sq1, sq2, sq3);
			}
		else
			return CalcIndex4A (sq0, sq1, sq2, sq3);
		}
	};

template <int pi1, int pi2, int pi3> class T32
	{
public:
	static INDEX TB_FASTCALL IndCalc
		(
		square	*psqW,
		square	*psqB,
		square	sqEnP,
		int		fInvert
		)
		{
		square sq0, sq1, sq2, sq3, sq4;

		sq0 = SqFindKing (psqW);
		sq1 = SqFindFirst (psqW, pi1);
		if (pi1 == pi2)
			sq2 = SqFindSecond (psqW, pi2);
		else
			sq2 = SqFindFirst (psqW, pi2);
		sq3 = SqFindKing (psqB);
		sq4 = SqFindOne  (psqB, pi3);

		if (x_piecePawn == pi1 || x_piecePawn == pi2 || x_piecePawn == pi3)
			{
			if (fInvert)
				{
				sq0 = reflect_x (sq0);
				sq1 = reflect_x (sq1);
				sq2 = reflect_x (sq2);
				sq3 = reflect_x (sq3);
				sq4 = reflect_x (sq4);
				}
			if (x_piecePawn == pi3)
				return CalcIndex5B (sq0, sq1, sq2, sq3, sq4);
			else
				return CalcIndex5D (sq0, sq1, sq2, sq3, sq4);
			}
		else
			return CalcIndex5A (sq0, sq1, sq2, sq3, sq4);
		}
	};

#if defined (T41_INCLUDE)

template <int pi1, int pi2, int pi3> class T41
	{
public:
	static INDEX TB_FASTCALL IndCalc
		(
		square	*psqW,
		square	*psqB,
		square	sqEnP,
		int		fInvert
		)
		{
		square sq0, sq1, sq2, sq3, sq4;

		sq0 = SqFindKing (psqW);
		sq1 = SqFindFirst (psqW, pi1);
		sq2 = SqFindFirst (psqW, pi2);
		sq3 = SqFindFirst (psqW, pi3);
		sq4 = SqFindKing (psqB);

		if (x_piecePawn == pi1 || x_piecePawn == pi2 || x_piecePawn == pi3)
			{
			// There are pawns on the board
			if (fInvert)
				{
				sq0 = reflect_x (sq0);
				sq1 = reflect_x (sq1);
				sq2 = reflect_x (sq2);
				sq3 = reflect_x (sq3);
				sq4 = reflect_x (sq4);
				}
			return CalcIndex5C (sq0, sq1, sq2, sq3, sq4);
			}
		else	// No pawns
			return CalcIndex5A (sq0, sq1, sq2, sq3, sq4);
		}
	};

#endif

#endif	//----------------------------------------------------------------------

// All tablebases enumerated

#define tbid_kk      0
#define tbid_kpk     1
#define tbid_knk     2
#define tbid_kbk     3
#define tbid_krk     4
#define tbid_kqk     5
#define tbid_kpkp    6
#define tbid_knkp    7
#define tbid_knkn    8
#define tbid_kbkp    9
#define tbid_kbkn   10
#define tbid_kbkb   11
#define tbid_krkp   12
#define tbid_krkn   13
#define tbid_krkb   14
#define tbid_krkr   15
#define tbid_kqkp   16
#define tbid_kqkn   17
#define tbid_kqkb   18
#define tbid_kqkr   19
#define tbid_kqkq   20
#define tbid_kppk   21
#define tbid_knpk   22
#define tbid_knnk   23
#define tbid_kbpk   24
#define tbid_kbnk   25
#define tbid_kbbk   26
#define tbid_krpk   27
#define tbid_krnk   28
#define tbid_krbk   29
#define tbid_krrk   30
#define tbid_kqpk   31
#define tbid_kqnk   32
#define tbid_kqbk   33
#define tbid_kqrk   34
#define tbid_kqqk   35
#define tbid_kppkp  36
#define tbid_kppkn  37
#define tbid_kppkb  38
#define tbid_kppkr  39
#define tbid_kppkq  40
#define tbid_knpkp  41
#define tbid_knpkn  42
#define tbid_knpkb  43
#define tbid_knpkr  44
#define tbid_knpkq  45
#define tbid_knnkp  46
#define tbid_knnkn  47
#define tbid_knnkb  48
#define tbid_knnkr  49
#define tbid_knnkq  50
#define tbid_kbpkp  51
#define tbid_kbpkn  52
#define tbid_kbpkb  53
#define tbid_kbpkr  54
#define tbid_kbpkq  55
#define tbid_kbnkp  56
#define tbid_kbnkn  57
#define tbid_kbnkb  58
#define tbid_kbnkr  59
#define tbid_kbnkq  60
#define tbid_kbbkp  61
#define tbid_kbbkn  62
#define tbid_kbbkb  63
#define tbid_kbbkr  64
#define tbid_kbbkq  65
#define tbid_krpkp  66
#define tbid_krpkn  67
#define tbid_krpkb  68
#define tbid_krpkr  69
#define tbid_krpkq  70
#define tbid_krnkp  71
#define tbid_krnkn  72
#define tbid_krnkb  73
#define tbid_krnkr  74
#define tbid_krnkq  75
#define tbid_krbkp  76
#define tbid_krbkn  77
#define tbid_krbkb  78
#define tbid_krbkr  79
#define tbid_krbkq  80
#define tbid_krrkp  81
#define tbid_krrkn  82
#define tbid_krrkb  83
#define tbid_krrkr  84
#define tbid_krrkq  85
#define tbid_kqpkp  86
#define tbid_kqpkn  87
#define tbid_kqpkb  88
#define tbid_kqpkr  89
#define tbid_kqpkq  90
#define tbid_kqnkp  91
#define tbid_kqnkn  92
#define tbid_kqnkb  93
#define tbid_kqnkr  94
#define tbid_kqnkq  95
#define tbid_kqbkp  96
#define tbid_kqbkn  97
#define tbid_kqbkb  98
#define tbid_kqbkr  99
#define tbid_kqbkq 100
#define tbid_kqrkp 101
#define tbid_kqrkn 102
#define tbid_kqrkb 103
#define tbid_kqrkr 104
#define tbid_kqrkq 105
#define tbid_kqqkp 106
#define tbid_kqqkn 107
#define tbid_kqqkb 108
#define tbid_kqqkr 109
#define tbid_kqqkq 110

#if defined (T41_INCLUDE)
#  define tbid_kpppk	111
#  define tbid_knppk	112
#  define tbid_knnpk	113
#  define tbid_knnnk	114
#  define tbid_kbppk	115
#  define tbid_kbnpk	116
#  define tbid_kbnnk	117
#  define tbid_kbbpk	118
#  define tbid_kbbnk	119
#  define tbid_kbbbk	120
#  define tbid_krppk	121
#  define tbid_krnpk	122
#  define tbid_krnnk	123
#  define tbid_krbpk	124
#  define tbid_krbnk	125
#  define tbid_krbbk	126
#  define tbid_krrpk	127
#  define tbid_krrnk	128
#  define tbid_krrbk	129
#  define tbid_krrrk	130
#  define tbid_kqppk	131
#  define tbid_kqnpk	132
#  define tbid_kqnnk	133
#  define tbid_kqbpk	134
#  define tbid_kqbnk	135
#  define tbid_kqbbk	136
#  define tbid_kqrpk	137
#  define tbid_kqrnk	138
#  define tbid_kqrbk	139
#  define tbid_kqrrk	140
#  define tbid_kqqpk	141
#  define tbid_kqqnk	142
#  define tbid_kqqbk	143
#  define tbid_kqqrk	144
#  define tbid_kqqqk	145
#endif

#if defined (T33_INCLUDE)
#  if defined (T41_INCLUDE)
#    define	BASE_33	145
#  else
#    define	BASE_33	110
#  endif
#  define tbid_knnknn	(BASE_33 + 1)
#  define tbid_kbnknn	(BASE_33 + 2)
#  define tbid_kbbknn	(BASE_33 + 3)
#  define tbid_kbbkbn	(BASE_33 + 4)
#  define tbid_kbbkbb	(BASE_33 + 5)
#  define tbid_krnknn	(BASE_33 + 6)
#  define tbid_krnkbb	(BASE_33 + 7)
#  define tbid_krbknn	(BASE_33 + 8)
#  define tbid_krbkbb	(BASE_33 + 9)
#  define tbid_krrknn	(BASE_33 + 10)
#  define tbid_krrkbn	(BASE_33 + 11)
#  define tbid_krrkbb	(BASE_33 + 12)
#  define tbid_krrkrn	(BASE_33 + 13)
#  define tbid_krrkrb	(BASE_33 + 14)
#  define tbid_krrkrr	(BASE_33 + 15)
#  define tbid_kqnknn	(BASE_33 + 16)
#  define tbid_kqnkbb	(BASE_33 + 17)
#  define tbid_kqnkrr	(BASE_33 + 18)
#  define tbid_kqbknn	(BASE_33 + 19)
#  define tbid_kqbkbb	(BASE_33 + 20)
#  define tbid_kqbkrr	(BASE_33 + 21)
#  define tbid_kqrknn	(BASE_33 + 22)
#  define tbid_kqrkbb	(BASE_33 + 23)
#  define tbid_kqrkrr	(BASE_33 + 24)
#  define tbid_kqqknn	(BASE_33 + 25)
#  define tbid_kqqkbn	(BASE_33 + 26)
#  define tbid_kqqkbb	(BASE_33 + 27)
#  define tbid_kqqkrn	(BASE_33 + 28)
#  define tbid_kqqkrb	(BASE_33 + 29)
#  define tbid_kqqkrr	(BASE_33 + 30)
#  define tbid_kqqkqn	(BASE_33 + 31)
#  define tbid_kqqkqb	(BASE_33 + 32)
#  define tbid_kqqkqr	(BASE_33 + 33)
#  define tbid_kqqkqq	(BASE_33 + 34)
#  if defined (T_INDEX64)
#    define tbid_kbnkbn (BASE_33 + 35)
#    define tbid_krnkrn (BASE_33 + 36)
#    define tbid_krbkrb (BASE_33 + 37)
#    define tbid_kqnkqn (BASE_33 + 38)
#    define tbid_kqbkqb (BASE_33 + 39)
#    define tbid_kqrkqr (BASE_33 + 40)
#    define tbid_krnkbn (BASE_33 + 41)
#    define tbid_krbkbn (BASE_33 + 42)
#    define tbid_krbkrn (BASE_33 + 43)
#    define tbid_kqnkbn (BASE_33 + 44)
#    define tbid_kqnkrn (BASE_33 + 45)
#    define tbid_kqnkrb (BASE_33 + 46)
#    define tbid_kqbkbn (BASE_33 + 47)
#    define tbid_kqbkrn (BASE_33 + 48)
#    define tbid_kqbkrb (BASE_33 + 49)
#    define tbid_kqbkqn (BASE_33 + 50)
#    define tbid_kqrkbn (BASE_33 + 51)
#    define tbid_kqrkrn (BASE_33 + 52)
#    define tbid_kqrkrb (BASE_33 + 53)
#    define tbid_kqrkqn (BASE_33 + 54)
#    define tbid_kqrkqb (BASE_33 + 55)
#    define	C33	(tbid_kqrkqb - BASE_33)
#  else
#    define	C33	(tbid_kqqkqq - BASE_33)
#  endif
#else
#  define C33	0
#endif

#if defined (T41_INCLUDE)
#  define BASE_42	(145 + C33)
#else
#  define BASE_42	(110 + C33)
#endif

#if defined (T42_INCLUDE)
#  define tbid_knnnkn	(BASE_42 + 1)
#  define tbid_kbnnkn	(BASE_42 + 2)
#  define tbid_kbbnkn	(BASE_42 + 3)
#  define tbid_kbbbkn	(BASE_42 + 4)
#  define tbid_krnnkn	(BASE_42 + 5)
#  define tbid_krbbkn	(BASE_42 + 6)
#  define tbid_krrnkn	(BASE_42 + 7)
#  define tbid_krrbkn	(BASE_42 + 8)
#  define tbid_krrrkn	(BASE_42 + 9)
#  define tbid_kqnnkn	(BASE_42 + 10)
#  define tbid_kqbbkn	(BASE_42 + 11)
#  define tbid_kqrrkn	(BASE_42 + 12)
#  define tbid_kqqnkn	(BASE_42 + 13)
#  define tbid_kqqbkn	(BASE_42 + 14)
#  define tbid_kqqrkn	(BASE_42 + 15)
#  define tbid_kqqqkn	(BASE_42 + 16)
#  define tbid_knnnkb	(BASE_42 + 17)
#  define tbid_kbnnkb	(BASE_42 + 18)
#  define tbid_kbbnkb	(BASE_42 + 19)
#  define tbid_kbbbkb	(BASE_42 + 20)
#  define tbid_krnnkb	(BASE_42 + 21)
#  define tbid_krbbkb	(BASE_42 + 22)
#  define tbid_krrnkb	(BASE_42 + 23)
#  define tbid_krrbkb	(BASE_42 + 24)
#  define tbid_krrrkb	(BASE_42 + 25)
#  define tbid_kqnnkb	(BASE_42 + 26)
#  define tbid_kqbbkb	(BASE_42 + 27)
#  define tbid_kqrrkb	(BASE_42 + 28)
#  define tbid_kqqnkb	(BASE_42 + 29)
#  define tbid_kqqbkb	(BASE_42 + 30)
#  define tbid_kqqrkb	(BASE_42 + 31)
#  define tbid_kqqqkb	(BASE_42 + 32)
#  define tbid_knnnkr	(BASE_42 + 33)
#  define tbid_kbnnkr	(BASE_42 + 34)
#  define tbid_kbbnkr	(BASE_42 + 35)
#  define tbid_kbbbkr	(BASE_42 + 36)
#  define tbid_krnnkr	(BASE_42 + 37)
#  define tbid_krbbkr	(BASE_42 + 38)
#  define tbid_krrnkr	(BASE_42 + 39)
#  define tbid_krrbkr	(BASE_42 + 40)
#  define tbid_krrrkr	(BASE_42 + 41)
#  define tbid_kqnnkr	(BASE_42 + 42)
#  define tbid_kqbbkr	(BASE_42 + 43)
#  define tbid_kqrrkr	(BASE_42 + 44)
#  define tbid_kqqnkr	(BASE_42 + 45)
#  define tbid_kqqbkr	(BASE_42 + 46)
#  define tbid_kqqrkr	(BASE_42 + 47)
#  define tbid_kqqqkr	(BASE_42 + 48)
#  define tbid_knnnkq	(BASE_42 + 49)
#  define tbid_kbnnkq	(BASE_42 + 50)
#  define tbid_kbbnkq	(BASE_42 + 51)
#  define tbid_kbbbkq	(BASE_42 + 52)
#  define tbid_krnnkq	(BASE_42 + 53)
#  define tbid_krbbkq	(BASE_42 + 54)
#  define tbid_krrnkq	(BASE_42 + 55)
#  define tbid_krrbkq	(BASE_42 + 56)
#  define tbid_krrrkq	(BASE_42 + 57)
#  define tbid_kqnnkq	(BASE_42 + 58)
#  define tbid_kqbbkq	(BASE_42 + 59)
#  define tbid_kqrrkq	(BASE_42 + 60)
#  define tbid_kqqnkq	(BASE_42 + 61)
#  define tbid_kqqbkq	(BASE_42 + 62)
#  define tbid_kqqrkq	(BASE_42 + 63)
#  define tbid_kqqqkq	(BASE_42 + 64)
#  if defined (T_INDEX64)
#    define tbid_krbnkn	(BASE_42 + 65)
#    define tbid_kqbnkn (BASE_42 + 66)
#    define tbid_kqrnkn (BASE_42 + 67)
#    define tbid_kqrbkn (BASE_42 + 68)
#    define tbid_krbnkb (BASE_42 + 69)
#    define tbid_kqbnkb (BASE_42 + 70)
#    define tbid_kqrnkb (BASE_42 + 71)
#    define tbid_kqrbkb (BASE_42 + 72)
#    define tbid_krbnkr (BASE_42 + 73)
#    define tbid_kqbnkr (BASE_42 + 74)
#    define tbid_kqrnkr (BASE_42 + 75)
#    define tbid_kqrbkr (BASE_42 + 76)
#    define tbid_krbnkq (BASE_42 + 77)
#    define tbid_kqbnkq (BASE_42 + 78)
#    define tbid_kqrnkq (BASE_42 + 79)
#    define tbid_kqrbkq (BASE_42 + 80)

#    define tbid_kpppkp	(BASE_42 + 81)
#    define tbid_knppkp	(BASE_42 + 82)
#    define tbid_knnpkp	(BASE_42 + 83)
#    define tbid_knnnkp	(BASE_42 + 84)
#    define tbid_kbppkp	(BASE_42 + 85)
#    define tbid_kbnpkp	(BASE_42 + 86)
#    define tbid_kbnnkp	(BASE_42 + 87)
#    define tbid_kbbpkp	(BASE_42 + 88)
#    define tbid_kbbnkp	(BASE_42 + 89)
#    define tbid_kbbbkp	(BASE_42 + 90)
#    define tbid_krppkp	(BASE_42 + 91)
#    define tbid_krnpkp	(BASE_42 + 92)
#    define tbid_krnnkp	(BASE_42 + 93)
#    define tbid_krbpkp	(BASE_42 + 94)
#    define tbid_krbnkp	(BASE_42 + 95)
#    define tbid_krbbkp	(BASE_42 + 96)
#    define tbid_krrpkp	(BASE_42 + 97)
#    define tbid_krrnkp	(BASE_42 + 98)
#    define tbid_krrbkp	(BASE_42 + 99)
#    define tbid_krrrkp	(BASE_42 + 100)
#    define tbid_kqppkp	(BASE_42 + 101)
#    define tbid_kqnpkp	(BASE_42 + 102)
#    define tbid_kqnnkp	(BASE_42 + 103)
#    define tbid_kqbpkp	(BASE_42 + 104)
#    define tbid_kqbnkp	(BASE_42 + 105)
#    define tbid_kqbbkp	(BASE_42 + 106)
#    define tbid_kqrpkp	(BASE_42 + 107)
#    define tbid_kqrnkp	(BASE_42 + 108)
#    define tbid_kqrbkp	(BASE_42 + 109)
#    define tbid_kqrrkp	(BASE_42 + 110)
#    define tbid_kqqpkp	(BASE_42 + 111)
#    define tbid_kqqnkp	(BASE_42 + 112)
#    define tbid_kqqbkp	(BASE_42 + 113)
#    define tbid_kqqrkp	(BASE_42 + 114)
#    define tbid_kqqqkp	(BASE_42 + 115)
#    define tbid_kpppkn	(BASE_42 + 116)
#    define tbid_knppkn	(BASE_42 + 117)
#    define tbid_knnpkn	(BASE_42 + 118)
#    define tbid_kbppkn	(BASE_42 + 119)
#    define tbid_kbnpkn	(BASE_42 + 120)
#    define tbid_kbbpkn	(BASE_42 + 121)
#    define tbid_krppkn	(BASE_42 + 122)
#    define tbid_krnpkn	(BASE_42 + 123)
#    define tbid_krbpkn	(BASE_42 + 124)
#    define tbid_krrpkn	(BASE_42 + 125)
#    define tbid_kqppkn	(BASE_42 + 126)
#    define tbid_kqnpkn	(BASE_42 + 127)
#    define tbid_kqbpkn	(BASE_42 + 128)
#    define tbid_kqrpkn	(BASE_42 + 129)
#    define tbid_kqqpkn	(BASE_42 + 130)
#    define tbid_kpppkb	(BASE_42 + 131)
#    define tbid_knppkb	(BASE_42 + 132)
#    define tbid_knnpkb	(BASE_42 + 133)
#    define tbid_kbppkb	(BASE_42 + 134)
#    define tbid_kbnpkb	(BASE_42 + 135)
#    define tbid_kbbpkb	(BASE_42 + 136)
#    define tbid_krppkb	(BASE_42 + 137)
#    define tbid_krnpkb	(BASE_42 + 138)
#    define tbid_krbpkb	(BASE_42 + 139)
#    define tbid_krrpkb	(BASE_42 + 140)
#    define tbid_kqppkb	(BASE_42 + 141)
#    define tbid_kqnpkb	(BASE_42 + 142)
#    define tbid_kqbpkb	(BASE_42 + 143)
#    define tbid_kqrpkb	(BASE_42 + 144)
#    define tbid_kqqpkb	(BASE_42 + 145)
#    define tbid_kpppkr	(BASE_42 + 146)
#    define tbid_knppkr	(BASE_42 + 147)
#    define tbid_knnpkr	(BASE_42 + 148)
#    define tbid_kbppkr	(BASE_42 + 149)
#    define tbid_kbnpkr	(BASE_42 + 150)
#    define tbid_kbbpkr	(BASE_42 + 151)
#    define tbid_krppkr	(BASE_42 + 152)
#    define tbid_krnpkr	(BASE_42 + 153)
#    define tbid_krbpkr	(BASE_42 + 154)
#    define tbid_krrpkr	(BASE_42 + 155)
#    define tbid_kqppkr	(BASE_42 + 156)
#    define tbid_kqnpkr	(BASE_42 + 157)
#    define tbid_kqbpkr	(BASE_42 + 158)
#    define tbid_kqrpkr	(BASE_42 + 159)
#    define tbid_kqqpkr	(BASE_42 + 160)
#    define tbid_kpppkq	(BASE_42 + 161)
#    define tbid_knppkq	(BASE_42 + 162)
#    define tbid_knnpkq	(BASE_42 + 163)
#    define tbid_kbppkq	(BASE_42 + 164)
#    define tbid_kbnpkq	(BASE_42 + 165)
#    define tbid_kbbpkq	(BASE_42 + 166)
#    define tbid_krppkq	(BASE_42 + 167)
#    define tbid_krnpkq	(BASE_42 + 168)
#    define tbid_krbpkq	(BASE_42 + 169)
#    define tbid_krrpkq	(BASE_42 + 170)
#    define tbid_kqppkq	(BASE_42 + 171)
#    define tbid_kqnpkq	(BASE_42 + 172)
#    define tbid_kqbpkq	(BASE_42 + 173)
#    define tbid_kqrpkq	(BASE_42 + 174)
#    define tbid_kqqpkq	(BASE_42 + 175)

#    define C42 175
#  else
#    define C42 64
#  endif
#endif

#if defined (T42_INCLUDE)
#  define cTb	(BASE_42 + C42 + 1)
#else
#  define cTb	(BASE_42 + 1)
#endif

// Compression

#include "tbdecode.h"

#if !defined (CPUS)
#  define	CPUS	1
#endif

#if defined (SMP)
  static	lock_t	lockDecode;
#endif
extern "C" int TB_CRC_CHECK = 0;
static int cCompressed = 0;
static decode_block *rgpdbDecodeBlocks[CPUS];

// Information about tablebases

#define MAX_EXTENTS                 9   /* Maximum # of 2Gb file extents */

#if defined (T33_INCLUDE) || defined (T42_INCLUDE)
#  define	MAX_TOTAL_PIECES		6	/* Maximum # of pieces on the board */
#else
#  define	MAX_TOTAL_PIECES		5	/* Maximum # of pieces on the board */
#endif
#define	MAX_NON_KINGS			(MAX_TOTAL_PIECES - 2)

#if !defined (TB_DIRECTORY_SIZE)
#  define	TB_DIRECTORY_SIZE		32	/* # of cache buckets */
#endif

#if !defined (PFNCALCINDEX_DECLARED)
typedef INDEX (TB_FASTCALL * PfnCalcIndex) (square *psqW, square *psqB,
										 square sqEnP, int fInverse);
#  define	PFNCALCINDEX_DECLARED
#endif

struct CTbCache;

typedef struct		// Hungarian: tbcb
	{
#if defined (SMP)
	lock_t				         m_lock;			// Lock on this cache bucket list
#endif
	volatile CTbCache * volatile m_ptbcFirst;	// Cached file chunks in LRU order
	}
	CTbCacheBucket;

typedef struct		// Hungarian: tbd
	{
	int		        m_iTbId;
	unsigned int    m_fSymmetric:1;
	unsigned int	m_f16bit:1;
    unsigned int    m_fSplit:1;
	PfnCalcIndex	m_rgpfnCalcIndex[2];
	char			m_rgchName[MAX_TOTAL_PIECES+1];
	INDEX			m_rgcbLength[2];
	char			*m_rgpchFileName[2][MAX_EXTENTS];
#if defined (SMP)
	lock_t			m_rglockFiles[2];
#endif
	FILE	        *m_rgfpFiles[2][MAX_EXTENTS];
	decode_info		*m_rgpdiDecodeInfo[2][MAX_EXTENTS];
	CTbCacheBucket  *m_prgtbcbBuckets[2];	// Cached file chunks in LRU order
	BYTE			*m_rgpbRead[2];
	}
	CTbDesc;

#if defined (T_INDEX64) && defined (_MSC_VER)
#  define	TB(name, fSym, f16bit, fSplit, funW, funB, cbW, cbB)\
                    { tbid_##name, fSym, f16bit, fSplit, { funW, funB }, #name,
{ cbW##ui64, cbB##ui64 } },
#elif defined (T_INDEX64)
#  define	TB(name, fSym, f16bit, fSplit, funW, funB, cbW, cbB)\
                    { tbid_##name, fSym, f16bit, fSplit, { funW, funB }, #name,
{ cbW##llu, cbB##llu } },
#else
#  define	TB(name, fSym, f16bit, fSplit, funW, funB, cbW, cbB)\
                    { tbid_##name, fSym, f16bit, fSplit, { funW, funB }, #name,
{ cbW##u, cbB##u } },
#endif

#define	P	x_piecePawn
#define	N	x_pieceKnight
#define	B	x_pieceBishop
#define	R	x_pieceRook
#define	Q	x_pieceQueen

CTbDesc	rgtbdDesc[cTb] =
	{
	TB (kk, true, false, false, NULL, NULL, 0, 0)

	TB (kpk, false, false, false, (T21<P>::IndCalcW), (T21<P>::IndCalcB), 81664,
84012)
	TB (knk, false, false, false, (T21<N>::IndCalcW), (T21<N>::IndCalcB), 26282,
28644)
	TB (kbk, false, false, false, (T21<B>::IndCalcW), (T21<B>::IndCalcB), 27243,
28644)
	TB (krk, false, false, false, (T21<R>::IndCalcW), (T21<R>::IndCalcB), 27030,
28644)
	TB (kqk, false, false, false, (T21<Q>::IndCalcW), (T21<Q>::IndCalcB), 25629,
28644)

	TB (kpkp, false, false, false, (T22<P, P>::IndCalcW), (T22<P, P>::IndCalcB),
3863492, 3863492)
	TB (knkp, false, false, false, (T22<N, P>::IndCalcW), (T22<N, P>::IndCalcB),
4931904, 4981504)
	TB (knkn, true,  false, false, (T22<N, N>::IndCalcW), (T22<N, N>::IndCalcB),
1603202, 1603202)
	TB (kbkp, false, false, false, (T22<B, P>::IndCalcW), (T22<B, P>::IndCalcB),
5112000, 4981504)
	TB (kbkn, false, false, false, (T22<B, N>::IndCalcW), (T22<B, N>::IndCalcB),
1661823, 1603202)
	TB (kbkb, true,  false, false, (T22<B, B>::IndCalcW), (T22<B, B>::IndCalcB),
1661823, 1661823)
	TB (krkp, false, false, false, (T22<R, P>::IndCalcW), (T22<R, P>::IndCalcB),
5072736, 4981504)
	TB (krkn, false, false, false, (T22<R, N>::IndCalcW), (T22<R, N>::IndCalcB),
1649196, 1603202)
	TB (krkb, false, false, false, (T22<R, B>::IndCalcW), (T22<R, B>::IndCalcB),
1649196, 1661823)
	TB (krkr, true,  false, false, (T22<R, R>::IndCalcW), (T22<R, R>::IndCalcB),
1649196, 1649196)
	TB (kqkp, false, false, false, (T22<Q, P>::IndCalcW), (T22<Q, P>::IndCalcB),
4810080, 4981504)
	TB (kqkn, false, false, false, (T22<Q, N>::IndCalcW), (T22<Q, N>::IndCalcB),
1563735, 1603202)
	TB (kqkb, false, false, false, (T22<Q, B>::IndCalcW), (T22<Q, B>::IndCalcB),
1563735, 1661823)
	TB (kqkr, false, false, false, (T22<Q, R>::IndCalcW), (T22<Q, R>::IndCalcB),
1563735, 1649196)
	TB (kqkq, true,  false, false, (T22<Q, Q>::IndCalcW), (T22<Q, Q>::IndCalcB),
1563735, 1563735)
	TB (kppk, false, false, false, (T31<P, P>::IndCalcW), (T31<P, P>::IndCalcB),
1806671, 1912372)
	TB (knpk, false, false, false, (T31<N, P>::IndCalcW), (T31<N, P>::IndCalcB),
4648581, 5124732)
	TB (knnk, false, false, false, (T31<N, N>::IndCalcW), (T31<N, N>::IndCalcB),
735304,  873642)
	TB (kbpk, false, false, false, (T31<B, P>::IndCalcW), (T31<B, P>::IndCalcB),
4817128, 5124732)
	TB (kbnk, false, false, false, (T31<B, N>::IndCalcW), (T31<B, N>::IndCalcB),
1550620, 1747284)
	TB (kbbk, false, false, false, (T31<B, B>::IndCalcW), (T31<B, B>::IndCalcB),
789885,  873642)
	TB (krpk, false, false, false, (T31<R, P>::IndCalcW), (T31<R, P>::IndCalcB),
4779530, 5124732)
	TB (krnk, false, false, false, (T31<R, N>::IndCalcW), (T31<R, N>::IndCalcB),
1538479, 1747284)
	TB (krbk, false, false, false, (T31<R, B>::IndCalcW), (T31<R, B>::IndCalcB),
1594560, 1747284)
	TB (krrk, false, false, false, (T31<R, R>::IndCalcW), (T31<R, R>::IndCalcB),
777300,  873642)
	TB (kqpk, false, false, false, (T31<Q, P>::IndCalcW), (T31<Q, P>::IndCalcB),
4533490, 5124732)
	TB (kqnk, false, false, false, (T31<Q, N>::IndCalcW), (T31<Q, N>::IndCalcB),
1459616, 1747284)
	TB (kqbk, false, false, false, (T31<Q, B>::IndCalcW), (T31<Q, B>::IndCalcB),
1512507, 1747284)
	TB (kqrk, false, false, false, (T31<Q, R>::IndCalcW), (T31<Q, R>::IndCalcB),
1500276, 1747284)
	TB (kqqk, false, false, false, (T31<Q, Q>::IndCalcW), (T31<Q, Q>::IndCalcB),
698739,  873642)

#if !defined (KPPKP_16BIT)
	TB (kppkp, false, false, false, (T32<P, P, P>::IndCalcW), (T32<P, P,
P>::IndCalcB),  84219361,  89391280)
#else
	TB (kppkp, false, true,  false, (T32<P, P, P>::IndCalcW), (T32<P, P,
P>::IndCalcB),  84219361,  89391280)
#endif
	TB (kppkn, false, false, false, (T32<P, P, N>::IndCalcW), (T32<P, P,
N>::IndCalcB), 108400260, 115899744)
	TB (kppkb, false, false, false, (T32<P, P, B>::IndCalcW), (T32<P, P,
B>::IndCalcB), 108400260, 120132000)
	TB (kppkr, false, false, false, (T32<P, P, R>::IndCalcW), (T32<P, P,
R>::IndCalcB), 108400260, 119209296)
	TB (kppkq, false, false, false, (T32<P, P, Q>::IndCalcW), (T32<P, P,
Q>::IndCalcB), 108400260, 113036880)
	TB (knpkp, false, false, false, (T32<N, P, P>::IndCalcW), (T32<N, P,
P>::IndCalcB), 219921779, 231758952)
	TB (knpkn, false, false, false, (T32<N, P, N>::IndCalcW), (T32<N, P,
N>::IndCalcB), 278914860, 295914240)
	TB (knpkb, false, false, false, (T32<N, P, B>::IndCalcW), (T32<N, P,
B>::IndCalcB), 278914860, 306720000)
	TB (knpkr, false, false, false, (T32<N, P, R>::IndCalcW), (T32<N, P,
R>::IndCalcB), 278914860, 304369920)
	TB (knpkq, false, false, false, (T32<N, P, Q>::IndCalcW), (T32<N, P,
Q>::IndCalcB), 278914860, 288610560)
	TB (knnkp, false, false, false, (T32<N, N, P>::IndCalcW), (T32<N, N,
P>::IndCalcB), 137991648, 149445120)
	TB (knnkn, false, false, false, (T32<N, N, N>::IndCalcW), (T32<N, N,
N>::IndCalcB),  44118240,  48096060)
	TB (knnkb, false, false, false, (T32<N, N, B>::IndCalcW), (T32<N, N,
B>::IndCalcB),  44118240,  49854690)
	TB (knnkr, false, false, false, (T32<N, N, R>::IndCalcW), (T32<N, N,
R>::IndCalcB),  44118240,  49475880)
	TB (knnkq, false, false, false, (T32<N, N, Q>::IndCalcW), (T32<N, N,
Q>::IndCalcB),  44118240,  46912050)
	TB (kbpkp, false, false, false, (T32<B, P, P>::IndCalcW), (T32<B, P,
P>::IndCalcB), 227896016, 231758952)
	TB (kbpkn, false, false, false, (T32<B, P, N>::IndCalcW), (T32<B, P,
N>::IndCalcB), 289027680, 295914240)
	TB (kbpkb, false, false, false, (T32<B, P, B>::IndCalcW), (T32<B, P,
B>::IndCalcB), 289027680, 306720000)
	TB (kbpkr, false, false, false, (T32<B, P, R>::IndCalcW), (T32<B, P,
R>::IndCalcB), 289027680, 304369920)
	TB (kbpkq, false, false, false, (T32<B, P, Q>::IndCalcW), (T32<B, P,
Q>::IndCalcB), 289027680, 288610560)
	TB (kbnkp, false, false, false, (T32<B, N, P>::IndCalcW), (T32<B, N,
P>::IndCalcB), 290989584, 298890240)
	TB (kbnkn, false, false, false, (T32<B, N, N>::IndCalcW), (T32<B, N,
N>::IndCalcB),  93037200,  96192120)
	TB (kbnkb, false, false, false, (T32<B, N, B>::IndCalcW), (T32<B, N,
B>::IndCalcB),  93037200,  99709380)
	TB (kbnkr, false, false, false, (T32<B, N, R>::IndCalcW), (T32<B, N,
R>::IndCalcB),  93037200,  98951760)
	TB (kbnkq, false, false, false, (T32<B, N, Q>::IndCalcW), (T32<B, N,
Q>::IndCalcB),  93037200,  93824100)
	TB (kbbkp, false, false, false, (T32<B, B, P>::IndCalcW), (T32<B, B,
P>::IndCalcB), 148223520, 149445120)
	TB (kbbkn, false, false, false, (T32<B, B, N>::IndCalcW), (T32<B, B,
N>::IndCalcB),  47393100,  48096060)
	TB (kbbkb, false, false, false, (T32<B, B, B>::IndCalcW), (T32<B, B,
B>::IndCalcB),  47393100,  49854690)
	TB (kbbkr, false, false, false, (T32<B, B, R>::IndCalcW), (T32<B, B,
R>::IndCalcB),  47393100,  49475880)
	TB (kbbkq, false, false, false, (T32<B, B, Q>::IndCalcW), (T32<B, B,
Q>::IndCalcB),  47393100,  46912050)
	TB (krpkp, false, false, false, (T32<R, P, P>::IndCalcW), (T32<R, P,
P>::IndCalcB), 226121876, 231758952)
	TB (krpkn, false, false, false, (T32<R, P, N>::IndCalcW), (T32<R, P,
N>::IndCalcB), 286777440, 295914240)
	TB (krpkb, false, false, false, (T32<R, P, B>::IndCalcW), (T32<R, P,
B>::IndCalcB), 286777440, 306720000)
	TB (krpkr, false, false, false, (T32<R, P, R>::IndCalcW), (T32<R, P,
R>::IndCalcB), 286777440, 304369920)
	TB (krpkq, false, false, false, (T32<R, P, Q>::IndCalcW), (T32<R, P,
Q>::IndCalcB), 286777440, 288610560)
	TB (krnkp, false, false, false, (T32<R, N, P>::IndCalcW), (T32<R, N,
P>::IndCalcB), 288692928, 298890240)
	TB (krnkn, false, false, false, (T32<R, N, N>::IndCalcW), (T32<R, N,
N>::IndCalcB),  92308740,  96192120)
	TB (krnkb, false, false, false, (T32<R, N, B>::IndCalcW), (T32<R, N,
B>::IndCalcB),  92308740,  99709380)
	TB (krnkr, false, false, false, (T32<R, N, R>::IndCalcW), (T32<R, N,
R>::IndCalcB),  92308740,  98951760)
	TB (krnkq, false, false, false, (T32<R, N, Q>::IndCalcW), (T32<R, N,
Q>::IndCalcB),  92308740,  93824100)
	TB (krbkp, false, false, false, (T32<R, B, P>::IndCalcW), (T32<R, B,
P>::IndCalcB), 299203200, 298890240)
	TB (krbkn, false, false, false, (T32<R, B, N>::IndCalcW), (T32<R, B,
N>::IndCalcB),  95673600,  96192120)
	TB (krbkb, false, false, false, (T32<R, B, B>::IndCalcW), (T32<R, B,
B>::IndCalcB),  95673600,  99709380)
	TB (krbkr, false, false, false, (T32<R, B, R>::IndCalcW), (T32<R, B,
R>::IndCalcB),  95673600,  98951760)
	TB (krbkq, false, false, false, (T32<R, B, Q>::IndCalcW), (T32<R, B,
Q>::IndCalcB),  95673600,  93824100)
	TB (krrkp, false, false, false, (T32<R, R, P>::IndCalcW), (T32<R, R,
P>::IndCalcB), 145901232, 149445120)
	TB (krrkn, false, false, false, (T32<R, R, N>::IndCalcW), (T32<R, R,
N>::IndCalcB),  46658340,  48096060)
	TB (krrkb, false, false, false, (T32<R, R, B>::IndCalcW), (T32<R, R,
B>::IndCalcB),  46658340,  49854690)
	TB (krrkr, false, false, false, (T32<R, R, R>::IndCalcW), (T32<R, R,
R>::IndCalcB),  46658340,  49475880)
	TB (krrkq, false, false, false, (T32<R, R, Q>::IndCalcW), (T32<R, R,
Q>::IndCalcB),  46658340,  46912050)
	TB (kqpkp, false, false, false, (T32<Q, P, P>::IndCalcW), (T32<Q, P,
P>::IndCalcB), 214481388, 231758952)
	TB (kqpkn, false, false, false, (T32<Q, P, N>::IndCalcW), (T32<Q, P,
N>::IndCalcB), 272015040, 295914240)
	TB (kqpkb, false, false, false, (T32<Q, P, B>::IndCalcW), (T32<Q, P,
B>::IndCalcB), 272015040, 306720000)
	TB (kqpkr, false, false, false, (T32<Q, P, R>::IndCalcW), (T32<Q, P,
R>::IndCalcB), 272015040, 304369920)
	TB (kqpkq, false, false, false, (T32<Q, P, Q>::IndCalcW), (T32<Q, P,
Q>::IndCalcB), 272015040, 288610560)
	TB (kqnkp, false, false, false, (T32<Q, N, P>::IndCalcW), (T32<Q, N,
P>::IndCalcB), 273904512, 298890240)
	TB (kqnkn, false, false, false, (T32<Q, N, N>::IndCalcW), (T32<Q, N,
N>::IndCalcB),  87576960,  96192120)
	TB (kqnkb, false, false, false, (T32<Q, N, B>::IndCalcW), (T32<Q, N,
B>::IndCalcB),  87576960,  99709380)
	TB (kqnkr, false, false, false, (T32<Q, N, R>::IndCalcW), (T32<Q, N,
R>::IndCalcB),  87576960,  98951760)
	TB (kqnkq, false, false, false, (T32<Q, N, Q>::IndCalcW), (T32<Q, N,
Q>::IndCalcB),  87576960,  93824100)
	TB (kqbkp, false, false, false, (T32<Q, B, P>::IndCalcW), (T32<Q, B,
P>::IndCalcB), 283818240, 298890240)
	TB (kqbkn, false, false, false, (T32<Q, B, N>::IndCalcW), (T32<Q, B,
N>::IndCalcB),  90750420,  96192120)
	TB (kqbkb, false, false, false, (T32<Q, B, B>::IndCalcW), (T32<Q, B,
B>::IndCalcB),  90750420,  99709380)
	TB (kqbkr, false, false, false, (T32<Q, B, R>::IndCalcW), (T32<Q, B,
R>::IndCalcB),  90750420,  98951760)
	TB (kqbkq, false, false, false, (T32<Q, B, Q>::IndCalcW), (T32<Q, B,
Q>::IndCalcB),  90750420,  93824100)
	TB (kqrkp, false, false, false, (T32<Q, R, P>::IndCalcW), (T32<Q, R,
P>::IndCalcB), 281568240, 298890240)
	TB (kqrkn, false, false, false, (T32<Q, R, N>::IndCalcW), (T32<Q, R,
N>::IndCalcB),  90038460,  96192120)
	TB (kqrkb, false, false, false, (T32<Q, R, B>::IndCalcW), (T32<Q, R,
B>::IndCalcB),  90038460,  99709380)
	TB (kqrkr, false, false, false, (T32<Q, R, R>::IndCalcW), (T32<Q, R,
R>::IndCalcB),  90038460,  98951760)
	TB (kqrkq, false, false, false, (T32<Q, R, Q>::IndCalcW), (T32<Q, R,
Q>::IndCalcB),  90038460,  93824100)
	TB (kqqkp, false, false, false, (T32<Q, Q, P>::IndCalcW), (T32<Q, Q,
P>::IndCalcB), 131170128, 149445120)
	TB (kqqkn, false, false, false, (T32<Q, Q, N>::IndCalcW), (T32<Q, Q,
N>::IndCalcB),  41944320,  48096060)
	TB (kqqkb, false, false, false, (T32<Q, Q, B>::IndCalcW), (T32<Q, Q,
B>::IndCalcB),  41944320,  49854690)
	TB (kqqkr, false, false, false, (T32<Q, Q, R>::IndCalcW), (T32<Q, Q,
R>::IndCalcB),  41944320,  49475880)
	TB (kqqkq, false, false, false, (T32<Q, Q, Q>::IndCalcW), (T32<Q, Q,
Q>::IndCalcB),  41944320,  46912050)

#if defined (T41_INCLUDE)
	TB (kpppk, false, false, false, (T41<P, P, P>::IndCalcW), (T41<P, P,
P>::IndCalcB),  26061704,  28388716)
	TB (knppk, false, false, false, (T41<N, P, P>::IndCalcW), (T41<N, P,
P>::IndCalcB), 102898651, 114742320)
	TB (knnpk, false, false, false, (T41<N, N, P>::IndCalcW), (T41<N, N,
P>::IndCalcB), 130135501, 153741960)
	TB (knnnk, false, false, false, (T41<N, N, N>::IndCalcW), (T41<N, N,
N>::IndCalcB),  13486227,  17472840)
	TB (kbppk, false, false, false, (T41<B, P, P>::IndCalcW), (T41<B, P,
P>::IndCalcB), 106602156, 114742320)
	TB (kbnpk, false, false, false, (T41<B, N, P>::IndCalcW), (T41<B, N,
P>::IndCalcB), 274352939, 307483920)
	TB (kbnnk, false, false, false, (T41<B, N, N>::IndCalcW), (T41<B, N,
N>::IndCalcB),  43406294, 52418520)
	TB (kbbpk, false, false, false, (T41<B, B, P>::IndCalcW), (T41<B, B,
P>::IndCalcB), 139715040, 153741960)
	TB (kbbnk, false, false, false, (T41<B, B, N>::IndCalcW), (T41<B, B,
N>::IndCalcB),  44983618,  52418520)
	TB (kbbbk, false, false, false, (T41<B, B, B>::IndCalcW), (T41<B, B,
B>::IndCalcB),  15010230,  17472840)
	TB (krppk, false, false, false, (T41<R, P, P>::IndCalcW), (T41<R, P,
P>::IndCalcB), 105758666, 114742320)
	TB (krnpk, false, false, false, (T41<R, N, P>::IndCalcW), (T41<R, N,
P>::IndCalcB), 272153675, 307483920)
	TB (krnnk, false, false, false, (T41<R, N, N>::IndCalcW), (T41<R, N,
N>::IndCalcB),  43056198,  52418520)
	TB (krbpk, false, false, false, (T41<R, B, P>::IndCalcW), (T41<R, B,
P>::IndCalcB), 281991360, 307483920)
	TB (krbnk, false, false, false, (T41<R, B, N>::IndCalcW), (T41<R, B,
N>::IndCalcB),  90787358, 104837040)
	TB (krbbk, false, false, false, (T41<R, B, B>::IndCalcW), (T41<R, B,
B>::IndCalcB),  46242089,  52418520)
	TB (krrpk, false, false, false, (T41<R, R, P>::IndCalcW), (T41<R, R,
P>::IndCalcB), 137491197, 153741960)
	TB (krrnk, false, false, false, (T41<R, R, N>::IndCalcW), (T41<R, R,
N>::IndCalcB),  44265261,  52418520)
	TB (krrbk, false, false, false, (T41<R, R, B>::IndCalcW), (T41<R, R,
B>::IndCalcB),  45873720,  52418520)
	TB (krrrk, false, false, false, (T41<R, R, R>::IndCalcW), (T41<R, R,
R>::IndCalcB),  14644690,  17472840)
	TB (kqppk, false, false, false, (T41<Q, P, P>::IndCalcW), (T41<Q, P,
P>::IndCalcB), 100347220, 114742320)
	TB (kqnpk, false, false, false, (T41<Q, N, P>::IndCalcW), (T41<Q, N,
P>::IndCalcB), 258294639, 307483920)
	TB (kqnnk, false, false, false, (T41<Q, N, N>::IndCalcW), (T41<Q, N,
N>::IndCalcB),  40873646,  52418520)
	TB (kqbpk, false, false, false, (T41<Q, B, P>::IndCalcW), (T41<Q, B,
P>::IndCalcB), 267576632, 307483920)
	TB (kqbnk, false, false, false, (T41<Q, B, N>::IndCalcW), (T41<Q, B,
N>::IndCalcB),  86166717, 104837040)
	TB (kqbbk, false, false, false, (T41<Q, B, B>::IndCalcW), (T41<Q, B,
B>::IndCalcB),  43879679,  52418520)
	TB (kqrpk, false, false, false, (T41<Q, R, P>::IndCalcW), (T41<Q, R,
P>::IndCalcB), 265421907, 307483920)
	TB (kqrnk, false, false, false, (T41<Q, R, N>::IndCalcW), (T41<Q, R,
N>::IndCalcB),  85470603, 104837040)
	TB (kqrbk, false, false, false, (T41<Q, R, B>::IndCalcW), (T41<Q, R,
B>::IndCalcB),  88557959, 104837040)
	TB (kqrrk, false, false, false, (T41<Q, R, R>::IndCalcW), (T41<Q, R,
R>::IndCalcB),  43157690,  52418520)
	TB (kqqpk, false, false, false, (T41<Q, Q, P>::IndCalcW), (T41<Q, Q,
P>::IndCalcB), 123688859, 153741960)
	TB (kqqnk, false, false, false, (T41<Q, Q, N>::IndCalcW), (T41<Q, Q,
N>::IndCalcB),  39840787,  52418520)
	TB (kqqbk, false, false, false, (T41<Q, Q, B>::IndCalcW), (T41<Q, Q,
B>::IndCalcB),  41270973,  52418520)
	TB (kqqrk, false, false, false, (T41<Q, Q, R>::IndCalcW), (T41<Q, Q,
R>::IndCalcB),  40916820,  52418520)
	TB (kqqqk, false, false, false, (T41<Q, Q, Q>::IndCalcW), (T41<Q, Q,
Q>::IndCalcB),  12479974,  17472840)
#endif

#if defined (T33_INCLUDE)
	TB (knnknn, true,  false, false, (T33<N, N, N, N>::IndCalcW), (T33<N, N, N,
N>::IndCalcB),  1301488080,  1301488080)
	TB (kbnknn, false, false, false, (T33<B, N, N, N>::IndCalcW), (T33<B, N, N,
N>::IndCalcB),  2744597400,  2602976160)
	TB (kbbknn, false, false, false, (T33<B, B, N, N>::IndCalcW), (T33<B, B, N,
N>::IndCalcB),  1398096450,  1301488080)
	TB (kbbkbn, false, false, false, (T33<B, B, B, N>::IndCalcW), (T33<B, B, B,
N>::IndCalcB),  2796192900,  2744597400)
	TB (kbbkbb, true,  false, false, (T33<B, B, B, B>::IndCalcW), (T33<B, B, B,
B>::IndCalcB),  1398096450,  1398096450)
	TB (krnknn, false, true,  false, (T33<R, N, N, N>::IndCalcW), (T33<R, N, N,
N>::IndCalcB),  2723107830,  2602976160)
	TB (krnkbb, false, true,  false, (T33<R, N, B, B>::IndCalcW), (T33<R, N, B,
B>::IndCalcB),  2723107830,  2796192900)
	TB (krbknn, false, true,  false, (T33<R, B, N, N>::IndCalcW), (T33<R, B, N,
N>::IndCalcB),  2822371200,  2602976160)
	TB (krbkbb, false, false, false, (T33<R, B, B, B>::IndCalcW), (T33<R, B, B,
B>::IndCalcB),  2822371200,  2796192900)
	TB (krrknn, false, false, false, (T33<R, R, N, N>::IndCalcW), (T33<R, R, N,
N>::IndCalcB),  1376421030,  1301488080)
	TB (krrkbn, false, false, false, (T33<R, R, B, N>::IndCalcW), (T33<R, R, B,
N>::IndCalcB),  2752842060,  2744597400)
	TB (krrkbb, false, false, false, (T33<R, R, B, B>::IndCalcW), (T33<R, R, B,
B>::IndCalcB),  1376421030,  1398096450)
	TB (krrkrn, false, false, false, (T33<R, R, R, N>::IndCalcW), (T33<R, R, R,
N>::IndCalcB),  2752842060,  2723107830)
	TB (krrkrb, false, false, false, (T33<R, R, R, B>::IndCalcW), (T33<R, R, R,
B>::IndCalcB),  2752842060,  2822371200)
	TB (krrkrr, true,  false, false, (T33<R, R, R, R>::IndCalcW), (T33<R, R, R,
R>::IndCalcB),  1376421030,  1376421030)
	TB (kqnknn, false, false, false, (T33<Q, N, N, N>::IndCalcW), (T33<Q, N, N,
N>::IndCalcB),  2583520320,  2602976160)
	TB (kqnkbb, false, false, false, (T33<Q, N, B, B>::IndCalcW), (T33<Q, N, B,
B>::IndCalcB),  2583520320,  2796192900)
	TB (kqnkrr, false, true,  false, (T33<Q, N, R, R>::IndCalcW), (T33<Q, N, R,
R>::IndCalcB),  2583520320,  2752842060)
	TB (kqbknn, false, false, false, (T33<Q, B, N, N>::IndCalcW), (T33<Q, B, N,
N>::IndCalcB),  2677137390,  2602976160)
	TB (kqbkbb, false, false, false, (T33<Q, B, B, B>::IndCalcW), (T33<Q, B, B,
B>::IndCalcB),  2677137390,  2796192900)
	TB (kqbkrr, false, false, false, (T33<Q, B, R, R>::IndCalcW), (T33<Q, B, R,
R>::IndCalcB),  2677137390,  2752842060)
	TB (kqrknn, false, false, false, (T33<Q, R, N, N>::IndCalcW), (T33<Q, R, N,
N>::IndCalcB),  2656134570,  2602976160)
	TB (kqrkbb, false, false, false, (T33<Q, R, B, B>::IndCalcW), (T33<Q, R, B,
B>::IndCalcB),  2656134570,  2796192900)
	TB (kqrkrr, false, false, false, (T33<Q, R, R, R>::IndCalcW), (T33<Q, R, R,
R>::IndCalcB),  2656134570,  2752842060)
	TB (kqqknn, false, false, false, (T33<Q, Q, N, N>::IndCalcW), (T33<Q, Q, N,
N>::IndCalcB),  1237357440,  1301488080)
	TB (kqqkbn, false, false, false, (T33<Q, Q, B, N>::IndCalcW), (T33<Q, Q, B,
N>::IndCalcB),  2474714880,  2744597400)
	TB (kqqkbb, false, false, false, (T33<Q, Q, B, B>::IndCalcW), (T33<Q, Q, B,
B>::IndCalcB),  1237357440,  1398096450)
	TB (kqqkrn, false, false, false, (T33<Q, Q, R, N>::IndCalcW), (T33<Q, Q, R,
N>::IndCalcB),  2474714880,  2723107830)
	TB (kqqkrb, false, false, false, (T33<Q, Q, R, B>::IndCalcW), (T33<Q, Q, R,
B>::IndCalcB),  2474714880,  2822371200)
	TB (kqqkrr, false, false, false, (T33<Q, Q, R, R>::IndCalcW), (T33<Q, Q, R,
R>::IndCalcB),  1237357440,  1376421030)
	TB (kqqkqn, false, false, false, (T33<Q, Q, Q, N>::IndCalcW), (T33<Q, Q, Q,
N>::IndCalcB),  2474714880,  2583520320)
	TB (kqqkqb, false, false, false, (T33<Q, Q, Q, B>::IndCalcW), (T33<Q, Q, Q,
B>::IndCalcB),  2474714880,  2677137390)
	TB (kqqkqr, false, false, false, (T33<Q, Q, Q, R>::IndCalcW), (T33<Q, Q, Q,
R>::IndCalcB),  2474714880,  2656134570)
	TB (kqqkqq, true,  false, false, (T33<Q, Q, Q, Q>::IndCalcW), (T33<Q, Q, Q,
Q>::IndCalcB),  1237357440,  1237357440)
#if defined (T_INDEX64)
	TB (kbnkbn, true,  false, false, (T33<B, N, B, N>::IndCalcW), (T33<B, N, B,
N>::IndCalcB),  5489194800,  5489194800)
	TB (krnkrn, true,  false, false, (T33<R, N, R, N>::IndCalcW), (T33<R, N, R,
N>::IndCalcB),  5446215660,  5446215660)
	TB (krbkrb, true,  false, false, (T33<R, B, R, B>::IndCalcW), (T33<R, B, R,
B>::IndCalcB),  5644742400,  5644742400)
	TB (kqnkqn, true,  false, false, (T33<Q, N, Q, N>::IndCalcW), (T33<Q, N, Q,
N>::IndCalcB),  5167040640,  5167040640)
	TB (kqbkqb, true,  false, false, (T33<Q, B, Q, B>::IndCalcW), (T33<Q, B, Q,
B>::IndCalcB),  5354274780,  5354274780)
	TB (kqrkqr, true,  false, false, (T33<Q, R, Q, R>::IndCalcW), (T33<Q, R, Q,
R>::IndCalcB),  5312269140,  5312269140)
	TB (krnkbn, false, true,  true,  (T33<R, N, B, N>::IndCalcW), (T33<R, N, B,
N>::IndCalcB),  5446215660,  5489194800)
	TB (krbkbn, false, false, true,  (T33<R, B, B, N>::IndCalcW), (T33<R, B, B,
N>::IndCalcB),  5644742400,  5489194800)
	TB (krbkrn, false, false, false, (T33<R, B, R, N>::IndCalcW), (T33<R, B, R,
N>::IndCalcB),  5644742400,  5446215660)
	TB (kqnkbn, false, false, false, (T33<Q, N, B, N>::IndCalcW), (T33<Q, N, B,
N>::IndCalcB),  5167040640,  5489194800)
	TB (kqnkrn, false, false, true,  (T33<Q, N, R, N>::IndCalcW), (T33<Q, N, R,
N>::IndCalcB),  5167040640,  5446215660)
	TB (kqnkrb, false, false, true,  (T33<Q, N, R, B>::IndCalcW), (T33<Q, N, R,
B>::IndCalcB),  5167040640,  5644742400)
	TB (kqbkbn, false, false, false, (T33<Q, B, B, N>::IndCalcW), (T33<Q, B, B,
N>::IndCalcB),  5354274780,  5489194800)
	TB (kqbkrn, false, false, true,  (T33<Q, B, R, N>::IndCalcW), (T33<Q, B, R,
N>::IndCalcB),  5354274780,  5446215660)
	TB (kqbkrb, false, false, true,  (T33<Q, B, R, B>::IndCalcW), (T33<Q, B, R,
B>::IndCalcB),  5354274780,  5644742400)
	TB (kqbkqn, false, false, false, (T33<Q, B, Q, N>::IndCalcW), (T33<Q, B, Q,
N>::IndCalcB),  5354274780,  5167040640)
	TB (kqrkbn, false, false, false, (T33<Q, R, B, N>::IndCalcW), (T33<Q, R, B,
N>::IndCalcB),  5312269140,  5489194800)
	TB (kqrkrn, false, false, false, (T33<Q, R, R, N>::IndCalcW), (T33<Q, R, R,
N>::IndCalcB),  5312269140,  5446215660)
	TB (kqrkrb, false, false, false, (T33<Q, R, R, B>::IndCalcW), (T33<Q, R, R,
B>::IndCalcB),  5312269140,  5644742400)
	TB (kqrkqn, false, false, false, (T33<Q, R, Q, N>::IndCalcW), (T33<Q, R, Q,
N>::IndCalcB),  5312269140,  5167040640)
	TB (kqrkqb, false, false, false, (T33<Q, R, Q, B>::IndCalcW), (T33<Q, R, Q,
B>::IndCalcB),  5312269140,  5354274780)
#endif
#endif

#if defined (T42_INCLUDE)
	TB (knnnkn, false, false, false, (T42<N, N, N, N>::IndCalcW), (T42<N, N, N,
N>::IndCalcB),  795687393,  945889180)
	TB (kbnnkn, false, false, false, (T42<B, N, N, N>::IndCalcW), (T42<B, N, N,
N>::IndCalcB), 2560971346, 2837667540)
	TB (kbbnkn, false, false, false, (T42<B, B, N, N>::IndCalcW), (T42<B, B, N,
N>::IndCalcB), 2654033462, 2837667540)
	TB (kbbbkn, false, false, false, (T42<B, B, B, N>::IndCalcW), (T42<B, B, B,
N>::IndCalcB),  885603570,  945889180)
	TB (krnnkn, false, false, false, (T42<R, N, N, N>::IndCalcW), (T42<R, N, N,
N>::IndCalcB), 2540315682, 2837667540)
	TB (krbbkn, false, false, false, (T42<R, B, B, N>::IndCalcW), (T42<R, B, B,
N>::IndCalcB), 2728283251, 2837667540)
	TB (krrnkn, false, false, false, (T42<R, R, N, N>::IndCalcW), (T42<R, R, N,
N>::IndCalcB), 2611650399, 2837667540)
	TB (krrbkn, false, false, false, (T42<R, R, B, N>::IndCalcW), (T42<R, R, B,
N>::IndCalcB), 2706549480, 2837667540)
	TB (krrrkn, false, false, false, (T42<R, R, R, N>::IndCalcW), (T42<R, R, R,
N>::IndCalcB),  864592254,  945889180)
	TB (kqnnkn, false, false, false, (T42<Q, N, N, N>::IndCalcW), (T42<Q, N, N,
N>::IndCalcB), 2411545114, 2837667540)
	TB (kqbbkn, false, false, false, (T42<Q, B, B, N>::IndCalcW), (T42<Q, B, B,
N>::IndCalcB), 2588901061, 2837667540)
	TB (kqrrkn, false, false, false, (T42<Q, R, R, N>::IndCalcW), (T42<Q, R, R,
N>::IndCalcB), 2547484064, 2837667540)
	TB (kqqnkn, false, false, false, (T42<Q, Q, N, N>::IndCalcW), (T42<Q, Q, N,
N>::IndCalcB), 2350606433, 2837667540)
	TB (kqqbkn, false, false, false, (T42<Q, Q, B, N>::IndCalcW), (T42<Q, Q, B,
N>::IndCalcB), 2434987407, 2837667540)
	TB (kqqrkn, false, false, false, (T42<Q, Q, R, N>::IndCalcW), (T42<Q, Q, R,
N>::IndCalcB), 2415271436, 2837667540)
	TB (kqqqkn, false, false, false, (T42<Q, Q, Q, N>::IndCalcW), (T42<Q, Q, Q,
N>::IndCalcB),  736854363,  945889180)
	TB (knnnkb, false, false, false, (T42<N, N, N, B>::IndCalcW), (T42<N, N, N,
B>::IndCalcB),  795687393,  980475570)
	TB (kbnnkb, false, false, false, (T42<B, N, N, B>::IndCalcW), (T42<B, N, N,
B>::IndCalcB), 2560971346, 2941426710)
	TB (kbbnkb, false, false, false, (T42<B, B, N, B>::IndCalcW), (T42<B, B, N,
B>::IndCalcB), 2654033462, 2941426710)
	TB (kbbbkb, false, false, false, (T42<B, B, B, B>::IndCalcW), (T42<B, B, B,
B>::IndCalcB),  885603570,  980475570)
	TB (krnnkb, false, false, false, (T42<R, N, N, B>::IndCalcW), (T42<R, N, N,
B>::IndCalcB), 2540315682, 2941426710)
	TB (krbbkb, false, false, false, (T42<R, B, B, B>::IndCalcW), (T42<R, B, B,
B>::IndCalcB), 2728283251, 2941426710)
	TB (krrnkb, false, false, false, (T42<R, R, N, B>::IndCalcW), (T42<R, R, N,
B>::IndCalcB), 2611650399, 2941426710)
	TB (krrbkb, false, false, false, (T42<R, R, B, B>::IndCalcW), (T42<R, R, B,
B>::IndCalcB), 2706549480, 2941426710)
	TB (krrrkb, false, false, false, (T42<R, R, R, B>::IndCalcW), (T42<R, R, R,
B>::IndCalcB),  864592254,  980475570)
	TB (kqnnkb, false, false, false, (T42<Q, N, N, B>::IndCalcW), (T42<Q, N, N,
B>::IndCalcB), 2411545114, 2941426710)
	TB (kqbbkb, false, false, false, (T42<Q, B, B, B>::IndCalcW), (T42<Q, B, B,
B>::IndCalcB), 2588901061, 2941426710)
	TB (kqrrkb, false, false, false, (T42<Q, R, R, B>::IndCalcW), (T42<Q, R, R,
B>::IndCalcB), 2547484064, 2941426710)
	TB (kqqnkb, false, false, false, (T42<Q, Q, N, B>::IndCalcW), (T42<Q, Q, N,
B>::IndCalcB), 2350606433, 2941426710)
	TB (kqqbkb, false, false, false, (T42<Q, Q, B, B>::IndCalcW), (T42<Q, Q, B,
B>::IndCalcB), 2434987407, 2941426710)
	TB (kqqrkb, false, false, false, (T42<Q, Q, R, B>::IndCalcW), (T42<Q, Q, R,
B>::IndCalcB), 2415271436, 2941426710)
	TB (kqqqkb, false, false, false, (T42<Q, Q, Q, B>::IndCalcW), (T42<Q, Q, Q,
B>::IndCalcB),  736854363,  980475570)
	TB (knnnkr, false, false, false, (T42<N, N, N, R>::IndCalcW), (T42<N, N, N,
R>::IndCalcB),  795687393,  973025640)
	TB (kbnnkr, false, false, false, (T42<B, N, N, R>::IndCalcW), (T42<B, N, N,
R>::IndCalcB), 2560971346, 2919076920)
	TB (kbbnkr, false, false, false, (T42<B, B, N, R>::IndCalcW), (T42<B, B, N,
R>::IndCalcB), 2654033462, 2919076920)
	TB (kbbbkr, false, false, false, (T42<B, B, B, R>::IndCalcW), (T42<B, B, B,
R>::IndCalcB),  885603570,  973025640)
	TB (krnnkr, false, false, false, (T42<R, N, N, R>::IndCalcW), (T42<R, N, N,
R>::IndCalcB), 2540315682, 2919076920)
	TB (krbbkr, false, false, false, (T42<R, B, B, R>::IndCalcW), (T42<R, B, B,
R>::IndCalcB), 2728283251, 2919076920)
	TB (krrnkr, false, false, false, (T42<R, R, N, R>::IndCalcW), (T42<R, R, N,
R>::IndCalcB), 2611650399, 2919076920)
	TB (krrbkr, false, false, false, (T42<R, R, B, R>::IndCalcW), (T42<R, R, B,
R>::IndCalcB), 2706549480, 2919076920)
	TB (krrrkr, false, false, false, (T42<R, R, R, R>::IndCalcW), (T42<R, R, R,
R>::IndCalcB),  864592254,  973025640)
	TB (kqnnkr, false, false, false, (T42<Q, N, N, R>::IndCalcW), (T42<Q, N, N,
R>::IndCalcB), 2411545114, 2919076920)
	TB (kqbbkr, false, false, false, (T42<Q, B, B, R>::IndCalcW), (T42<Q, B, B,
R>::IndCalcB), 2588901061, 2919076920)
	TB (kqrrkr, false, false, false, (T42<Q, R, R, R>::IndCalcW), (T42<Q, R, R,
R>::IndCalcB), 2547484064, 2919076920)
	TB (kqqnkr, false, false, false, (T42<Q, Q, N, R>::IndCalcW), (T42<Q, Q, N,
R>::IndCalcB), 2350606433, 2919076920)
	TB (kqqbkr, false, false, false, (T42<Q, Q, B, R>::IndCalcW), (T42<Q, Q, B,
R>::IndCalcB), 2434987407, 2919076920)
	TB (kqqrkr, false, false, false, (T42<Q, Q, R, R>::IndCalcW), (T42<Q, Q, R,
R>::IndCalcB), 2415271436, 2919076920)
	TB (kqqqkr, false, false, false, (T42<Q, Q, Q, R>::IndCalcW), (T42<Q, Q, Q,
R>::IndCalcB),  736854363,  973025640)
	TB (knnnkq, false, false, false, (T42<N, N, N, Q>::IndCalcW), (T42<N, N, N,
Q>::IndCalcB),  795687393,  922603650)
	TB (kbnnkq, false, false, false, (T42<B, N, N, Q>::IndCalcW), (T42<B, N, N,
Q>::IndCalcB), 2560971346, 2767810950)
	TB (kbbnkq, false, false, false, (T42<B, B, N, Q>::IndCalcW), (T42<B, B, N,
Q>::IndCalcB), 2654033462, 2767810950)
	TB (kbbbkq, false, false, false, (T42<B, B, B, Q>::IndCalcW), (T42<B, B, B,
Q>::IndCalcB),  885603570,  922603650)
	TB (krnnkq, false, false, false, (T42<R, N, N, Q>::IndCalcW), (T42<R, N, N,
Q>::IndCalcB), 2540315682, 2767810950)
	TB (krbbkq, false, false, false, (T42<R, B, B, Q>::IndCalcW), (T42<R, B, B,
Q>::IndCalcB), 2728283251, 2767810950)
	TB (krrnkq, false, false, false, (T42<R, R, N, Q>::IndCalcW), (T42<R, R, N,
Q>::IndCalcB), 2611650399, 2767810950)
	TB (krrbkq, false, false, false, (T42<R, R, B, Q>::IndCalcW), (T42<R, R, B,
Q>::IndCalcB), 2706549480, 2767810950)
	TB (krrrkq, false, false, false, (T42<R, R, R, Q>::IndCalcW), (T42<R, R, R,
Q>::IndCalcB),  864592254,  922603650)
	TB (kqnnkq, false, false, false, (T42<Q, N, N, Q>::IndCalcW), (T42<Q, N, N,
Q>::IndCalcB), 2411545114, 2767810950)
	TB (kqbbkq, false, false, false, (T42<Q, B, B, Q>::IndCalcW), (T42<Q, B, B,
Q>::IndCalcB), 2588901061, 2767810950)
	TB (kqrrkq, false, false, false, (T42<Q, R, R, Q>::IndCalcW), (T42<Q, R, R,
Q>::IndCalcB), 2547484064, 2767810950)
	TB (kqqnkq, false, false, false, (T42<Q, Q, N, Q>::IndCalcW), (T42<Q, Q, N,
Q>::IndCalcB), 2350606433, 2767810950)
	TB (kqqbkq, false, false, false, (T42<Q, Q, B, Q>::IndCalcW), (T42<Q, Q, B,
Q>::IndCalcB), 2434987407, 2767810950)
	TB (kqqrkq, false, false, false, (T42<Q, Q, R, Q>::IndCalcW), (T42<Q, Q, R,
Q>::IndCalcB), 2415271436, 2767810950)
	TB (kqqqkq, false, false, false, (T42<Q, Q, Q, Q>::IndCalcW), (T42<Q, Q, Q,
Q>::IndCalcB),  736854363,  922603650)
#if defined (T_INDEX64)
	TB (krbnkn, false, false, false, (T42<R, B, N, N>::IndCalcW), (T42<R, B, N,
N>::IndCalcB), 5356454122, 5675335080)
	TB (kqbnkn, false, false, false, (T42<Q, B, N, N>::IndCalcW), (T42<Q, B, N,
N>::IndCalcB), 5083836303, 5675335080)
	TB (kqrnkn, false, false, false, (T42<Q, R, N, N>::IndCalcW), (T42<Q, R, N,
N>::IndCalcB), 5042765577, 5675335080)
	TB (kqrbkn, false, false, false, (T42<Q, R, B, N>::IndCalcW), (T42<Q, R, B,
N>::IndCalcB), 5224919581, 5675335080)
	TB (krbnkb, false, false, false, (T42<R, B, N, B>::IndCalcW), (T42<R, B, N,
B>::IndCalcB), 5356454122, 5882853420)
	TB (kqbnkb, false, false, false, (T42<Q, B, N, B>::IndCalcW), (T42<Q, B, N,
B>::IndCalcB), 5083836303, 5882853420)
	TB (kqrnkb, false, false, false, (T42<Q, R, N, B>::IndCalcW), (T42<Q, R, N,
B>::IndCalcB), 5042765577, 5882853420)
	TB (kqrbkb, false, false, false, (T42<Q, R, B, B>::IndCalcW), (T42<Q, R, B,
B>::IndCalcB), 5224919581, 5882853420)
	TB (krbnkr, false, false, false, (T42<R, B, N, R>::IndCalcW), (T42<R, B, N,
R>::IndCalcB), 5356454122, 5838153840)
	TB (kqbnkr, false, false, false, (T42<Q, B, N, R>::IndCalcW), (T42<Q, B, N,
R>::IndCalcB), 5083836303, 5838153840)
	TB (kqrnkr, false, false, false, (T42<Q, R, N, R>::IndCalcW), (T42<Q, R, N,
R>::IndCalcB), 5042765577, 5838153840)
	TB (kqrbkr, false, false, false, (T42<Q, R, B, R>::IndCalcW), (T42<Q, R, B,
R>::IndCalcB), 5224919581, 5838153840)
	TB (krbnkq, false, false, false, (T42<R, B, N, Q>::IndCalcW), (T42<R, B, N,
Q>::IndCalcB), 5356454122, 5535621900)
	TB (kqbnkq, false, false, true,  (T42<Q, B, N, Q>::IndCalcW), (T42<Q, B, N,
Q>::IndCalcB), 5083836303, 5535621900)
	TB (kqrnkq, false, false, false, (T42<Q, R, N, Q>::IndCalcW), (T42<Q, R, N,
Q>::IndCalcB), 5042765577, 5535621900)
	TB (kqrbkq, false, false, false, (T42<Q, R, B, Q>::IndCalcW), (T42<Q, R, B,
Q>::IndCalcB), 5224919581, 5535621900)

	TB (kpppkp, false, false, false, (T42<P, P, P, P>::IndCalcW), (T42<P, P, P,
P>::IndCalcB),  1196632735,  1349124426)
	TB (knppkp, false, false, true,  (T42<N, P, P, P>::IndCalcW), (T42<N, P, P,
P>::IndCalcB),  4796630713,  5271860528)
	TB (knnpkp, false, false, true,  (T42<N, N, P, P>::IndCalcW), (T42<N, N, P,
P>::IndCalcB),  6156616111,  6835422612)
	TB (knnnkp, false, false, false, (T42<N, N, N, P>::IndCalcW), (T42<N, N, N,
P>::IndCalcB),  2531022144,  2939087360)
	TB (kbppkp, false, false, true,  (T42<B, P, P, P>::IndCalcW), (T42<B, P, P,
P>::IndCalcB),  4969303175,  5271860528)
	TB (kbnpkp, false, false, true,  (T42<B, N, P, P>::IndCalcW), (T42<B, N, P,
P>::IndCalcB), 12979462304, 13670845224)
	TB (kbnnkp, false, false, true,  (T42<B, N, N, P>::IndCalcW), (T42<B, N, N,
P>::IndCalcB),  8146120416,  8817262080)
	TB (kbbpkp, false, false, true,  (T42<B, B, P, P>::IndCalcW), (T42<B, B, P,
P>::IndCalcB),  6609838740,  6835422612)
	TB (kbbnkp, false, false, true,  (T42<B, B, N, P>::IndCalcW), (T42<B, B, N,
P>::IndCalcB),  8441899104,  8817262080)
	TB (kbbbkp, false, false, false, (T42<B, B, B, P>::IndCalcW), (T42<B, B, B,
P>::IndCalcB),  2816801280,  2939087360)
	TB (krppkp, false, false, true,  (T42<R, P, P, P>::IndCalcW), (T42<R, P, P,
P>::IndCalcB),  4929998839,  5271860528)
	TB (krnpkp, false, false, true,  (T42<R, N, P, P>::IndCalcW), (T42<R, N, P,
P>::IndCalcB), 12875424829, 13670845224)
	TB (krnnkp, false, false, true,  (T42<R, N, N, P>::IndCalcW), (T42<R, N, N,
P>::IndCalcB),  8079921360,  8817262080)
	TB (krbpkp, false, false, true,  (T42<R, B, P, P>::IndCalcW), (T42<R, B, P,
P>::IndCalcB), 13340861520, 13670845224)
	TB (krbnkp, false, false, true,  (T42<R, B, N, P>::IndCalcW), (T42<R, B, N,
P>::IndCalcB), 17036639904, 17634524160)
	TB (krbbkp, false, false, true,  (T42<R, B, B, P>::IndCalcW), (T42<R, B, B,
P>::IndCalcB),  8677177872,  8817262080)
	TB (krrpkp, false, false, true,  (T42<R, R, P, P>::IndCalcW), (T42<R, R, P,
P>::IndCalcB),  6504899238,  6835422612)
	TB (krrnkp, false, false, true,  (T42<R, R, N, P>::IndCalcW), (T42<R, R, N,
P>::IndCalcB),  8306047872,  8817262080)
	TB (krrbkp, false, false, true,  (T42<R, R, B, P>::IndCalcW), (T42<R, R, B,
P>::IndCalcB),  8607504960,  8817262080)
	TB (krrrkp, false, false, false, (T42<R, R, R, P>::IndCalcW), (T42<R, R, R,
P>::IndCalcB),  2749283520,  2939087360)
	TB (kqppkp, false, false, true,  (T42<Q, P, P, P>::IndCalcW), (T42<Q, P, P,
P>::IndCalcB),  4677701571,  5271860528)
	TB (kqnpkp, false, false, true,  (T42<Q, N, P, P>::IndCalcW), (T42<Q, N, P,
P>::IndCalcB), 12219736849, 13670845224)
	TB (kqnnkp, false, false, true,  (T42<Q, N, N, P>::IndCalcW), (T42<Q, N, N,
P>::IndCalcB),  7670559696,  8817262080)
	TB (kqbpkp, false, false, true,  (T42<Q, B, P, P>::IndCalcW), (T42<Q, B, P,
P>::IndCalcB), 12658882024, 13670845224)
	TB (kqbnkp, false, false, true,  (T42<Q, B, N, P>::IndCalcW), (T42<Q, B, N,
P>::IndCalcB), 16170070752, 17634524160)
	TB (kqbbkp, false, false, true,  (T42<Q, B, B, P>::IndCalcW), (T42<Q, B, B,
P>::IndCalcB),  8234170512,  8817262080)
	TB (kqrpkp, false, false, true,  (T42<Q, R, P, P>::IndCalcW), (T42<Q, R, P,
P>::IndCalcB), 12557225406, 13670845224)
	TB (kqrnkp, false, false, true,  (T42<Q, R, N, P>::IndCalcW), (T42<Q, R, N,
P>::IndCalcB), 16038464256, 17634524160)
	TB (kqrbkp, false, false, true,  (T42<Q, R, B, P>::IndCalcW), (T42<Q, R, B,
P>::IndCalcB), 16617170832, 17634524160)
	TB (kqrrkp, false, false, true,  (T42<Q, R, R, P>::IndCalcW), (T42<Q, R, R,
P>::IndCalcB),  8101097520,  8817262080)
	TB (kqqpkp, false, false, true,  (T42<Q, Q, P, P>::IndCalcW), (T42<Q, Q, P,
P>::IndCalcB),  5851888362,  6835422612)
	TB (kqqnkp, false, false, true,  (T42<Q, Q, N, P>::IndCalcW), (T42<Q, Q, N,
P>::IndCalcB),  7476276864,  8817262080)
	TB (kqqbkp, false, false, true,  (T42<Q, Q, B, P>::IndCalcW), (T42<Q, Q, B,
P>::IndCalcB),  7744392000,  8817262080)
	TB (kqqrkp, false, false, true,  (T42<Q, Q, R, P>::IndCalcW), (T42<Q, Q, R,
P>::IndCalcB),  7680886080,  8817262080)
	TB (kqqqkp, false, false, false, (T42<Q, Q, Q, P>::IndCalcW), (T42<Q, Q, Q,
P>::IndCalcB),  2343300048,  2939087360)
	TB (kpppkn, false, false, false, (T42<P, P, P, N>::IndCalcW), (T42<P, P, P,
N>::IndCalcB),  1537640536,  1777129408)
	TB (knppkn, false, false, true,  (T42<N, P, P, N>::IndCalcW), (T42<N, P, P,
N>::IndCalcB),  6071020409,  6838084896)
	TB (knnpkn, false, false, true,  (T42<N, N, P, N>::IndCalcW), (T42<N, N, P,
N>::IndCalcB),  7677994559,  8729470080)
	TB (kbppkn, false, false, true,  (T42<B, P, P, N>::IndCalcW), (T42<B, P, P,
N>::IndCalcB),  6289527204,  6838084896)
	TB (kbnpkn, false, false, true,  (T42<B, N, P, N>::IndCalcW), (T42<B, N, P,
N>::IndCalcB), 16186823401, 17458940160)
	TB (kbbpkn, false, false, true,  (T42<B, B, P, N>::IndCalcW), (T42<B, B, P,
N>::IndCalcB),  8243187360,  8729470080)
	TB (krppkn, false, false, true,  (T42<R, P, P, N>::IndCalcW), (T42<R, P, P,
N>::IndCalcB),  6239761412,  6838084896)
	TB (krnpkn, false, false, true,  (T42<R, N, P, N>::IndCalcW), (T42<R, N, P,
N>::IndCalcB), 16057066825, 17458940160)
	TB (krbpkn, false, false, true,  (T42<R, B, P, N>::IndCalcW), (T42<R, B, P,
N>::IndCalcB), 16637490240, 17458940160)
	TB (krrpkn, false, false, true,  (T42<R, R, P, N>::IndCalcW), (T42<R, R, P,
N>::IndCalcB),  8112305064,  8729470080)
	TB (kqppkn, false, false, true,  (T42<Q, P, P, N>::IndCalcW), (T42<Q, P, P,
N>::IndCalcB),  5920486098,  6838084896)
	TB (kqnpkn, false, false, true,  (T42<Q, N, P, N>::IndCalcW), (T42<Q, N, P,
N>::IndCalcB), 15239383701, 17458940160)
	TB (kqbpkn, false, false, true,  (T42<Q, B, P, N>::IndCalcW), (T42<Q, B, P,
N>::IndCalcB), 15787021288, 17458940160)
	TB (kqrpkn, false, false, true,  (T42<Q, R, P, N>::IndCalcW), (T42<Q, R, P,
N>::IndCalcB), 15660230819, 17458940160)
	TB (kqqpkn, false, false, true,  (T42<Q, Q, P, N>::IndCalcW), (T42<Q, Q, P,
N>::IndCalcB),  7297961576,  8729470080)
	TB (kpppkb, false, false, false, (T42<P, P, P, B>::IndCalcW), (T42<P, P, P,
B>::IndCalcB),  1537640536,  1842024000)
	TB (knppkb, false, false, true,  (T42<N, P, P, B>::IndCalcW), (T42<N, P, P,
B>::IndCalcB),  6071020409,  7087788000)
	TB (knnpkb, false, false, true,  (T42<N, N, P, B>::IndCalcW), (T42<N, N, P,
B>::IndCalcB),  7677994559,  9048240000)
	TB (kbppkb, false, false, true,  (T42<B, P, P, B>::IndCalcW), (T42<B, P, P,
B>::IndCalcB),  6289527204,  7087788000)
	TB (kbnpkb, false, false, true,  (T42<B, N, P, B>::IndCalcW), (T42<B, N, P,
B>::IndCalcB), 16186823401, 18096480000)
	TB (kbbpkb, false, false, true,  (T42<B, B, P, B>::IndCalcW), (T42<B, B, P,
B>::IndCalcB),  8243187360,  9048240000)
	TB (krppkb, false, false, true,  (T42<R, P, P, B>::IndCalcW), (T42<R, P, P,
B>::IndCalcB),  6239761412,  7087788000)
	TB (krnpkb, false, false, true,  (T42<R, N, P, B>::IndCalcW), (T42<R, N, P,
B>::IndCalcB), 16057066825, 18096480000)
	TB (krbpkb, false, false, true,  (T42<R, B, P, B>::IndCalcW), (T42<R, B, P,
B>::IndCalcB), 16637490240, 18096480000)
	TB (krrpkb, false, false, true,  (T42<R, R, P, B>::IndCalcW), (T42<R, R, P,
B>::IndCalcB),  8112305064,  9048240000)
	TB (kqppkb, false, false, true,  (T42<Q, P, P, B>::IndCalcW), (T42<Q, P, P,
B>::IndCalcB),  5920486098,  7087788000)
	TB (kqnpkb, false, false, true,  (T42<Q, N, P, B>::IndCalcW), (T42<Q, N, P,
B>::IndCalcB), 15239383701, 18096480000)
	TB (kqbpkb, false, false, true,  (T42<Q, B, P, B>::IndCalcW), (T42<Q, B, P,
B>::IndCalcB), 15787021288, 18096480000)
	TB (kqrpkb, false, false, true,  (T42<Q, R, P, B>::IndCalcW), (T42<Q, R, P,
B>::IndCalcB), 15660230819, 18096480000)
	TB (kqqpkb, false, false, true,  (T42<Q, Q, P, B>::IndCalcW), (T42<Q, Q, P,
B>::IndCalcB),  7297961576,  9048240000)
	TB (kpppkr, false, false, false, (T42<P, P, P, R>::IndCalcW), (T42<P, P, P,
R>::IndCalcB),  1537640536,  1827875872)
	TB (knppkr, false, false, true,  (T42<N, P, P, R>::IndCalcW), (T42<N, P, P,
R>::IndCalcB),  6071020409,  7033481568)
	TB (knnpkr, false, false, true,  (T42<N, N, P, R>::IndCalcW), (T42<N, N, P,
R>::IndCalcB),  7677994559,  8978912640)
	TB (kbppkr, false, true,  true,  (T42<B, P, P, R>::IndCalcW), (T42<B, P, P,
R>::IndCalcB),  6289527204,  7033481568)
	TB (kbnpkr, false, true,  true,  (T42<B, N, P, R>::IndCalcW), (T42<B, N, P,
R>::IndCalcB), 16186823401, 17957825280)
	TB (kbbpkr, false, true,  true,  (T42<B, B, P, R>::IndCalcW), (T42<B, B, P,
R>::IndCalcB),  8243187360,  8978912640)
	TB (krppkr, false, false, true,  (T42<R, P, P, R>::IndCalcW), (T42<R, P, P,
R>::IndCalcB),  6239761412,  7033481568)
	TB (krnpkr, false, false, true,  (T42<R, N, P, R>::IndCalcW), (T42<R, N, P,
R>::IndCalcB), 16057066825, 17957825280)
	TB (krbpkr, false, false, true,  (T42<R, B, P, R>::IndCalcW), (T42<R, B, P,
R>::IndCalcB), 16637490240, 17957825280)
	TB (krrpkr, false, false, true,  (T42<R, R, P, R>::IndCalcW), (T42<R, R, P,
R>::IndCalcB),  8112305064,  8978912640)
	TB (kqppkr, false, false, true,  (T42<Q, P, P, R>::IndCalcW), (T42<Q, P, P,
R>::IndCalcB),  5920486098,  7033481568)
	TB (kqnpkr, false, false, true,  (T42<Q, N, P, R>::IndCalcW), (T42<Q, N, P,
R>::IndCalcB), 15239383701, 17957825280)
	TB (kqbpkr, false, false, true,  (T42<Q, B, P, R>::IndCalcW), (T42<Q, B, P,
R>::IndCalcB), 15787021288, 17957825280)
	TB (kqrpkr, false, false, true,  (T42<Q, R, P, R>::IndCalcW), (T42<Q, R, P,
R>::IndCalcB), 15660230819, 17957825280)
	TB (kqqpkr, false, false, true,  (T42<Q, Q, P, R>::IndCalcW), (T42<Q, Q, P,
R>::IndCalcB),  7297961576,  8978912640)
	TB (kpppkq, false, false, false, (T42<P, P, P, Q>::IndCalcW), (T42<P, P, P,
Q>::IndCalcB),  1537640536,  1733232160)
	TB (knppkq, false, false, true,  (T42<N, P, P, Q>::IndCalcW), (T42<N, P, P,
Q>::IndCalcB),  6071020409,  6669309024)
	TB (knnpkq, false, false, true,  (T42<N, N, P, Q>::IndCalcW), (T42<N, N, P,
Q>::IndCalcB),  7677994559,  8514011520)
	TB (kbppkq, false, false, true,  (T42<B, P, P, Q>::IndCalcW), (T42<B, P, P,
Q>::IndCalcB),  6289527204,  6669309024)
	TB (kbnpkq, false, false, true,  (T42<B, N, P, Q>::IndCalcW), (T42<B, N, P,
Q>::IndCalcB), 16186823401, 17028023040)
	TB (kbbpkq, false, false, true,  (T42<B, B, P, Q>::IndCalcW), (T42<B, B, P,
Q>::IndCalcB),  8243187360,  8514011520)
	TB (krppkq, false, false, true,  (T42<R, P, P, Q>::IndCalcW), (T42<R, P, P,
Q>::IndCalcB),  6239761412,  6669309024)
	TB (krnpkq, false, false, true,  (T42<R, N, P, Q>::IndCalcW), (T42<R, N, P,
Q>::IndCalcB), 16057066825, 17028023040)
	TB (krbpkq, false, false, true,  (T42<R, B, P, Q>::IndCalcW), (T42<R, B, P,
Q>::IndCalcB), 16637490240, 17028023040)
	TB (krrpkq, false, true,  true,  (T42<R, R, P, Q>::IndCalcW), (T42<R, R, P,
Q>::IndCalcB),  8112305064,  8514011520)
	TB (kqppkq, false, false, true,  (T42<Q, P, P, Q>::IndCalcW), (T42<Q, P, P,
Q>::IndCalcB),  5920486098,  6669309024)
	TB (kqnpkq, false, false, true,  (T42<Q, N, P, Q>::IndCalcW), (T42<Q, N, P,
Q>::IndCalcB), 15239383701, 17028023040)
	TB (kqbpkq, false, false, true,  (T42<Q, B, P, Q>::IndCalcW), (T42<Q, B, P,
Q>::IndCalcB), 15787021288, 17028023040)
	TB (kqrpkq, false, false, true,  (T42<Q, R, P, Q>::IndCalcW), (T42<Q, R, P,
Q>::IndCalcB), 15660230819, 17028023040)
	TB (kqqpkq, false, false, true,  (T42<Q, Q, P, Q>::IndCalcW), (T42<Q, Q, P,
Q>::IndCalcB),  7297961576,  8514011520)

#endif
#endif
    };

#undef	P
#undef	N
#undef	B
#undef	R
#undef	Q

//	Helper structure
//	Used to classify on-board position

union CUTbReference		// Hungarian: utbr
	{
	int				m_iDesc;			// Negative if have to inverse
	int				m_cPieces;
	CUTbReference	*m_utbReference;
	};

//	Root of the search tree

static CUTbReference rgutbReference [MAX_NON_KINGS + 2];

// Convert TB name (e.g. KQKR) into set of counters

static const char *PchSetHalfCounters
	(
	int			*piCounters,
	const char	*pch
	)
	{
	memset (piCounters, 0, 5 * sizeof (int));
	while ('\0' != *pch && 'k' != *pch)
		{
		piece pi;

		pi = x_piecePawn;	// To make compiler happy
		switch (*pch)
			{
		case 'p':
			pi = x_piecePawn;
			break;
		case 'n':
			pi = x_pieceKnight;
			break;
		case 'b':
			pi = x_pieceBishop;
			break;
		case 'r':
			pi = x_pieceRook;
			break;
		case 'q':
			pi = x_pieceQueen;
			break;
		default:
			assert (0);
			}
		piCounters [pi-1] ++;
		pch ++;
		}
		return pch;
	};

static void VSetCounters
	(
	int			*piCounters,
	const char	*pch
	)
	{
	assert ('k' == *pch);
	pch = PchSetHalfCounters (piCounters, pch+1);
	assert ('k' == *pch);
	pch = PchSetHalfCounters (piCounters+5, pch+1);
	assert ('\0' == *pch);
	}

//	Following functions return TB index
//	They differ by input arguments

extern "C" int IDescFindFromCounters
	(
	int	*piCount
	)
	{
	CUTbReference *putbr = rgutbReference;

	if (piCount[0] > putbr->m_cPieces)
		goto not_found;
	putbr = putbr[1 + piCount[0]].m_utbReference;
	if (piCount[1] > putbr->m_cPieces)
		goto not_found;
	putbr = putbr[1 + piCount[1]].m_utbReference;
	if (piCount[2] > putbr->m_cPieces)
		goto not_found;
	putbr = putbr[1 + piCount[2]].m_utbReference;
	if (piCount[3] > putbr->m_cPieces)
		goto not_found;
	putbr = putbr[1 + piCount[3]].m_utbReference;
	if (piCount[4] > putbr->m_cPieces)
		goto not_found;
	putbr = putbr[1 + piCount[4]].m_utbReference;
	if (piCount[5] > putbr->m_cPieces)
		goto not_found;
	putbr = putbr[1 + piCount[5]].m_utbReference;
	if (piCount[6] > putbr->m_cPieces)
		goto not_found;
	putbr = putbr[1 + piCount[6]].m_utbReference;
	if (piCount[7] > putbr->m_cPieces)
		goto not_found;
	putbr = putbr[1 + piCount[7]].m_utbReference;
	if (piCount[8] > putbr->m_cPieces)
		goto not_found;
	putbr = putbr[1 + piCount[8]].m_utbReference;
	if (piCount[9] <= putbr->m_cPieces)
		return putbr[1 + piCount[9]].m_iDesc;
not_found:
	return 0;
	}

int	IDescFind
	(
	square	*p_piW,	// IN | Pointer to array of white pieces (king excluded)
	square	*p_piB,	// IN | Pointer to array of black pieces (king excluded)
	int		cWhite,	// IN | Counter of white pieces (king excluded)
	int		cBlack	// IN | Counter of black pieces (king excluded)
	)
	{
	int	rgiCount[10];

	// Set pieces counters
	rgiCount[0] =
	rgiCount[1] =
	rgiCount[2] =
	rgiCount[3] =
	rgiCount[4] =
	rgiCount[5] =
	rgiCount[6] =
	rgiCount[7] =
	rgiCount[8] =
	rgiCount[9] = 0;
	while (cWhite)
		{
		rgiCount[(*p_piW)-1] ++;
		p_piW ++;
		cWhite --;
		}
	while (cBlack)
		{
		rgiCount[5-1+(*p_piB)] ++;
		p_piB ++;
		cBlack --;
		}
	return IDescFindFromCounters (rgiCount);
	}

int	IDescFindByName
	(
	char	*pchName
	)
	{
	int	rgiCount[10];

	VSetCounters (rgiCount, pchName);
	return IDescFindFromCounters (rgiCount);
	}

//-----------------------------------------------------------------------------
//
//	Function used during initialization

//	Set of functions to create search table

static CUTbReference *PutbrCreateSubtable
	(
	int	cPieces,	//	IN | # of pieces ramaining on board
	int	iDepth		//	IN | Recursion depth (# of piece classes left)
	)
	{
	CUTbReference *putbr;

	putbr = (CUTbReference *) PvMalloc ((cPieces + 2) * sizeof (CUTbReference));
	putbr[0].m_cPieces = cPieces;
	if (0 == iDepth)
		{
		for (int i = 0; i <= cPieces; i ++)
			putbr[i+1].m_iDesc = 0;
		}
	else
		{
		for (int i = 0; i <= cPieces; i ++)
			putbr[i+1].m_utbReference = PutbrCreateSubtable (cPieces-i, iDepth-1);
		}
	return putbr;
	}

static bool fTbTableCreated = false;

static void VCreateEmptyTbTable (void)
	{
	if (fTbTableCreated)
		return;
	fTbTableCreated = true;
	rgutbReference[0].m_cPieces = MAX_NON_KINGS;
	for (int i = 0; i <= MAX_NON_KINGS; i ++)
		rgutbReference[i+1].m_utbReference = PutbrCreateSubtable (MAX_NON_KINGS - i,
8);
	}

// Insert TB (e.g. KQKR) into search table

static bool FRegisterHalf
	(
	int		iTb,
	int		*piCount
	)
	{
	CUTbReference	*putbr;

	putbr = rgutbReference;
	for (int i = 0; i < 9; i ++)
		{
		if (piCount[i] > putbr->m_cPieces)
			return false;
		putbr = putbr[1 + piCount[i]].m_utbReference;
		}
	if (piCount[9] > putbr->m_cPieces)
		return false;
	putbr[1 + piCount[9]].m_iDesc = iTb;
	return true;
	}

// Insert TB (both, e.g. KQKR and KRKQ) into search table

static bool FRegisterTb
	(
	CTbDesc	*ptbDesc
	)
	{
	int		rgiCount[10];
	bool	fInserted;

	VSetCounters (rgiCount, ptbDesc->m_rgchName);
	fInserted = FRegisterHalf (ptbDesc->m_iTbId, rgiCount);
	if (fInserted)
		{
		if (ptbDesc->m_fSymmetric)
			return true;
		for (int i = 0; i < 5; i ++)
			{
			int	iTemp;

			iTemp = rgiCount[i];
			rgiCount[i] = rgiCount[i+5];
			rgiCount[i+5] = iTemp;
			}
		fInserted = FRegisterHalf (-ptbDesc->m_iTbId, rgiCount);
		assert (fInserted);
		}
	return fInserted;
	}

// File mapping - Win32 code only

#if defined (_WIN32) || defined(_WIN64)

static BYTE * PbMapFileForRead
	(
	char	*szName,
	HANDLE	*phFile,
	HANDLE	*phFileMapping
	)
	{
	HANDLE	hFile;
	HANDLE	hFileMapping;
	LPVOID	lpFileBase;

	hFile = CreateFile (szName, GENERIC_READ, FILE_SHARE_READ,
						NULL, OPEN_EXISTING,
						FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL);
	if (INVALID_HANDLE_VALUE == hFile)
		{
		printf("*** Couldn't open file %s with CreateFile()\n", szName);
		exit (1);
		}
	hFileMapping = CreateFileMapping (hFile, NULL, PAGE_READONLY, 0, 0, NULL);
	if (0 == hFileMapping)
		{
		CloseHandle (hFile);
		printf ("*** Couldn't open file %s mapping with CreateFileMapping()\n",
szName);
		exit (1);
		}
	lpFileBase = MapViewOfFile (hFileMapping, FILE_MAP_READ, 0, 0, 0);
	if (0 == lpFileBase)
		{
		CloseHandle (hFileMapping);
		CloseHandle (hFile);
		printf ("*** Couldn't map view of file %s with MapViewOfFile()\n", szName);
		exit (1);
		}
	if (NULL != phFile)
		*phFile = hFile;
	if (NULL != phFileMapping)
		*phFileMapping = hFileMapping;
	return (BYTE*) lpFileBase;
	}

static void	VUnmapFile
	(
	BYTE	*pbFileBase,
	HANDLE	hFile,
	HANDLE	hFileMapping
	)
	{
	BOOL fFailed;

	fFailed = (0 == UnmapViewOfFile (pbFileBase)) |
			  (0 == CloseHandle (hFileMapping)) |
			  (0 == CloseHandle (hFile));
	if (fFailed)
		{
		printf ("*** Couldn't unmap file\n");
		exit (1);
		}
	}

#endif

//-----------------------------------------------------------------------------
//
//	TB caching

#if !defined (TB_CB_CACHE_CHUNK)
#define	TB_CB_CACHE_CHUNK			8192 /* Must be power of 2 */
#define	LOG2_TB_CB_CACHE_CHUNK		13
#endif

#define TB_CHUNK(index)             ((index) >> LOG2_TB_CB_CACHE_CHUNK)
#define TB_OFFSET(index)            ((index) % TB_CB_CACHE_CHUNK)
#define	TB_DIRECTORY_ENTRY(chunk)	((chunk) % TB_DIRECTORY_SIZE)

#define WIDE_TB_CHUNK(index)        ((index) >> (LOG2_TB_CB_CACHE_CHUNK-1))
#define WIDE_TB_OFFSET(index)       ((index) % (TB_CB_CACHE_CHUNK/2))*2

struct CTbCache			//Hungarian: tbc
	{
	int volatile                m_iTb;
	color volatile              m_color;
	unsigned volatile           m_indChunk;
	volatile CTbCache *volatile m_ptbcNext;	    // Next element in double-linked
general LRU list
	volatile CTbCache *volatile m_ptbcPrev;	    // Previous element in
double-linked general LRU list
	volatile CTbCache *volatile m_ptbcTbNext;	// Next element in double-linked
cache bucket LRU list
	volatile CTbCache *volatile m_ptbcTbPrev;	// Previous element in double-linked
cache bucket LRU list
	BYTE		                *m_pbData;
	};

static CTbCache	*ptbcTbCache;	// Cache memory
static ULONG	ctbcTbCache;	// Cache size (in entries)

static volatile CTbCache * volatile ptbcHead;		// Head of that list
static volatile CTbCache * volatile ptbcTail;		// Last element in that list
static volatile CTbCache * volatile ptbcFree;		// First free cache header

static INLINE void VTbCloseFile
	(
	int		iTb,
	color	side
	)
	{
    for (int iExtent = 0; iExtent < MAX_EXTENTS; iExtent ++) {
	    if (NULL != rgtbdDesc[iTb].m_rgfpFiles[side][iExtent])
		    {
		    Lock (rgtbdDesc[iTb].m_rglockFiles[side]);
	        if (NULL != rgtbdDesc[iTb].m_rgfpFiles[side][iExtent])
		        {
		        fclose (rgtbdDesc[iTb].m_rgfpFiles[side][iExtent]);
		        rgtbdDesc[iTb].m_rgfpFiles[side][iExtent] = NULL;
                }
		    Unlock (rgtbdDesc[iTb].m_rglockFiles[side]);
		    }
        }
	}

extern "C" void VTbCloseFiles (void)
	{
	// Initialized?
	if (0 == ctbcTbCache)
		return;

	// Walk through TB cache and close all opened files
	for (int iTb = 1; iTb < cTb; iTb ++)
		{
		VTbCloseFile (iTb, x_colorWhite);
		VTbCloseFile (iTb, x_colorBlack);
		}
	}

void VTbClearCache (void)
	{
	CTbCacheBucket	*prgtbcbBuckets;
	CTbCache *ptbc;
	BYTE *pb;
	ULONG i;

	// Initialized?
	if (0 == ctbcTbCache)
		return;
	VTbCloseFiles();

	// Initialize all lists
	pb = (BYTE *) & ptbcTbCache [ctbcTbCache];
	for (i = 0, ptbc = ptbcTbCache; i < ctbcTbCache; i ++, ptbc ++)
		{
		ptbc->m_pbData = pb + i*(TB_CB_CACHE_CHUNK+32+4);
		ptbc->m_ptbcTbPrev =
		ptbc->m_ptbcTbNext =
		ptbc->m_ptbcPrev = NULL;
		ptbc->m_ptbcNext = (ptbc + 1);
		}
	ptbc[-1].m_ptbcNext = NULL;

	// Clear references from TBs
	for (int iTb = 1; iTb < cTb; iTb ++)
		{
        for (color sd=x_colorWhite; sd <= x_colorBlack; sd ++)
            {
            prgtbcbBuckets = rgtbdDesc[iTb].m_prgtbcbBuckets[sd];
		    if (NULL != prgtbcbBuckets)
                {
#if defined (SMP)
		        for (i = 0; i < TB_DIRECTORY_SIZE; i ++)
			        LockFree (prgtbcbBuckets[i].m_lock);
#endif
			    memset (prgtbcbBuckets, 0, TB_DIRECTORY_SIZE * sizeof (CTbCacheBucket));
#if defined (SMP)
		        for (i = 0; i < TB_DIRECTORY_SIZE; i ++)
			        LockInit (prgtbcbBuckets[i].m_lock);
#endif
                }
            }
		}

	// Set globals
	ptbcHead = ptbcTail = NULL;
	ptbcFree = ptbcTbCache;
	}

extern "C" int FTbSetCacheSize
	(
	void	*pv,
	ULONG	cbSize
	)
	{
	VTbCloseFiles();
	ctbcTbCache = 0;
	ptbcHead = NULL;
	if (cbSize < sizeof (CTbCache))
		return false;
	ptbcTbCache = (CTbCache*) pv;
	ctbcTbCache = cbSize / (sizeof (CTbCache) + TB_CB_CACHE_CHUNK+32+4);
	VTbClearCache();
	return true;
	}

// Table registered

INLINE int FRegisteredExtent
    (
    int     iTb,
    color   side,
    int     iExtent
    )
    {
    if (rgtbdDesc[iTb].m_fSymmetric)
        side = x_colorWhite;
	return (NULL != rgtbdDesc[iTb].m_rgpchFileName[side][iExtent]);
    }

INLINE int FRegistered
    (
    int     iTb,
    color   side
    )
    {
    int iExtent, cExtents;

    cExtents = rgtbdDesc[iTb].m_fSplit ? MAX_EXTENTS : 1;
    for (iExtent = 0; iExtent < cExtents; iExtent ++)
        {
	    if (FRegisteredExtent (iTb, side, iExtent))
            return true;
        }
    return false;
    }

extern "C" int FRegisteredFun
	(
	int		iTb,
	color	side
	)
	{
	return FRegistered (iTb, side);
	}

// Return function that calculates the necessary index:

#define PfnIndCalc(iTb, side)	(rgtbdDesc[iTb].m_rgpfnCalcIndex[side])
extern "C" PfnCalcIndex PfnIndCalcFun
	(
	int		iTb,
	color	side
	)
	{
	return PfnIndCalc (iTb, side);
	}

// Read whole file into memory

extern "C" int FReadTableToMemory
	(
	int		iTb,	// IN | Tablebase
	color	side,	// IN | Side to move
	BYTE	*pb		// IN | Either buffer or NULL
	)
	{
	char	*pszName;
	INDEX	cb;
	FILE	*fp;

	if (rgtbdDesc[iTb].m_fSymmetric)
		side = x_colorWhite;
	if (!FRegistered (iTb, side))
		return false;
	if (rgtbdDesc[iTb].m_fSplit)
		return false;
	for (int iExtent = 0; iExtent < MAX_EXTENTS; iExtent ++)
		{
		if (NULL != rgtbdDesc[iTb].m_rgpdiDecodeInfo[side][iExtent])
			return false;
    	}
    if (NULL != rgtbdDesc[iTb].m_rgpbRead[side])
        return true;
	pszName = rgtbdDesc[iTb].m_rgpchFileName[side][0];
	fp = fopen (pszName, "rb");
	if (NULL == fp)
		return false;

	// Find database size
#if defined (NEW)
	cb = rgtbdDesc[iTb].m_rgcbLength[side];
	if (0 == cb)
		{
#endif
		if (0 != fseek (fp, 0L, SEEK_END))
			{
			printf ("*** Seek in %s failed\n", pszName);
			exit (1);
			}
		cb = ftell (fp);
		if (-1 == (int) cb)
			{
			printf ("*** Cannot find length of %s\n", pszName);
			exit (1);
			}
		if (0 != fseek (fp, 0L, SEEK_SET))
			{
			printf ("*** Seek in %s failed\n", pszName);
			exit (1);
			}
#if defined (NEW)
		}
#if defined (T33_INCLUDE) || defined (KPPKP_16BIT)
    else if (rgtbdDesc[iTb].m_f16bit)
        {
        if ((size_t) cb != cb)   // Overflow
		    {
		    printf ("*** %s too big to read into memory\n", pszName);
		    exit (1);
		    }
        }
#endif
#endif

	// If buffer not specified, allocate memory for it
	if (NULL == pb)
		pb = (BYTE*) PvMalloc (cb);

	// Read file into memory
	if (cb != (INDEX) fread (pb, 1, cb, fp))
		{
		printf ("*** Read from %s failed\n", pszName);
		exit (1);
		}
	fclose (fp);

	// All done
	rgtbdDesc[iTb].m_rgpbRead[side] = pb;
	return true;
	}

#if defined (_WIN32) || defined(_WIN64)

// Map whole file into memory

extern "C" int FMapTableToMemory
	(
	int		iTb,	// IN | Tablebase
	color	side	// IN | Side to move
	)
	{
	char *pszName;

	if (rgtbdDesc[iTb].m_fSymmetric)
		side = x_colorWhite;
	if (!FRegistered (iTb, side))
		return false;
	if (rgtbdDesc[iTb].m_fSplit)
		return false;
	for (int iExtent = 0; iExtent < MAX_EXTENTS; iExtent ++)
		{
		if (NULL != rgtbdDesc[iTb].m_rgpdiDecodeInfo[side][iExtent])
			return false;
    	}
	pszName = rgtbdDesc[iTb].m_rgpchFileName[side][0];
	if (NULL == rgtbdDesc[iTb].m_rgpbRead[side])
		{
		rgtbdDesc[iTb].m_rgpbRead[side] = PbMapFileForRead (pszName, NULL, NULL);
		if (fVerbose)
			printf ("%s mapped\n", pszName);
		}
	return true;
	}

// Map whole file into memory

int FMapTableToMemory
	(
	int		iTb,			// IN  | Tablebase
	color	side,			// IN  | Side to move
	HANDLE	*phFile,		// OUT | File handle will be written here
	HANDLE	*phFileMapping	// OUT | File mapping handle will be written here
	)
	{
	char *pszName;

	if (rgtbdDesc[iTb].m_fSymmetric)
		side = x_colorWhite;
	if (!FRegistered (iTb, side))
		return false;
	if (rgtbdDesc[iTb].m_fSplit)
		return false;
	pszName = rgtbdDesc[iTb].m_rgpchFileName[side][0];
	if (NULL == rgtbdDesc[iTb].m_rgpbRead[side])
		{
		rgtbdDesc[iTb].m_rgpbRead[side] = PbMapFileForRead (pszName, phFile,
phFileMapping);
		if (fVerbose)
			printf ("%s mapped\n", pszName);
		}
	return true;
	}

// Unmap whole file from memory

int FUnMapTableFromMemory
	(
	int		iTb,			// IN | Tablebase
	color	side,			// IN | Side to move
	HANDLE	hFile,			// IN | File handle will be written here
	HANDLE	hFileMapping	// IN | File mapping handle will be written here
	)
	{
	char *pszName;

	if (rgtbdDesc[iTb].m_fSymmetric)
		side = x_colorWhite;
	if (!FRegistered (iTb, side))
		return false;
	if (rgtbdDesc[iTb].m_fSplit)
		return false;
	pszName = rgtbdDesc[iTb].m_rgpchFileName[side][0];
	if (NULL != rgtbdDesc[iTb].m_rgpbRead[side])
		{
		VUnmapFile (rgtbdDesc[iTb].m_rgpbRead[side], hFile, hFileMapping);
		rgtbdDesc[iTb].m_rgpbRead[side] = NULL;
		if (fVerbose)
			printf ("%s unmapped\n", pszName);
		}
	return true;
	}

#endif

// Probe TB - lower level (not exportable) function

static int TB_FASTCALL TbtProbeTable
	(
	int		 iTb,
	color	 side,
	unsigned indChunk,
	unsigned indInChunk
	)
	{
    CTbDesc *ptbd;
    int iDirectory, iExtent, iPhysicalChunk;
    volatile CTbCache * ptbc;
    volatile CTbCache * ptbcTbFirst;
    const char *pszFileName;

	ptbd = & rgtbdDesc[iTb];
	iDirectory = TB_DIRECTORY_ENTRY (indChunk);

	// Head of the cache bucket LRU list
	Lock (ptbd->m_prgtbcbBuckets[side][iDirectory].m_lock);
	ptbcTbFirst = ptbd->m_prgtbcbBuckets[side][iDirectory].m_ptbcFirst;

	// First, search entry in the cache
	for (ptbc = ptbcTbFirst; NULL != ptbc; ptbc = ptbc->m_ptbcTbNext)
		{
		if (indChunk == ptbc->m_indChunk)
			{
			// Found - move cache entry to the head of the general LRU list
			Lock (lockLRU);
			if (ptbc != ptbcHead)
				{
				// Remove it from its current position
				ptbc->m_ptbcPrev->m_ptbcNext = ptbc->m_ptbcNext;
				if (NULL == ptbc->m_ptbcNext)
					ptbcTail = ptbc->m_ptbcPrev;
				else
					ptbc->m_ptbcNext->m_ptbcPrev = ptbc->m_ptbcPrev;
				// Insert it at the head
				ptbc->m_ptbcPrev = NULL;
				ptbc->m_ptbcNext = ptbcHead;
				ptbcHead->m_ptbcPrev = ptbc;
				ptbcHead = ptbc;
				}
			Unlock (lockLRU);
			// Move cache entry to the head of the cache bucket LRU list
			if (ptbc != ptbcTbFirst)
				{
				// Remove it from list
				ptbc->m_ptbcTbPrev->m_ptbcTbNext = ptbc->m_ptbcTbNext;
				if (NULL != ptbc->m_ptbcTbNext)
					ptbc->m_ptbcTbNext->m_ptbcTbPrev = ptbc->m_ptbcTbPrev;
				// Insert it at head
				ptbc->m_ptbcTbPrev = NULL;
				ptbc->m_ptbcTbNext = ptbcTbFirst;
				ptbcTbFirst->m_ptbcTbPrev = ptbc;
				ptbd->m_prgtbcbBuckets[side][iDirectory].m_ptbcFirst = ptbc;
				}
			int	tb;

			tb = (tb_t) (ptbc->m_pbData[(ULONG)indInChunk]);
			Unlock (ptbd->m_prgtbcbBuckets[side][iDirectory].m_lock);
			return tb;
			}
		}
	// Not in the cache - have to read it from disk.
	// I decided to write simple code - so sometimes it's possible that
	// 2 threads will simultaneously read exactly the same chunk into 2
	// different cache entries. In that case, all subsequent cache probes
	// will hit the first cache entry, so the second one will 'drift' to
	// the end of general LRU list and will be reused.

	// Unlock cache bucket, so other threads can continue execution
	Unlock (ptbd->m_prgtbcbBuckets[side][iDirectory].m_lock);
	// First, find cache entry we can use
	Lock (lockLRU);
	// Get it either from a free list, or reuse last element of the LRU list
	if (NULL != ptbcFree)
		{
		ptbc = ptbcFree;
		ptbcFree = ptbc->m_ptbcNext;
		Unlock (lockLRU);
		}
	else
		{
		unsigned iTailDirectory;
		int		 iTailTb;
		color	 colorTail;

		assert (NULL != ptbcTail);
#if defined (SMP)
		// "Optimistic" model - assuming that there is low content
		// (not hundreds of threads)
		for (;;)
			{
			ptbc = ptbcTail;
			iTailTb = ptbc->m_iTb;
			iTailDirectory = TB_DIRECTORY_ENTRY (ptbc->m_indChunk);
			colorTail = ptbc->m_color;
			// To avoid deadlocks, have to first acquire cache buckets lock,
			// and only then general LRU lock. So, free general LRU lock and
			// acquire 2 locks in a proper order.
			Unlock (lockLRU);
			Lock (rgtbdDesc[iTailTb].m_prgtbcbBuckets[colorTail][iTailDirectory].m_lock);
			Lock (lockLRU);
			// Have structures been modified while we re-acquired locks?
			// (to be more precise, it's Ok, if structures were modified,
			// but cache entry again become the last element of the list,
			// and TB, color, and cache bucket did not changed, so we locked
			// proper locks).
			if (ptbc == ptbcTail && ptbc->m_iTb == iTailTb &&
				ptbc->m_color == colorTail &&
				TB_DIRECTORY_ENTRY (ptbc->m_indChunk) == iTailDirectory)
				break;
			// Sorry - try once again...
			Unlock
(rgtbdDesc[iTailTb].m_prgtbcbBuckets[colorTail][iTailDirectory].m_lock);
			}
#else
		ptbc = ptbcTail;
		iTailTb = ptbc->m_iTb;
		iTailDirectory = TB_DIRECTORY_ENTRY (ptbc->m_indChunk);
		colorTail = ptbc->m_color;
#endif

		// Remove cache entry from the general LRU list
		ptbcTail = ptbc->m_ptbcPrev;
		if (NULL == ptbcTail)
			ptbcHead = NULL;
		else
			ptbcTail->m_ptbcNext = NULL;
		Unlock (lockLRU);

		// Remove it from cache bucket list
		if (NULL != ptbc->m_ptbcTbNext)
			ptbc->m_ptbcTbNext->m_ptbcTbPrev = ptbc->m_ptbcTbPrev;
		if (NULL == ptbc->m_ptbcTbPrev)
			rgtbdDesc[iTailTb].m_prgtbcbBuckets[colorTail][iTailDirectory].m_ptbcFirst =
ptbc->m_ptbcTbNext;
		else
			ptbc->m_ptbcTbPrev->m_ptbcTbNext = ptbc->m_ptbcTbNext;
		Unlock
(rgtbdDesc[iTailTb].m_prgtbcbBuckets[colorTail][iTailDirectory].m_lock);
		}

	// Ok, now we have "orphan" cache entry - it's excluded from all lists,
	// so other threads will never touch it.
	ptbc->m_iTb = iTb;
	ptbc->m_color = side;
	ptbc->m_indChunk = indChunk;

	// Now read it from the disk
	FILE	*fp;
	size_t	cb;

	// First, check: is necessary file opened?
	// As files are not thread-safe, lock file
	Lock (ptbd->m_rglockFiles[side]);
    if (ptbd->m_fSplit)
        {
        iExtent = indChunk >> (31 - LOG2_TB_CB_CACHE_CHUNK);
        iPhysicalChunk = indChunk - (iExtent << (31 - LOG2_TB_CB_CACHE_CHUNK));
        }
    else
        {
        iExtent = 0;
        iPhysicalChunk = indChunk;
        }
    fp = ptbd->m_rgfpFiles[side][iExtent];
	if (NULL == fp)
		{
		// Not - try to open it
        pszFileName = ptbd->m_rgpchFileName[side][iExtent];
        if (NULL != pszFileName)
            {
		    fp = fopen (pszFileName, "rb");
		    if (NULL == fp)
			    {
			    // Failed. Close all the opened files and retry
			    Unlock (ptbd->m_rglockFiles[side]);
			    VTbCloseFiles ();
			    Lock (ptbd->m_rglockFiles[side]);
			    // Theoretically, it's possible that other threads opened a lot of
			    // files in the interval between VTbCloseFiles() and Lock(). If
			    // so, we'll fail - I don't like to have one more global lock
			    // especially for file open, at least not in first version.
			    // Problem can happen only on systems with small limit of
			    // simultaneously open files and high number of threads - unlikely
			    // combination.
			    fp = ptbd->m_rgfpFiles[side][iExtent];
			    if (NULL == fp)
				    {
				    fp = fopen (pszFileName, "rb");
				    if (NULL == fp)
                        {
#if defined (STOP_ON_ERROR)
                        printf ("*** Unable to open file %s\n", pszFileName);
                        fflush (stdout);
                        exit(1);
#endif
					    goto ERROR_LABEL;
                        }
				    }
			    }
		    ptbd->m_rgfpFiles[side][iExtent] = fp;
		    }
        }

	// File opened. Now seek and read necessary chunk
	if (NULL == ptbd->m_rgpdiDecodeInfo[side][iExtent])
		{
        long lPos;
        int  iResult;

        lPos = (long) (iPhysicalChunk*TB_CB_CACHE_CHUNK);
#if defined (T33_INCLUDE) || defined (T42_INCLUDE)
        if (lPos < 0)
            {
            iResult = fseek (fp, 0L, SEEK_SET);
            if (iResult)
                {
#if defined (STOP_ON_ERROR)
                printf ("*** Unable to seek file %s offset %08X\n",
                        pszFileName, 0);
                fflush (stdout);
                exit(1);
#endif
				goto ERROR_LABEL;
                }
            do
                {
                iResult = fseek (fp, 0x40000000, SEEK_CUR);
                if (iResult)
                    {
#if defined (STOP_ON_ERROR)
                    printf ("*** Unable to seek file %s offset %08X\n",
                            pszFileName, 0x40000000);
                    fflush (stdout);
                    exit(1);
#endif
				    goto ERROR_LABEL;
                    }
                lPos -= 0x40000000;
                } while (lPos < 0);
            iResult = fseek (fp, lPos, SEEK_CUR);
            }
        else
#endif
            iResult = fseek (fp, lPos, SEEK_SET);
		// Read uncompressed file
		if (iResult)
            {
#if defined (STOP_ON_ERROR)
            printf ("*** Unable to seek file %s offset %08X\n",
                    pszFileName, lPos);
            fflush (stdout);
            exit(1);
#endif
			goto ERROR_LABEL;
            }
		cb = fread (ptbc->m_pbData, 1, TB_CB_CACHE_CHUNK, fp);
		if (cb != TB_CB_CACHE_CHUNK)
			{
			// Could not read TB_CB_CACHE_CHUNK - check for error
			if (ferror (fp) || ((size_t) -1 == cb))
                {
#if defined (STOP_ON_ERROR)
                printf ("*** Read error, file %s\n", pszFileName);
                fflush (stdout);
                exit(1);
#endif
				goto ERROR_LABEL;
                }
			}
		Unlock (ptbd->m_rglockFiles[side]);
		}
	else
		{
		// Read compressed file
		int	fWasError;
		decode_block	*block;
		decode_info		*info = ptbd->m_rgpdiDecodeInfo[side][iExtent];

#if defined (SMP)
		// Find free decode block
		decode_block	**pBlock;

		Lock (lockDecode);
		pBlock = rgpdbDecodeBlocks;
		while (NULL == *pBlock)
			pBlock ++;
		block = *pBlock;
		*pBlock = NULL;
		Unlock (lockDecode);
#else
		block = rgpdbDecodeBlocks[0];
#endif

		// Initialize decode block and read chunk
		fWasError = 0 != comp_init_block (block, TB_CB_CACHE_CHUNK, ptbc->m_pbData) ||
					0 != comp_read_block (block, info, fp, iPhysicalChunk);

		// Release lock on file, so other threads can proceed with that file
		Unlock (ptbd->m_rglockFiles[side]);

		// Decompress chunk
		if (!fWasError)
			fWasError |= (0 != comp_decode_and_check_crc (block, info, block->orig.size,
TB_CRC_CHECK));

		// Release block
#if defined (SMP)
		Lock (lockDecode);
		*pBlock = block;
		Unlock (lockDecode);
#endif

		// Read Ok?
		if (fWasError)
            {
#if defined (STOP_ON_ERROR)
            printf ("*** Decompression error, file %s\n", pszFileName);
            fflush (stdout);
            exit(1);
#endif
			goto ERROR_LABEL_2;
            }
		}

	// Read - now acquire locks and insert cache entry in both lists
	Lock (ptbd->m_prgtbcbBuckets[side][iDirectory].m_lock);
	Lock (lockLRU);

	// Insert cache entry into general LRU list
	ptbc->m_ptbcPrev = NULL;
	ptbc->m_ptbcNext = ptbcHead;
	if (NULL == ptbcHead)
		ptbcTail = ptbc;
	else
		ptbcHead->m_ptbcPrev = ptbc;
	ptbcHead = ptbc;

	// Insert cache entry into cache bucket LRU list
	ptbc->m_ptbcTbPrev = NULL;
	ptbc->m_ptbcTbNext = ptbd->m_prgtbcbBuckets[side][iDirectory].m_ptbcFirst;
	if (NULL != ptbc->m_ptbcTbNext)
		ptbc->m_ptbcTbNext->m_ptbcTbPrev = ptbc;
	ptbd->m_prgtbcbBuckets[side][iDirectory].m_ptbcFirst = ptbc;

	// All done
	int tb;

	tb = (tb_t) (ptbc->m_pbData[indInChunk]);
	// Release locks
	Unlock (ptbd->m_prgtbcbBuckets[side][iDirectory].m_lock);
	Unlock (lockLRU);
	return tb;

	// I/O error. Here I don't want to halt the program, because that can
	// happen in the middle of the important game. Just return failure.
ERROR_LABEL:
	Unlock (ptbd->m_rglockFiles[side]);
ERROR_LABEL_2:
	Lock (lockLRU);
	ptbd->m_rgpchFileName[side][iExtent] = NULL;
	ptbc->m_ptbcNext = ptbcFree;
	ptbcFree = ptbc;
	Unlock (lockLRU);
	return L_bev_broken;
	}

// Probe TB - upper level function

static int	TB_FASTCALL TbtProbeTable
	(
	int		iTb,
	color	side,
	INDEX	indOffset
	)
	{
	CTbDesc	*ptbd;

	assert (iTb > 0 && iTb < cTb);
	ptbd = & rgtbdDesc[iTb];
	if (ptbd->m_fSymmetric)
		side = x_colorWhite;

	// It's better for offset be smaller than TB size
	assert (!FRegistered (iTb, side) || indOffset < ptbd->m_rgcbLength[side]);

	// Entire file read/mapped to memory?
	if (NULL != ptbd->m_rgpbRead[side])
		return (tb_t) ptbd->m_rgpbRead[side][indOffset];

	// Cache initialized? TB registered?
	if (0 == ctbcTbCache || NULL == ptbd->m_prgtbcbBuckets[side])
		return bev_broken;

#if defined (T33_INCLUDE) || defined (KPPKP_16BIT)
    if (ptbd->m_f16bit)
        return bev_broken;
#endif

	int tb;

	tb = TbtProbeTable (iTb, side,(unsigned) TB_CHUNK (indOffset), (unsigned)
TB_OFFSET (indOffset));
	return (L_bev_broken == tb) ? bev_broken : (tb_t) tb;
	}

// 16-bit version (recommended)

#define FOutOfBound(iTb, side, indOffset)\
		(tbid_kppkp == iTb && x_colorBlack == side &&\
		 (indOffset == 0x0362BC7C || indOffset == 0x0362DE44 || indOffset ==
0x03637648 ||\
		  indOffset == 0x03639810 || indOffset == 0x038D4F29 || indOffset ==
0x040A2CAB ||\
		  indOffset == 0x043C778C))

extern "C" int TB_FASTCALL L_TbtProbeTable
	(
	int		iTb,
	color	side,
	INDEX	indOffset
	)
	{
	int	tbtScore;
	CTbDesc	*ptbd;

	assert (iTb > 0 && iTb < cTb);
	ptbd = & rgtbdDesc[iTb];
	if (ptbd->m_fSymmetric)
		side = x_colorWhite;

	// Entire file read/mapped to memory?
	if (NULL != ptbd->m_rgpbRead[side])
        {
#if defined (KPPKP_16BIT)
    	if (!ptbd->m_f16bit)
			{
			tbtScore = (tb_t) ptbd->m_rgpbRead[side][indOffset];
	    	return S_to_L (tbtScore);
			}
        else
	    	return (((int) (((signed char) ptbd->m_rgpbRead[side][indOffset*2+1]))) <<
8) +
                    ptbd->m_rgpbRead[side][indOffset*2];
#elif defined (T33_INCLUDE)
    	if (!ptbd->m_f16bit)
            {
		    if (FOutOfBound (iTb, side, indOffset))
			    return -32639;
            else
				{
				tbtScore = (tb_t) ptbd->m_rgpbRead[side][indOffset];
	    	    return S_to_L (tbtScore);
				}
            }
        else
	    	return (((int) (((signed char) ptbd->m_rgpbRead[side][indOffset*2+1]))) <<
8) +
                    ptbd->m_rgpbRead[side][indOffset*2];
#else
		if (FOutOfBound (iTb, side, indOffset))
			return -32639;
        else
			{
			tbtScore = (tb_t) ptbd->m_rgpbRead[side][indOffset];
	    	return S_to_L (tbtScore);
			}
#endif
        }

	// Cache initialized? TB registered?
	if (0 == ctbcTbCache || NULL == ptbd->m_prgtbcbBuckets[side])
		return L_bev_broken;

#if defined (T33_INCLUDE)
	if (ptbd->m_f16bit)
		{
		// Inefficient, but very simple, code
		int	iLo;
		int	iHi;

		iLo = TbtProbeTable (iTb, side, (unsigned) WIDE_TB_CHUNK (indOffset),
(unsigned) WIDE_TB_OFFSET (indOffset));
		iHi = TbtProbeTable (iTb, side, (unsigned) WIDE_TB_CHUNK (indOffset),
(unsigned) WIDE_TB_OFFSET (indOffset)+1);
        tbtScore = (L_bev_broken == iLo || L_bev_broken == iHi) ? L_bev_broken :
((iHi << 8) + (iLo & 0xFF));
		}
	else
		{
#if !defined (KPPKP_16BIT)
		if (FOutOfBound (iTb, side, indOffset))
			return -32639;
#endif
		tbtScore = TbtProbeTable (iTb, side, (unsigned) TB_CHUNK (indOffset),
(unsigned) TB_OFFSET (indOffset));
		tbtScore = L_bev_broken == tbtScore ? L_bev_broken : S_to_L (tbtScore);
		}
#elif !defined (KPPKP_16BIT)
	if (FOutOfBound (iTb, side, indOffset))
		return -32639;
	tbtScore = TbtProbeTable (iTb, side, (unsigned) TB_CHUNK (indOffset),
(unsigned) TB_OFFSET (indOffset));
	tbtScore = L_bev_broken == tbtScore ? L_bev_broken : S_to_L (tbtScore);
#else
	if (tbid_kppkp != iTb)
		{
		// All tables but kppkp are 8-bit tables
		tbtScore = TbtProbeTable (iTb, side, (unsigned) TB_CHUNK (indOffset),
(unsigned) TB_OFFSET (indOffset));
		tbtScore = L_bev_broken == tbtScore ? L_bev_broken : S_to_L (tbtScore);
		}
	else
		{
		// Special handling of kppkp - it's 16-bit table
		// Inefficient, but very simple, code
		int	iLo;
		int	iHi;

		iLo = TbtProbeTable (iTb, side, (unsigned) WIDE_TB_CHUNK (indOffset),
(unsigned) WIDE_TB_OFFSET (indOffset));
		iHi = TbtProbeTable (iTb, side, (unsigned) WIDE_TB_CHUNK (indOffset),
(unsigned) WIDE_TB_OFFSET (indOffset)+1);
        tbtScore = (L_bev_broken == iLo || L_bev_broken == iHi) ? L_bev_broken :
((iHi << 8) + (iLo & 0xFF));
		}
#endif
	return tbtScore;
	}

//-----------------------------------------------------------------------------
//
//	Global initialization

// TODO: Check size of split tables, too

static void VCheckSize
    (
    int     iTb,
    color   side,
    int     iExtent,
    INDEX   cb,
    char    *rgchTbName
    )
    {
#if defined (NEW)
    INDEX   cbOk1, cbOk2;

	if (0 == rgtbdDesc[iTb].m_rgcbLength[side])
        return;

    cbOk1 = rgtbdDesc[iTb].m_rgcbLength[side];
    cbOk2 = cbOk1;
#if defined (T_INDEX64)
    if (rgtbdDesc[iTb].m_fSplit)
        {
        cbOk1 = (1u << (rgtbdDesc[iTb].m_f16bit ? 30 : 31));
        cbOk2 = cbOk2 % (1u << (rgtbdDesc[iTb].m_f16bit ? 30 : 31));
        }
#endif

    if (cb != cbOk1 && cb != cbOk2)
		{
		printf ("*** %s corrupted "
                DEC_INDEX_FORMAT" "DEC_INDEX_FORMAT" "DEC_INDEX_FORMAT"\n",
                rgchTbName, cbOk1, cbOk2, cb);
    	exit (1);
	    }
#endif
    }


#if defined (_WIN32) || defined (_WIN64)
int     iDrivesMap;
BOOL    rgfAccessed[26];
BOOL    rgfNotReady[26];
#endif

static int FCheckExtentExistance
	(
	char	*pszPath,
	int		iTb,
	color	side,
    int     iExtent
	)
	{
	FILE			*fp;
	char			*pchCopy;
	const char		*pchExt = PchExt (side);
	char			rgchTbName[1024];
    char            rgchExtent[4];
	CTbCacheBucket	*prgtbcbBuckets;
	INDEX			cb;
	decode_info		*comp_info = NULL;
    int	            fWasError;
	decode_block	*block;
    BYTE            rgbBuffer[TB_CB_CACHE_CHUNK+32+4];

	if (FRegisteredExtent (iTb, side, iExtent) || NULL !=
rgtbdDesc[iTb].m_rgpbRead[side])
		return true;

#if defined (_WIN32) || defined (_WIN64)
    // Do not repeatedely probe device that is not ready
    // (i.e. unmapped disk or CD-ROM that does not contain the disk).
    if (NULL != pszPath && 0 != pszPath[0] && ':' == pszPath[1])
        {
        int  iDrive;
        char szRoot[5];
        WIN32_FIND_DATA fd;
        HANDLE hResult;

        iDrive = tolower(pszPath[0]) - 'a';
        if (iDrive >= 0 && iDrive < 26)
            {
            if (rgfNotReady[iDrive])
                return false;
            if (!rgfAccessed[iDrive])
                {
                if (iDrivesMap && 0 == (iDrivesMap & (1 << iDrive)))
                    return false;
                szRoot[0] = pszPath[0];
                szRoot[1] = pszPath[1];
                szRoot[2] = '\\';
                szRoot[3] = '*';
                szRoot[4] = 0;
                hResult = FindFirstFile (szRoot, &fd);
                if (INVALID_HANDLE_VALUE == hResult)
                    {
                    if (ERROR_NOT_READY == GetLastError())
                        {
                        rgfNotReady[iDrive] = true;
                        return false;
                        }
                    }
                else
                    FindClose (hResult);
                rgfAccessed[iDrive] = true;
                }
            }
        }
#endif

	strcpy (rgchTbName, pszPath);
	if (0 != pszPath[0] && DELIMITER[0] != pszPath[strlen(pszPath)-1])
		strcat (rgchTbName, DELIMITER);
	strcat (rgchTbName, rgtbdDesc[iTb].m_rgchName);
    if (rgtbdDesc[iTb].m_fSplit)
        {
        rgchExtent[0] = '.';
        rgchExtent[1] = (char) (iExtent + '0');
        rgchExtent[2] = '\0';
    	strcat (rgchTbName, rgchExtent);
        }
	strcat (rgchTbName, pchExt);
	fp = fopen (rgchTbName, "rb");
#if !defined (NEW) && !defined (_WIN32) && !defined(_WIN64)
	// For case-sensitive systems, have to try once more
	if (NULL == fp)
		{
		for (int i = strchr(rgchTbName,'.')-rgchTbName-1; i>=0 &&
isalpha(rgchTbName[i]); i--)
			rgchTbName[i] = toupper (rgchTbName[i]);
		fp = fopen (rgchTbName, "rb");
		}
#endif
	if (NULL != fp)
		{
		// Found uncompressed table
		if (rgtbdDesc[iTb].m_f16bit ||
            ((int)(cb = rgtbdDesc[iTb].m_rgcbLength[side])) < 0 ||
            cb != (unsigned) cb)
            {
            // Do not check the length for too large files
			cb = rgtbdDesc[iTb].m_rgcbLength[side];
            }
		else
            {
            if (0 != fseek (fp, 0L, SEEK_END))
			    {
			    printf ("*** Seek in %s failed\n", rgchTbName);
			    exit (1);
			    }
		    cb = (INDEX) ftell (fp);
            VCheckSize (iTb, side, iExtent, cb, rgchTbName);
            }
		}
	else
		{
		// Check for compressed table.
		// First, check for kxykz.nb?.emd
		strcat (rgchTbName, ".emd");
		fp = fopen (rgchTbName, "rb");
		if (NULL == fp)
			{
			// Check for kxykz_nb?.emd
			rgchTbName [strlen(rgchTbName)-8] = '_';
			fp = fopen (rgchTbName, "rb");
			}
		if (NULL == fp)
			{
			// Check for kxykz_nb?_emd
			rgchTbName [strlen(rgchTbName)-4] = '_';
			fp = fopen (rgchTbName, "rb");
			}
		if (NULL == fp)
			{
			// Check for kxykznb?.emd (8+3 format)
			int	cch;

			rgchTbName [strlen(rgchTbName)-4] = '.';
			cch = strlen (rgchTbName);
			memmove (rgchTbName+cch-8, rgchTbName+cch-7, 8);
			fp = fopen (rgchTbName, "rb");
			if (NULL == fp)
				return false;
			}
		cCompressed ++;
		int iResult = comp_open_file (&comp_info, fp, TB_CRC_CHECK);
		if (0 != iResult)
			{
			printf ("*** Unable to read %s - ", rgchTbName);
			switch (iResult & 0xFF)
				{
			case COMP_ERR_READ:
				printf ("read error\n");
				break;
			case COMP_ERR_NOMEM:
				printf ("out of memory\n");
				break;
			case COMP_ERR_BROKEN:
				printf ("file broken\n");
				break;
			default:
				printf ("error %d\n", iResult);
				break;
				}
			exit (1);
			}
		if (comp_info->block_size != TB_CB_CACHE_CHUNK)
			{
			printf ("*** %s: Unsupported block size %d\n", rgchTbName,
comp_info->block_size);
			exit (1);
			}
        if (rgtbdDesc[iTb].m_f16bit)
            {
    		cb = ((INDEX)comp_info->block_size/2)*(comp_info->n_blk-1) +
                  (INDEX)comp_info->last_block_size/2;
            VCheckSize (iTb, side, iExtent, cb, rgchTbName);
			}
		else
            {
    		cb = ((INDEX)comp_info->block_size)*(comp_info->n_blk-1) +
                 (INDEX)comp_info->last_block_size;
            VCheckSize (iTb, side, iExtent, cb, rgchTbName);
            }

#if SANITY_CHECK
		block = rgpdbDecodeBlocks[0];
        if (NULL == block)
            {
			int iResult = comp_alloc_block (&rgpdbDecodeBlocks[0], TB_CB_CACHE_CHUNK);
			if (0 != iResult)
				{
				printf ("*** Cannot allocate decode block: error code %d\n", iResult);
				exit (1);
				}
    		block = rgpdbDecodeBlocks[0];
            }
		// Initialize decode block and read chunk
		fWasError = 0 != comp_init_block (block, TB_CB_CACHE_CHUNK, rgbBuffer) ||
					0 != comp_read_block (block, comp_info, fp, TB_CHUNK (cb-1)) ||
                    0 != comp_decode_and_check_crc (block, comp_info,
block->orig.size, TB_CRC_CHECK);
        if (fWasError)
		    {
		    printf ("*** Sanity check on %s failed\n", rgchTbName);
		    exit (1);
		    }
#endif
        }

	fclose (fp);
	if (FRegisterTb (& (rgtbdDesc[iTb])))
		{
		pchCopy = (char*) PvMalloc (strlen(rgchTbName)+1);
		strcpy (pchCopy, rgchTbName);
        free (rgtbdDesc[iTb].m_rgpchFileName[side][iExtent]);
		rgtbdDesc[iTb].m_rgpchFileName[side][iExtent] = pchCopy;
        if (NULL == rgtbdDesc[iTb].m_prgtbcbBuckets[side])
            {
		    prgtbcbBuckets = (CTbCacheBucket*) PvMalloc
(TB_DIRECTORY_SIZE*sizeof(CTbCacheBucket));
		    memset (prgtbcbBuckets, 0, TB_DIRECTORY_SIZE*sizeof(CTbCacheBucket));
#if defined (SMP)
		    for (int i = 0; i < TB_DIRECTORY_SIZE; i ++)
			    LockInit (prgtbcbBuckets[i].m_lock);
#endif
		    rgtbdDesc[iTb].m_prgtbcbBuckets[side] = prgtbcbBuckets;
    		if (fVerbose)
	    		printf ("%s registered\n", pchCopy);
            }
        else
            {
    		if (fVerbose)
	    		printf ("%s found\n", pchCopy);
            }
		rgtbdDesc[iTb].m_rgpdiDecodeInfo[side][iExtent] = comp_info;
		return true;
		}
	else
		{
		printf ("*** Unable to register %s\n", rgchTbName);
		exit (1);
		}
	return false;
	}

int FCheckExistance
	(
	char	*pszPath,
	int		iTb,
	color	side
	)
    {
    int  fFound;
    int  cExtents;

    cExtents = rgtbdDesc[iTb].m_fSplit ? MAX_EXTENTS : 1;
    fFound = false;
    for (int iExtent = 0; iExtent < cExtents; iExtent++)
        fFound |= FCheckExtentExistance (pszPath, iTb, side, iExtent);
    return fFound;
    }

extern "C" int IInitializeTb
	(
	char *pszPath
	)
	{
	char	szTemp[1024];
	color	sd;
	int		iTb, iMaxTb, iExtent, i;
	CTbCacheBucket	*prgtbcbBuckets;

#if defined (_WIN32) || defined (_WIN64)
    // For Windows, get bit map of ready devices
    iDrivesMap = GetLogicalDrives();
    memset (rgfAccessed, 0, sizeof(rgfAccessed));
    memset (rgfNotReady, 0, sizeof(rgfNotReady));
#endif

	cbAllocated = cbEGTBCompBytes = 0;
	// If there are open files, close those
	VTbCloseFiles ();
#if defined (SMP)
	// Init all locks
	LockInit (lockLRU);
	LockInit (lockDecode);
	for (iTb = 1; iTb < cTb; iTb ++)
		{
		LockInit (rgtbdDesc[iTb].m_rglockFiles[x_colorWhite]);
		LockInit (rgtbdDesc[iTb].m_rglockFiles[x_colorBlack]);
		}
#endif
#if defined (NEW)
	// Create enumeration tables
	VInitEnumerations ();
#endif
	// Create empty TB search table
	VCreateEmptyTbTable ();
	// Free memory from TB table
	for (iTb = 1; iTb < cTb; iTb ++)
		{
		for (sd = x_colorWhite; sd <= x_colorBlack; sd = (color) (sd + 1))
			{
			if (NULL != rgtbdDesc[iTb].m_prgtbcbBuckets[sd] &&
				NULL == rgtbdDesc[iTb].m_rgpbRead[sd])
				{
                prgtbcbBuckets = rgtbdDesc[iTb].m_prgtbcbBuckets[sd];
#if defined (SMP)
		        for (i = 0; i < TB_DIRECTORY_SIZE; i ++)
			        LockFree (prgtbcbBuckets[i].m_lock);
#endif
				free (prgtbcbBuckets);
				rgtbdDesc[iTb].m_prgtbcbBuckets[sd] = NULL;
				}
            for (iExtent = 0; iExtent < MAX_EXTENTS; iExtent ++)
                {
			    if (NULL != rgtbdDesc[iTb].m_rgpchFileName[sd][iExtent])
				    {
				    free (rgtbdDesc[iTb].m_rgpchFileName[sd][iExtent]);
				    rgtbdDesc[iTb].m_rgpchFileName[sd][iExtent] = NULL;
				    }
				if (NULL != rgtbdDesc[iTb].m_rgpdiDecodeInfo[sd][iExtent])
					{
					free (rgtbdDesc[iTb].m_rgpdiDecodeInfo[sd][iExtent]);
					rgtbdDesc[iTb].m_rgpdiDecodeInfo[sd][iExtent] = NULL;
					}
                }
			}
		}
	// Free compressed blocks
	for (i = 0; i < CPUS; i ++)
		{
		if (NULL != rgpdbDecodeBlocks[i])
			{
			free (rgpdbDecodeBlocks[i]);
			rgpdbDecodeBlocks[i] = NULL;
			}
		}
	// Search for existing TBs
	iMaxTb = 0;
	for (;;)
		{
		for (i = 0; pszPath[i] != '\0' && pszPath[i] != ',' && pszPath[i] != ';'
#if !defined (_WIN32) && !defined (__MWERKS__) && !defined(_WIN64)
			 && pszPath[i] != ':'
#endif
			 ; i ++)
			{
			szTemp[i] = pszPath[i];
			}
		szTemp[i] = '\0';
		for (iTb = 1; iTb < cTb; iTb ++)
			{
			if (FCheckExistance (szTemp, iTb, x_colorWhite))
				{
				if (iTb > iMaxTb)
					iMaxTb = iTb;
				}
		if (! rgtbdDesc[iTb].m_fSymmetric && FCheckExistance (szTemp, iTb,
x_colorBlack))
				{
				if (iTb > iMaxTb)
					iMaxTb = iTb;
				}
			}
		pszPath += i;
		if ('\0' == *pszPath)
			break;
		pszPath ++;
		}

	// If there were compressed files, have to allocate buffer(s)
	if (0 != cCompressed)
		{
		for (i = 0; i < CPUS; i ++)
			{
            if (NULL == rgpdbDecodeBlocks[i])
                {
			    int iResult = comp_alloc_block (&rgpdbDecodeBlocks[i],
TB_CB_CACHE_CHUNK);
			    if (0 != iResult)
				    {
				    printf ("*** Cannot allocate decode block: error code %d\n", iResult);
				    exit (1);
				    }
            }
			}
		if (fVerbose)
			printf ("Allocated %dKb for decompression tables, indices, and buffers.\n",
					(cbEGTBCompBytes+1023)/1024);
		}

	// All done!
#if defined T33_INCLUDE
	if (iMaxTb >= tbid_knnknn)
		return 6;
#elif defined (T42_INCLUDE)
	if (iMaxTb >= tbid_knnnkn)
		return 6;
#endif
	if (iMaxTb >= tbid_kppkp)
		return 5;
	if (iMaxTb >= tbid_kpkp)
		return 4;
	if (iMaxTb >= tbid_kpk)
		return 3;
	return 0;
	}



This page took 0.01 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.