int movegen_w(move *movelist,long long from_squares,long long to_squares)
{
 unsigned char from_nr=0,rank_pattern,file_pattern,a1h8_pattern,a8h1_pattern;
 int movenr=0;
 register long long from,to,froms,tos;
 register long long pawn_fields_empty;		// bitboard of empty fields in front of pawns

// following two lines needed, e.g. because of the format of the rook_moves and bishop_moves tables !
// because of them its clear that movegen_w produces only (pseudo) legal moves for white

 from_squares &= board.w_occ;		// only white pieces allowed in movegen_w !
 to_squares &= (~board.w_occ);		// you cannot move to a square that is occupied by a piece of your own colour !


// WHITE PAWNS (captures right)
	tos = ( (board.pawns & NOT_RIGHT_EDGE & from_squares) << 9) & board.b_occ & to_squares; 	

	froms = tos >> 9;
	while (from = GET_LSB(froms))
	{
			board.w_attacks |= from;
		        movelist[movenr].from = from;
			movelist[movenr].to = GET_LSB(tos);			
                        movelist[movenr].det.ll = 0;
			movelist[movenr].det.ail.piece = PAWN;
			movelist[movenr].det.ail.flags |= NORMAL_CAPTURE;
			movenr++;
			CLEAR_LSB(tos);
		        CLEAR_LSB(froms);
	};

// WHITE PAWNS (captures left)
	tos = ( (board.pawns & NOT_LEFT_EDGE & from_squares) << 7) & board.b_occ & to_squares;
	froms = tos >> 7;
	while (from = GET_LSB(froms))
	{
			board.w_attacks |= from;
		        movelist[movenr].from = from;
			movelist[movenr].to = GET_LSB(tos);			
                        movelist[movenr].det.ll = 0;
			movelist[movenr].det.ail.piece = PAWN;
			movelist[movenr].det.ail.flags |= NORMAL_CAPTURE;
			movenr++;
			CLEAR_LSB(tos);
		        CLEAR_LSB(froms);
	};

// WHITE PAWNS (one step)
	pawn_fields_empty = ( (board.pawns & from_squares) << 8) & (~board.occ.ll);	// bitboard of empty fields in front of pawns
        tos = pawn_fields_empty & to_squares;
	froms = tos >> 8;		
	while (from = GET_LSB(froms))
	{
			board.w_attacks |= from;
	 		movelist[movenr].from = from;
			movelist[movenr].to = GET_LSB(tos);			
                        movelist[movenr].det.ll = 0;
			movelist[movenr].det.ail.piece = PAWN;
			movelist[movenr].det.ail.flags = 0;
			movenr++;
			CLEAR_LSB(tos);
	                CLEAR_LSB(froms);
	};

// WHITE PAWNS (two steps)
	tos = ( (pawn_fields_empty & RANK_3) << 8) & (~board.occ.ll);			// empty fields in front of pawns, the empty fields must be on
											// RANK_3 because the pawns have to on RANK_2 to move two steps !!
	froms = tos >> 16;
	while (from = GET_LSB(froms))
	{
			board.w_attacks |= from;
		        movelist[movenr].from = from;
			movelist[movenr].to = GET_LSB(tos);			
                        movelist[movenr].det.ll = 0;
			movelist[movenr].det.ail.piece = PAWN;
			movelist[movenr].det.ail.flags = 0 | PAWN_TWO_STEPS;
			movenr++;
			CLEAR_LSB(tos);
		        CLEAR_LSB(froms);
	};


// WHITE KNIGHT
	froms = board.knights & from_squares;
	while (from = GET_LSB(froms))
	{
		from_nr = (bit[board.w_figpos[KNIGHT][0]] & from ? board.w_figpos[KNIGHT][0] : board.w_figpos[KNIGHT][1]);

		tos = knight_moves[from_nr] & to_squares;

		while (to = GET_LSB(tos))
		{
			board.w_attacks |= from;
			movelist[movenr].from = from;
			movelist[movenr].to = to;			
                        movelist[movenr].det.ll = 0;
			movelist[movenr].det.ail.piece = KNIGHT;
			movelist[movenr].det.ail.from_nr = from_nr;
			movelist[movenr].det.ail.flags |= FROM_NR_COMPUTED;
                        if (board.b_occ & to) movelist[movenr].det.ail.flags |= NORMAL_CAPTURE;
			movenr++;
			CLEAR_LSB(tos);
		};	
	        CLEAR_LSB(froms);
	};


// WHITE ROOK
	froms = board.rooks & from_squares;
	while (from = GET_LSB(froms))
	{
		from_nr = (bit[board.w_figpos[ROOK][0]] & from ? board.w_figpos[ROOK][0] : board.w_figpos[ROOK][1]);
		
		rank_pattern = board.occ.byte[from_nr >> 3];
		file_pattern = board.occ_l90.byte[l90_to_normal[from_nr] >> 3];

		tos = (rank_moves[from_nr][rank_pattern] | file_moves[from_nr][file_pattern]) & to_squares;

		while (to = GET_LSB(tos))
		{
			board.w_attacks |= from;
			movelist[movenr].from = from;
			movelist[movenr].to = to;			
                        movelist[movenr].det.ll = 0;
			movelist[movenr].det.ail.piece = ROOK;
			movelist[movenr].det.ail.from_nr = from_nr;
			movelist[movenr].det.ail.flags |= FROM_NR_COMPUTED;
                        if (board.b_occ & to) movelist[movenr].det.ail.flags |= NORMAL_CAPTURE;
			movenr++;
			CLEAR_LSB(tos);
		};	
	        CLEAR_LSB(froms);
	};

// WHITE BISHOP
	froms = board.bishops & from_squares;
	while (from = GET_LSB(froms))
	{
		from_nr = (bit[board.w_figpos[BISHOP][0]] & from ? board.w_figpos[BISHOP][0] : board.w_figpos[BISHOP][1]);

		a1h8_pattern = board.occ_a1h8.byte[a1h8_to_normal[from_nr] >> 3];
		a8h1_pattern = board.occ_a8h1.byte[a8h1_to_normal[from_nr] >> 3];

		tos = (a1h8_moves[from_nr][a1h8_pattern] | a8h1_moves[from_nr][a8h1_pattern]) & to_squares;

		while (to = GET_LSB(tos))
		{
			board.w_attacks |= from;
			movelist[movenr].from = from;
			movelist[movenr].to = to;			
                        movelist[movenr].det.ll = 0;
			movelist[movenr].det.ail.piece = BISHOP;
			movelist[movenr].det.ail.from_nr = from_nr;
			movelist[movenr].det.ail.flags |= FROM_NR_COMPUTED;
                        if (board.b_occ & to) movelist[movenr].det.ail.flags |= NORMAL_CAPTURE;
			movenr++;
			CLEAR_LSB(tos);
		};	
	        CLEAR_LSB(froms);
	};

// WHITE QUEEN
	froms = board.queens & from_squares;
	while (from = GET_LSB(froms))
	{
		from_nr = board.w_figpos[QUEEN][0];

		a1h8_pattern = board.occ_a1h8.byte[a1h8_to_normal[from_nr] >> 3];
		a8h1_pattern = board.occ_a8h1.byte[a8h1_to_normal[from_nr] >> 3];

		tos = (a1h8_moves[from_nr][a1h8_pattern] | a8h1_moves[from_nr][a8h1_pattern]) & to_squares;

		rank_pattern = board.occ.byte[from_nr >> 3];
		file_pattern = board.occ_l90.byte[l90_to_normal[from_nr] >> 3];

		tos = tos | ((rank_moves[from_nr][rank_pattern] | file_moves[from_nr][file_pattern]) & to_squares);

		while (to = GET_LSB(tos))
		{
			board.w_attacks |= from;
			movelist[movenr].from = from;
			movelist[movenr].to = to;			
                        movelist[movenr].det.ll = 0;
			movelist[movenr].det.ail.piece = QUEEN;
			movelist[movenr].det.ail.from_nr = from_nr;
			movelist[movenr].det.ail.flags |= FROM_NR_COMPUTED;
                        if (board.b_occ & to) movelist[movenr].det.ail.flags |= NORMAL_CAPTURE;
			movenr++;
			CLEAR_LSB(tos);
		};	
	        CLEAR_LSB(froms);
	};



// WHITE KING
	froms = board.kings & from_squares;
	while (from = GET_LSB(froms))
	{
		from_nr = board.w_figpos[KING][0];
		tos = king_moves[from_nr] & to_squares;
		while (to = GET_LSB(tos))
		{
			board.w_attacks |= from;
			movelist[movenr].from = from;
			movelist[movenr].to = to;			
                        movelist[movenr].det.ll = 0;
			movelist[movenr].det.ail.piece = KING;
			movelist[movenr].det.ail.from_nr = from_nr;
			movelist[movenr].det.ail.flags |= FROM_NR_COMPUTED;
                        if (board.b_occ & to) movelist[movenr].det.ail.flags |= NORMAL_CAPTURE;
			movenr++;
			CLEAR_LSB(tos);
		};	
	        CLEAR_LSB(froms);
	};

/*

// CASTLES
	if (board.flags & MAY_WHITE_CASTLE)
	{
	 if (board.flags & MAY_WHITE_CA

*/


 return movenr;
}



int movegen_b(move *movelist,long long from_squares,long long to_squares)
{
 unsigned char from_nr=0,rank_pattern,file_pattern,a1h8_pattern,a8h1_pattern;
 int movenr=0;
 register long long from,to,froms,tos;
 register long long pawn_fields_empty;		// bitboard of empty fields in front of pawns

// following two lines needed, e.g. because of the format of the rook_moves and bishop_moves tables !
// because of them its clear that movegen_w produces only (pseudo) legal moves for white

 from_squares &= board.b_occ;		// only white pieces allowed in movegen_w !
 to_squares &= (~board.b_occ);		// you cannot move to a square that is occupied by a piece of your own colour !


// BLACK PAWNS (captures right)
	tos = ( (board.pawns & NOT_RIGHT_EDGE & from_squares) >> 7) & board.w_occ & to_squares; 	

	froms = tos << 7;
	while (from = GET_LSB(froms))
	{
			board.b_attacks |= from;
		        movelist[movenr].from = from;
			movelist[movenr].to = GET_LSB(tos);			
                        movelist[movenr].det.ll = 0;
			movelist[movenr].det.ail.piece = -PAWN;
			movelist[movenr].det.ail.flags |= NORMAL_CAPTURE;
			movenr++;
			CLEAR_LSB(tos);
		        CLEAR_LSB(froms);
	};

// BLACK PAWNS (captures left)
	tos = ( (board.pawns & NOT_LEFT_EDGE & from_squares) >> 9) & board.w_occ & to_squares;
	froms = tos << 9;
	while (from = GET_LSB(froms))
	{
			board.b_attacks |= from;
		        movelist[movenr].from = from;
			movelist[movenr].to = GET_LSB(tos);			
                        movelist[movenr].det.ll = 0;
			movelist[movenr].det.ail.piece = -PAWN;
			movelist[movenr].det.ail.flags |= NORMAL_CAPTURE;
			movenr++;
			CLEAR_LSB(tos);
		        CLEAR_LSB(froms);
	};

// BLACK PAWNS (one step)
	pawn_fields_empty = ( (board.pawns & from_squares) >> 8) & (~board.occ.ll);	// bitboard of empty fields in front of pawns
        tos = pawn_fields_empty & to_squares;
	froms = tos << 8;		
	while (from = GET_LSB(froms))
	{
			board.b_attacks |= from;
	 		movelist[movenr].from = from;
			movelist[movenr].to = GET_LSB(tos);			
                        movelist[movenr].det.ll = 0;
			movelist[movenr].det.ail.piece = -PAWN;
			movelist[movenr].det.ail.flags = 0;
			movenr++;
			CLEAR_LSB(tos);
	                CLEAR_LSB(froms);
	};

// BLACK PAWNS (two steps)
	tos = ( (pawn_fields_empty & RANK_6) >> 8) & (~board.occ.ll);			// empty fields in front of pawns, the empty fields must be on
											// RANK_3 because the pawns have to on RANK_2 to move two steps !!
	froms = tos << 16;
	while (from = GET_LSB(froms))
	{
			board.b_attacks |= from;
		        movelist[movenr].from = from;
			movelist[movenr].to = GET_LSB(tos);			
                        movelist[movenr].det.ll = 0;
			movelist[movenr].det.ail.piece = -PAWN;
			movelist[movenr].det.ail.flags = 0 | PAWN_TWO_STEPS;
			movenr++;
			CLEAR_LSB(tos);
		        CLEAR_LSB(froms);
	};


// BLACK KNIGHT
	froms = board.knights & from_squares;
	while (from = GET_LSB(froms))
	{
		from_nr = ( (bit[board.b_figpos[KNIGHT][0]] & from) == 0 ? board.b_figpos[KNIGHT][0] : board.b_figpos[KNIGHT][1]);						

		tos = knight_moves[from_nr] & to_squares;

		while (to = GET_LSB(tos))
		{
			board.b_attacks |= from;
			movelist[movenr].from = from;
			movelist[movenr].to = to;			
                        movelist[movenr].det.ll = 0;
			movelist[movenr].det.ail.piece = -KNIGHT;
			movelist[movenr].det.ail.from_nr = from_nr;
			movelist[movenr].det.ail.flags |= FROM_NR_COMPUTED;
                        if (board.w_occ & to) movelist[movenr].det.ail.flags |= NORMAL_CAPTURE;
			movenr++;
			CLEAR_LSB(tos);
		};	
	        CLEAR_LSB(froms);
	};


// BLACK ROOK
	froms = board.rooks & from_squares;
	while (from = GET_LSB(froms))
	{
		from_nr = ( (bit[board.b_figpos[ROOK][0]] & from) ==  ? board.b_figpos[ROOK][1] : board.b_figpos[ROOK][2]);								

		rank_pattern = board.occ.byte[from_nr >> 3];
		file_pattern = board.occ_l90.byte[l90_to_normal[from_nr] >> 3];

		tos = (rank_moves[from_nr][rank_pattern] | file_moves[from_nr][file_pattern]) & to_squares;

		while (to = GET_LSB(tos))
		{
			board.b_attacks |= from;
			movelist[movenr].from = from;
			movelist[movenr].to = to;			
                        movelist[movenr].det.ll = 0;
			movelist[movenr].det.ail.piece = -ROOK;
			movelist[movenr].det.ail.from_nr = from_nr;
			movelist[movenr].det.ail.flags |= FROM_NR_COMPUTED;
                        if (board.w_occ & to) movelist[movenr].det.ail.flags |= NORMAL_CAPTURE;
			movenr++;
			CLEAR_LSB(tos);
		};	
	        CLEAR_LSB(froms);
	};

// BLACK BISHOP
	froms = board.bishops & from_squares;
	while (from = GET_LSB(froms))
	{
		from_nr = (bit[board.b_figpos[BISHOP][0]] & from ? board.b_figpos[BISHOP][0] : board.b_figpos[BISHOP][1]);								

		a1h8_pattern = board.occ_a1h8.byte[a1h8_to_normal[from_nr] >> 3];
		a8h1_pattern = board.occ_a8h1.byte[a8h1_to_normal[from_nr] >> 3];

		tos = (a1h8_moves[from_nr][a1h8_pattern] | a8h1_moves[from_nr][a8h1_pattern]) & to_squares;

		while (to = GET_LSB(tos))
		{
			board.b_attacks |= from;
			movelist[movenr].from = from;
			movelist[movenr].to = to;			
                        movelist[movenr].det.ll = 0;
			movelist[movenr].det.ail.piece = -BISHOP;
			movelist[movenr].det.ail.from_nr = from_nr;
			movelist[movenr].det.ail.flags |= FROM_NR_COMPUTED;
                        if (board.w_occ & to) movelist[movenr].det.ail.flags |= NORMAL_CAPTURE;
			movenr++;
			CLEAR_LSB(tos);
		};	
	        CLEAR_LSB(froms);
	};

// BLACK QUEEN
	froms = board.queens & from_squares;
	while (from = GET_LSB(froms))
	{
		from_nr = board.b_figpos[QUEEN][0];

		a1h8_pattern = board.occ_a1h8.byte[a1h8_to_normal[from_nr] >> 3];
		a8h1_pattern = board.occ_a8h1.byte[a8h1_to_normal[from_nr] >> 3];

		tos = (a1h8_moves[from_nr][a1h8_pattern] | a8h1_moves[from_nr][a8h1_pattern]) & to_squares;

		rank_pattern = board.occ.byte[from_nr >> 3];
		file_pattern = board.occ_l90.byte[l90_to_normal[from_nr] >> 3];

		tos = tos | ((rank_moves[from_nr][rank_pattern] | file_moves[from_nr][file_pattern]) & to_squares);

		while (to = GET_LSB(tos))
		{
			board.b_attacks |= from;
			movelist[movenr].from = from;
			movelist[movenr].to = to;			
                        movelist[movenr].det.ll = 0;
			movelist[movenr].det.ail.piece = -QUEEN;
			movelist[movenr].det.ail.from_nr = from_nr;
			movelist[movenr].det.ail.flags |= FROM_NR_COMPUTED;
                        if (board.w_occ & to) movelist[movenr].det.ail.flags |= NORMAL_CAPTURE;
			movenr++;
			CLEAR_LSB(tos);
		};	
	        CLEAR_LSB(froms);
	};



// BLACK KING
	froms = board.kings & from_squares;
	while (from = GET_LSB(froms))
	{
		from_nr = board.b_figpos[KING][0];
		tos = king_moves[from_nr] & to_squares;
		while (to = GET_LSB(tos))
		{
			board.b_attacks |= from;
			movelist[movenr].from = from;
			movelist[movenr].to = to;			
                        movelist[movenr].det.ll = 0;
			movelist[movenr].det.ail.piece = -KING;
			movelist[movenr].det.ail.from_nr = from_nr;
			movelist[movenr].det.ail.flags |= FROM_NR_COMPUTED;
                        if (board.w_occ & to) movelist[movenr].det.ail.flags |= NORMAL_CAPTURE;
			movenr++;
			CLEAR_LSB(tos);
		};	
	        CLEAR_LSB(froms);
	};

/*

// CASTLES
	if (board.flags & MAY_BLACK_CASTLE)
	{

*/


 return movenr;
}
