static int probe_tb2(struct Player *player, struct Player *opp, bitboard player_occ, bitboard opp_occ, int alpha, int beta) { int i, j; bitboard player_att[5]; bitboard opp_att[5]; // first try captures if (opp->num > 1) { int capts = 0; for (i = 0; i < player->num; i++) { int from = player->pos[i]; bitboard bb = PieceRange(from, player->type[i], player_occ | opp_occ); player_att[i] = bb; bb &= opp_occ; if (bb) { capts = 1; opp->num--; bitboard occ2 = player_occ ^ bit[from]; do { int to = FirstOne(bb); player->pos[i] = to; for (j = 0; opp->pos[j] != to; j++); int tmp_type = opp->type[j]; opp->type[j] = opp->type[opp->num]; opp->pos[j] = opp->pos[opp->num]; #ifdef HAS_PAWNS if ((player->type[i] & 0x07) == PAWN && ((to + 0x08) & 0x30) == 0) { int t = player->type[i]; int m; for (m = KING - PAWN; m >= KNIGHT - PAWN; m--) { player->type[i] = t + m; int v = -probe_tb2(opp, player, opp_occ ^ bit[to], occ2 ^ bit[to], -beta, -alpha); if (v > alpha) { alpha = v; if (alpha >= beta) break; } } player->type[i] = t; } else { #endif int v = -probe_tb2(opp, player, opp_occ ^ bit[to], occ2 ^ bit[to], -beta, -alpha); if (v > alpha) alpha = v; #ifdef HAS_PAWNS } #endif opp->type[j] = tmp_type; opp->pos[j] = to; if (alpha >= beta) { player->pos[i] = from; opp->num++; return alpha; } ClearFirst(bb); } while (bb); player->pos[i] = from; opp->num++; } } if (capts) return alpha; } else { for (i = 0; i < player->num; i++) { bitboard bb = PieceRange(player->pos[i], player->type[i], player_occ); player_att[i] = bb; if (bb & opp_occ) return -2; } } #if 1 if (player->num + opp->num < 6) goto skip_threats; #endif // now try threats. there are two cases bitboard atts = 0ULL; for (i = 0; i < opp->num; i++) { opp_att[i] = PieceRange(opp->pos[i], opp->type[i], player_occ | opp_occ); atts |= opp_att[i]; } // first case: opponent currently is not attacking any pieces // we only need to consider moves moving into opponent attacks if (!(atts & player_occ)) { if (player->num > 1) { player->num--; for (i = 0; i <= player->num; i++) { #ifdef HAS_PAWNS if ((player->type[i] & 0x07) == 1) continue; #endif bitboard bb = player_att[i] & atts; if (!bb) continue; int pos = player->pos[i]; int type = player->type[i]; player->pos[i] = player->pos[player->num]; player->type[i] = player->type[player->num]; do { int sq = FirstOne(bb); int beta2 = beta; for (j = 0; j < opp->num; j++) { if (!(bit[sq] & opp_att[j])) continue; int tmp_pos = opp->pos[j]; opp->pos[j] = sq; #ifdef HAS_PAWNS if ((opp->type[j] & 0x07) == PAWN && ((sq + 0x08) & 0x30) == 0) { int t = opp->type[j]; int m; for (m = KING - PAWN; m >= KNIGHT - PAWN; m--) { opp->type[j] = t + m; int v = probe_tb2(player, opp, player_occ ^ bit[pos], opp_occ ^ bit[sq] ^ bit[tmp_pos], alpha, beta2); if (v < beta2) { beta2 = v; if (beta2 <= alpha) break; } } opp->type[j] = t; } else { #endif int v = probe_tb2(player, opp, player_occ ^ bit[pos], opp_occ ^ bit[sq] ^ bit[tmp_pos], alpha, beta2); if (v < beta2) beta2 = v; #ifdef HAS_PAWNS } #endif opp->pos[j] = tmp_pos; if (beta2 <= alpha) break; } if (beta2 > alpha) { if (beta2 >= beta) { player->pos[i] = pos; player->type[i] = type; player->num++; return beta2; } alpha = beta2; } ClearFirst(bb); } while (bb); player->pos[i] = pos; player->type[i] = type; } player->num++; } else { for (i = 0; i < player->num; i++) { #ifdef HAS_PAWNS if ((player->type[i] & 0x07) == 1) continue; #endif if (player_att[i] & atts) return 2; } } } else { // second case: just try all moves for (i = 0; i < player->num; i++) { #ifdef HAS_PAWNS if ((player->type[i] & 0x07) == 1) continue; #endif bitboard bb = player_att[i] & ~player_occ; if (bb) { int from = player->pos[i]; do { int capts; int to = FirstOne(bb); player->pos[i] = to; int v = -probe_tb_capts(opp, player, opp_occ, player_occ ^ bit[from] ^ bit[to], -beta, -alpha, &capts); if (capts && v > alpha) { if (v >= beta) { player->pos[i] = from; return v; } alpha = v; } ClearFirst(bb); } while (bb); player->pos[i] = from; } } } int pieces[6]; int pos[6]; skip_threats: for (i = 0; i < player->num; i++) { pieces[i] = player->type[i]; pos[i] = player->pos[i]; } for (j = 0; j < opp->num; j++, i++) { pieces[i] = opp->type[j]; pos[i] = opp->pos[j]; } for (; i < numpcs; i++) pieces[i] = 0; int v = probe_table(pieces, pos, pieces[0] < 8); return alpha > v ? alpha : v; }
/* * Return the physical address of the requested table or zero if one * is not found. */ vm_paddr_t acpi_find_table(const char *sig) { ACPI_PHYSICAL_ADDRESS rsdp_ptr; ACPI_TABLE_RSDP *rsdp; ACPI_TABLE_XSDT *xsdt; ACPI_TABLE_HEADER *table; vm_paddr_t addr; int i, count; if (resource_disabled("acpi", 0)) return (0); /* * Map in the RSDP. Since ACPI uses AcpiOsMapMemory() which in turn * calls pmap_mapbios() to find the RSDP, we assume that we can use * pmap_mapbios() to map the RSDP. */ if ((rsdp_ptr = AcpiOsGetRootPointer()) == 0) return (0); rsdp = pmap_mapbios(rsdp_ptr, sizeof(ACPI_TABLE_RSDP)); if (rsdp == NULL) { if (bootverbose) printf("ACPI: Failed to map RSDP\n"); return (0); } addr = 0; if (rsdp->Revision >= 2 && rsdp->XsdtPhysicalAddress != 0) { /* * AcpiOsGetRootPointer only verifies the checksum for * the version 1.0 portion of the RSDP. Version 2.0 has * an additional checksum that we verify first. */ if (AcpiTbChecksum((UINT8 *)rsdp, ACPI_RSDP_XCHECKSUM_LENGTH)) { if (bootverbose) printf("ACPI: RSDP failed extended checksum\n"); return (0); } xsdt = map_table(rsdp->XsdtPhysicalAddress, 2, ACPI_SIG_XSDT); if (xsdt == NULL) { if (bootverbose) printf("ACPI: Failed to map XSDT\n"); pmap_unmapbios((vm_offset_t)rsdp, sizeof(ACPI_TABLE_RSDP)); return (0); } count = (xsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) / sizeof(UINT64); for (i = 0; i < count; i++) if (probe_table(xsdt->TableOffsetEntry[i], sig)) { addr = xsdt->TableOffsetEntry[i]; break; } acpi_unmap_table(xsdt); } pmap_unmapbios((vm_offset_t)rsdp, sizeof(ACPI_TABLE_RSDP)); if (addr == 0) { if (bootverbose) printf("ACPI: No %s table found\n", sig); return (0); } if (bootverbose) printf("%s: Found table at 0x%jx\n", sig, (uintmax_t)addr); /* * Verify that we can map the full table and that its checksum is * correct, etc. */ table = map_table(addr, 0, sig); if (table == NULL) return (0); acpi_unmap_table(table); return (addr); }