diff --git a/CHESS.ASM b/CHESS.ASM new file mode 100644 index 0000000..000e82a --- /dev/null +++ b/CHESS.ASM @@ -0,0 +1,2234 @@ +;*********************************************************** +; +; 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 + \ No newline at end of file diff --git a/CHESS.DOC b/CHESS.DOC new file mode 100644 index 0000000..7e0eb05 --- /dev/null +++ b/CHESS.DOC @@ -0,0 +1,20 @@ +This chess game uses algebraic chess notation. The files are lettered +"a" to "h" and the ranks are numbered 1 to 8. The lower left-hand corner +(from White's viewpoint) is a1. + +Moves are entered as ff-tt (f=from, t=to), so to play the white king's +pawn up two squares you would enter E2-E4. You must enter your file +letters in upper case, while the computer will always use lower case. + +To castle, enter only the king's move. The computer castles the same way. +To capture En Passant, enter your pawn's actual move. + +Ply depth is the number of half-turns the computer looks ahead. For +example, with a ply depth of 3, the computer will consider + 1. All of his possible moves + 2. All of your responses to those moves. + 3. All of his possible replies to your responses. +Start at ply depth 2 to get the feel for it. + +A move of "R" will restart the game. + \ No newline at end of file