Added the reconstructed source code of CHESS.COM. The ATTACK routine and its subroutines have not been given meaningful label names and comments yet.
2234 lines
66 KiB
NASM
2234 lines
66 KiB
NASM
;***********************************************************
|
|
;
|
|
; SARGON
|
|
;
|
|
; Sargon is a computer chess playing program designed
|
|
; and coded by Dan and Kathe Spracklen. Copyright 1978. All
|
|
; rights reserved. No part of this publication may be
|
|
; reproduced without the prior written permission.
|
|
;***********************************************************
|
|
|
|
;***********************************************************
|
|
; SYSTEM EQUATES
|
|
;***********************************************************
|
|
INCHAR EQU 1
|
|
PRINTBUF EQU 9
|
|
INBUF EQU 10
|
|
SYSTEM EQU 5
|
|
|
|
;***********************************************************
|
|
; EQUATES
|
|
;***********************************************************
|
|
;
|
|
PAWN: EQU 1
|
|
KNIGHT: EQU 2
|
|
BISHOP: EQU 3
|
|
ROOK: EQU 4
|
|
QUEEN: EQU 5
|
|
KING: EQU 6
|
|
WHITE: EQU 0
|
|
BLACK: EQU 80H
|
|
BPAWN: EQU BLACK+PAWN
|
|
|
|
ORG 100H
|
|
|
|
;***********************************************************
|
|
; MAIN PROGRAM DRIVER
|
|
;***********************************************************
|
|
; FUNCTION: -- To coordinate the game moves.
|
|
;
|
|
; CALLED BY: -- None
|
|
;
|
|
; CALLS: -- INITBD
|
|
; CPTRMV
|
|
; PLYRMV
|
|
;
|
|
; ARGUMENTS: None
|
|
;***********************************************************
|
|
DRIVER: MOV SP,STACK ; Set stack pointer
|
|
MOV DX,CLRMSG ; Request color choice
|
|
MOV CL,PRINTBUF
|
|
CALL SYSTEM
|
|
MOV CL,INCHAR ; Accept response
|
|
CALL SYSTEM
|
|
CMP AL,57H ; Did player request white ?
|
|
JZ DR05 ; Yes - branch
|
|
CMP AL,42H ; Did player request black ?
|
|
JNZ DRIVER ; No - error
|
|
XOR AL,AL
|
|
JP DR10 ; Jump
|
|
DR05: MOV AL,BLACK ; Set computers color to black
|
|
DR10: MOV [KOLOR],AL
|
|
DR15: MOV DX,PLYDEP ; Request depth of search
|
|
MOV CL,PRINTBUF
|
|
CALL SYSTEM
|
|
MOV CL,INCHAR
|
|
CALL SYSTEM
|
|
SUB AL,31H ; Subtract Ascii constant
|
|
JB DR15 ; Under minimum - prompt again
|
|
CMP AL,6 ; Over maximum of 6 ?
|
|
JNB DR15 ; Yes - prompt again
|
|
INC AL ; Increment by one
|
|
MOV [PLYMAX],AL ; Set desired depth
|
|
MOV DX,CRLF ; Output CRLF
|
|
MOV CL,PRINTBUF
|
|
CALL SYSTEM
|
|
XOR AL,AL
|
|
MOV [COLOR],AL ; Set color to white
|
|
INC AL
|
|
MOV [MOVENO],AL ; Set move number to 1
|
|
CALL INITBD ; Init board
|
|
MOV AL,[KOLOR] ; Get color
|
|
OR AL,AL ; Computer move ?
|
|
JZ DR25 ; Yes - jump
|
|
DR20: CALL PLYRMV ; Do player move
|
|
DR25: CALL CPTRMV ; Do computer move
|
|
MOV BX,MOVENO
|
|
INC B,[BX] ; Increment move number
|
|
JP DR20 ; Back to player move
|
|
|
|
;***********************************************************
|
|
; TABLES SECTION
|
|
;***********************************************************
|
|
ORG 200H ; Start at 200H
|
|
START:
|
|
ORG START+80H
|
|
PUT START+80H
|
|
TBASE: EQU START+100H
|
|
;**********************************************************
|
|
; DIRECT -- Direction Table. Used to determine the dir-
|
|
; ection of movement of each piece.
|
|
;***********************************************************
|
|
DIRECT: EQU $-TBASE
|
|
DB +09,+11,-11,-09
|
|
DB +10,-10,+01,-01
|
|
DB -21,-12,+08,+19
|
|
DB +21,+12,-08,-19
|
|
DB +10,+10,+11,+09
|
|
DB -10,-10,-11,-09
|
|
;***********************************************************
|
|
; DPOINT -- Direction Table Pointer. Used to determine
|
|
; where to begin in the direction table for any
|
|
; given piece.
|
|
;***********************************************************
|
|
DPOINT: EQU $-TBASE
|
|
DB 20,16,8,0,4,0,0
|
|
|
|
;***********************************************************
|
|
; DCOUNT -- Direction Table Counter. Used to determine
|
|
; the number of directions of movement for any
|
|
; given piece.
|
|
;***********************************************************
|
|
DCOUNT: EQU $-TBASE
|
|
DB 4,4,8,4,4,8,8
|
|
|
|
;***********************************************************
|
|
; PVALUE -- Point Value. Gives the point value of each
|
|
; piece, or the worth of each piece.
|
|
;***********************************************************
|
|
PVALUE: EQU $-TBASE-1
|
|
DB 1,3,3,5,9,10
|
|
|
|
;***********************************************************
|
|
; PIECES -- The initial arrangement of the first rank of
|
|
; pieces on the board. Use to set up the board
|
|
; for the start of the game.
|
|
;***********************************************************
|
|
PIECES: EQU $-TBASE
|
|
DB 4,2,3,5,6,3,2,4
|
|
|
|
;***********************************************************
|
|
; BOARD -- Board Array. Used to hold the current position
|
|
; of the board during play. The board itself
|
|
; looks like:
|
|
; FFFFFFFFFFFFFFFFFFFF
|
|
; FFFFFFFFFFFFFFFFFFFF
|
|
; FF0402030506030204FF
|
|
; FF0101010101010101FF
|
|
; FF0000000000000000FF
|
|
; FF0000000000000000FF
|
|
; FF0000000000000060FF
|
|
; FF0000000000000000FF
|
|
; FF8181818181818181FF
|
|
; FF8482838586838284FF
|
|
; FFFFFFFFFFFFFFFFFFFF
|
|
; FFFFFFFFFFFFFFFFFFFF
|
|
; The values of FF form the border of the
|
|
; board, and are used to indicate when a piece
|
|
; moves off the board. The individual bits of
|
|
; the other bytes in the board array are as
|
|
; follows:
|
|
; Bit 7 -- Color of the piece
|
|
; 1 -- Black
|
|
; 0 -- White
|
|
; Bit 6 -- Not used
|
|
; Bit 5 -- Not used
|
|
; Bit 4 --Castle flag for Kings only
|
|
; Bit 3 -- Piece has moved flag
|
|
; Bits 2-0 Piece type
|
|
; 1 -- Pawn
|
|
; 2 -- Knight
|
|
; 3 -- Bishop
|
|
; 4 -- Rook
|
|
; 5 -- Queen
|
|
; 6 -- King
|
|
; 7 -- Not used
|
|
; 0 -- Empty Square
|
|
;***********************************************************
|
|
BOARD: EQU $-TBASE
|
|
BOARDA: DS 120
|
|
|
|
;***********************************************************
|
|
; ATKLIST -- Attack List. A two part array, the first
|
|
; half for white and the second half for black.
|
|
; It is used to hold the attackers of any given
|
|
; square in the order of their value.
|
|
;
|
|
; WACT -- White Attack Count. This is the first
|
|
; byte of the array and tells how many pieces are
|
|
; in the white portion of the attack list.
|
|
;
|
|
; BACT -- Black Attack Count. This is the eighth byte of
|
|
; the array and does the same for black.
|
|
;***********************************************************
|
|
ATKLST: DW 0,0,0,0,0,0,0
|
|
WACT: EQU ATKLST
|
|
BACT: EQU ATKLST+7
|
|
|
|
;***********************************************************
|
|
; PLIST -- Pinned Piece Array. This is a two part array.
|
|
; PLISTA contains the pinned piece position.
|
|
; PLISTD contains the direction from the pinned
|
|
; piece to the attacker.
|
|
;***********************************************************
|
|
PLIST: EQU $-TBASE-1
|
|
PLISTD: EQU PLIST+10
|
|
PLISTA: DW 0,0,0,0,0,0,0,0,0,0
|
|
|
|
;***********************************************************
|
|
; POSK -- Position of Kings. A two byte area, the first
|
|
; byte of which hold the position of the white
|
|
; king and the second holding the position of
|
|
; the black king.
|
|
;
|
|
; POSQ -- Position of Queens. Like POSK,but for queens.
|
|
;***********************************************************
|
|
POSK: DB 24,95
|
|
POSQ: DB 14,94
|
|
DB -1
|
|
|
|
;***********************************************************
|
|
; SCORE -- Score Array. Used during Alpha-Beta pruning to
|
|
; hold the scores at each ply. It includes two
|
|
; "dummy" entries for ply -1 and ply 0.
|
|
;***********************************************************
|
|
SCORE: DW 0,0,0,0,0,0
|
|
|
|
;***********************************************************
|
|
; PLYIX -- Ply Table. Contains pairs of pointers, a pair
|
|
; for each ply. The first pointer points to the
|
|
; top of the list of possible moves at that ply.
|
|
; The second pointer points to which move in the
|
|
; list is the one currently being considered.
|
|
;***********************************************************
|
|
PLYIX: DW 0,0,0,0,0,0,0,0,0,0
|
|
DW 0,0,0,0,0,0,0,0,0,0
|
|
|
|
;***********************************************************
|
|
; STACK -- Contains the stack for the program.
|
|
;***********************************************************
|
|
ORG START+2FFH
|
|
STACK:
|
|
|
|
;***********************************************************
|
|
; TABLE INDICES SECTION
|
|
;
|
|
; M1-M4 -- Working indices used to index into
|
|
; the board array.
|
|
;
|
|
; T1-T3 -- Working indices used to index into Direction
|
|
; Count, Direction Value, and Piece Value tables.
|
|
;
|
|
; INDX1 -- General working indices. Used for various
|
|
; INDX2 purposes.
|
|
;
|
|
; NPINS -- Number of Pins. Count and pointer into the
|
|
; pinned piece list.
|
|
;
|
|
; MLPTRI -- Pointer into the ply table which tells
|
|
; which pair of pointers are in current use.
|
|
;
|
|
; MLPTRJ -- Pointer into the move list to the move that is
|
|
; currently being processed.
|
|
;
|
|
; SCRIX -- Score Index. Pointer to the score table for
|
|
; the ply being examined.
|
|
;
|
|
; BESTM -- Pointer into the move list for the move that
|
|
; is currently considered the best by the
|
|
; Alpha-Beta pruning process.
|
|
;
|
|
; MLLST -- Pointer to the previous move placed in the move
|
|
; list. Used during generation of the move list.
|
|
;
|
|
; MLNXT -- Pointer to the next available space in the move
|
|
; list.
|
|
;
|
|
;***********************************************************
|
|
ORG START+0
|
|
PUT START+0
|
|
M1: DW TBASE
|
|
M2: DW TBASE
|
|
M3: DW TBASE
|
|
M4: DW TBASE
|
|
T1: DW TBASE
|
|
T2: DW TBASE
|
|
T3: DW TBASE
|
|
INDX1: DW TBASE
|
|
INDX2: DW TBASE
|
|
NPINS: DW TBASE
|
|
MLPTRI: DW PLYIX
|
|
MLPTRJ: DW 0
|
|
SCRIX: DW 0
|
|
BESTM: DW 0
|
|
MLLST: DW 0
|
|
MLNXT: DW MLIST
|
|
|
|
;***********************************************************
|
|
; VARIABLES SECTION
|
|
;
|
|
; KOLOR -- Indicates computer's color. White is 0, and
|
|
; Black is 80H.
|
|
;
|
|
; COLOR -- Indicates color of the side with the move.
|
|
;
|
|
; P1-P3 -- Working area to hold the contents of the board
|
|
; array for a given square.
|
|
;
|
|
; PMATE -- The move number at which a checkmate is
|
|
; discovered during look ahead.
|
|
;
|
|
; MOVENO -- Current move number.
|
|
;
|
|
; PLYMAX -- Maximum depth of search using Alpha-Beta
|
|
; pruning.
|
|
;
|
|
; NPLY -- Current ply number during Alpha-Beta
|
|
; pruning.
|
|
;
|
|
; CKFLG -- A non-zero value indicates the king is in check.
|
|
;
|
|
; MATEF -- A zero value indicates no legal moves.
|
|
;
|
|
; VALM -- The score of the current move being examined.
|
|
;
|
|
; BRDC -- A measure of mobility equal to the total number
|
|
; of squares white can move to minus the number
|
|
; black can move to.
|
|
;
|
|
; PTSL -- The maximum number of points which could be lost
|
|
; through an exchange by the player not on the
|
|
; move.
|
|
;
|
|
; PTSW1 -- The maximum number of points which could be won
|
|
; through an exchange by the player not on the
|
|
; move.
|
|
;
|
|
; PTSW2 -- The second highest number of points which could
|
|
; be won through a different exchange by the player
|
|
; not on the move.
|
|
;
|
|
; MTRL -- A measure of the difference in material
|
|
; currently on the board. It is the total value of
|
|
; the white pieces minus the total value of the
|
|
; black pieces.
|
|
;
|
|
; BC0 -- The value of board control(BRDC) at ply 0.
|
|
;
|
|
; MV0 -- The value of material(MTRL) at ply 0.
|
|
;
|
|
; PTSCK -- A non-zero value indicates that the piece has
|
|
; just moved itself into a losing exchange of
|
|
; material.
|
|
;
|
|
; BMOVES -- Our very tiny book of openings. Determines
|
|
; the first move for the computer.
|
|
;
|
|
;***********************************************************
|
|
KOLOR: DB 0
|
|
COLOR: DB 0
|
|
P1: DB 0
|
|
P2: DB 0
|
|
P3: DB 0
|
|
PMATE: DB 0
|
|
MOVENO: DB 0
|
|
PLYMAX: DB 2
|
|
NPLY: DB 0
|
|
CKFLG: DB 0
|
|
MATEF: DB 0
|
|
VALM: DB 0
|
|
BRDC: DB 0
|
|
PTSL: DB 0
|
|
PTSW1: DB 0
|
|
PTSW2: DB 0
|
|
MTRL: DB 0
|
|
BC0: DB 0
|
|
MV0: DB 0
|
|
PTSCK: DB 0
|
|
BMOVES: DB 35,55,10H
|
|
DB 34,54,10H
|
|
DB 85,65,10H
|
|
DB 84,64,10H
|
|
|
|
;***********************************************************
|
|
; MOVE LIST SECTION
|
|
;
|
|
; MLIST -- A 2048 byte storage area for generated moves.
|
|
; This area must be large enough to hold all
|
|
; the moves for a single leg of the move tree.
|
|
;
|
|
; MLEND -- The address of the last available location
|
|
; in the move list.
|
|
;
|
|
; MLPTR -- The Move List is a linked list of individual
|
|
; moves each of which is 6 bytes in length. The
|
|
; move list pointer(MLPTR) is the link field
|
|
; within a move.
|
|
;
|
|
; MLFRP -- The field in the move entry which gives the
|
|
; board position from which the piece is moving.
|
|
;
|
|
; MLTOP -- The field in the move entry which gives the
|
|
; board position to which the piece is moving.
|
|
;
|
|
; MLFLG -- A field in the move entry which contains flag
|
|
; information. The meaning of each bit is as
|
|
; follows:
|
|
; Bit 7 -- The color of any captured piece
|
|
; 0 -- White
|
|
; 1 -- Black
|
|
; Bit 6 -- Double move flag (set for castling and
|
|
; en passant pawn captures)
|
|
; Bit 5 -- Pawn Promotion flag; set when pawn
|
|
; promotes.
|
|
; Bit 4 -- When set, this flag indicates that
|
|
; this is the first move for the
|
|
; piece on the move.
|
|
; Bit 3 -- This flag is set is there is a piece
|
|
; captured, and that piece has moved at
|
|
; least once.
|
|
; Bits 2-0 Describe the captured piece. A
|
|
; zero value indicates no capture.
|
|
;
|
|
; MLVAL -- The field in the move entry which contains the
|
|
; score assigned to the move.
|
|
;
|
|
;***********************************************************
|
|
ORG START+300H
|
|
PUT START+300H
|
|
MLIST: DS 2048
|
|
MLEND: EQU MLIST+2040
|
|
MLPTR: EQU 0
|
|
MLFRP: EQU 2
|
|
MLTOP: EQU 3
|
|
MLFLG: EQU 4
|
|
MLVAL: EQU 5
|
|
|
|
;***********************************************************
|
|
; PROGRAM CODE SECTION
|
|
;***********************************************************
|
|
; BOARD SETUP ROUTINE
|
|
;***********************************************************
|
|
; FUNCTION: To initialize the board array, setting the
|
|
; pieces in their initial positions for the
|
|
; start of the game.
|
|
;
|
|
; CALLED BY: DRIVER
|
|
;
|
|
; CALLS: None
|
|
;
|
|
; ARGUMENTS: None
|
|
;***********************************************************
|
|
INITBD: MOV CX,60 ; Pre-fill board with -1's
|
|
MOV DI,BOARDA
|
|
MOV AX,-1
|
|
REP
|
|
STOW
|
|
MOV CH,8
|
|
MOV SI,BOARDA
|
|
IB2: MOV AL,[SI-8] ; Fill non-border squares
|
|
MOV [SI+21],AL ; White pieces
|
|
LAHF
|
|
OR AL,080H
|
|
SAHF ; Change to black
|
|
MOV [SI+91],AL ; Black pieces
|
|
MOV B,[SI+31],PAWN ; White Pawns
|
|
MOV B,[SI+81],BPAWN ; Black Pawns
|
|
MOV B,[SI+41],0 ; Empty squares
|
|
MOV B,[SI+51],0
|
|
MOV B,[SI+61],0
|
|
MOV B,[SI+71],0
|
|
INC SI
|
|
DEC CH
|
|
JNZ IB2
|
|
MOV SI,POSK ; Init King/Queen position list
|
|
MOV B,[SI+0],25
|
|
MOV B,[SI+1],95
|
|
MOV B,[SI+2],24
|
|
MOV B,[SI+3],94
|
|
RET
|
|
|
|
;***********************************************************
|
|
; PATH ROUTINE
|
|
;***********************************************************
|
|
; FUNCTION: To generate a single possible move for a given
|
|
; piece along its current path of motion including:
|
|
|
|
; Fetching the contents of the board at the new
|
|
; position, and setting a flag describing the
|
|
; contents:
|
|
; 0 -- New position is empty
|
|
; 1 -- Encountered a piece of the
|
|
; opposite color
|
|
; 2 -- Encountered a piece of the
|
|
; same color
|
|
; 3 -- New position is off the
|
|
; board
|
|
;
|
|
; CALLED BY: MPIECE
|
|
; ATTACK
|
|
; PINFND
|
|
;
|
|
; CALLS: None
|
|
;
|
|
; ARGUMENTS: Direction from the direction array giving the
|
|
; constant to be added for the new position.
|
|
;***********************************************************
|
|
PATH: ADD [M2],CL ; Add direction constant to previous position
|
|
MOV SI,[M2] ; Load board index
|
|
MOV AL,[SI+BOARD] ; Get contents of board
|
|
CMP AL,-1 ; In border area ?
|
|
JZ PA2 ; Yes - jump
|
|
MOV [P2],AL ; Save piece
|
|
MOV AH,AL ; Save piece in register
|
|
AND AL,7 ; Clear flags
|
|
MOV [T2],AL ; Save piece type
|
|
JZ RET ; Return if empty
|
|
XOR AH,[P1] ; Compare with moving piece
|
|
SHL AH ; Set flag
|
|
MOV AL,2
|
|
SBB AL,0
|
|
RET ; Return
|
|
PA2: MOV AL,3 ; Set off board flag
|
|
RET
|
|
|
|
;***********************************************************
|
|
; PIECE MOVER ROUTINE
|
|
;***********************************************************
|
|
; FUNCTION: To generate all the possible legal moves for a
|
|
; given piece.
|
|
;
|
|
; CALLED BY: GENMOV
|
|
;
|
|
; CALLS: PATH
|
|
; ADMOVE
|
|
; CASTLE
|
|
; ENPSNT
|
|
;
|
|
; ARGUMENTS: The piece to be moved.
|
|
;***********************************************************
|
|
MPIECE: XOR AL,[BX] ; Piece to move
|
|
AND AL,87H ; Clear flag bit
|
|
CMP AL,BPAWN ; Is it a black Pawn ?
|
|
JNZ MP1 ; No-Skip
|
|
DEC AL ; Decrement for black Pawns
|
|
MP1: AND AL,7 ; Get piece type
|
|
MOV [T1],AL ; Save piece type
|
|
MOV DI,[T1] ; Load index to DCOUNT/DPOINT
|
|
MOV CH,[DI+DCOUNT] ; Get direction count
|
|
MOV AL,[DI+DPOINT] ; Get direction pointer
|
|
MOV [INDX2],AL ; Save as index to direct
|
|
MOV DI,[INDX2] ; Load index
|
|
MP5: MOV CL,[DI+DIRECT] ; Get move direction
|
|
MOV AL,[M1] ; From position
|
|
MOV [M2],AL ; Initialize to position
|
|
MP10: CALL PATH ; Calculate next position
|
|
CMP AL,2 ; Ready for new direction ?
|
|
JNC MP15 ; Yes - Jump
|
|
AND AL,AL ; Test for empty square
|
|
PUSHF
|
|
MOV AL,[T1] ; Get piece moved
|
|
CMP AL,PAWN+1 ; Is it a Pawn ?
|
|
JC MP20 ; Yes - Jump
|
|
CALL ADMOVE ; Add move to list
|
|
POPF
|
|
JNZ MP15 ; No - Jump
|
|
MOV AL,[T1] ; Piece type
|
|
CMP AL,KING ; King ?
|
|
JZ MP15 ; Yes - Jump
|
|
CMP AL,BISHOP ; Bishop, Rook, or Queen ?
|
|
JNC MP10 ; Yes - Jump
|
|
MP15: INC DI ; Increment direction index
|
|
DEC CH
|
|
JNZ MP5 ; Decr. count-jump if non-zerc
|
|
MOV AL,[T1] ; Piece type
|
|
CMP AL,KING ; King ?
|
|
JNZ RET
|
|
JMP CASTLE ; Yes - Try Castling
|
|
; ***** PAWN LOGIC *****
|
|
MP20: MOV AL,CH ; Counter for direction
|
|
CMP AL,3 ; On diagonal moves ?
|
|
JC MP35 ; Yes - Jump
|
|
JZ MP30 ; -or-jump if on 2 square move
|
|
POPF
|
|
JNZ MP15 ; No - jump
|
|
MOV AL,[M2] ; Get "to" position
|
|
CMP AL,91 ; Promote white Pawn ?
|
|
JNC MP25 ; Yes - Jump
|
|
CMP AL,29 ; Promote black Pawn ?
|
|
JNC MP26 ; No - Jump
|
|
MP25: OR B,[P2],020H ; Set promote flag
|
|
MP26: CALL ADMOVE ; Add to move list
|
|
INC DI ; Adjust to two square move
|
|
DEC CH
|
|
TEST B,[P1],008H ; Check Pawn moved flag, has it moved before ?
|
|
JZ MP10 ; No - Jump
|
|
JMP MP15 ; Jump
|
|
MP30: POPF
|
|
JNZ MP15 ; No - Jump
|
|
MP31: CALL ADMOVE ; Add to move list
|
|
JMP MP15 ; Jump
|
|
MP35: POPF
|
|
JZ MP36 ; Yes - Jump
|
|
MOV AL,[M2] ; Get "to" position
|
|
CMP AL,91 ; Promote white Pawn ?
|
|
JNC MP37 ; Yes - Jump
|
|
CMP AL,29 ; Black Pawn promotion ?
|
|
JNC MP31 ; No- Jump
|
|
MP37: OR B,[P2],020H ; Set promote flag
|
|
JP MP31 ; Jump
|
|
MP36: CALL ENPSNT ; Try en passant capture
|
|
JMP MP15 ; Jump
|
|
|
|
;***********************************************************
|
|
; EN PASSANT ROUTINE
|
|
;***********************************************************
|
|
; FUNCTION: -- To test for en passant Pawn capture and
|
|
; to add it to the move list if it is
|
|
; legal.
|
|
;
|
|
; CALLED BY: -- MPIECE
|
|
;
|
|
; CALLS: -- ADMOVE
|
|
; ADJPTR
|
|
;
|
|
; ARGUMENTS: -- None
|
|
;***********************************************************
|
|
ENPSNT: MOV AL,[M1] ; Set position of Pawn
|
|
TEST B,[P1],080H ; Check color, is it white ?
|
|
JZ EP5 ; Yes - skip
|
|
ADD AL,10 ; Add 10 for black
|
|
EP5: CMP AL,61 ; On en passant capture rank ?
|
|
JC RET ; No - return
|
|
CMP AL,69 ; On en passant capture rank ?
|
|
JNC RET ; No - return
|
|
MOV SI,[MLPTRJ] ; Get pointer to previous move
|
|
TEST B,[SI+MLFLG],010H ; First move for that piece ?
|
|
JZ RET ; No - return
|
|
MOV AL,[SI+MLTOP] ; Get "to" position
|
|
MOV [M4],AL ; Store as index to board
|
|
MOV SI,[M4] ; Load board index
|
|
MOV AL,[SI+BOARD] ; Get piece moved
|
|
MOV [P3],AL ; Save it
|
|
AND AL,7 ; Get piece type
|
|
CMP AL,PAWN ; Is it a Pawn ?
|
|
JNZ RET ; No - return
|
|
MOV AL,[M4] ; Get "to" position
|
|
MOV BX,M2 ; Get present "to" position
|
|
SUB AL,[BX] ; Find difference
|
|
JNS EP10 ; Positive ? Yes - Jump
|
|
NEG AL ; Else take absolute value
|
|
EP10: CMP AL,10 ; Is difference 10 ?
|
|
JNZ RET ; No - return
|
|
OR B,[P2],040H ; Set double move flag
|
|
CALL ADMOVE ; Add Pawn move to move list
|
|
MOV AL,[M1] ; Save initial Pawn position
|
|
MOV [M3],AL
|
|
MOV AL,[M4] ; Set "from" and "to" positions
|
|
; for dummy move
|
|
MOV [M1],AL
|
|
MOV [M2],AL
|
|
MOV AL,[P3] ; Save captured Pawn
|
|
MOV [P2],AL
|
|
CALL ADMOVE ; Add Pawn capture to move list
|
|
MOV AL,[M3] ; Restore "from" position
|
|
MOV [M1],AL
|
|
|
|
;***********************************************************
|
|
; ADJUST MOVE LIST POINTER FOR DOUBLE MOVE
|
|
;***********************************************************
|
|
; FUNCTION: -- To adjust move list pointer to link around
|
|
; second move in double move.
|
|
;
|
|
; CALLED BY: -- ENPSNT
|
|
; CASTLE
|
|
; (This mini-routine is not really called,
|
|
; but is jumped to to save time.)
|
|
;
|
|
; CALLS: -- None
|
|
;
|
|
; ARGUMENTS: -- None
|
|
;***********************************************************
|
|
ADJPTR: MOV BX,[MLLST] ; Get list pointer
|
|
SUB BX,6 ; Back up list pointer
|
|
MOV [MLLST],BX ; Save list pointer
|
|
MOV [BX],0 ; Zero out link
|
|
RET ; Return
|
|
|
|
;***********************************************************
|
|
; CASTLE ROUTINE
|
|
;***********************************************************
|
|
; FUNCTION: -- To determine whether castling is legal
|
|
; (Queen side, King side, or both) and add it
|
|
; to the move list if it is.
|
|
;
|
|
; CALLED BY: -- MPIECE
|
|
;
|
|
; CALLS: -- ATTACK
|
|
; ADMOVE
|
|
; ADJPTR
|
|
;
|
|
; ARGUMENTS: -- None
|
|
;***********************************************************
|
|
CASTLE:
|
|
TEST B,[P1],008H ; Has king moved ?
|
|
JNZ RET ; Yes - return
|
|
MOV AL,[CKFLG] ; Fetch Check Flag
|
|
AND AL,AL ; Is the King in check ?
|
|
JNZ RET ; Yes - Return
|
|
MOV CX,0FF03H ; Initialize King-side values
|
|
CA5: ADD CL,[M1] ; Rook position
|
|
MOV AL,CL
|
|
MOV [M3],AL ; Store as board index
|
|
MOV SI,[M3] ; Load board index
|
|
MOV AL,[SI+BOARD] ; Get contents of board
|
|
AND AL,7FH ; Clear color bit
|
|
CMP AL,ROOK ; Has Rook ever moved ?
|
|
JNZ CA20 ; Yes - Jump
|
|
MOV AL,CL ; Restore Rook position
|
|
JP CA15 ; Jump
|
|
CA10: MOV SI,[M3] ; Load board index
|
|
MOV AL,[SI+BOARD] ; Get contents of board
|
|
AND AL,AL ; Empty ?
|
|
JNZ CA20 ; No - Jump
|
|
MOV AL,[M3] ; Current position
|
|
CMP AL,22 ; White Queen Knight square ?
|
|
JZ CA15 ; Yes - Jump
|
|
CMP AL,92 ; Black Queen Knight square ?
|
|
JZ CA15 ; Yes - Jump
|
|
CALL ATTACK ; Look for attack on square
|
|
AND AL,AL ; Any attackers ?
|
|
JNZ CA20 ; Yes - Jump
|
|
MOV AL,[M3] ; Current position
|
|
CA15: ADD AL,CH ; Next position
|
|
MOV [M3],AL ; Save as board index
|
|
MOV BX,M1 ; King position
|
|
CMP AL,[BX] ; Reached King ?
|
|
JNZ CA10 ; No - jump
|
|
SUB AL,CH ; Determine King's position
|
|
SUB AL,CH
|
|
MOV [M2],AL ; Save it
|
|
MOV BX,P2 ; Address of flags
|
|
MOV B,[BX],40H ; Set double move flag
|
|
CALL ADMOVE ; Put king move in list
|
|
MOV BX,M1 ; Addr of King "from" position
|
|
MOV AL,[BX] ; Get King's "from" position
|
|
MOV [BX],CL ; Store Rook "from" position
|
|
SUB AL,CH ; Get Rook "to" position
|
|
MOV [M2],AL ; Store Rook "to" position
|
|
XOR AL,AL ; Zero
|
|
MOV [P2],AL ; Zero move flags
|
|
CALL ADMOVE ; Put Rook move in list
|
|
CALL ADJPTR ; Re-adjust move list pointer
|
|
MOV AL,[M3] ; Restore King position
|
|
MOV [M1],AL ; Store
|
|
CA20: MOV AL,CH ; Scan Index
|
|
CMP AL,1 ; Done ?
|
|
JZ RET ; Yes - return
|
|
MOV CX,01FCH ; Set Queen-side initial values
|
|
JMP CA5 ; Jump
|
|
|
|
;***********************************************************
|
|
; ADMOVE ROUTINE
|
|
;***********************************************************
|
|
; FUNCTION: -- To add a move to the move list
|
|
;
|
|
; CALLED BY: -- MPIECE
|
|
; ENPSNT
|
|
; CASTLE
|
|
;
|
|
; CALLS: -- None
|
|
;
|
|
; ARGUMENT: -- None
|
|
;***********************************************************
|
|
ADMOVE: MOV DX,[MLNXT] ; Addr of next loc in move list
|
|
MOV BX,MLEND ; Address of list end
|
|
SUB BX,DX ; Calculate difference
|
|
JC AM10 ; Jump if out of space
|
|
MOV BX,[MLLST] ; Addr of prev. list area
|
|
MOV [MLLST],DX ; Save next as previous
|
|
MOV [BX],DX ; Store link address
|
|
TEST B,[P1],008H ; Has moved piece moved before ?
|
|
JNZ AM5 ; Yes - jump
|
|
OR B,[P2],010H ; Set first move flag
|
|
AM5: XCHG DX,DI ; Address of move area
|
|
XOR AX,AX ; Store zero in link address
|
|
CLD
|
|
STOW
|
|
MOV AL,[M1] ; Store "from" move position
|
|
STOB
|
|
MOV AL,[M2] ; Store "to" move position
|
|
STOB
|
|
MOV AL,[P2] ; Store move flags/capt. piece
|
|
STOB
|
|
XOR AL,AL ; Store initial move value
|
|
STOB
|
|
MOV [MLNXT],DI ; Save address for next move
|
|
MOV DI,DX
|
|
RET ; Return
|
|
AM10: MOV [BX],0 ; Abort entry on table ovflow
|
|
RET
|
|
|
|
;***********************************************************
|
|
; GENERATE MOVE ROUTINE
|
|
;***********************************************************
|
|
; FUNCTION: -- To generate the move set for all of the
|
|
; pieces of a given color.
|
|
;
|
|
; CALLED BY: -- FNDMOV
|
|
;
|
|
; CALLS: -- MPIECE
|
|
; INCHK
|
|
;
|
|
; ARGUMENTS: -- None
|
|
;***********************************************************
|
|
GENMOV: CALL INCHK ; Test for King in check
|
|
MOV [CKFLG],AL ; Save attack count as flag
|
|
MOV DX,[MLNXT] ; Addr of next avail list space
|
|
MOV BX,[MLPTRI] ; Ply list pointer index
|
|
INC BX ; Increment to next ply
|
|
INC BX
|
|
MOV [BX],DX ; Save move list pointer
|
|
INC BX
|
|
INC BX
|
|
MOV [MLPTRI],BX ; Save new index
|
|
MOV [MLLST],BX ; Last pointer for chain init.
|
|
MOV AL,21 ; First position on board
|
|
GM5: MOV [M1],AL ; Save as index
|
|
MOV SI,[M1] ; Load board index
|
|
MOV AL,[SI+BOARD] ; Fetch board contents
|
|
AND AL,AL ; Is it empty ?
|
|
JZ GM10 ; Yes - Jump
|
|
CMP AL,-1 ; Is it a border square ?
|
|
JZ GM10 ; Yes - Jump
|
|
MOV [P1],AL ; Save piece
|
|
MOV BX,COLOR ; Address of color of piece
|
|
XOR AL,[BX] ; Test color of piece
|
|
TEST AL,080H ; Match ?
|
|
JNZ GM10
|
|
CALL MPIECE ; Yes - call Move Piece
|
|
GM10: MOV AL,[M1] ; Fetch current board position
|
|
INC AL ; Incr to next board position
|
|
CMP AL,99 ; End of board array ?
|
|
JNZ GM5 ; No - Jump
|
|
RET ; Return
|
|
|
|
;***********************************************************
|
|
; CHECK ROUTINE
|
|
;***********************************************************
|
|
; FUNCTION: -- To determine whether or not the
|
|
; King is in check.
|
|
;
|
|
; CALLED BY: -- GENMOV
|
|
; FNDMOV
|
|
; EVAL
|
|
;
|
|
; CALLS: -- ATTACK
|
|
;
|
|
; ARGUMENTS: -- Color of King
|
|
;***********************************************************
|
|
INCHK: MOV AL,[COLOR] ; Get color
|
|
INCHK1: MOV BX,POSK ; Addr of white King position
|
|
AND AL,AL ; White ?
|
|
JZ IC5 ; Yes - Skip
|
|
INC BX ; Addr of black King position
|
|
IC5: MOV AL,[BX] ; Fetch King position
|
|
MOV [M3],AL ; Save
|
|
MOV SI,[M3] ; Load board index
|
|
MOV AL,[SI+BOARD] ; Fetch board contents
|
|
MOV [P1],AL ; Save
|
|
AND AL,7 ; Get piece type
|
|
MOV [T1],AL ; Save
|
|
|
|
;
|
|
; *** NOTE FROM BROKEN PIPE ***
|
|
;
|
|
; THIS ATTACK ROUTINE DOES NOT MATCH SARGON'S ATTACK ROUTINE,
|
|
; IT IS MOST LIKELY TIM PATERSON'S OWN IMPLEMENTATION.
|
|
;
|
|
; I DO NOT KNOW HOW TO PLAY CHESS, SO I CANNOT UNDERSTAND ANY
|
|
; OF THE CODE. I NEED SOMEONE EXPERIENCED IN CHESS AND CHESS
|
|
; PROGRAMMING TO DISASSEMBLE THIS ROUTINE AND ITS SUBROUTINES.
|
|
;
|
|
ATTACK: PUSH CX
|
|
MOV BP,[M3]
|
|
ADD BP,BOARD
|
|
MOV DH,0
|
|
MOV SI,DIRECT+TBASE
|
|
MOV AH,6
|
|
CALL L102D
|
|
MOV AH,2
|
|
CALL L102D
|
|
MOV AH,32
|
|
MOV AL,[BP+11]
|
|
AND AL,87H
|
|
CMP AL,81H
|
|
JNZ L0FF8
|
|
OR [BP+11],AH
|
|
L0FF8: MOV AL,[BP+9]
|
|
AND AL,87H
|
|
CMP AL,81H
|
|
JNZ L1004
|
|
OR [BP+9],AH
|
|
L1004: MOV AL,[BP-11]
|
|
AND AL,87H
|
|
CMP AL,1
|
|
JNZ L1010
|
|
OR [BP-11],AH
|
|
L1010: MOV AL,[BP-9]
|
|
AND AL,87H
|
|
CMP AL,1
|
|
JNZ L101C
|
|
OR [BP-9],AH
|
|
L101C: MOV SI,DIRECT+TBASE
|
|
MOV AH,3
|
|
CALL L1046
|
|
MOV AH,4
|
|
CALL L1046
|
|
XOR AL,AL
|
|
POP CX
|
|
RET
|
|
|
|
L102D: MOV CX,8
|
|
L1030: XCHG AX,BX
|
|
LODB
|
|
CBW
|
|
XCHG AX,BX
|
|
MOV DI,BP
|
|
ADD DI,BX
|
|
MOV AL,[DI]
|
|
AND AL,7
|
|
CMP AL,AH
|
|
JNZ L1043
|
|
CALL L107C
|
|
L1043: LOOP L1030
|
|
RET
|
|
|
|
L1046: MOV CL,4
|
|
L1048: MOV DX,0C0H
|
|
XCHG AX,BX
|
|
LODB
|
|
CBW
|
|
XCHG AX,BX
|
|
MOV DI,BP
|
|
L1051: ADD DI,BX
|
|
MOV AL,[DI]
|
|
AND AL,27H
|
|
JZ L1051
|
|
CMP AL,AH
|
|
JZ L106D
|
|
CMP AL,5
|
|
JZ L1068
|
|
CMP AL,33
|
|
JZ L106A
|
|
L1065: LOOP L1048
|
|
RET
|
|
L1068: INC DH
|
|
L106A: AND B,[DI],0DFH
|
|
L106D: MOV AL,[DI]
|
|
ADD AL,128
|
|
RCR AL
|
|
AND DL,AL
|
|
JZ L1065
|
|
CALL L107C
|
|
JP L1051
|
|
|
|
L107C: MOV AL,[DI]
|
|
CMP B,[T1],7
|
|
JZ L10B3
|
|
XOR AL,[BP]
|
|
JNS RET
|
|
POP AX
|
|
POP AX
|
|
MOV AX,0DFFFH
|
|
CMP [BP+9],AL
|
|
JZ L1097
|
|
AND [BP+9],AH
|
|
L1097: CMP [BP+11],AL
|
|
JZ L109F
|
|
AND [BP+11],AH
|
|
L109F: CMP [BP-9],AL
|
|
JZ L10A7
|
|
AND [BP-9],AH
|
|
L10A7: CMP [BP-11],AL
|
|
JZ L10AF
|
|
AND [BP-11],AH
|
|
L10AF: MOV AL,1
|
|
POP CX
|
|
RET
|
|
L10B3: PUSH CX
|
|
PUSH DI
|
|
MOV CL,[NPINS]
|
|
JCXZ L10E0
|
|
PUSH AX
|
|
MOV AX,DI
|
|
SUB AX,BOARDA
|
|
MOV DI,PLISTA
|
|
L10C4: OR AL,AL
|
|
REPE
|
|
SCAB
|
|
JNZ L10DF
|
|
OR AH,AH
|
|
JNZ L10DB
|
|
MOV AH,[DI+9]
|
|
CMP AH,BL
|
|
JZ L10C4
|
|
NEG AH
|
|
CMP AH,BL
|
|
JZ L10C4
|
|
L10DB: POP AX
|
|
POP DI
|
|
POP CX
|
|
RET
|
|
L10DF: POP AX
|
|
L10E0: MOV CL,AL
|
|
AND CL,7
|
|
MOV DI,PVALUE+TBASE
|
|
ADD DI,CX
|
|
MOV CL,[DI]
|
|
MOV DI,ATKLST
|
|
TEST AL,80H
|
|
JZ L10F6
|
|
ADD DI,7
|
|
L10F6: OR DH,DH
|
|
JZ L10FC
|
|
MOV AL,5
|
|
L10FC: AND AL,7
|
|
INC B,[DI]
|
|
XCHG AL,CL
|
|
ADD DI,CX
|
|
MOV CH,[DI]
|
|
TEST CH,0FH
|
|
JZ L111F
|
|
TEST CH,0F0H
|
|
JZ L1115
|
|
INC DI
|
|
MOV CH,[DI]
|
|
XCHG AL,CH
|
|
L1115: SHL AL
|
|
SHL AL
|
|
SHL AL
|
|
SHL AL
|
|
OR AL,CH
|
|
L111F: MOV [DI],AL
|
|
POP DI
|
|
POP CX
|
|
RET
|
|
|
|
;***********************************************************
|
|
; PIN FIND ROUTINE
|
|
;***********************************************************
|
|
; FUNCTION: -- To produce a list of all pieces pinned
|
|
; against the King or Queen, for both white
|
|
; and black.
|
|
;
|
|
; CALLED BY: -- FNDMOV
|
|
; EVAL
|
|
;
|
|
; CALLS: -- PATH
|
|
; ATTACK
|
|
;
|
|
; ARGUMENTS: -- None
|
|
;***********************************************************
|
|
PINFND: XOR AL,AL ; Zero pin count
|
|
MOV [NPINS],AL
|
|
MOV DX,POSK ; Addr of King/Queen pos list
|
|
PF1: MOV BP,DX
|
|
MOV AL,[BP] ; Get position of royal piece
|
|
AND AL,AL ; Is it on board ?
|
|
JNZ PF1A ; Yes- continue
|
|
JMP PF26
|
|
PF1A: CMP AL,-1 ; At end of list ?
|
|
JZ RET ; Yes return
|
|
MOV [M3],AL ; Save position as board index
|
|
MOV SI,[M3] ; Load index to board
|
|
MOV AL,[SI+BOARD] ; Get contents of board
|
|
MOV [P1],AL ; Save
|
|
MOV CH,8 ; Init scan direction count
|
|
XOR AL,AL
|
|
MOV [INDX2],AL ; Init direction index
|
|
MOV DI,[INDX2]
|
|
PF2: MOV AL,[M3] ; Get King/Queen position
|
|
MOV [M2],AL ; Save
|
|
XOR AL,AL
|
|
MOV [M4],AL ; Clear pinned piece saved pos
|
|
MOV CL,[DI+DIRECT] ; Get direction of scan
|
|
PF5: CALL PATH ; Compute next position
|
|
AND AL,AL ; Is it empty ?
|
|
JZ PF5 ; Yes - jump
|
|
CMP AL,3 ; Off board ?
|
|
JZ JPF25 ; Yes - jump
|
|
CMP AL,2 ; Piece of same color
|
|
MOV AL,[M4] ; Load pinned piece position
|
|
JZ PF15 ; Yes - jump
|
|
AND AL,AL ; Possible pin ?
|
|
JZ JPF25 ; No - jump
|
|
MOV AL,[T2] ; Piece type encountered
|
|
CMP AL,QUEEN ; Queen ?
|
|
JZ PF19 ; Yes - jump
|
|
MOV BL,AL ; Save piece type
|
|
MOV AL,CH ; Direction counter
|
|
CMP AL,5 ; Non-diagonal direction ?
|
|
JC PF10 ; Yes - jump
|
|
MOV AL,BL ; Piece type
|
|
CMP AL,BISHOP ; Bishop ?
|
|
JNZ PF25 ; No - jump
|
|
JMP PF20 ; Jump
|
|
JPF25: JMP PF25
|
|
PF10: MOV AL,BL ; Piece type
|
|
CMP AL,ROOK ; Rook ?
|
|
JNZ PF25 ; No - jump
|
|
JMP PF20 ; Jump
|
|
PF15: AND AL,AL ; Possible pin ?
|
|
JNZ PF25 ; No - jump
|
|
MOV AL,[M2] ; Save possible pin position
|
|
MOV [M4],AL
|
|
JMP PF5 ; Jump
|
|
PF19: MOV AL,[P1] ; Load King or Queen
|
|
AND AL,7 ; Clear flags
|
|
CMP AL,QUEEN ; Queen ?
|
|
JNZ PF20 ; No - jump
|
|
PUSH CX ; Save regs.
|
|
PUSH DX
|
|
PUSH DI
|
|
XOR AX,AX ; Zero out attack list
|
|
MOV CX,7
|
|
MOV BX,ATKLST
|
|
XCHG DI,BX
|
|
CLD
|
|
REP
|
|
STOW
|
|
XCHG DI,BX
|
|
MOV AL,7 ; Set attack flag
|
|
MOV [T1],AL
|
|
CALL ATTACK ; Find attackers/defenders
|
|
MOV BX,WACT ; White queen attackers
|
|
MOV DX,BACT ; Black queen attackers
|
|
TEST B,[P1],080H ; Is queen white ?
|
|
JZ PF19A ; Yes - skip
|
|
XCHG DX,BX ; Reverse for black
|
|
PF19A: MOV AL,[BX] ; Number of defenders
|
|
XCHG DX,BX ; Reverse for attackers
|
|
SUB AL,[BX] ; Defenders minus attackers
|
|
DEC AL ; Less 1
|
|
POP DI ; Restore regs.
|
|
POP DX
|
|
POP CX
|
|
JNS PF25 ; Jump if pin not valid
|
|
PF20: MOV BX,NPINS ; Address of pinned piece count
|
|
INC B,[BX] ; Increment
|
|
MOV SI,[NPINS] ; Load pin list index
|
|
MOV [SI+PLISTD],CL ; Save direction of pin
|
|
MOV AL,[M4] ; Position of pinned piece
|
|
MOV [SI+PLIST],AL ; Save in list
|
|
PF25: INC DI ; Increment direction index
|
|
DEC CH
|
|
JZ PF26 ; Done ? Yes - Continue
|
|
JMP PF2
|
|
PF26: INC DX ; Incr King/Queen pos index
|
|
JMP PF1 ; Jump
|
|
|
|
;***********************************************************
|
|
; EXCHANGE ROUTINE
|
|
;***********************************************************
|
|
; FUNCTION: -- To determine the exchange value of a
|
|
; piece on a given square by examining all
|
|
; attackers and defenders of that piece.
|
|
;
|
|
; CALLED BY: -- POINTS
|
|
;
|
|
; CALLS: -- NEXTAD
|
|
;
|
|
; ARGUMENTS: -- None.
|
|
;***********************************************************
|
|
XCHNG: XCHG BX,[HL]
|
|
XCHG DX,[DE]
|
|
XCHG CX,[BC] ; Swap regs.
|
|
MOV AL,[P1] ; Piece attacked
|
|
MOV BX,WACT ; Addr of white attkrs/dfndrs
|
|
MOV DX,BACT ; Addr of black attkrs/dfndrs
|
|
TEST AL,080H ; Is piece white ?
|
|
JZ XC5 ; Yes - jump
|
|
XCHG DX,BX ; Swap list pointers
|
|
XC5: MOV CH,[BX] ; Init list counts
|
|
XCHG DX,BX
|
|
MOV CL,[BX]
|
|
XCHG DX,BX
|
|
XCHG BX,[HL]
|
|
XCHG DX,[DE]
|
|
XCHG CX,[BC] ; Restore regs.
|
|
MOV CL,0 ; Init attacker/defender flag
|
|
MOV DL,0 ; Init points lost count
|
|
MOV SI,[T3] ; Load piece value index
|
|
MOV DH,[SI+PVALUE] ; Get attacked piece value
|
|
SAL DH ; Double it
|
|
MOV CH,DH ; Save
|
|
CALL NEXTAD ; Retrieve first attacker
|
|
JNZ XC10
|
|
JMP RET ; Return if none
|
|
XC10: MOV BL,AL ; Save attacker value
|
|
CALL NEXTAD ; Get next defender
|
|
JZ XC18 ; Jump if none
|
|
LAHF
|
|
CMP CH,BL ; Attacked less than attacker ?
|
|
JNC XC19 ; No - jump
|
|
XC15: CMP AL,BL ; Defender less than attacker ?
|
|
JC RET ; Yes - return
|
|
CALL NEXTAD ; Retrieve next attacker value
|
|
JZ RET ; Return if none
|
|
MOV BL,AL ; Save attacker value
|
|
CALL NEXTAD ; Retrieve next defender value
|
|
JNZ XC15 ; Jump if none
|
|
XC18: LAHF
|
|
XC19: TEST CL,001H ; Attacker or defender ?
|
|
JZ XC20 ; Jump if defender
|
|
NEG CH ; Negate value for attacker
|
|
XC20: ADD DL,CH ; Total points lost
|
|
SAHF
|
|
JZ RET ; Return if none
|
|
MOV CH,BL ; Prev attckr becomes defender
|
|
JMP XC10 ; Jump
|
|
|
|
;***********************************************************
|
|
; NEXT ATTACKER/DEFENDER ROUTINE
|
|
;***********************************************************
|
|
; FUNCTION: -- To retrieve the next attacker or defender
|
|
; piece value from the attack list, and delete
|
|
; that piece from the list.
|
|
;
|
|
; CALLED BY: -- XCHNG
|
|
;
|
|
; CALLS: -- None
|
|
;
|
|
; ARGUMENTS: -- Attack list addresses.
|
|
; Side flag
|
|
; Attack list counts
|
|
;***********************************************************
|
|
NEXTAD: INC CL ; Increment side flag
|
|
XCHG BX,[HL]
|
|
XCHG DX,[DE]
|
|
XCHG CX,[BC] ; Swap registers
|
|
XCHG CH,CL ; Swap list counts
|
|
XCHG DX,BX ; Swap list pointers
|
|
XOR AL,AL
|
|
CMP AL,CH ; At end of list ?
|
|
JZ NX6 ; Yes - jump
|
|
DEC CH ; Decrement list count
|
|
NX5: INC BX ; Increment list pointer
|
|
CMP AL,[BX] ; Check next item in list
|
|
JZ NX5 ; Jump if empty
|
|
MOV AL,[BX] ; Get value from list
|
|
MOV AH,AL
|
|
SHR AH
|
|
SHR AH
|
|
SHR AH
|
|
SHR AH
|
|
MOV [BX],AH
|
|
AND AL,0FH
|
|
DEC BX ; Decrement list pointer
|
|
ADD AL,AL ; Double it
|
|
NX6: XCHG BX,[HL]
|
|
XCHG DX,[DE]
|
|
XCHG CX,[BC] ; Restore regs.
|
|
RET ; Return
|
|
|
|
;***********************************************************
|
|
; POINT EVALUATION ROUTINE
|
|
;***********************************************************
|
|
;FUNCTION: -- To perform a static board evaluation and
|
|
; derive a score for a given board position
|
|
;
|
|
; CALLED BY: -- FNDMOV
|
|
; EVAL
|
|
;
|
|
; CALLS: -- ATTACK
|
|
; XCHNG
|
|
; LIMIT
|
|
;
|
|
; ARGUMENTS: -- None
|
|
;***********************************************************
|
|
POINTS: XOR AL,AL ; Zero out variables
|
|
MOV [MTRL],AL
|
|
MOV [BRDC],AL
|
|
MOV [PTSL],AL
|
|
MOV [PTSW1],AL
|
|
MOV [PTSW2],AL
|
|
MOV [PTSCK],AL
|
|
MOV BX,T1 ; Set attacker flag
|
|
MOV B,[BX],7
|
|
MOV AL,21 ; Init to first square on board
|
|
PT5: MOV [M3],AL ; Save as board index
|
|
MOV SI,[M3] ; Load board index
|
|
MOV AL,[SI+BOARD] ; Get piece from board
|
|
CMP AL,-1 ; Off board edge ?
|
|
JNZ PT5A
|
|
JMP PT25 ; Yes - jump
|
|
PT5A: MOV BX,P1 ; Save piece, if any
|
|
MOV [BX],AL
|
|
AND AL,7 ; Save piece type, if any
|
|
MOV [T3],AL
|
|
CMP AL,KNIGHT ; Less than a Knight (Pawn) ?
|
|
JC PT6X ; Yes - Jump
|
|
CMP AL,ROOK ; Rook, Queen or King ?
|
|
JC PT6B ; No - jump
|
|
CMP AL,KING ; Is it a King ?
|
|
JZ PT6AA ; Yes - jump
|
|
MOV AL,[MOVENO] ; Get move number
|
|
CMP AL,7 ; Less than 7 ?
|
|
JC PT6A ; Yes - Jump
|
|
JMP PT6X ; Jump
|
|
PT6AA: TEST B,[BX],010H ; Castled yet ?
|
|
JZ PT6A ; No - jump
|
|
MOV AL,+6 ; Bonus for castling
|
|
TEST B,[BX],080H ; Check piece color
|
|
JZ PT6D ; Jump if white
|
|
MOV AL,-6 ; Bonus for black castling
|
|
JP PT6D ; Jump
|
|
PT6A: TEST B,[BX],008H ; Has piece moved yet ?
|
|
JZ PT6X ; No - jump
|
|
JP PT6C ; Jump
|
|
PT6B: TEST B,[BX],008H ; Has piece moved yet ?
|
|
JNZ PT6X ; Yes - jump
|
|
PT6C: MOV AL,-2 ; Two point penalty for white
|
|
TEST B,[BX],080H ; Check piece color
|
|
JZ PT6D ; Jump if white
|
|
MOV AL,+2 ; Two point penalty for black
|
|
PT6D: MOV BX,BRDC ; Get address of board control
|
|
ADD [BX],AL ; Add on penalty/bonus points
|
|
PT6X: XOR AX,AX ; Zero out attack list
|
|
MOV CX,7
|
|
MOV BX,ATKLST
|
|
XCHG DI,BX
|
|
CLD
|
|
REP
|
|
STOW
|
|
XCHG DI,BX
|
|
CALL ATTACK ; Build attack list for square
|
|
MOV BX,BACT ; Get black attacker count addr
|
|
MOV AL,[WACT] ; Get white attacker count
|
|
SUB AL,[BX] ; Compute count difference
|
|
MOV BX,BRDC ; Address of board control
|
|
ADD AL,[BX] ; Accum board control score
|
|
MOV [BX],AL ; Save
|
|
MOV AL,[P1] ; Get piece on current square
|
|
AND AL,AL ; Is it empty ?
|
|
JZ PT25 ; Yes - jump
|
|
CALL XCHNG ; Evaluate exchange, if any
|
|
XOR AL,AL ; Check for a loss
|
|
CMP AL,DL ; Points lost ?
|
|
JZ PT23 ; No - Jump
|
|
DEC DH ; Deduct half a Pawn value
|
|
MOV AL,[P1] ; Get piece under attack
|
|
XOR AL,[COLOR] ; Compare color of side just moved with piece
|
|
TEST AL,080H ; Do colors match ?
|
|
MOV AL,DL ; Points lost
|
|
JNZ PT20 ; Jump if no match
|
|
MOV BX,PTSL ; Previous max points lost
|
|
CMP AL,[BX] ; Compare to current value
|
|
JC PT23 ; Jump if greater than
|
|
MOV [BX],DL ; Store new value as max lost
|
|
MOV SI,[MLPTRJ] ; Load pointer to this move
|
|
MOV AL,[M3] ; Get position of lost piece
|
|
CMP AL,[SI+MLTOP] ; Is it the one moving ?
|
|
JNZ PT23 ; No - jump
|
|
MOV [PTSCK],AL ; Save position as a flag
|
|
JP PT23 ; Jump
|
|
PT20: MOV BX,PTSW1 ; Previous maximum points won
|
|
CMP AL,[BX] ; Compare to current value
|
|
JC PT21 ; Jump if greater than
|
|
MOV AL,[BX] ; Load previous max value
|
|
MOV [BX],DL ; Store new value as max won
|
|
PT21: MOV BX,PTSW2 ; Previous 2nd max points won
|
|
CMP AL,[BX] ; Compare to current value
|
|
JC PT23 ; Jump if greater than
|
|
MOV [BX],AL ; Store as new 2nd max lost
|
|
PT23: TEST B,[P1],080H ; Test piece color
|
|
MOV AL,DH ; Value of piece
|
|
JZ PT24 ; Jump if white
|
|
NEG AL ; Negate for black
|
|
PT24: MOV BX,MTRL ; Get addrs of material total
|
|
ADD AL,[BX] ; Add new value
|
|
MOV [BX],AL ; Store
|
|
PT25: MOV AL,[M3] ; Get current board position
|
|
INC AL ; Increment
|
|
CMP AL,99 ; At end of board ?
|
|
JZ PT25AA
|
|
JMP PT5 ; No - jump
|
|
PT25AA: MOV AL,[PTSCK] ; Moving piece lost flag
|
|
AND AL,AL ; Was it lost ?
|
|
JZ PT25A ; No - jump
|
|
MOV AL,[PTSW2] ; 2nd max points won
|
|
MOV [PTSW1],AL ; Store as max points won
|
|
XOR AL,AL ; Zero out 2nd max points won
|
|
MOV [PTSW2],AL
|
|
PT25A: MOV AL,[PTSL] ; Get max points lost
|
|
AND AL,AL ; Is it zero ?
|
|
JZ PT26 ; Yes - jump
|
|
DEC AL ; Decrement it
|
|
PT26: MOV CH,AL ; Save it
|
|
MOV AL,[PTSW1] ; Max,points won
|
|
AND AL,AL ; Is it zero ?
|
|
JZ PT27 ; Yes - jump
|
|
MOV AL,[PTSW2] ; 2nd max points won
|
|
AND AL,AL ; Is it zero ?
|
|
JZ PT27 ; Yes - jump
|
|
DEC AL ; Decrement it
|
|
SHR AL ; Divide it by 2
|
|
PT27: SUB AL,CH ; Subtract points lost
|
|
TEST B,[COLOR],080H ; Is color of side just moved white ?
|
|
JZ PT28 ; Yes - jump
|
|
NEG AL ; Negate for black
|
|
PT28: MOV BX,MTRL ; Net material on board
|
|
ADD AL,[BX] ; Add exchange adjustments
|
|
MOV BX,MV0 ; Material at ply 0
|
|
SUB AL,[BX] ; Subtract from current
|
|
MOV CH,AL ; Save
|
|
MOV AL,30 ; Load material limit
|
|
CALL LIMIT ; Limit to plus or minus value
|
|
MOV DL,AL ; Save limited value
|
|
MOV AL,[BRDC] ; Get board control points
|
|
MOV BX,BC0 ; Board control at ply zero
|
|
SUB AL,[BX] ; Get difference
|
|
MOV CH,AL ; Save
|
|
MOV AL,[PTSCK] ; Moving piece lost flag
|
|
AND AL,AL ; Is it zero ?
|
|
JZ PT29 ; Yes - jump
|
|
MOV CH,0 ; Zero board control points
|
|
PT29: MOV AL,6 ; Load board control limit
|
|
CALL LIMIT ; Limit to plus or minus value
|
|
MOV DH,AL ; Save limited value
|
|
MOV AL,DL ; Get material points
|
|
ADD AL,AL ; Multiply by 4
|
|
ADD AL,AL
|
|
ADD AL,DH ; Add board control
|
|
TEST B,[COLOR],080H ; Is color of side just moved white ?
|
|
JNZ PT30 ; No - jump
|
|
NEG AL ; Negate for white
|
|
PT30: ADD AL,80H ; Rescale score (neutral = 80H)
|
|
MOV [VALM],AL ; Save score
|
|
MOV SI,[MLPTRJ] ; Load move list pointer
|
|
MOV [SI+MLVAL],AL ; Save score in move list
|
|
RET ; Return
|
|
|
|
;***********************************************************
|
|
; LIMIT ROUTINE
|
|
;***********************************************************
|
|
; FUNCTION: -- To limit the magnitude of a given value
|
|
; to another given value.
|
|
;
|
|
; CALLED BY: -- POINTS
|
|
;
|
|
; CALLS: -- None
|
|
;
|
|
; ARGUMENTS: -- Input - Value, to be limited in the CH
|
|
; register.
|
|
; - Value to limit to in the AL register
|
|
; Output - Limited value in the AL register.
|
|
;***********************************************************
|
|
LIMIT: TEST CH,080H ; Is value negative ?
|
|
JZ LIM10 ; No - jump
|
|
NEG AL ; Make positive
|
|
CMP AL,CH ; Compare to limit
|
|
JNC RET ; Return if outside limit
|
|
MOV AL,CH ; Output value as is
|
|
RET ; Return
|
|
LIM10: CMP AL,CH ; Compare to limit
|
|
JC RET ; Return if outside limit
|
|
MOV AL,CH ; Output value as is
|
|
RET ; Return
|
|
|
|
;***********************************************************
|
|
; MOVE ROUTINE
|
|
;***********************************************************
|
|
; FUNCTION: -- To execute a move from the move list on the
|
|
; board array.
|
|
;
|
|
; CALLED BY: -- CPTRMV
|
|
; PLYRMV
|
|
; EVAL
|
|
; FNDMOV
|
|
; VALMOV
|
|
;
|
|
; CALLS: -- None
|
|
;
|
|
; ARGUMENTS: -- None
|
|
;***********************************************************
|
|
MOVE: MOV BX,[MLPTRJ] ; Load move list pointer
|
|
INC BX ; Increment past link bytes
|
|
INC BX
|
|
MV1: MOV AL,[BX] ; "From" position
|
|
MOV [M1],AL ; Save
|
|
INC BX ; Increment pointer
|
|
MOV AL,[BX] ; "To" position
|
|
MOV [M2],AL ; Save
|
|
INC BX ; Increment pointer
|
|
MOV DH,[BX] ; Get captured piece/flags
|
|
MOV SI,[M1] ; Load "from" pos board index
|
|
MOV DL,[SI+BOARD] ; Get piece moved
|
|
TEST DH,020H ; Test Pawn promotion flag
|
|
JNZ MV15 ; Jump if set
|
|
MOV AL,DL ; Piece moved
|
|
AND AL,7 ; Clear flag bits
|
|
CMP AL,QUEEN ; Is it a queen ?
|
|
JZ MV20 ; Yes - jump
|
|
CMP AL,KING ; Is it a king ?
|
|
JZ MV30 ; Yes - jump
|
|
MV5: MOV DI,[M2] ; Load "to" pos board index
|
|
OR DL,008H ; Set piece moved flag
|
|
MOV [DI+BOARD],DL ; Insert piece at new position
|
|
MOV B,[SI+BOARD],0 ; Empty previous position
|
|
TEST DH,040H ; Double move ?
|
|
JNZ MV40 ; Yes - jump
|
|
MOV AL,DH ; Get captured piece, if any
|
|
AND AL,7
|
|
CMP AL,QUEEN ; Was it a queen ?
|
|
JNZ RET ; No - return
|
|
MOV BX,POSQ ; Addr of saved Queen position
|
|
TEST DH,080H ; Is Queen white ?
|
|
JZ MV10 ; Yes - jump
|
|
INC BX ; Increment to black Queen pos
|
|
MV10: XOR AL,AL ; Set saved position to zero
|
|
MOV [BX],AL
|
|
RET ; Return
|
|
MV15: OR DL,004H ; Change Pawn to a Queen
|
|
JMP MV5 ; Jump
|
|
MV20: MOV BX,POSQ ; Addr of saved Queen position
|
|
MV21: TEST DL,080H ; Is Queen white ?
|
|
JZ MV22 ; Yes - jump
|
|
INC BX ; Increment to black Queen pos
|
|
MV22: MOV AL,[M2] ; Get new Queen position
|
|
MOV [BX],AL ; Save
|
|
JMP MV5 ; Jump
|
|
MV30: MOV BX,POSK ; Get saved King position
|
|
TEST DH,020H ; Castling ?
|
|
JZ MV21 ; No - jump
|
|
OR DL,010H ; Set King castled flag
|
|
JMP MV21 ; Jump
|
|
MV40: MOV BX,[MLPTRJ] ; Get move list pointer
|
|
ADD BX,8 ; Increment to next move
|
|
JMP MV1 ; Jump (2nd part of dbl move)
|
|
|
|
;***********************************************************
|
|
; UN-MOVE ROUTINE
|
|
;***********************************************************
|
|
; FUNCTION: -- To reverse the process of the move routine,
|
|
; thereby restoring the board array to its
|
|
; previous position.
|
|
;
|
|
; CALLED BY: -- VALMOV
|
|
; EVAL
|
|
; FNDMOV
|
|
; ASCEND
|
|
;
|
|
; CALLS: -- None
|
|
;
|
|
; ARGUMENTS: -- None
|
|
;***********************************************************
|
|
UNMOVE: MOV BX,[MLPTRJ] ; Load move list pointer
|
|
INC BX ; Increment past link bytes
|
|
INC BX
|
|
UM1: MOV AL,[BX] ; Get "from" position
|
|
MOV [M1],AL ; Save
|
|
INC BX ; Increment pointer
|
|
MOV AL,[BX] ; Get "to" position
|
|
MOV [M2],AL ; Save
|
|
INC BX ; Increment pointer
|
|
MOV DH,[BX] ; Get captured piece/flags
|
|
MOV SI,[M2] ; Load "to" pos board index
|
|
MOV DL,[SI+BOARD] ; Get piece moved
|
|
TEST DH,020H ; Was it a Pawn promotion ?
|
|
JNZ UM15 ; Yes - jump
|
|
MOV AL,DL ; Get piece moved
|
|
AND AL,7 ; Clear flag bits
|
|
CMP AL,QUEEN ; Was it a Queen ?
|
|
JZ UM20 ; Yes - jump
|
|
CMP AL,KING ; Was it a King ?
|
|
JZ UM30 ; Yes - jump
|
|
UM5: TEST DH,010H ; Is this 1st move for piece ?
|
|
JNZ UM16 ; Yes - jump
|
|
UM6: MOV DI,[M1] ; Load "from" pos board index
|
|
MOV [DI+BOARD],DL ; Return to previous board pos
|
|
MOV AL,DH ; Get captured piece, if any
|
|
AND AL,8FH ; Clear flags
|
|
MOV [SI+BOARD],AL ; Return to board
|
|
TEST DH,040H ; Was it a double move ?
|
|
JNZ UM40 ; Yes - jump
|
|
MOV AL,DH ; Get captured piece, if any
|
|
AND AL,7 ; Clear flag bits
|
|
CMP AL,QUEEN ; Was it a Queen ?
|
|
JNZ RET ; No - return
|
|
MOV BX,POSQ ; Address of saved Queen pos
|
|
TEST DH,080H ; Is Queen white ?
|
|
JZ UM10 ; Yes - jump
|
|
INC BX ; Increment to black Queen pos
|
|
UM10: MOV AL,[M2] ; Queen's previous position
|
|
MOV [BX],AL ; Save
|
|
RET ; Return
|
|
UM15: AND DL,0FBH ; Restore Queen to Pawn
|
|
JMP UM5 ; Jump
|
|
UM16: AND DL,0F7H ; Clear piece moved flag
|
|
JMP UM6 ; Jump
|
|
UM20: MOV BX,POSQ ; Addr of saved Queen position
|
|
UM21: TEST DL,080H ; Is Queen white ?
|
|
JZ UM22 ; Yes - jump
|
|
INC BX ; Increment to black Queen pos
|
|
UM22: MOV AL,[M1] ; Get previous position
|
|
MOV [BX],AL ; Save
|
|
JMP UM5 ; Jump
|
|
UM30: MOV BX,POSK ; Address of saved King pos
|
|
TEST DH,040H ; Was it a castle ?
|
|
JZ UM21 ; No - jump
|
|
AND DL,0EFH ; Clear castled flag
|
|
JMP UM21 ; Jump
|
|
UM40: MOV BX,[MLPTRJ] ; Load move list pointer
|
|
ADD BX,8 ; Increment to next move
|
|
JMP UM1 ; Jump (2nd part of dbl move)
|
|
|
|
;***********************************************************
|
|
; SORT ROUTINE
|
|
;***********************************************************
|
|
; FUNCTION: -- To sort the move list in order of
|
|
; increasing move value scores.
|
|
;
|
|
; CALLED BY: -- FNDMOV
|
|
;
|
|
; CALLS: -- EVAL
|
|
;
|
|
; ARGUMENTS: -- None
|
|
;***********************************************************
|
|
SORTM: MOV CX,[MLPTRI] ; Move list begin pointer
|
|
MOV DX,0 ; Initialize working pointers
|
|
SR5: MOV BH,CH
|
|
MOV BL,CL
|
|
MOV CL,[BX] ; Link to next move
|
|
INC BX
|
|
MOV CH,[BX]
|
|
MOV [BX],DH ; Store to link in list
|
|
DEC BX
|
|
MOV [BX],DL
|
|
XOR AL,AL ; End of list ?
|
|
CMP AL,CH
|
|
JZ RET ; Yes - return
|
|
SR10: MOV [MLPTRJ],CX ; Save list pointer
|
|
CALL EVAL ; Evaluate move
|
|
MOV BX,[MLPTRI] ; Begining of move list
|
|
MOV CX,[MLPTRJ] ; Restore list pointer
|
|
SR15: MOV DL,[BX] ; Next move for compare
|
|
INC BX
|
|
MOV DH,[BX]
|
|
XOR AL,AL ; At end of list ?
|
|
CMP AL,DH
|
|
JZ SR25 ; Yes - jump
|
|
MOV SI,DX ; Transfer move pointer
|
|
MOV AL,[VALM] ; Get new move value
|
|
CMP AL,[SI+MLVAL] ; Less than list value ?
|
|
JNC SR30 ; No - jump
|
|
SR25: MOV [BX],CH ; Link new move into list
|
|
DEC BX
|
|
MOV [BX],CL
|
|
JMP SR5 ; Jump
|
|
SR30: XCHG DX,BX ; Swap pointers
|
|
JMP SR15 ; Jump
|
|
|
|
;***********************************************************
|
|
; EVALUATION ROUTINE
|
|
;***********************************************************
|
|
; FUNCTION: -- To evaluate a given move in the move list.
|
|
; It first makes the move on the board, then if
|
|
; the move is legal, it evaluates it, and then
|
|
; restores the board position.
|
|
;
|
|
; CALLED BY: -- SORT
|
|
;
|
|
; CALLS: -- MOVE
|
|
; INCHK
|
|
; PINFND
|
|
; POINTS
|
|
; UNMOVE
|
|
;
|
|
; ARGUMENTS: -- None
|
|
;***********************************************************
|
|
EVAL: CALL MOVE ; Make move on the board array
|
|
CALL INCHK ; Determine if move is legal
|
|
AND AL,AL ; Legal move ?
|
|
JZ EV5 ; Yes - jump
|
|
XOR AL,AL ; Score of zero
|
|
MOV [VALM],AL ; For illegal move
|
|
JMP UNMOVE ; Jump
|
|
EV5: CALL PINFND ; Compile pinned list
|
|
CALL POINTS ; Assign points to move
|
|
JMP UNMOVE ; Restore board array
|
|
|
|
;***********************************************************
|
|
; FIND MOVE ROUTINE
|
|
;***********************************************************
|
|
; FUNCTION: -- To determine the computer's best move by
|
|
; performing a depth first tree search using
|
|
; the techniques of alpha-beta pruning.
|
|
;
|
|
; CALLED BY: -- CPTRMV
|
|
;
|
|
; CALLS: -- PINFND
|
|
; POINTS
|
|
; GENMOV
|
|
; SORTM
|
|
; ASCEND
|
|
; UNMOVE
|
|
;
|
|
; ARGUMENTS: -- None
|
|
;***********************************************************
|
|
FNDMOV: MOV AL,[MOVENO] ; Current move number
|
|
CMP AL,1 ; First move ?
|
|
JNZ L0003
|
|
CALL BOOK ; Yes - execute book opening
|
|
L0003:
|
|
XOR AL,AL ; Initialize ply number to zero
|
|
MOV [NPLY],AL
|
|
MOV BX,0 ; Initialize best move to zero
|
|
MOV [BESTM],BX
|
|
MOV BX,MLIST ; Initialize ply list pointers
|
|
MOV [MLNXT],BX
|
|
MOV BX,PLYIX-2
|
|
MOV [MLPTRI],BX
|
|
MOV AL,[KOLOR] ; Initialize color
|
|
MOV [COLOR],AL
|
|
MOV BX,SCORE ; Initialize score index
|
|
MOV [SCRIX],BX
|
|
MOV AL,[PLYMAX] ; Get max ply number
|
|
ADD AL,2 ; Add 2
|
|
MOV CH,AL ; Save as counter
|
|
XOR AL,AL ; Zero out score table
|
|
FM1: MOV [BX],AL
|
|
INC BX
|
|
DEC CH
|
|
JNZ FM1
|
|
MOV [BC0],AL ; Zero ply 0 board control
|
|
MOV [MV0],AL ; Zero ply 0 material
|
|
CALL PINFND ; Compile pin list
|
|
CALL POINTS ; Evaluate board at ply 0
|
|
MOV AL,[BRDC] ; Get board control points
|
|
MOV [BC0],AL ; Save
|
|
MOV AL,[MTRL] ; Get material count
|
|
MOV [MV0],AL ; Save
|
|
FM5: MOV BX,NPLY ; Address of ply counter
|
|
INC B,[BX] ; Increment ply count
|
|
XOR AL,AL ; Initialize mate flag
|
|
MOV [MATEF],AL
|
|
CALL GENMOV ; Generate list of moves
|
|
MOV AL,[NPLY] ; Current ply counter
|
|
MOV BX,PLYMAX ; Address of maximum ply number
|
|
CMP AL,[BX] ; At max ply ?
|
|
JNC L0004
|
|
CALL SORTM ; No - call sort
|
|
L0004:
|
|
MOV BX,[MLPTRI] ; Load ply index pointer
|
|
MOV [MLPTRJ],BX ; Save as last move pointer
|
|
FM15: MOV BX,[MLPTRJ] ; Load last move pointer
|
|
MOV DL,[BX] ; Get next move pointer
|
|
INC BX
|
|
MOV DH,[BX]
|
|
MOV AL,DH
|
|
AND AL,AL ; End of move list ?
|
|
JNZ FM15A
|
|
JMP FM25 ; Yes - jump
|
|
FM15A: MOV [MLPTRJ],DX ; Save current move pointer
|
|
MOV BX,[MLPTRI] ; Save in ply pointer list
|
|
MOV [BX],DL
|
|
INC BX
|
|
MOV [BX],DH
|
|
MOV AL,[NPLY] ; Current ply counter
|
|
MOV BX,PLYMAX ; Maximum ply number ?
|
|
CMP AL,[BX] ; Compare
|
|
JC FM18 ; Jump if not max
|
|
CALL MOVE ; Execute move on board array
|
|
CALL INCHK ; Check for legal move
|
|
AND AL,AL ; Is move legal
|
|
JZ FM16 ; Yes - jump
|
|
CALL UNMOVE ; Restore board position
|
|
JMP FM15 ; Jump
|
|
FM16: MOV AL,[NPLY] ; Get ply counter
|
|
MOV BX,PLYMAX ; Max ply number
|
|
CMP AL,[BX] ; Beyond max ply ?
|
|
JZ FM17
|
|
JMP FM35 ; Yes - jump
|
|
FM17: MOV AL,[COLOR] ; Get current color
|
|
XOR AL,80H ; Get opposite color
|
|
CALL INCHK1 ; Determine if King is in check
|
|
AND AL,AL ; In check ?
|
|
JZ FM35 ; No - jump
|
|
JMP FM19 ; Jump (One more ply for check)
|
|
FM18: MOV SI,[MLPTRJ] ; Load move pointer
|
|
MOV AL,[SI+MLVAL] ; Get move score
|
|
AND AL,AL ; Is it zero (illegal move) ?
|
|
JZ FM15 ; Yes - jump
|
|
CALL MOVE ; Execute move on board array
|
|
FM19: XOR B,[COLOR],80H ; Toggle color, is new color white ?
|
|
JS FM20 ; No - jump
|
|
INC B,[MOVENO] ; Increment move number
|
|
FM20: MOV BX,[SCRIX] ; Load score table pointer
|
|
MOV AL,[BX] ; Get score two plys above
|
|
INC BX ; Increment to current ply
|
|
MOV [SCRIX],BX ; Save it
|
|
INC BX
|
|
MOV [BX],AL ; Save score as initial value
|
|
JMP FM5 ; Jump
|
|
FM25: MOV AL,[MATEF] ; Get mate flag
|
|
AND AL,AL ; Checkmate or stalemate ?
|
|
JNZ FM30 ; No - jump
|
|
MOV AL,[CKFLG] ; Get check flag
|
|
AND AL,AL ; Was King in check ?
|
|
MOV AL,80H ; Pre-set stalemate score
|
|
JZ FM36 ; No - jump (stalemate)
|
|
MOV AL,[MOVENO] ; Get move number
|
|
MOV [PMATE],AL ; Save
|
|
MOV AL,0FFH ; Pre-set checkmate score
|
|
JMP FM36 ; Jump
|
|
FM30: MOV AL,[NPLY] ; Get ply counter
|
|
CMP AL,1 ; At top of tree ?
|
|
JZ RET ; Yes - return
|
|
CALL ASCEND ; Ascend one ply in tree
|
|
MOV BX,[SCRIX] ; Load score table pointer
|
|
INC BX ; Increment to current ply
|
|
INC BX
|
|
MOV AL,[BX] ; Get score
|
|
DEC BX ; Restore pointer
|
|
DEC BX
|
|
JMP FM37 ; Jump
|
|
JFM15: JMP FM15
|
|
FM35: CALL PINFND ; Compile pin list
|
|
CALL POINTS ; Evaluate move
|
|
CALL UNMOVE ; Restore board position
|
|
MOV AL,[VALM] ; Get value of move
|
|
FM36: OR B,[MATEF],001H ; Set mate flag
|
|
MOV BX,[SCRIX] ; Load score table pointer
|
|
FM37: CMP AL,[BX] ; Compare to score 2 ply above
|
|
JC FM40 ; Jump if less
|
|
JZ FM40 ; Jump if equal
|
|
NEG AL ; Negate score
|
|
INC BX ; Incr score table pointer
|
|
CMP AL,[BX] ; Compare to score 1 ply above
|
|
JC JFM15 ; Jump if less than
|
|
JZ JFM15 ; Jump if equal
|
|
MOV [BX],AL ; Save as new score 1 ply above
|
|
MOV AL,[NPLY] ; Get current ply counter
|
|
CMP AL,1 ; At top of tree ?
|
|
JNZ JFM15 ; No - jump
|
|
MOV BX,[MLPTRJ] ; Load current move pointer
|
|
MOV [BESTM],BX ; Save as best move pointer
|
|
MOV AL,[SCORE+1] ; Get best move score
|
|
CMP AL,0FFH ; Was it a checkmate ?
|
|
JNZ JFM15 ; No - jump
|
|
MOV BX,PLYMAX ; Get maximum ply number
|
|
SUB B,[BX],2 ; Subtract 2
|
|
MOV AL,[KOLOR] ; Get computer's color
|
|
TEST AL,080H ; Is it white ?
|
|
JZ RET ; Yes - return
|
|
MOV BX,PMATE ; Checkmate move number
|
|
DEC B,[BX] ; Decrement
|
|
RET ; Return
|
|
FM40: CALL ASCEND ; Ascend one ply in tree
|
|
JMP FM15 ; Jump
|
|
|
|
;***********************************************************
|
|
; ASCEND TREE ROUTINE
|
|
;***********************************************************
|
|
; FUNCTION: -- To adjust all necessary parameters to
|
|
; ascend one ply in the tree.
|
|
;
|
|
; CALLED BY: -- FNDMOV
|
|
;
|
|
; CALLS: -- UNMOVE
|
|
;
|
|
; ARGUMENTS: -- None
|
|
;***********************************************************
|
|
ASCEND: XOR B,[COLOR],80H ; Toggle color, is new color white ?
|
|
JNS AC5 ; Yes - jump
|
|
DEC B,[MOVENO] ; Decrement move number
|
|
AC5: DEC [SCRIX] ; Decrement score table index
|
|
DEC B,[NPLY] ; Decrement ply counter
|
|
MOV BX,[MLPTRI] ; Load ply list pointer
|
|
DEC BX ; Load pointer to move list top
|
|
DEC BX
|
|
MOV DX,[BX]
|
|
MOV [MLNXT],DX ; Update move list avail ptr
|
|
DEC BX ; Get ptr to next move to undo
|
|
DEC BX
|
|
MOV DX,[BX]
|
|
MOV [MLPTRI],BX ; Save new ply list pointer
|
|
MOV [MLPTRJ],DX ; Save next move pointer
|
|
JMP UNMOVE ; Restore board to previous ply
|
|
|
|
;***********************************************************
|
|
; ONE MOVE BOOK OPENING
|
|
; **********************************************************
|
|
; FUNCTION: -- To provide an opening book of a single
|
|
; move.
|
|
;
|
|
; CALLED BY: -- FNDMOV
|
|
;
|
|
; CALLS: -- None
|
|
;
|
|
; ARGUMENTS: -- None
|
|
;***********************************************************
|
|
BOOK: POP AX
|
|
MOV B,[SCORE+1],0 ; Zero out score table
|
|
MOV [BESTM],BMOVES-2 ; Init best move ptr to book
|
|
MOV BX,BESTM ; Initialize address of pointer
|
|
MOV AL,[KOLOR] ; Get computer's color
|
|
AND AL,AL ; Is it white ?
|
|
JNZ BM5 ; No - jump
|
|
MOV AL,0 ; Load random number (0)
|
|
TEST AL,001H ; Test random bit
|
|
JZ RET ; Return if zero (P-K4)
|
|
ADD B,[BX],3 ; P-Q4
|
|
RET ; Return
|
|
BM5: ADD B,[BX],6 ; Increment to black moves
|
|
MOV SI,[MLPTRJ] ; Pointer to opponents 1st move
|
|
MOV AL,[SI+MLFRP] ; Get "from" position
|
|
CMP AL,22 ; Is it a Queen Knight move ?
|
|
JZ BM9 ; Yes - Jump
|
|
CMP AL,27 ; Is it a King Knight move ?
|
|
JZ BM9 ; Yes - jump
|
|
CMP AL,34 ; Is it a Queen Pawn ?
|
|
JZ BM9 ; Yes - jump
|
|
JC RET ; If Queen side Pawn opening -
|
|
; return (P-K4)
|
|
CMP AL,35 ; Is it a King Pawn ?
|
|
JZ RET ; Yes - return (P-K4)
|
|
BM9: ADD B,[BX],3 ; (P-Q4)
|
|
RET ; Return to CPTRMV
|
|
|
|
;***********************************************************
|
|
; COMPUTER MOVE ROUTINE
|
|
;***********************************************************
|
|
; FUNCTION: -- To control the search for the computers move
|
|
; and the display of that move on the board
|
|
; and in the move list.
|
|
;
|
|
; CALLED BY: -- DRIVER
|
|
;
|
|
; CALLS: -- FNDMOV
|
|
; FCDMAT
|
|
; MOVE
|
|
; BITASN
|
|
; INCHK
|
|
;
|
|
; ARGUMENTS: -- None
|
|
;***********************************************************
|
|
CPTRMV: CALL FNDMOV ; Select best move
|
|
MOV BX,[BESTM] ; Move list pointer variable
|
|
MOV [MLPTRJ],BX ; Pointer to move data
|
|
MOV AL,[SCORE+1] ; To check for mates
|
|
CMP AL,1 ; Mate against computer ?
|
|
JNZ CP0C ; No - jump
|
|
MOV CL,1 ; Computer mate flag
|
|
CALL FCDMAT ; Full checkmate ?
|
|
CP0C: CALL MOVE ; Produce move on board array
|
|
MOV SI,[MLPTRJ] ; Get pointer to move
|
|
MOV DH,[SI+MLTOP] ; "To" position of the move
|
|
CALL BITASN ; Convert to Ascii
|
|
MOV [MVEMSG+3],BX ; Put in move message
|
|
MOV DH,[SI+MLFRP] ; "From" position of the move
|
|
CALL BITASN ; Convert to Ascii
|
|
MOV [MVEMSG],BX ; Put in move message
|
|
MOV DX,MVEMSG ; Output move
|
|
MOV CL,PRINTBUF
|
|
CALL SYSTEM
|
|
CP1C: MOV AL,[COLOR] ; Should computer call check ?
|
|
MOV CH,AL
|
|
XOR AL,80H ; Toggle color
|
|
MOV [COLOR],AL
|
|
CALL INCHK ; Check for check
|
|
AND AL,AL ; Is enemy in check ?
|
|
MOV AL,CH ; Restore color
|
|
MOV [COLOR],AL
|
|
JZ CP24 ; No - return
|
|
MOV DX,CKMSG ; Output "check"
|
|
MOV CL,PRINTBUF
|
|
CALL SYSTEM
|
|
CP24: MOV AL,[SCORE+1] ; Check again for mates
|
|
CMP AL,0FFH ; Player mated ?
|
|
JNZ RET ; No - return
|
|
MOV CL,0 ; Set player mate flag
|
|
CALL FCDMAT ; Full checkmate ?
|
|
RET ; Return
|
|
|
|
;***********************************************************
|
|
; FORCED MATE HANDLING
|
|
;***********************************************************
|
|
; FUNCTION: -- To examine situations where there exits
|
|
; a forced mate and determine whether or
|
|
; not the current move is checkmate. If it is,
|
|
; a losing player is offered another game,
|
|
; while a loss for the computer signals the
|
|
; King to tip over in resignation.
|
|
;
|
|
; CALLED BY: -- CPTRMV
|
|
;
|
|
; CALLS: -- None
|
|
;
|
|
; ARGUMENTS: -- The only value passed in a register is the
|
|
; flag which tells FCDMAT whether the computer
|
|
; or the player is mated.
|
|
;***********************************************************
|
|
FCDMAT: MOV AL,[MOVENO] ; Current move number
|
|
MOV CH,AL ; Save
|
|
MOV AL,[PMATE] ; Move number where mate occurs
|
|
SUB AL,CH ; Number of moves till mate
|
|
AND AL,AL ; Checkmate ?
|
|
JNZ RET ; No - return
|
|
RCR AH
|
|
TEST CL,001H ; Check flag for who is mated
|
|
RCL AH
|
|
JZ FM04 ; Jump if player
|
|
MOV DX,CKMSG ; Print "CHECK"
|
|
MOV CL,PRINTBUF
|
|
CALL SYSTEM
|
|
MOV DX,UWIN ; Output "YOU WIN"
|
|
MOV CL,PRINTBUF
|
|
CALL SYSTEM
|
|
JP FM08 ; Jump
|
|
FM04: MOV DX,CKMSG ; Print "CHECK"
|
|
MOV CL,PRINTBUF
|
|
CALL SYSTEM
|
|
MOV DX,IWIN ; Output "I WIN"
|
|
MOV CL,PRINTBUF
|
|
CALL SYSTEM
|
|
FM08: POP BX ; Remove return addresses
|
|
POP BX
|
|
MOV CL,INCHAR ; Input any char to play again
|
|
CALL SYSTEM
|
|
JMP DRIVER ; Jump (Rest of game init)
|
|
|
|
;***********************************************************
|
|
; BOARD INDEX TO ASCII SQUARE NAME
|
|
;***********************************************************
|
|
; FUNCTION: -- To translate a hexadecimal index in the
|
|
; board array into an ascii description
|
|
; of the square in algebraic chess notation.
|
|
;
|
|
; CALLED BY: -- CPTRMV
|
|
;
|
|
; CALLS: -- DIVIDE
|
|
;
|
|
; ARGUMENTS: -- Board index input in register DH and the
|
|
; Ascii square name is output in register BX.
|
|
;***********************************************************
|
|
BITASN: SUB AL,AL ; Get ready for division
|
|
MOV DL,10
|
|
CALL DIVIDE ; Divide
|
|
DEC DH ; Get rank on 1-8 basis
|
|
ADD AL,60H ; Convert file to Ascii (a-h)
|
|
MOV BL,AL ; Save
|
|
MOV AL,DH ; Rank
|
|
ADD AL,30H ; Convert rank to Ascii (1-8)
|
|
MOV BH,AL ; Save
|
|
RET ; Return
|
|
|
|
;***********************************************************
|
|
; PLAYERS MOVE ANALYSIS
|
|
;***********************************************************
|
|
; FUNCTION: -- To accept and validate the players move
|
|
; Also allows player to resign the game by
|
|
; entering R.
|
|
;
|
|
; CALLED BY: -- DRIVER
|
|
;
|
|
; CALLS: -- ASNTBI
|
|
; VALMOV
|
|
;
|
|
; ARGUMENTS: -- None
|
|
;***********************************************************
|
|
PLYRMV: MOV DX,BUFFER ; Ask for input
|
|
MOV CL,INBUF
|
|
CALL SYSTEM
|
|
MOV DX,CRLF ; Output CRLF
|
|
MOV CL,PRINTBUF
|
|
CALL SYSTEM
|
|
MOV BX,BUFFER+1 ; Point to input length
|
|
MOV AL,[BX] ; Get input length
|
|
OR AL,AL ; Empty ?
|
|
JZ PLYRMV ; Jump if empty
|
|
MOV CH,AL ; Save length
|
|
LAHF
|
|
INC BX ; Point to actual buffer
|
|
SAHF
|
|
MOV AL,[BX] ; Get first char
|
|
CMP AL,"R" ; Restart game ?
|
|
JNZ PL05 ; Jump if not restart
|
|
JMP DRIVER
|
|
PL05: MOV AL,CH ; Get input length
|
|
CMP AL,5 ; Long enough ?
|
|
JC PL08 ; Jump if less than 5 chars
|
|
CALL ASNTBI ; Convert "from" to a board index
|
|
JC PL08 ; Jump if invalid
|
|
MOV [MVEMSG],AL ; Move list "from" position
|
|
CALL ATBINX ; Convert "to" to a board index
|
|
JC PL08 ; Jump if invalid
|
|
MOV [MVEMSG+1],AL ; Move list "to" position
|
|
CALL VALMOV ; Determines if a legal move
|
|
OR AL,AL ; Legal ?
|
|
JZ RET ; Yes - return
|
|
PL08: MOV DX,INVAL ; Output "INVALID MOVE--TRY AGAIN"
|
|
MOV CL,PRINTBUF
|
|
CALL SYSTEM
|
|
JP PLYRMV ; Jump
|
|
|
|
;***********************************************************
|
|
; ASCII SQUARE NAME TO BOARD INDEX
|
|
;***********************************************************
|
|
; FUNCTION: -- To convert an algebraic square name in
|
|
; Ascii to a hexadecimal board index.
|
|
; This routine also checks the input for
|
|
; validity.
|
|
;
|
|
; CALLED BY: -- PLYRMV
|
|
;
|
|
; CALLS: -- None
|
|
;
|
|
; ARGUMENTS: -- Accepts the square name in pointer BX
|
|
; and outputs the board index in register AL.
|
|
; CF = 0 if ok. CF = 1 if invalid.
|
|
;***********************************************************
|
|
ATBINX: INC BX ; Increment pointer to skip a char
|
|
ASNTBI: MOV AL,[BX] ; Ascii file letter (a - h)
|
|
INC BX
|
|
SUB AL,41H ; File 1 - 8
|
|
JC RET ; Not file letter
|
|
CMP AL,8 ; Check upper bound
|
|
CMC
|
|
JC RET ; Invalid
|
|
MOV CH,AL
|
|
MOV AL,[BX]
|
|
SUB AL,31H ; Rank 1 - 8
|
|
JC RET
|
|
CMP AL,8 ; Check upper bound
|
|
CMC
|
|
JC RET
|
|
ADD AL,AL ; Multiply rank by 10
|
|
MOV CL,AL
|
|
ADD AL,AL
|
|
ADD AL,AL
|
|
ADD AL,CL
|
|
ADD AL,CH ; 10 * rank + file
|
|
INC BX ; Increment pointer
|
|
ADD AL,21
|
|
RET ; Return
|
|
|
|
;***********************************************************
|
|
; VALIDATE MOVE SUBROUTINE
|
|
;***********************************************************
|
|
; FUNCTION: -- To check a players move for validity.
|
|
;
|
|
; CALLED BY: -- PLYRMV
|
|
;
|
|
; CALLS: -- GENMOV
|
|
; MOVE
|
|
; INCHK
|
|
; UNMOVE
|
|
;
|
|
; ARGUMENTS: -- Returns flag in register AL, 0 for valid
|
|
; and 1 for invalid move.
|
|
;***********************************************************
|
|
VALMOV: MOV BX,[MLPTRJ] ; Save last move pointer
|
|
PUSH BX ; Save register
|
|
MOV AL,[KOLOR] ; Computers color
|
|
XOR AL,80H ; Toggle color
|
|
MOV [COLOR],AL ; Store
|
|
MOV BX,PLYIX-2 ; Load move list index
|
|
MOV [MLPTRI],BX
|
|
MOV BX,MLIST+1024 ; Next available list pointer
|
|
MOV [MLNXT],BX
|
|
CALL GENMOV ; Generate opponents moves
|
|
MOV SI,MLIST+1024 ; Index to start of moves
|
|
VA5: MOV AL,[MVEMSG] ; "From" position
|
|
CMP AL,[SI+MLFRP] ; Is it in list ?
|
|
JNZ VA6 ; No - jump
|
|
MOV AL,[MVEMSG+1] ; "To" position
|
|
CMP AL,[SI+MLTOP] ; Is it in list ?
|
|
JZ VA7 ; Yes - jump
|
|
VA6: MOV DL,[SI+MLPTR] ; Pointer to next list move
|
|
MOV DH,[SI+MLPTR+1]
|
|
XOR AL,AL ; At end of list ?
|
|
CMP AL,DH
|
|
JZ VA10 ; Yes - jump
|
|
PUSH DX ; Move to SI register
|
|
POP SI
|
|
JP VA5 ; Jump
|
|
VA7: MOV [MLPTRJ],SI ; Save opponents move pointer
|
|
CALL MOVE ; Make move on board array
|
|
CALL INCHK ; Was it a legal move ?
|
|
AND AL,AL
|
|
JNZ VA9 ; No - jump
|
|
VA8: POP BX ; Restore saved register
|
|
RET ; Return
|
|
VA9: CALL UNMOVE ; Un-do move on board array
|
|
VA10: MOV AL,1 ; Set flag for invalid move
|
|
POP BX ; Restore saved register
|
|
MOV [MLPTRJ],BX ; Save move pointer
|
|
RET ; Return
|
|
|
|
;***********************************************************
|
|
; POSITIVE INTEGER DIVISION
|
|
;***********************************************************
|
|
DIVIDE: PUSH CX
|
|
MOV CH,8
|
|
DD04: SAL DH
|
|
RCL AL
|
|
SUB AL,DL
|
|
JS DD05
|
|
INC DH
|
|
JP DD06
|
|
DD05: ADD AL,DL
|
|
DD06: DEC CH
|
|
JNZ DD04
|
|
POP CX
|
|
RET
|
|
|
|
CLRMSG: DB 13,10,"Choose your color (W/B): $"
|
|
PLYDEP: DB 13,10,"Ply depth (1-6): $"
|
|
MVEMSG: DB " ",13,10,"$"
|
|
CKMSG: DB "CHECK",13,10,"$"
|
|
UWIN: DB "You win",13,10,"$"
|
|
IWIN: DB "I win"
|
|
CRLF: DB 13,10,"$"
|
|
INVAL: DB "INVALID MOVE--TRY AGAIN",13,10,"$"
|
|
BUFFER: DB 7
|
|
DS 6
|
|
|
|
IX: DS 2
|
|
IY: DS 2
|
|
BC: DS 2
|
|
DE: DS 2
|
|
HL: DS 2
|
|
|